Voordat we een spel kunnen maken met python, hebben we eerst modules nodig. Niet alle modules kun je zomaar installeren, zoals de module pygame. Die moeten we apart downloaden via deze link: http://www.pygame.org/download.shtml je download dan het pygame-1.9.1release.tar.gz bestand.

Daarna installeer je ze door command prompt te openen en in te typen:

Python –m pip install pygame

Nadat je dit hebt gedaan ga je ze in je eerste paar regels van je code inporteren.

#importing 1

import pygame

import random

from pygame.locals import *

Zoals je ziet gebruiken we ‘import’ en dan de module om te importeren. De module ‘random’ is een standaard module, deze hoef je niet apart te installeren. De tekst ‘#importing’ is een comment, deze hoef je niet perse over te typen, want dit stukje wordt niet gezien als code. Maar het is wel handig om te gebruiken. Het is namelijk erg overzichtelijk als je boven elk deel van de code zet wat het precies doet. Dit zal je vaker terug zien in deze code. Er staat een cijfer achter de code. Dit geeft het gedeelte van de code aan. Dit gebruik ik later om naar verschillende delen van de code te wijzen.

Oke, nu we alle modules geïnstalleerd hebben moet er een scherm aangemaakt worden om het spel in laten af te spelen.

#intializing 2

pygame.init()

width, height = 850, 720

screen = pygame.display.set_mode((width, height))

keys = [False, False, False, False]

health = 3

shooting = 0

badtimer = 100

badtimer1 = 0

badguys = []

randomx = []

index = 0

clock = pygame.time.Clock()

Hier worden allerlei dingen aangegeven die maar één keer aangegeven moeten worden om vaker te gebruiken. er zijn maar 3 codes die hiervan uitgelegd moeten worden.·         Zoals ‘pygame.init()’, dit wordt maar één keer gebruikt om de pygame module te initialiseren en vaker te gebruiken. ·         ‘screen = pygame.display.set_mode((width, height))’ is om het scherm van het spel te initialiseren. Hier gebruiken we ‘width’ en ‘height’. Dit zijn twee variabelen die in de regel daarboven zijn aangegeven. Hier lees je straks meer over. ‘clock = pygame.time.Clock()’ dit wordt gebruikt om straks de FPS (Frames Per Second) te bepalen. De rest van de codes zijn alleen maar variabelen of lists die later worden gebruikt in de game. Een variabele wordt hier voor het eerst gebruikt om ze een begin waarde te geven, deze kunnen later in de code makkelijk veranderd worden. Bij een variabele kun je maar één getal opslaan. Een list (Engels voor: lijst). Kunnen een hele lijst met verschillende getallen enz. opslaan. Hiermee kunnen we later de random spawnende vijanden in opslaan. Genoeg over dit gedeelte. We gaan nu de sprites importeren

#importing pictures 3.1

badshippic = pygame.image.load(“resources/badship.png”)

goodshippic = pygame.image.load(“resources/goodship.png”)

heartpic = pygame.image.load(“resources/hearts.png”)

Bij dit gedeelte van de code worden de sprites (ook wel de plaatjes van de spelers en vijanden) geïmporteerd. Er staat voor gedaan hoe het precies moet, maar hier is nog een duidelijker voorbeeld:‘variabelefoto = pygame.image.load(“plaats van het plaatje”)’Maar omdat de geïmporteerde plaatjes nog moeten aanpassen omdat 128 x 128 iets te groot is voor het spel. Dit brengt ons bij het volgende deel.

#transforming pictures 3.2

badship = pygame.transform.scale(badshippic,(64,64))

goodship = pygame.transform.scale(goodshippic,(64,64))

heart = pygame.transform.scale(heartpic,(26,25))

 

Hier worden weer nieuwe variabelen aangemaakt. Je had dezelfde variabele van net kunnen gebruiken. Maar persoonlijk vind ik dit iets overzichtelijker. Hier nog een voorbeeld hoe je het plaatje kunt transformeren.‘variabele = pygame.transform.scale(variabelefoto,(breedte,hoogte))’Let er wel op dat als je foto niet precies vierkant is, dat je dezelfde proporties blijft gebruiken. anders krijg je een uitgerekte foto.

#get rekt m8 3.3

goodrect = pygame.Rect(goodship.get_rect())

goodrect.x, goodrect.y = [425,650]

Hier worden het vierkant van de speler zelf gemaakt. Dit wordt later gebruikt om te kijken wanneer de speler botst met een vijand. ‘goodrect’ is het variabele voor het vierkant. Later kun je ‘goodrect.x’ gebruiken om de horizontale positie van het  vierkant te bepalen. Hetzelfde geldt voor de verticale positie. Deze worden meteen in de volgende regel aangepast, zodat jezelf het beginpunt van de speler kan bepalen. De ‘goodrect.x’ wordt later gebruikt als plaats om het schip te tekenen.

