Kollisioner med cirklar

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.

bild

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).

bild

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.

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) );

bild

Ladda gärna hem exemplet nedan och läs igenom koden och prova!

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *

Scroll to top