Dit is deel twee van een vijfdelige serie tutorials over het maken van spellen met Python 3 en Pygame. In deel een introduceerde ik de serie, behandelde ik de basisprincipes van gameprogrammering, introduceerde Pygame en onderzocht ik de game-architectuur.
In dit deel zullen we kijken naar de textobject
klasse die wordt gebruikt om tekst op het scherm weer te geven. We zullen het hoofdvenster maken, inclusief een achtergrondafbeelding, en dan zullen we leren om objecten zoals stenen, de bal en de peddel te tekenen.
De textobject
klasse is ontworpen om tekst op het scherm weer te geven. De casus zou kunnen worden gemaakt vanuit een ontwerpstandpunt dat het een subklasse van zou moeten zijn GameObject
omdat het ook een visueel object is en je het misschien wilt verplaatsen. Maar ik wilde geen deep class-hiërarchieën introduceren, wanneer alle tekst die Breakout op het scherm weergeeft, blijft staan.
De textobject
maakt een font-object. Het maakt de tekst in een apart tekstoppervlak dat vervolgens wordt geblazen (gerenderd) op het hoofdoppervlak. Een interessant aspect van de textobject
is dat het geen vaste tekst heeft. In plaats daarvan krijgt het een functie genaamd text_func ()
dat wordt elke keer dat het wordt gegenereerd genoemd.
Dit stelt ons in staat de weergave van levens bij te werken en te scoren in Breakout, alleen door een functie te bieden die de huidige levens en de huidige score retourneert, in plaats van bij te houden welke tekstobjecten levens weergeven en scoren en hun tekst bijwerken telkens wanneer ze veranderen. Dit is een handige truc van functioneel programmeren en voor grotere spellen kan het je helpen alles netjes en opgeruimd te houden.
Pygame-klasse importeren TextObject: def __init __ (self, x, y, text_func, color, font_name, font_size): self.pos = (x, y) self.text_func = text_func self.color = color self.font = pygame.font. SysFont (font_name, font_size) self.bounds = self.get_surface (text_func ()) def draw (self, surface, centralized = False): text_surface, self.bounds = \ self.get_surface (self.text_func ()) indien gecentraliseerd: pos = (self.pos [0] - self.bounds.width // 2, self.pos [1]) else: pos = self.pos surface.blit (text_surface, pos) def get_surface (self, text): text_surface = self.font.render (text, False, self.color) return text_surface, text_surface.get_rect () def update (self): pass
Pygame-spellen draaien in Windows. Je kunt ze ook op volledig scherm weergeven. Hier is hoe je een leeg Pygame-venster weergeeft. Je kunt al veel van de elementen zien die ik eerder heb besproken. Eerst, Pygame in het()
wordt gebeld en vervolgens worden het hoofdtekeningoppervlak en de klok gemaakt.
De volgende is de hoofdlus, die consequent het scherm met eenvormig grijs vult en de klok oproept Kruis aan()
methode met de framesnelheid.
import pygame pygame.init () scherm = pygame.display.set_mode ((800, 600)) clock = pygame.time.Clock () while True: screen.fill ((192, 192, 192)) pygame.display.update () clock.tick (60)
Meestal is een uniforme achtergrondkleur niet erg spannend. Pygame doet afbeeldingen erg goed. Voor Breakout heb ik meegesleept en ben ik op zoek gegaan naar een fraai beeld van de echte ruimtevaart van de NASA. De code lijkt erg op elkaar. Eerst, net voor de hoofdlus, laadt het de achtergrondafbeelding met behulp van de pygame.image.load ()
functie. Dan, in plaats van het vullen van het scherm met kleur, "blits" (kopieer de bits) het beeld naar het scherm op positie (0,0). Het effect is dat het beeld op het scherm wordt weergegeven.
import pygame pygame.init () scherm = pygame.display.set_mode ((800, 600)) clock = pygame.time.Clock () background_image = pygame.image.load ('images / background.jpg') while True: scherm .blit (background_image, (0, 0)) pygame.display.update () clock.tick (60)
Pygame kan alles tekenen. De pygame.draw
module heeft functies voor het tekenen van de volgende vormen:
In Breakout zijn alle objecten (behalve de tekst) slechts vormen. Laten we kijken naar de methode draw () van de verschillende Breakout-objecten.
Bakstenen zijn stenen. Het zijn maar rechthoeken. Pygame levert de pygame.draw.rect ()
functie, waarbij een oppervlak, een kleur en een Rect-object (links, boven, breedte en hoogte) worden genomen en een rechthoek wordt gerenderd. Als de optionele breedte-parameter groter is dan nul, tekent deze de omtrek. Als de breedte nul is (wat de standaardwaarde is), tekent deze een effen rechthoek.
Merk op dat de Steen
class is een subklasse van GameObject
en krijgt alle eigenschappen ervan, maar het heeft ook een kleur die het zelf beheert (omdat er game-objecten kunnen zijn die geen enkele kleur hebben). Negeer de Special effect
veld voor nu.
pygame importeren uit game-object importeren GameObject-klasse Brick (GameObject): def __init __ (zelf, x, y, w, h, kleur, special_effect = Geen): GameObject .__ init __ (zelf, x, y, w, h) self.color = color self.special_effect = special_effect def draw (self, surface): pygame.draw.rect (surface, self.color, self.bounds)
De bal in Breakout is slechts een cirkel. Pygame levert de pygame.draw.circle ()
functie die de kleur, het midden, de radius en de parameter voor de parameter voor de opties gebruikt, die standaard op nul staat. Zoals met de pygame.draw.rect ()
functie, als de breedte nul is, wordt een dichte cirkel getekend. De bal is ook een afgeleide klasse van GameObject.
Omdat de bal altijd beweegt (in tegenstelling tot de stenen), heeft deze ook een snelheid die wordt doorgegeven aan de GameObject
basisklasse die moet worden beheerd. De klasse Ball heeft een kleine draai omdat de x- en y-parameters het midden aangeven, terwijl de x- en y-parameters worden doorgegeven aan de GameObject
basisklasse zijn de linkerbovenhoek van het selectiekader. Om van centrum naar linkerbovenhoek te converteren, hoeft u alleen de straal af te trekken.
pygame importeren uit game-object importeren GameObject-klasse Ball (GameObject): def __init __ (zelf, x, y, r, kleur, snelheid): GameObject .__ init __ (zelf, x - r, y - r, r * 2, r * 2, snelheid) self.radius = r self.diameter = r * 2 self.color = color def draw (self, surface): pygame.draw.circle (surface, self.color, self.center, self.radius)
De paddle is nog een andere rechthoek die inderdaad naar links en rechts beweegt als reactie op het indrukken van de pijltoetsen door de speler. Dat betekent dat de positie van de paddle kan veranderen van het ene frame naar het volgende, maar voor zover het tekenen gaat, is het slechts een rechthoek die op de huidige positie moet worden weergegeven, wat dat ook is. Hier is de relevante code:
import pygame import config als c van game-object import GameObject-klasse Paddle (GameObject): def __init __ (zelf, x, y, w, h, kleur, offset): GameObject .__ init __ (zelf, x, y, w, h) zelf. color = color self.offset = offset self.moving_left = False self.moving_right = False def draw (self, surface): pygame.draw.rect (surface, self.color, self.bounds)
In dit deel hebt u kennisgemaakt met de klasse TextObject en hoe u tekst op het scherm kunt weergeven. Je bent ook bekend met tekenobjecten zoals stenen, de bal en de peddel.
Onthoud intussen dat we veel inhoud van Python beschikbaar hebben voor verkoop en voor studie in de Envato-markt.
In deel drie zul je zien hoe het afhandelen van gebeurtenissen werkt en hoe Pygame je in staat stelt om gebeurtenissen zoals druk op de knop, muisbewegingen en muisklikken te onderscheppen en erop te reageren. Daarna bespreken we gameplay-onderwerpen zoals het verplaatsen van de bal, het instellen van de snelheid van de bal en het verplaatsen van de paddle.