#the badboy 5#the badboy 5
class badboy():
def __init__(self, x, y, image):
self.image = image
self.rect = pygame.Rect(self.image.get_rect())
self.rect.x = x
self.rect.y = y
badguys.append(self)
screen.blit(image,(self.rect.x,self.rect.y))

Hier gebruiken we een class om de vijand te maken. Dit doen we omdat dit makkelijker is om de vijanden op willekeurige plaatsen te spawnen. Een class is simpelweg een object in je code. Hierin zet je een def is een functie. na def komt te naam van de functie. Hier gebruiken we __init__, dit is omdat we dan de class initialiseren met de functie. Bij een functie zet je erachter tussen haakjes bepaalde variabelen zodat wanneer je de functie oproept die variabelen erachter kan zetten tussen haakjes. Dit is misschien lastig te begrijpen, dus heir is een simpel voorbeeld wat niks met het spel te maken heeft:

Def multiply (number1, number2):
Answer = number1 * number2
Print(Answer)

Dit is een veel simpelere functie, om het te gebruiken hoef je alleen maar de functie op te roepen en de getallen in te vullen, dan wordt het antwoord zo geprint door python zelf:

Multiply(2,4)

Hier geeft python je het cijfer 8. Voor de rest staat er in de functie alleen code om de vijand te initialiseren. Bijvoorbeeld ‘self.rect = pygame.Rect(self.image.get_rect())’ hier wordt het vierkant gemaakt voor de vijand om te botsen. Daarna worden de ingevoegde x en y punten gebruikt om ze op die plek neer te zetten. ‘badguys.append(self)’ zorgt ervoor dat de gehele class in de lijst van ‘badguys’ komt te staan, dat is de lijst die in gedeelte 2 is gebruikt. Het ‘screen.blit’ wordt later helemaal uitgelegd. Het is in ieder geval om de vijand te tekenen. Hopelijk heb je nu enig idee hoe functies werken, en anders wees maar niet bang. Het komt hierna niet meer terug in de code. Laten we maar verder gaan.

#the great loop 6
while True:
clock.tick(60)

Hier begint de loop. Je begint de loop met ‘while True:’ je kan ook in gedeelte 2 van de code een variabele gelijk zetten aan True om die te gebruiken. Belangrijke opmerking, nadat je de loop begint moet je alle codes beginnen met een Tab (de tab toets). Dit komt omdat het allemaal binnen de loop moet staan. Dit is belangrijk om de code uit te voeren, anders werkt de code niet. Je zult ook in de code zien dat er veel verschillende ruimtes zijn. Je moet vaker een Tab gebruiken, niet alleen na de while. Hier is een lijstje met de woorden waarna je een Tab moet gebruiken:

  • While
  • For
  • If
  • Elif (else if)
  • else

#key press down 7.1

for event in pygame.event.get():

if event.type == pygame.KEYDOWN:

if event.key==K_w:

keys[0]=True

elif event.key==K_a:

keys[1]=True

elif event.key==K_s:

keys[2]=True

elif event.key==K_d:

keys[3]=True

 

#key release up 7.2

if event.type == pygame.KEYUP:

if event.key==pygame.K_w:

keys[0]=False

elif event.key==pygame.K_a:

keys[1]=False

elif event.key==pygame.K_s:

keys[2]=False

elif event.key==pygame.K_d:

keys[3]=False

Hier wordt er gekeken of je een toets indrukt. Eerst wordt er door alle soorten events van pygame heen gekeken voor het event dat de toets ingedrukt wordt. Dit doen ze met for en if. Met for gaan de door de hele lijst met mogelijke events. Events zijn acties die kunnen gebeuren in pygame. Daarna komt er een if-statement. Dit houdt in dat als er iets gelijk staat aan iets anders doe iets. Even een simpel voorbeeldje:

fruit = apple

If fruit == apple:

Print(“Hello”)

Hier zegt python hallo. Aangezien je eerst aangeeft dat fruit een appel is. En als dat zo is, dan zegt python hello. Zie je ook dat er na de if-statement een tabje gebruikt is? Een verschil dat je wellicht opgevallen is, is dat er bij ‘fruit = apple’ maar één ‘=’ is gebruikt. En bij ‘if fruit == apple’ twee. Dit is omdat je eerst de variabele gelijk zet aan appel, hier geef je aan wat fruit is als je onder ‘fruit = apple’ nog een regel zet met: ‘fruit = pear’ dan verander de variabele fruit van appel in peer. En als je er twee gebruikt dan wordt er gekeken of het variabele fruit gelijk is aan appel. Dus stel het variabele fruit zou peer zijn. Dat veranderd de variabele niet in apple als je twee ‘=’ tekens gebruikt.

