Gamesdust
usr.mnu
zoeken

Home
Nieuws
Reviews
Previews
Columns
Walkthroughs
English
Forum

Login

Registreer

Hoe maak ik een game? Les 2: if, while en ons eerste spel!

Door: Switchboy op: 2014-05-07, 5351 views

ArtikellogoAltijd al een game willen maken, maar weet je niet waar je moet beginnen? Of lijkt het je te moeilijk? Dan zijn deze lessen voor jou! Games maken is namelijk helemaal niet moeilijk en zelfs leuk! En met deze lessen leer je stap voor stap hoe het moet!

Deze les gaat ervan uit dat je de introductie en de vorige les hebt gevolgd.

Aan het einde van deze les kan je:
- Twee variabelen met elkaar vergelijken
- Het programma vervolgens een bepaalde actie uit laten voeren
- Het programma een actie laten uitvoeren totdat een variabele voldoet aan een conditie
- Een manier om een random getal te genereren
- Je eerste “game” af!

Aan het einde van de vorige les hadden we een hele simpele rekenmachine. Maar dat programma had een achilleshiel. En als je het programma aan je kleine broertje of neefje hebt laten zien snap je al wat ik bedoel. Het programma controleerde niet of wat er ingevuld is geen onzin was. Je kan het programma laten crashen door er in plaats van een getal, letters in te typen!

Het programma skipte dan meteen helemaal door naar het einde en negeerde zelfs de “std::cin.get();”.
Hoe kunnen we dat oplossen?

Wat er gebeurd is dat de ingevoerde waarde, een letter, niet in een int variabele kan worden opgeslagen. Cin(); geeft een waarschuwing en laat alles wat ingetyped is in de buffer staan. Hierdoor wordt op de volgende plaatsen waar cin gebruikt wordt de nieuwe input genegeerd en wordt weer geprobeerd de buffer in de variabele te laden. Wat dus weer mislukt!

Kunnen we dit oplossen? Ja gelukkig houd cin ook bij of het inladen van de variabele goed of fout is gegaan. Dit kan je in je programme oproepen met “std::cin.good()”. Deze functie zal een boolean terug geven. Dit betekend dat de uitkomst of “true” (waar) of “false” (niet waar) is. We hebben dus iets nodig waarbij we het programma iets kunnen laten doen wanneer “std::cin.good()” false is.

Dit kan met een “if(){}” statement. Hiermee kan je kijken of wat binnen de haakjes staat waar of niet waar is. Als wat binnen de haakjes staat waar is, zal de code binnen de “{}” uitgevoerd worden. Hoe werkt dit vergelijken dan? Daar worden de volgende opperators voor gebruikt in C++:

== “is gelijk aan”
!= “is niet gelijk aan”
< “is kleiner dan”
<= “is kleiner of gelijk aan”
> “is groter dan”
>= “is groter of gelijk aan”



Nu weten we dus hoe onze if statement eruit moet komen te zien! Namelijk zo:

if(std::cin.good() == false)
{

}


Nu kunnen we tussen de “{}” wat code plaatsen om ons probleem op te lossen. Hiervoor moeten we de cin buffer leegmaken. Dit kunnen we doen met “std::cin.ignore(10000,'n');”. De error vlag halen we vervolgens weg met “std::cin.clear();”. Nu kunnen we cin weer gebruiken! Let op! Je moet eerst de error vlag weghalen voordat je cin weer kan gebruiken! Dus zet de cin.clear() altijd vooraan!

Het is netjes om de gebruiker op de hoogte te brengen van waarom iets fout is gegaan en om, voor nu, het programma vervolgens af te sluiten. Dit kan door “return 0;” als laatste tussen de “{}”-tekens te zetten de volledige error code ziet er dan zo uit:


if(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren!" << std::endl;
std::cin.get();
return 0;
}


Ons volledige programma ziet er na het toepassen van deze fix er zo uit:

#include <iostream>

