Bookmark and Share

Svårighetsgrad
Svårighetsgrad
Betyg (9 röster)
BetygBetygBetygBetygBetyg
 

Kollisioner med rektanglar

Kollisionshantering och beräkningar är självklart en viktig del i spel. Den modell för kollisioner som presenteras i denna artikel lämpar sig såklart inte i alla situationer utan snarast i de allra enklaste av fall. Planerar du att göra spel som t.ex. Pong, Breakout eller Space Invaders däremot så fungerar modellen väl.

I spel så har vi oftast en massa föremål som ska ritas ut. Dessa föremål måste ha variabler/data som beskriver:

Utöver detta så behöver vi också veta när två föremål kolliderar med varandra. Vi börjar med ett exempel på ett rymdskepp och en meteor. Vi utgår från att du redan kan hantera positioner, hastigheter och grafik och kan rita ut något liknande:

bild

Kollisioner

Hur ska vi nu kunna avgöra om dessa två föremål kolliderar eller ej? Till vår hjälp ska vi nu använda klassen Rectangle som du tidigare använt vid uppritning. Denna datatyp är perfekt för att skapa rektanglar runt våra föremål. Datatypen finns i namnutrymmet System.Drawing, men om du använder XNA så finns det redan en datatyp vid namn Rectangle. Problemet är bara att de fungerar lite olika men vi kommer att använda oss av XNA i detta exempel.

Okej, vi testar att skapa två variabler av typen Rectangle som ska "rama in" våra föremål.

Vi anger fasta värden på bredd och höjd (48x60 för player osv.). Variablerna playerX, playerY, meteorX och meteorY har vi sedan tidigare för att hålla reda på var på skärmen föremålen är. Dessa är av typen double. Därför är vi tvungna att konvertera värdet på variablerna till int när vi skapar rektangeln.

Detta kallas typecasting!

Det går till som i exemplet ovan att man skriver (int) framför variabeln som man vill "kasta om" till en annan datatyp temporärt. Detta gör man främst med talvariabler såsom int, float, char, byte och double. Det går t.ex. inte med variabler av typen string.

Åter till våra boxar. Kommer vi att se dem på skärmen? Nej, självklart inte eftersom vi inte kommer att rita ut dem. Det är också hela poängen med dessa rektanglar, de kommer att användas för att avgöra om vi har kollisioner eller inte. Jag har ändå valt att rita ut rektanglarna så att ni får en bild av hur det fungerar.

bild

Hur avgör jag nu om de kolliderar?

Jo, det finns en inbyggd funktion i datatypen Rectangle som gör att en rektangel kan avgöra om den kolliderar med en annan rektangel. Funktionen kallas för Intersects och svarar ja eller nej. På dataspråk kallas det för en bool och har värdet true eller false.

Det kan se ut såhär:

På så sätt vet vi när vi kolliderar. Har du flera föremål, kanske i en List, så får du göra en loop för att sköta kollideringen mellan t.ex. player och alla andra föremål. Du måste då även ha alla rektanglar i en lista av rektanglar för att det ska fungera smidigt.

Uppdatering av rektanglar

Vi får inte glömma att flytta med rektanglarna varje gång vi flyttar våra föremål. Annars blir de ju genast värdelösa! Rektanglarna måste hela tiden spegla var föremålen finns. Om vi inte uppdaterar så kommer det att se ut såhär:

bild

Kommer vi att veta att vi har kolliderat? Nej, vi måste göra en uppdatering av rektanglarna hela tiden av typ:

Notera typecastingen igen.

Nu kommer det att se ut som:

bild

Den överlappande rektangeln har jag markerat med rött. Vi kan nu såklart avgöra att vi har kolliderat. Vad vi ska göra när vi väl kolliderar är en annan historia.

Överlappande rektanglar

Tyvärr finns det ingen funktion i XNA för att räkna fram den överlappande rektangeln när vi väl kolliderar, som den röda rektangeln i bilderna. En funktion som räknar ut den överlappande rektangeln skulle kunna se ut såhär:

DEMO

Koden för att räkna ut den överlappande rektangeln tillsammans används i detta demo. Grafiken som används är:

bild

Skeppet följer muspositionerna och om det finns en överlappande rektangel så ritas det ut ett rött område.

Viktiga begrepp

  • typecasting/typomvandling (eng. typecasting)

Kommentarer

1 inlägg