Hoppa till innehållet

Programmera spel i C++ för nybörjare/Studsande boll

Från Wikibooks


Baserat på VC++ 2010 express, Win 7 och SFML 1.6, du bör ha gjort installationerna för ett fungerande SFML-fönster i ditt projekt innan du börjar.

Hur får man saker att studsa på kanterna? Det är den enklaste formen av kollisionsberäkning men samtidigt grunden för tidiga spel som Pong och Space invaders.

Anta att du har en fyrkantig spelplan. I spelplanen finns en boll. Den bollen får inte gå utanför kanten. Hur gör man då? Skaffa en bollsprite med genomskinlig bakgrund (om du vill att den skall se snygg ut). Jag snodde en 24x24 pixels bild (th_Bag_Dive_Ball_Sprite.png) och döpte om den till ”bollsprite.png” Bilden finns på: http://s601.photobucket.com/albums/tt92/Thehellkidd/Pokemon/?start=20

Placera den i samma mapp som main.cpp filen, (se i exemplet med sprites hur man gör) så att programmet kan hitta bilden. Eftersom bollens hastighet skall styras utifrån är det bäst att ha en variabel i början som definierar bollens hastighet. Fördelen med att ha en variabel deklarerad i början är att den går att ändra ganska lätt. Utöver det måste vi hela tiden veta var bollen är i förhållande till väggarna för att se om den slår i någonstans.

Kommer du ihåg hur vi fick fram koordinaterna för kon och pojken i det andra exemplet med pojken och kon? Ange variablerna på samma sätt i början.

float  bollX=0.0f; //bollens x-koordinat
float  bollY=0.0f; //bollens y-koordinat

Vi måste också veta vilken hastighet vi skall ha på bollen, och hastigheten är detsamma som hur många steg den rör sig i X- och Y-led. Så även dessa variabler skall ändras, jag kallar dem fartX och fartY:

float fartX = 0.5f; //rörelse i xled
float fartY = 0.5f; //rörelse i yled

Jag gav dem 0.5f för enkelhetens skull, du kan ta vilket värde du vill. Vill du att den skall gå snabbare kan du alltid göra så att farten ökar 0.05f varje gång bollen träffar en vägg…

Placera sedan ut bollen en pixel in så att den inte aktiverar kollisionen direkt från början. boll.SetPosition(1.0f,1.0f); //Placera ut bilden i övre vänstra hörnet

Hur vet vi då om vi krockar? I loopen ser vi om vi krockar med höger vägg genom att se om bollens x >(800-24), dvs. spelfönstrets bredd – bollbildens bredd. Kom ihåg att man räknar bildens position utifrån dess övre vänstra hörn. Om den slår in i väggen skall den få ett negativt x-värde så att den går åt vänster istället.

bollX = boll.GetPosition().x;
if (bollx  > 766) //slår in I högervägg
fartX = fartX * -1; //spegelvänd riktning
Tumregel, multiplikation med negativa tal:
-2 * -2 = 4 (negativt  *  negativt blir positivt)
-2 * 2 = -4 (negativt * positivt blir negativt)
2 * -2 = -4 (positivt * negativt blir negativt)
2 * 2 = 4   (positivt * positivt blir positivt)

Bara genom att multiplicera med -1 byter vi alltså riktning eftersom det gör negativa tal positiva och positiva tal negativa.

Så kan vi göra med alla riktningarna:

if (bollX > 766 || bollX < 0 ) //den slår in i höger- eller vänsterväggen			   
fartX = fartX * -1; //spegelvänd riktning
				   
else if (bollY > 576 || bollY < 0) //den slår in neder- eller överväggen
fartY =  fartY * -1; //spegelvänd riktning

|| är tecknet för ”eller”. Det kan översättas som:

Om bollen är 766 pixlar från vänster vägg, eller har sitt övre vänstra hörn på en negativ del i koordinatsystemets x-axel (utanför skärmen åt vänster) så byt riktning.

Provkör koden.

#include <iostream>
#include <SFML\System.hpp>
#include <SFML\Graphics.hpp>
#include <SFML\Window.hpp>


int main() 
   {  //Början av programkörningen

	 float  bollX=0.0f; //x position för bollen
        float  bollY=0.0f; //y position för bollen
	 float fartX = 0.5f; //rörelse i xled
	 float fartY = 0.5f; //rörelse i yled

   sf::RenderWindow App(sf::VideoMode(800, 600, 32), "SFML studsande boll"); // Skapa fönstret vi skall visa färgerna i
 

        sf::Image bollbild; //skapa en tom bildhållare som heter bollbild
        if (!bollbild.LoadFromFile("ballsprite.png")) return EXIT_FAILURE; //fyll den tomma bildhållaren med 
                                                                     // bilden ballsprite.png  bilden är 24x24
        sf::Sprite boll(bollbild); //Skapar den grafiska spelpjäsen boll med grafiken från bollbild
		 boll.SetPosition(1.0f,1.0f); //Placera ut bilden i övre vänstra hörnet


        while (App.IsOpened())  // Start spel-loopen
      {  //while 1
         sf::Event Event; 

            while (App.GetEvent(Event)) // Ta hand om händelser 
            { //while 2

              if (Event.Type == sf::Event::Closed) //kryssat på [x] symbolen? stäng programmet
              App.Close(); 

                     if (Event.Type == sf::Event::KeyPressed) // En tangent har tryckts ner

                                    { //if 1

                               if (Event.Key.Code == sf::Key::Escape) // ESC tangenten = stäng programmet
                               App.Close(); 

                                       } //slut if 1

                            } //slut, while 2

		bollX=boll.GetPosition().x; //var är bollen i x-led
		bollY=boll.GetPosition().y; //var är bollen i y-led


                   if (bollX > 766 || bollX < 0 ) //den slår in i höger- eller vänsterväggen			   
                   fartX = fartX * -1; //spegelvänd riktning
				   
	           else if (bollY > 576 || bollY < 0) //den slår in neder- eller överväggen
                  fartY =  fartY * -1; //spegelvänd riktning

                  boll.Move(fartX,fartY); //bollen skickas iväg

                App.Clear(sf::Color(0, 0, 0)); //rensa allt i fönstret och ersätt med svart färg
                App.Draw(boll); //Rita upp figuren på den yta spelaren ser
                App.Display(); //visa upp ändringarna för användaren

} //slut, while 1

return 0;
} //slut på programkörningen