int main()
{
int onsgetal, onsgetal2;
std::cout << "Wat is het eerste getal?"<< std::endl;
std::cin >> onsgetal;
if(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren!" << std::endl;
std::cin.get();
return 0;
}
std::cout << "Wat is het tweede getal?"<< std::endl;
std::cin >> onsgetal2;
if(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren!" << std::endl;
std::cin.get();
return 0;
}
std::cout << "Het eerste getal is: " << onsgetal << std::endl;
std::cout << "Het tweede getal is: " << onsgetal2 << std::endl;
std::cout << onsgetal << " + " << onsgetal2 << " = " << onsgetal + onsgetal2 << std::endl;
std::cout << onsgetal << " - " << onsgetal2 << " = " << onsgetal - onsgetal2 << std::endl;
std::cout << onsgetal << " / " << onsgetal2 << " = " << (float) onsgetal / (float) onsgetal2 << std::endl;
std::cout << onsgetal << " * " << onsgetal2 << " = " << onsgetal * onsgetal2 << std::endl;
std::cin.ignore();
std::cin.get();
}



Als er nu iets niet klopt sluit het programma zichzelf af. Dit is beter dan een programma wat crashed, maar erg gebruiksvriendelijk is dit niet. We moeten dus iets verzinnen wat de gebruiker de kans geeft de fout te herstellen. We moeten dus iets maken wat blijft vragen om het getal zolang er geen getal is ingevuld.

Dit kan met iets wat heel erg lijkt op een if statemant, de “while(){}” statement. Net als bij de if statement kijkt while naar wat er tussen de haakjes staat. Als dat waar is dan wordt de code tussen de “{}” uitgevoerd. Zodra dat gebeurd is kijkt hij nog een keer naar de while statement en voert zo nodig de code nóg een keer uit. Dit gaat net zolang door totdat wat er tussen haakjes staat niet meer waar is! Eventueel in het oneindige!

Probeer nu zelf even te bedenken hoe je de while statement zou gebruiken om ons probleem op te lossen. Kijk hierna pas naar het antwoord.

Antwoord:


Als je code hierop lijkt is het goed gegaan:

#include <iostream>

int main()
{
int onsgetal, onsgetal2;
std::cout << "Wat is het eerste getal?"<< std::endl;
std::cin >> onsgetal;
while(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren! Probeer het nogmaals:" << std::endl;
std::cin >> onsgetal;
}
std::cout << "Wat is het tweede getal?"<< std::endl;
std::cin >> onsgetal2;
while(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren! Probeer het nogmaals:" << std::endl;
std::cin >> onsgetal2;
}
std::cout << "Het eerste getal is: " << onsgetal << std::endl;
std::cout << "Het tweede getal is: " << onsgetal2 << std::endl;
std::cout << onsgetal << " + " << onsgetal2 << " = " << onsgetal + onsgetal2 << std::endl;
std::cout << onsgetal << " - " << onsgetal2 << " = " << onsgetal - onsgetal2 << std::endl;
std::cout << onsgetal << " / " << onsgetal2 << " = " << (float) onsgetal / (float) onsgetal2 << std::endl;
std::cout << onsgetal << " * " << onsgetal2 << " = " << onsgetal * onsgetal2 << std::endl;
std::cin.ignore();
std::cin.get();
}



We kunnen nu even gaan spelen met onze if en while functies. We zouden iets kunnen maken waarbij je het eerste getal met het tweede getal vergelijkt en verschillende antwoorden geeft wanneer het getal hoger, lager of hetzelfde is.

Hiervoor hebben we dus de andere operators uit het lijstje bovenaan nodig. Probeer nu eerst zelf het programma te schrijven wat deze functionaliteit heeft.

Antwoord:
Je programma moet er ongeveer zo uitzien:

#include <iostream>

int main()
{
int onsgetal, onsgetal2;
std::cout << "Wat is het eerste getal?"<< std::endl;
std::cin >> onsgetal;
while(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren! Probeer het nogmaals:" << std::endl;
std::cin >> onsgetal;
}
std::cout << "Wat is het tweede getal?"<< std::endl;
std::cin >> onsgetal2;
while(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren! Probeer het nogmaals:" << std::endl;
std::cin >> onsgetal2;
}
std::cout << "Het eerste getal is: " << onsgetal << std::endl;
std::cout << "Het tweede getal is: " << onsgetal2 << std::endl;
if(onsgetal == onsgetal2)
{
std::cout << "Het eerste getal is hetzelfde als het tweede getal!" << std::endl;
}
if(onsgetal < onsgetal2)
{
std::cout << "Het eerste getal is lager als het tweede getal!" << std::endl;
}
if(onsgetal > onsgetal2)
{
std::cout << "Het eerste getal is hoger als het tweede getal!" << std::endl;
}
std::cin.ignore();
std::cin.get();
}


