Versjon 4 av sjakk med JavaFX og FXML
Så langt har en kunne flytt alle brikkene når som helst, men nå innfører vi hvilke spiller sin tur det er, og legger til muligheten for å flytte brikker ved å klikke på dem og på til-ruta.
Endringer i Chess
Hvilken spiller sin tur det er, regnes som spill-logikk, som må inn i Chess
-klassen.
Vi innfører et boolean
-felt kalt whitesTurn
og en tilsvarende is
-metode.
Det legges til en ekstra sjekk i move
-metoden på fargen på brikken som flyttes, og
hvis trekket gjennomføres så byttes hvilken spiller som har turen.
Endringer i FXML-koden
For å kunne støtte klikking på både rute og brikke, så må vi fikse litt på FXML-koden.
Som med flytt-knappen, må vi si fra hvilken kontroller-metode som skal trigges av klikk på rute og brikke.
Klikking tilsvarer mouseClicked
-hendelsen, så vi legger til et mouseClicked
-attributt på alle Rectangle
- og Label
-elementer
som tilsvarer ruter og brikker:
...
<Rectangle fx:id="a8s" onMouseClicked="#handleClickSquare" ... />
...
<Label fx:id="a8" ... onMouseClicked="#handleClickPiece">
...
Vi bruker ulike metoder for de to typene klikk. Merk også at vi har lagt inn et fx:id
på Rectangle
-elementet,
slik at vi kan referere til det fra kontrolleren vha. en variabel med samme navn.
Endringer i kontrolleren
Kontrolleren må utvides med metoder for håndtering av klikk, i tråd med endringene gjort i FXML-koden.
Når man klikker på en brikke, så kalles handleClickPiece
-metoden automagisk, og det skal tilsvare å oppgi ruta den står på som fra-rute i et flytt.
Problemet er å finne rute-koordinatene, når vi har lagt opp til at samme metode trigges av klikk på alle Label
-objektene.
Løsningen er todelt:
-
Vi lar
handleClickPiece
-metoden ta inn etMouseEvent
-objekt, som er et såkalt hendelsesobjekt med informasjon om hvilket GUI-objekt klikket var på. Dermed kan én og samme metode håndtere klikk på flere GUI-objekter og likevel skille dem fra hverandre. GUI-objektet får en tak i ved å kalle hendelsesobjektet singetSource
-metode. -
Vi har allerede en liste av
Label
-objekter i en egnet rekkefølge, og lager oss en tilsvarende forRectangle
-objektene som tilsvarer rutene. Posisjonen i lista hvor vi finner objektet som ble klikket på, kan brukes til å beregne både kolonnen og raden til ruta. Logikken blir den motsatte av den som brukes iupdateBoar
-metoden for å finneLabel
-objektet for en gitt brikke.
Når en har funnet rute-koordinatene så kan en legge dem inn i det tilsvarende innfyllingsfeltet, klikket blir på en måte en svarvei for å fylle det inn.
Klikker man på en av brikkene til den som har turen, så registreres hvilken brikke som er valgt vha. setSelectedPiece
-metoden.
updateBoard
-metoden er oppdatert til å endre bakgrunnsfargen til brikken som er valgt. Hvis en klikker på en motstander-brikke (eller en rute),
så oppdateres til-feltet og trekket utføres (om det er lovlig).
Visuelle effekter og CSS
Vanligvis endres visuelle effekter ved å endre spesifikke egenskaper vha. set-metoder. F.eks. kan skriftstypen til en Label
endres ved å kalle setFont
-metoden. Bakgrunnsfargen til en Label
settes imidlertid vha. en generell styling-mekanisme ala den som brukes med HTML og kalles [CSS](https://en.wikipedia.org/wiki/Cascading_Style_Sheets). Bakgrunnsfargen til en spesifikk Label
angis vha. -fx-backgroundcolor
-stilen slik:
label.setStyle("-fx-background-color: #c8c4e3;");
En bygger altså opp en String
på et bestemt format og kaller setStyle
. Flere egenskaper kan settes ved å legge dem etter hverandre.
En kan også lage stilregler som knyttes til et helt panel, vindu eller FXML-fil, slik en gjør med HTML. Les mer om hvordan dette fungerer og om hvilke visuelle egenskaper som kan settes på denne måten.