Inledning
Rektanglar kan var bra i många fall men det är inte alltid en rektangulär form passar bäst. Vi ska nu se hur man kan använda cirklar för att bestämma kollisioner.
En cirkel har en mittposition och som bekant en radie som bestämmer storleken på cirkel. För att illustrera detta så kan vi ta en titt på bilden nedan. Grafiken i detta exempel har ritats i Photoshop och den tänkta cirkeln kring skeppet och meteoriten har ritats med grön toning.
Matematik
Visst låter det skrämmande? Faktum är att vi ska använda oss av klassisk matematik i form av Pythagoras sats. För att repetera detta så kan vi åter igen titta på en bild (nedan).
Med denna formel kan vi alltså räkna ut olika sidor i en rätvinklig triangel givet att vi har minst två sidor. Vi ska snart se att vi alltid kan använda denna formel för att räkna ut avståndet mellan två punkter.
Praktik
Vi behöver några variabler som beskriver var på skärmen föremålen är samt vilken radie de har.
//Positioner
double playerX, playerY;
double meteorX = 300, meteorY = 200;
//Radier
double playerRadie = 24;
double meteorRadie = 55;
Eftersom "var på skärmen" måste vara centrum för föremålet så måste vi även ändra lite på uppritningen. Om vi drar ifrån halva föremålets höjd och bredd från X och Y-positionerna vid uppritning så kommer föremålen att centreras kring dess positioner.
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(meteor, new Rectangle((int)meteorX -55, (int)meteorY-55, 110, 110), Color.White);
spriteBatch.Draw(ship, new Rectangle((int)playerX-24, (int)playerY-30, 48, 60), Color.White);
if (bHit)
{
spriteBatch.Draw(hit, new Rectangle(150, 10, 150, 50), Color.White);
}
spriteBatch.End();
base.Draw(gameTime);
}
Avståndet mellan två föremål får inte vara mindre än summan av deras radie. Tänk dig två olika bollar framför dig. När du för dem tillsammans mot varandra så befinner sig alltid centrumpositionerna med avståndet radie + radie ifrån varandra. Dags för nästa bild.
Vi kan vid uppdateringsdelen i programmet nu räkna ut två sidor av en rätvinklig triangel. Skillnaden i X-positioner som vi kallar för xdiff och skillnader i Y-positioner som vi kallar för ydiff. Sedan är det bara att räkna ut avståndet (hypotenusan) med Pythagoras sats. Skulle avståndet vara mindre än summan av radierna så har vi alltså en kollision.
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
MouseState m = Mouse.GetState();
playerX = m.X;
playerY = m.Y;
//Kolla om vi kolliderar
double xdiff = playerX - meteorX;
double ydiff = playerY - meteorY;
if ((xdiff * xdiff + ydiff * ydiff) < (playerRadie + meteorRadie)*(playerRadie + meteorRadie))
{
bHit = true;
}
else
{
bHit = false;
}
base.Update(gameTime);
}
Notera att vi jämför värdena i kvadrat. Det är ingen större mening att beräkna roten ur, det skulle faktiskt bara krångla till det. Vill du ändå ha det exakta avståndet mellan två föremål så måste du ta roten ur t.ex genom:
double distance = Math.Sqrt( (xdiff * xdiff + ydiff * ydiff) );
Ladda gärna hem exemplet nedan och läs igenom koden och prova!