Deze code werkt helemaal correct, maar is eigenlijk niet heel efficient. Dat komt omdat alle if-statements ook echt doorlopen worden. We kunnen de code efficiënter maken door “else if(){}” Alles na de else wordt alleen uitgevoerd als de voorgaande if statement niet waar is. Een effieciënter voorbeeld zou als volgt zijn:

#include <iostream>

int main()
{
int onsgetal, onsgetal2;
std::cout << "Wat is het eerste getal?"<< std::endl;
std::cin >> onsgetal;
while(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren! Probeer het nogmaals:" << std::endl;
std::cin >> onsgetal;
}
std::cout << "Wat is het tweede getal?"<< std::endl;
std::cin >> onsgetal2;
while(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren! Probeer het nogmaals:" << std::endl;
std::cin >> onsgetal2;
}
std::cout << "Het eerste getal is: " << onsgetal << std::endl;
std::cout << "Het tweede getal is: " << onsgetal2 << std::endl;
if(onsgetal > onsgetal2)
{
std::cout << "Het eerste getal is hoger als het tweede getal!" << std::endl;
} else if(onsgetal < onsgetal2)
{
std::cout << "Het eerste getal is lager als het tweede getal!" << std::endl;
} else if(onsgetal2 == onsgetal)
{
std::cout << "Het tweede getal is hetzelfde als het eerste getal!" << std::endl;
}
std::cin.ignore();
std::cin.get();
}


De kans dat getal en getal2 hetzelfde zijn is het kleinst dus die moet als laatste in deze boom. Want die hoeft het minst vaak uitgevoerd te worden.
De volgende opdracht, probeer het programma te laten loopen totdat getal en getal2 hetzelfde zijn.

#include <iostream>

int main()
{
int onsgetal, onsgetal2;
std::cout << "Wat is het eerste getal?"<< std::endl;
std::cin >> onsgetal;
while(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren! Probeer het nogmaals:" << std::endl;
std::cin >> onsgetal;
}
std::cout << "Wat is het tweede getal?"<< std::endl;
std::cin >> onsgetal2;
while(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren! Probeer het nogmaals:" << std::endl;
std::cin >> onsgetal2;
}
std::cout << "Het eerste getal is: " << onsgetal << std::endl;
std::cout << "Het tweede getal is: " << onsgetal2 << std::endl;
while(onsgetal != onsgetal2){
if(onsgetal > onsgetal2)
{
std::cout << "Het eerste getal is hoger als het tweede getal! Probeer het nogmaals:" << std::endl;
std::cin.clear();
std::cin >> onsgetal2;
} else if(onsgetal < onsgetal2)
{
std::cout << "Het eerste getal is lager als het tweede getal! Probeer het nogmaals:" << std::endl;
std::cin.clear();
std::cin >> onsgetal2;
}
}
std::cout << "Het tweede getal is hetzelfde als het eerste getal!" << std::endl;
std::cin.ignore();
std::cin.get();
}


Dit begint al een klein beetje op een raad spelletje te lijken. Het zou leuk zijn als het spel zélf een willekeurig getal tussen de 0 en de 10 genereerde. Dat kan doormiddel van de functie “rand()” deze functie zit in de stdlib.h bibliotheek. Deze zullen we dus moeten includen. Verder willen we wel echt random nummers hebben en daarom moeten we de random functie eerst “seeden” met iets pseudo randoms. Het seeden gaat met de functie “srand()”. We kunnen hiervoor het beste de tijd gebruiken. Die kan je oproepen met de functie “time(NULL)” in de bibliotheek “time.h”, die moeten we dus ook includen.

Nu geeft “rand() % 10;” een willekeurige waarde terug van 0 t/m 9. Precies wat we willen voor ons spelletje! Als we nu in plaats van “cin >> onsgetal;”, “onsgetal = rand() % 10;” zeggen. Kunnen we nu dus een willekeurig getal onder de tien raden. Om het spelletje wat competetiever te maken voegen we een teller toe die het aantal pogingen bijhoud. Door in de while loop pogingen++; toe te voegen geef je de integer pogingen er iedere keer 1 bij als de loop doorlopen wordt.