Nadat de code heeft gekeken of er een toets ingedrukt wordt. Dan wordt er weer een if-statement gebruikt om te kijken welke toets het is. Als de lettertoets d is, doe dan dit. Een letter toets geef je aan met K_letter. Maar als je verder kijkt zie je elif staan. Dit is simpelweg een combinatie tussen else en if. Hier is het heel simpel uitgelegd:

  • else: als de if-statement niet klopt. Doe dan dit.
  • Elif: als de if-statement niet klopt. Kijk dan of dit wel klopt.

Zo zie je dat er verschillende toetsen af wordt gegaan om te kijken of die toets ingedrukt wordt. En als een goeie toets wordt ingedrukt, dan staat er ‘keys[0] = True’ als je even terugscrollt naar gedeelte 2 dan zie je daar ‘keys = [False, False, False, False]’ staan. Dit is een list met vier keer False (niet waar). En door ‘keys[0]’ pak je de allereerste false, en door ‘= True’ zorg je dat dat de toets als True (wel waar) gezien wordt. Dit gebruik je in het volgende gedeelte om te bewegen.

#moving 8

if keys[0]:

goodrect.y -= 2.5

elif keys[2]:

goodrect.y += 2.5

if keys[1]:

goodrect.x -= 2.5

elif keys[3]:

goodrect.x += 2.5

Hier zie je weer een (el)if-statement, en dan ‘keys[0]:’ , maar omdat ‘keys[0]’ zowel True als False kan zijn. Gebeurd er alleen iets wanneer ‘keys[0]’ gelijk staat aan True. Want dan staat er eigenlijk: ‘if True:’ en dan wordt de code uitgevoerd. En als dat zo is dan ‘goodrect.y -= 2.5’ want weet je nog dat we in gedeelte 3.3 hadden aangegeven wat goodrect.y was. Door -= of += te gebruiken dan verander je de variabele door er een bepaald getal bij op te tellen / af te trekken. Even een voorbeeld:

Number = 1

Number += 1

Print(Number)

Hier zegt python dan 2. Dus aangezien we later in de code ‘goodrect.y’ en ‘goodrect.x’ gebruiken om het plaatje van de speler te tekenen op die plaats.

(Wil je nu kijken wat je al hebt gemaakt. Zet helemaal onderaan in de while loop:

screen.blit(goodship, (goodrect.x,goodrect.y))

pygame.display.flip()

screen.fill(0)

deze code wordt later helemaal uitgelegd. Maar dan kun je nu al zien wat je zover hebt gemaakt. Om dat te zien sla je het bestand op (Ctrl + S) en drukt dan op F5.)

Kunnen we de speler verplaatsen. Het wordt maar is tijd om de vijanden te maken.

#badboys, badboys, what you gonna do? 9

x = random.randrange(0,786)

randomx.append(x)

y = random.randrange(-500,-64)

for i in range(0,15):

i = badboy(randomx[random.randint(0,len(randomx)-1)], y, badship)

index += 1

if len(badguys) >= 10:

badguys.pop(len(badguys)-1)

oké hier is weer een lastig stukje van de code. We hebben in gedeelte 2 van de code ook lege list ‘badguys = []’ en ‘randomx = []’ die gaan we hier gebruiken. Eerst gebruiken we de ‘random’ module. We maken twee nieuwe variabelen (omdat deze maar één keer wordt gebruikt in het hele spel heeft het geen nut om het bij gedeelte 2 te zetten, dat is vooral voor de veelgebruikte variabelen).  De variabele ‘x’ krijgt een willekeurig getal tussen 0 en 786 (ook kommagetallen), wil je alleen hele getallen dan gebruik je random.randint. Maar de x wordt toegevoegd in een lijst, later kiezen we een random getal uit die lijst als de positie voor de vijand. Dit doen we omdat als we de x niet in een lijst plaatsen blijft de x van de vijanden maar de hele tijd veranderen. Bij y maakt dit niks uit omdat we die sowieso al veranderen, y is maar een beginpunt. We gebruiken daar en willekeurig getal voor zodat niet alle vijanden op één lijn naar beneden komen.

