Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Kjør koden og så hva som skjer! Sjekk spesielt hva som skjer om du flytter spiller-figuren inn i de andre figurene.

Steg 4: Kollisjonssjekk

Hvis du fikk kjørt koden og den virket som forventet, så oppdaget du sikkert at spiller-figuren kunne kjøres rett over (eller under avhengig av rekkefølgen i FXML-fila). I et virkelig spill er det viktig å sjekke om spilleren kolliderer med ulike typer figurer og sørge for riktig effekt. F.eks. skal en ikke kunne gå gjennom vegger, dersom en støtter borti farlige ting så skal spilleren kanskje dø og noen ting skal en kanskje kunne plukke opp. Så først må en kunne sjekke om spilleren kolliderer, så kan en etterpå bestemme reaksjonen ut fra hva slags figur spilleren kræsjet i.

JavaFX har innebygde metoder for å sjekke om en figur overlapper med en annen. Så hvis en for hver gang spilleren flytter, sjekker om den overlapper med en av de andre figurene, så er en på god vei. Her er liksom-kode for dette:

Code Block
for hver figur i panelet:
	hvis figur ikke er spiller-figuren:
		hvis figur overlapper med spiller-figuren så:
			skriv beskjed om kollisjon

Det er greit å få tak i spiller-figuren, den ligger jo i player-variablen, men hvordan får en tak i alle (de andre) figurene? Det går an å lage en fx:id og variabel for hver figur, slik vi gjorde med spiller-figuren. Men det er fryktelig mye jobb, hvis vi har mange figurer. Derfor gir vi heller navn til hovedpanelet, slik at vi kan gå gjennom alle figurene som ligger inni det! Legg derfor inn en fx:id i FXML-koden for hovedpanelet og lag en tilsvarende variabel i FigurstyringController-klassen. Her er koden jeg har laget for variabelen:

Code Block
languagejava
@FXML
AnchorPane room; // bruk room som fx:id i FXML-koden

Nå kan vi fylle inn ordentlig kode i keyPressed-metoden, istedenfor liksom-koden:

Code Block
@FXML
void keyPressed(KeyEvent keyEvent) {


	... som over ...

	Bounds playerBounds = player.getBoundsInParent();
	for (Node child : room.getChildrenUnmodifiable()) {
		if (child != player) {
			Bounds childBounds = child.getBoundsInParent();
			if (playerBounds.intersects(childBounds)) {
				System.out.println("Kræsj!!!");
			}
		}
	}
}

Her har vi en for-løkke som går gjennom alle figurene som ligger inn i hovedpanelet. Hvor hver runde i lista vil child-variablene være en ny figur.

Hvis denne er ulike spilleren (child != player) så sjekker vi om de overlapper (eng: intersects) og i tilfelle skriver vi ut en beskjed.

Kjør koden, styr spiller-figuren bort til de ulike figurene og se hva som skjer!

 

P.S. Egentlig så sjekker vi ikke om figurene overlapper, men om en tenkt firkant (Bounds) rundt dem overlapper. Dette er enklere å finne ut, men det betyr også at det blir nokså unøyaktig, spesielt når en har runde figurer som den PacMan-aktige spilleren, den røde ovalen og den grønne sirkelen. Det går an å lage smartere kode for dette, men det er litt vanskelig så vi venter med det til senere...

Steg 5: Ulike reaksjon avhengig av hva en kolliderer med

Det som nå gjenstår er å lage kode som gjør ulike ting avhengig av hvilken (type) figur som spiller-figuren kræsjer med. Trikset er å få lagt inn en merkelapp i hver figur om hva slags type figur det er.

Med SceneBuilder, så gjør du som følger:

  • Velg en av figurene, f.eks. den røde ovalen, enten i tegnepanelet eller i element-treet nede til venstre.
  • Velg så Properties-seksjonen i egenskaper-panelet til høyre.
  • Finn Style Class-egenskapen i JavaFX CSS-gruppa.
  • Fyll inn dangerShape, evt. et annet navn (bare vanlige bokstaver)

Det skal se ut omtrent som i figuren til høyre.

Gjør tilsvarende for de andre figurene, men velg andre navn, f.eks. wallShape og targetShape, så du får ulike typer figurer.

Image Added

Koden som du skrev over må nå utvides slik at du skriver ut ulike beskjeder når du kolliderer med de ulike figurene. Bruk child.getStyleClass().contains("dangerShape") for å sjekke om figuren har dangerShape-merkelappen. Se om du klarer å legge inn if-setninger som sjekker for hver av de ulike merkelappene og skriver ut en egen beskjed for hver.

Til slutt får du en liten nøtte-oppgave: Det skal være umulig å gå inn i en vegg. Hvis merkelappen er wallShape så skal figuren altså ikke flytte seg likevel! Hint: Hvis spiller-figuren kræsjer i en vegg, så flytt spiller-figuren tilbake (altså like langt i motsatt retning).

Hva har du lært?

  • å få JavaFX til å kalle en metode automatisk når en tast trykkes ned
  • å flytte en figur avhengig av hvilken tast som trykkes
  • å klassifisere figurer med styleClass-attributtet
  • å sjekke om spiller kolliderer (overlapper) med andre figurer
  • å reagere på ulikt vis avhengig av hva slags type figur som spilleren treffer på

...