De volledige code:

#include <iostream>
#include <stdlib.h>
#include <time.h>

int main()
{
int onsgetal, onsgetal2;
srand(time(NULL));
onsgetal = rand() % 10;
std::cout << "Wat is het tweede getal?"<< std::endl;
std::cin >> onsgetal2;
while(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren! Probeer het nogmaals:" << std::endl;
std::cin >> onsgetal2;
}
int pogingen = 1;
while(onsgetal != onsgetal2){
if(onsgetal > onsgetal2)
{
std::cout << "Het eerste getal is hoger als het tweede getal! Probeer het nogmaals:" << std::endl;
std::cin.clear();
std::cin >> onsgetal2;
} else if(onsgetal < onsgetal2)
{
std::cout << "Het eerste getal is lager als het tweede getal! Probeer het nogmaals:" << std::endl;
std::cin.clear();
std::cin >> onsgetal2;
}
pogingen++
}
std::cout << "Het tweede getal is hetzelfde als het eerste getal!" << std::endl;
std::cout << "Het eerste getal is: " << onsgetal << std::endl;
std::cout << "Het tweede getal is: " << onsgetal2 << std::endl;
std::cout << "Je had " << pogingen << " pogingen nodig om het te raden!" std::endl;
std::cin.ignore();
std::cin.get();
}


Nu sluit het spelletje na iedere keer spelen zichzelf af. Laten we een while loop gebruiken om dat te veranderen. Let op! Zorg dat al je variabele in deze loop staan! Anders zijn ze bij de tweede keer spelen al “ingevuld”. Het makkelijkste is om een “do{}while()”-loop te gebruiken. Deze loop voert eerst 1x de code uit en checkt dan pas of de while statement klopt en voert dan zo nodig de code nog een keer uit.

#include <iostream>
#include <stdlib.h>
#include <time.h>

int main()
{
int doorspelen;
do {
int onsgetal, onsgetal2;
srand(time(NULL));
onsgetal = rand() % 10;
std::cout << "Wat is het getal?"<< std::endl;
std::cin >> onsgetal2;
while(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren! Probeer het nogmaals:" << std::endl;
std::cin >> onsgetal2;
}
int pogingen = 1;
while(onsgetal != onsgetal2)
{
if(onsgetal > onsgetal2)
{
std::cout << "Het getal is hoger! Probeer het nogmaals:" << std::endl;
std::cin.clear();
std::cin >> onsgetal2;
} else if(onsgetal < onsgetal2)
{
std::cout << "Het getal is lager! Probeer het nogmaals:" << std::endl;
std::cin.clear();
std::cin >> onsgetal2;
}
pogingen++;
}
std::cout << "Je hebt het getal geraden!!!" << std::endl;
std::cout << "Het eerste getal is: " << onsgetal << std::endl;
std::cout << "Het tweede getal is: " << onsgetal2 << std::endl;
std::cout << "Je had " << pogingen << " pogingen nodig om het te raden!" << std::endl;
std::cout << "Wil je nog een keer spelen? [1] = Ja" << std::endl;
std::cin.clear();
std::cin >> doorspelen;
while(std::cin.good() == false)
{
std::cin.clear();
std::cin.ignore(10000,'n');
std::cout << "je moet een getal invoeren! Probeer het nogmaals:" << std::endl;
std::cin >> onsgetal2;
}
} while(doorspelen == 1);
}


Dit was les 2. Als het goed is snap je nu hoe je if statements kan gebruiken, hoe je een while loop gebruikt, wat verschillende operators doen, hoe je een random nummer genereerd. En hoe je hiermee al een spelletje kan maken!

Als je vragen hebt kan je ze in de comments hieronder kwijt! Of kijk op het forum of je vraag daar misschien tussen staat.

Volgende en vorige item:
PC Cities: Skylines: Hoe begin ik een spel met winst?
PC Hoe maak ik een game? Les 1: Spelen met getallen

0 reacties

Reacties:

Er zijn nog geen reacties op dit bericht.
Wees de eerste die reageert, voer je reactie hieronder in!



Reageer

Je reageert nu als (uitloggen).





Over ons :: Contact :: Adverteren :: Review scores :: Privacy policy :: Disclaimer