Programmera spel i C++ för nybörjare/Pingis
Utseende
För att kunna spela det här spelet krävs följande
- en bild av en boll 24x24 som heter ball.png
- en bild av ett racket som heter racket.png och är 16 x 64 pixels stort
- Ett typsnitt som heter ELEPHNT.TTF
- Ett ljud som heter Wall_Hit.ogg
- Ett ljud som heter Paddle_Hit.ogg
- Ett ljud som heter Ball_Out.ogg
- Ett bakgrundsljud som heter bakgrund_ping_pong.ogg
Du startar spelet genom att trycka ner space-tangenten. Du styr höger racket med pil upp/ner och vänser racket med W- och S-tangenterna. Om man tävlar två mot varandra gäller det att inte förlora 5 bollar, om man har lagtävlingar gäller det att ha bollen i spel så länge som möjligt, man har 5 bollar på sig. Tiden syns i den lilla texten i botten medan poängen 0-5 syns i överkanten.
Kod:
#include <iostream>
#include <string> //För att kunna skriva ut resultaten på skärmen
#include <SFML\System.hpp>
#include <SFML\Window.hpp>
#include <SFML\Graphics.hpp>
#include <sstream> //För att kunna konvertera siffror till text
#include <SFML\Audio.hpp> //För att få ljud
using namespace std; // utifall att konsollen behövs för felsökning
//Funktioner------------------
char poang2char(int poang); //för att förvandla poängen från int till char.
string Tal2String(double siffrain); //För att förvandla tiden från klockan till en text att skriva ut
int main (int argc, char *argv)
{ //Början av programkörningen
float bollX=0.0f; //x position för bollen
float bollY=0.0f; //y position för bollen
float racketY=0.0f; //y position för racketen
float racket1Y=0.0f; //y position för höger racket
float fartX = 0.0f; //rörelse i xled
float fartY = 0.0f; //rörelse i yled, liten vinkel för lämplig rörelse
double tidsomgott = 0.0f; //Om man vill tävla om hur länge man kan ha bollen i luften
bool deadball = true; //Avgör om bollen har hamnat utanför och inte skjutits iväg
int poangvanster = 0; //vem får poäng?
int poanghoger = 0; //vem får poäng?
char temptext[20]={0}; //Behövs för att skapa en string av 0-0 resultat
//+ texten vinnare
char vinnareleft[30] = {'V','I','N','N','A','R','E',' ','V','Ä',
'N','S','T','E','R',' ','S','I','D','A',
'!','\n ','5',' ', '-',' '};
char vinnareright[30] = {' ',' ','-',' ', '5','\n ','V','I','N','N','A','R','E',' ','H','Ö',
'G','E','R',' ','S','I','D','A',
'!'};
bool gameover = false; //Har någon nått 5p?
//Kolla video mode för fullskärmsläge
sf::VideoMode Mode = sf::VideoMode::GetDesktopMode();
//Variabler för skärmen i fullskärmsläge.
int fonsterbredd = Mode.Width;
int fonsterhojd = Mode.Height;
int fargdjup=Mode.BitsPerPixel;
sf::WindowSettings Settings; //skapa ett SFML fönster
//Sätt det till fullscreen
sf::RenderWindow App(sf::VideoMode(Mode.Width, Mode.Height, Mode.BitsPerPixel), "SQUASH", sf::Style::Fullscreen, Settings); // Skapa fönstret vi skall visa ping pong i
float ElapsedTime = App.GetFrameTime(); //Skapar en konstant för att hålla hastigheten likvärdig på olika datorer
sf::Clock Clock; //en spelklocka för att hålla reda på hur länge man spelat
tidsomgott = Clock.GetElapsedTime();
//Ladda in ljudfilerna----------------------------------------------------------------------
sf::SoundBuffer paddlehit; //skapa en ljudbuffer/hållare
if (!paddlehit.LoadFromFile("Paddle_Hit.ogg")) //ladda in en fil I hållaren
{
// Error...
}
sf::Sound Traeff_racket; //skapa ett ljud för en racketträff
Traeff_racket.SetBuffer(paddlehit); // Ladda in ljudfilens värden i ljudet så att det går att spela upp.
//---
sf::SoundBuffer wallhit; //skapa en ljudbuffer/hållare
if (!wallhit.LoadFromFile("Wall_Hit.ogg")) //ladda in en fil I hållaren
{
// Error...
}
sf::Sound Traeff_wall; //skapa ett ljud för en vägg
Traeff_wall.SetBuffer(wallhit); // Ladda in ljudfilens värden i ljudet så att det går att spela upp.
//---
sf::SoundBuffer ballout; //skapa en ljudbuffer/hållare
if (!ballout.LoadFromFile("Ball_Out.ogg")) //ladda in en fil I hållaren
{
// Error...
}
sf::Sound Ball_Out; //skapa ett ljud för en vägg
Ball_Out.SetBuffer(ballout); // Ladda in ljudfilens värden i ljudet så att det går att spela upp.
//---
sf::Music bakgrundsmusik; //skapa filhållare
if (!bakgrundsmusik.OpenFromFile("bakgrund_ping_pong.ogg"))//fyll hållaren med din fil
{
// Error...
}
bakgrundsmusik.SetLoop(true); //få den att gå runt runt
bakgrundsmusik.Play(); //spela, obs versal i Play.
//Lada in text och typsnitt--------------------------------------
//Ladda in ett typsnitt
sf::Font resultatfont; //ladda en tom font
if (!resultatfont.LoadFromFile("ELEPHNT.TTF", 50)) return EXIT_FAILURE;
//Se till så att ttf-fonten finns i samma mapp som main.cpp
sf::String resultat_ut; //skapa en textremsa för resultaten
resultat_ut.SetText("0 - 0");
resultat_ut.SetFont(resultatfont); //Tilldelas typsnittet
resultat_ut.SetColor(sf::Color(255, 255, 255));//Vit färg
resultat_ut.SetPosition(fonsterbredd/2-35, 10.f); //placera ut texten halva x och 100 i y led
sf::String tid_ut; //skapa en textremsa för hur lång tid man spelat
tid_ut.SetText("0");
tid_ut.SetFont(resultatfont); //Tilldelas typsnittet
tid_ut.SetColor(sf::Color(255, 255, 255));//Vit färg
tid_ut.SetPosition(fonsterbredd/2-35, fonsterhojd-50.f); //placera ut texten halva x och långt ner i y led
//Ladda in bilderna
sf::Image bollbild; //skapa en tom bildhållare som heter Image
if (!bollbild.LoadFromFile("ball.png")) return EXIT_FAILURE; //fyll den tomma bildhållaren med bilden boll.png
//bilden är 24x24
sf::Sprite boll(bollbild); //Skapar den grafiska spelpjäsen boll med grafiken från bollbild
boll.SetPosition(1.0f,fonsterhojd/2-12); //Placera ut bilden mitt på kortsidan
sf::Image racketbild; //skapa en tom bildhållare som heter racket
if (!racketbild.LoadFromFile("racket.png")) return EXIT_FAILURE; //fyll den tomma bildhållaren med bilden racket.png
//bilden är 16x64
sf::Sprite racket(racketbild); //Skapar den grafiska spelpjäsen racket med grafiken från racketbild
racket.SetPosition(1.0f, (fonsterhojd/2 - 32)); //Placera ut bilden mitt på vänsterkanten
sf::Image racketbild1; //skapa en tom bildhållare som heter rackettbild1
//om man har samma bild till bägge racketarna är det bättre att använda samma bild, dvs:
//if (!racketbild1.LoadFromFile("racket.png")) return EXIT_FAILURE;
if (!racketbild1.LoadFromFile("racket.png")) return EXIT_FAILURE; //fyll den tomma bildhållaren med bilden racket.png
//bilden är 16x64
sf::Sprite racket1(racketbild1); //Skapar den grafiska spelpjäsen racket1 med grafiken från racketbild
racket1.SetPosition(fonsterbredd-17, fonsterhojd/2 - 32); //Placera ut bilden längs höger kant
while (App.IsOpened()) // Start spel-loopen
{ //while 1
sf::Event Event;
while (App.GetEvent(Event)) // Ta hand om händelser som tangentnedtryckning
{ //while 2
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
ElapsedTime = App.GetFrameTime(); //för att få en konstant hastighet på olika datorer
racketY=racket.GetPosition().y; //var är racket i y-led på vänster sida
racket1Y=racket1.GetPosition().y; //var är racket1 i y-led på höger sida
if (App.GetInput().IsKeyDown(sf::Key::Space) && fartX==0.0f)
//starta om bollen om farten är 0
{
fartX = (200.0f + sf::Randomizer::Random(0, 50))* ElapsedTime;//Rörelse i X-led
fartY = (10.0f + sf::Randomizer::Random(0, 5)) * ElapsedTime; //rörelse i yled, liten, liten vinkel
Traeff_racket.Play();
//Spela upp ljud
deadball = false; //Bollen är i spel igen
}
//Styr racketarna upp och ner längs spelplanens sidor
if (App.GetInput().IsKeyDown(sf::Key::W))
{
if (racketY > 0)
racket.Move(0, -700 * ElapsedTime); //racket upp
}
if (App.GetInput().IsKeyDown(sf::Key::S))
{
if (racketY < fonsterhojd - 64)
racket.Move(0, 700 * ElapsedTime); //racket ner
}
if (App.GetInput().IsKeyDown(sf::Key::Up))
{
if (racket1Y > 0)
racket1.Move(0, -700 * ElapsedTime); //racket 1 upp
}
if (App.GetInput().IsKeyDown(sf::Key::Down))
{
if (racket1Y < fonsterhojd - 64)
racket1.Move(0, 700 * ElapsedTime); //racket 1ner
}
bollX=boll.GetPosition().x; //var är bollen i x-led
bollY=boll.GetPosition().y; //var är bollen i y-led
if (bollX > fonsterbredd - 24 )
{ //den slår in i högerväggen
if(racket1Y - bollY < 24 && bollY - racket1Y < 64)
//om skillnaden mellan bollens höjd (24) och kanten på racketen
//är mindre än och om bollen träffar racketen (64hög) hågonstans…
{//om racket träffar
fartX = fartX * -1; //spegelvänd riktning
//annars försvinner bollen
//Låt dessutom bollens hastighet öka.
fartX = fartX - 0.1f; //rörelse i xled
fartY = fartY - 0.1f; //rörelse i yled
Traeff_racket.Play(); //Spela upp ljud
}//slut om racket träffar
else
{//Om racket inte träffar, bollen går ut genom höger sida
boll.SetPosition(1.0f,racketY+20); //på vänster racket.
fartX = 0.0f; //ingen fart
fartY = 0.0f; //ingenfart
poangvanster = poangvanster +1; //ge vänster spelare ett extra poäng
deadball = true; //Bollen är ur spel
Ball_Out.Play(); //Spela ljud förlorad boll
if (poangvanster >=5) //Man har uppnått 5p
gameover = true;
}//slut om racket inte träffar
}//slut på att se om den träffar högervägg
if( bollX < 0 ) //den slår in i vänsterväggen
{ //träffar den racketen?
if(racketY - bollY < 24 && bollY - racketY < 64)
//om skillnaden mellan bollens höjd (24) och kanten på racketen
//är mindre än och om bollen träffar racketen (64hög) hågonstans…
{//om racket träffar
fartX = fartX * -1; //spegelvänd riktning
//annars försvinner bollen
//Låt dessutom bollens hastighet öka.
fartX = fartX + 0.1f; //rörelse i xled
fartY = fartY + 0.1f; //rörelse i yled
//Spela upp ljud
Traeff_racket.Play();
}//slut om racket träffar
else
{//Om racket inte träffar
boll.SetPosition(fonsterbredd - 24,racket1Y+20); //Vänster sida
fartX = 0.0f; //ingen fart
fartY = 0.0f; //ingenfart
poanghoger = poanghoger +1; //Ge högerspelaren ett poäng till
deadball = true; //Bollen är ur spel
Ball_Out.Play(); //Spela ljud förlorad boll
if (poanghoger >=5) //Man har uppnått 5p
gameover = true; //Spelet är över
}//slut om racket inte träffar
}//slut på att se om den träffar racketen
else if (bollY > fonsterhojd - 24 || bollY < 0) //den slår in neder- eller överväggen
{
fartY = fartY * -1; //spegelvänd riktning
Traeff_wall.Play();
}
//Skicka iväg bollen med sina nya koordinater
boll.Move(fartX,fartY); //bollen skickas iväg
//Lägg in resultatsiffrorna för utskrift. Max 5 i resultat
resultat_ut.SetText("");//Se till så att det inte finns text kvar
temptext[0] = poang2char(poangvanster);
temptext[1] = ' ';
temptext[2] = '-';
temptext[3] = ' ';
temptext[4] = poang2char(poanghoger);
if (gameover == false)
{
resultat_ut.SetText(temptext);
}
else
if (poangvanster >=5 && gameover == true)
{
vinnareleft[26] = poang2char(poanghoger); //Skriv ut att vänster vunnit
resultat_ut.SetText(vinnareleft);
deadball=true; //Bollen kan inte spelas
}
else
if (poanghoger >=5 && gameover == true)
{
vinnareright[0] = poang2char(poangvanster);//Skriv ut att höger vunnit
resultat_ut.SetText(vinnareright);
deadball=true; //Bollen kan inte spelas
}
if (deadball == false)//Om bollen är i spel
{
tidsomgott = (tidsomgott + Clock.GetElapsedTime()); //Hur lång tid av partiet har gått
}
tid_ut.SetSize(14);//Liten storlek på talen som ritas ut
tid_ut.SetText(Tal2String(tidsomgott)); //Konvertera tiden till en textremsa som kan skrivas ut.
//Rita ut allting på spelplanen
App.Clear(sf::Color(0, 0, 0)); //rensa allt i fönstret och ersätt med svart färg
App.Draw(sf::Shape::Rectangle(fonsterbredd/2-1, 0, fonsterbredd/2+1, fonsterhojd , sf::Color(255, 0, 0) ));
App.Draw(boll); //Rita upp figuren på den yta spelaren ser
App.Draw(racket); //Rita upp figuren på den yta spelaren ser
App.Draw(racket1); //Rita upp racketen längs höger vägg
App.Draw(resultat_ut); //rita ut de valda bokstäverna
App.Draw(tid_ut); //rita ut den tid som gått
App.Display(); //visa upp ändringarna för användaren
} //slut, while 1
return 0;
} //slut på programkörningen
//Funktionsbeskrivningar---------------------------------------------------------------------
char poang2char(int poang)
{
char utchar ='X';
if ( poang == 0)
utchar = '0';
else if ( poang == 1)
utchar = '1';
else if ( poang == 2)
utchar = '2';
else if ( poang == 3)
utchar = '3';
else if ( poang == 4)
utchar = '4';
else if ( poang == 5)
utchar = '5';
else
utchar ='X';
return utchar;
}
string Tal2String(double siffrain)
{ //Förvandlar ett tal till text
//Detta kräver: #include <sstream>
// och: using namespace std;
std::string s;
std::stringstream out;
out << siffrain;
s = out.str();
return s;
}