Hierna gebruiken we weer een for loop, wat nog niet eerder verteld is, is dat while iets uitvoerd totdat de statement niet meer True is. Bij een for loop, wordt alles één keer uitgevoerd. Dus zoals je hier ziet: ‘for i in range(0,15):´ blijft het de code binnen zich uitvoeren totdat ‘i’ 15 keer uitgevoerd is. Maar eigenlijk blijft de code oneindig runnen. Omdat het alsnog in de while loop zit, wordt de for loop vaker uitgevoerd. En voor elke i gebruiken we de class in gedeelte 5. Als we naar de functie kijken van de class zien we dat we 4 variabelen voor de functie nodig hebben: self, x, y en image. Self hoef je niet in te vullen, want daarvoor wordt automatisch de class gepakt. En voor de x roepen we een willekeurig getal uit de lijst met willekeurige x’en. Kun je het nog volgen? Zoals ook bij de beweging een value van ‘keys’ werd gebruikt. Wordt hier een value uit de lijst van alle x’en gepakt. Weer gebruiken we de random module om een random getal te kiezen van de lijst. Dit keer zit het tussen 0 en len(randomx-1). Dit houdt in dat er een getal gekozen wordt tussen de 0 en de lengte van de lijst randomx – 1. Want als we die – 1 niet gebruiken, kun je een foutmelding krijgen. Omdat de code dat er een x toegevoegd wordt in de lijst tegelijkertijd runt met de code om een random getal te kiezen, de lengte van de lijst is dan wel 1, maar die is eigenlijk nog leeg. Daarom die – 1. Hierna gaan we ervoor zorgen dat de vijanden kunnen botsen en dat je hierdoor een leven kwijt raakt.

#colliding party 10

index = 0

for badguy in badguys:

badguy.rect.y += 3

screen.blit(badship,(badguy.rect.x,badguy.rect.y))

if badguy.rect.colliderect(goodrect):

badguys.pop(index)

health -= 1

if badguy.rect.y >= 730:

badguys.pop(index)

index += 1

hier weer een for loop. Nu eentje die een code uitvoert voor elke value in de lijst badguys. Dus voor elke vijand wordt deze code apart gerunnt. Bij elke badguy. Er komt telkens 3 bij het vierkant van vijand op de verticale as. Dit houdt in dat hij de heletijd naar beneden blijft bewegen.En als het vierkant van de vijand (aangegeven in gedeelte 5) botst met het vierkant van de speler (aangegeven in gedeelte 3.3) dat wordt de vijand uit de lijst verwijderd met ‘badguys.pop(index)’ badguys is de naam van de lijst. En index is het cijfer dat verwijderd moet worden. Hierna gaat er één leven vanaf. Daarnaast als de vijand uit beeld is (voorbij y = 730), dan wordt hij ook verwijderd. Je ziet op verschillende plaatsen dat index verhoogd wordt. Het lijkt dus alsof index een groter getal heeft dan de lengte van de lijst. Maar dit wordt gecompenseerd doordat de index telkens wordt gerefreshed naar nul. Het lijkt onwaarschijnlijk. Maar het werkt. Laten we nu maar zorgen dat we af kunnen gaan.

#Stay healthy!  11

if health == 3:

screen.blit(heart,(5,5))

screen.blit(heart,(55,5))

screen.blit(heart,(105,5))

elif health == 2:

screen.blit(heart,(5,5))

screen.blit(heart,(55,5))

elif health == 1:

screen.blit(heart,(5,5))

elif health <= 0:

pygame.quit()

quit()

Dit stukje moet niet al te lastig zijn. Alleen maar (el)if-statements. Om te kijken of de speler af is. ‘screen.blit’ wordt in het laatste gedeelte uitgelegd. Maar als ‘health <= 0:’ of terwijl: als de levens van de speler gelijk of lager zijn dan 0, dan ben je af. Pygame.quit(), zorgt dat het pygame scherm afsluit. En quit() zorgt dat de python shell afsluit.

#draw me like one of your french girl 12

screen.blit(goodship, (goodrect.x,goodrect.y))

pygame.display.flip()

screen.fill(0)

En nu het moment suprême: het tekenen van de speler. Eindelijk de uitleg over ‘screen.blit’. screen.blit is de code om te tekenen. Het had ook ‘rubberducky.blit’ kunnen zijn, aangezien het de variabele screen gebruikt die we in gedeelte 2 hebben aangemaakt. Als je daar inplaats van screen, rubberducky had staan. Dan zou het dus ‘rubberducky.blit’ zijn geweest. Maar screen.blit tekent een bepaald plaatje op een plek die je aangeeft. ‘screen.blit(goodship, (goodrect.x,goodrect.y))’ tekent de speler (aangegeven in gedeelte 3.2) op de plaatsen van het vierkant van de speler (aangegeven in gedeelte 3.3).

Pygame.display.flip()

zorgt dat het hele scherm van pygame wordt geüpdatet. Dit kan zorgen dat de sprites kunnen bewegen.
En als laatste. ‘screen.fill(0)’ zorgt dat het scherm helemaal geleegd wordt voordat er weer iets nieuws wordt getekend. Je kan proberen zonder, geeft ook wel een leuk effect. Maar is niet zo functioneel.

Categorieën: Python