Skip to content

2. Sprites

Sprite er en klasse for synlige spillobjekter i Pygame. Sprites kan lages ved å opprette klasser som arver Sprite-klassen, som ligger i pygame.sprite.Sprite.

En sprites må ha atributtene self.image og self.rect, og kan ha metoden update for å oppdatere figurene tilstand.

Figuren er lastet ned fra: https://kenney.nl/

  • self.image opprettes ofte ved å laste inn ett bilde, se linje 4 under.
  • self.rect opprettes som regel ved å hente rektangelen som ligger rundt bildet i self.image
class Figur(pygame.sprite.Sprite):
def __init__(self, x: int, y:int) -> None:
super().__init__()
self.image = pygame.image.load("yellow.png").convert_alpha()
self.rect = self.image.get_rect()
def update(self):
pass
Sprite uten bilde

En sprite kan lages uten å bruke bilde. Dette gjøres ofte når man ønsker å tegne geometriske figurer.

Koden under tegner en sirkel på self.image sin Surface. Legg merke til at for sprites skjer tegning i update-metoden.

class Ball(pygame.sprite.Sprite):
def __init__(self, x: int, y:int, width: int, height: int, color: str) -> None:
super().__init__()
self.image = pygame.Surface((width, height), pygame.SRCALPHA) #
self.rect = self.image.get_rect()
def update(self):
pygame.draw.circle(self.image, self.color, (self.rect.width // 2, self.rect.height // 2), self.rect.width // 2)

Attributten self.image representerer et bilde, den må være av datatypen pygame.Surface. Bilder kan skaleres med funksjonen pygame.transform.scale(BILDE, (BREDDE, HØYDE)), som returnerer et nytt bilde.

class Figur(pygame.sprite.Sprite):
def __init__(self, x: int, y:int) -> None:
super().__init__()
self.image = pygame.image.load("yellow.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (50, 50)) # skalerer bilde til 50x50
self.rect = self.image.get_rect()
def update(self):
pass

self.rect er rektangelen som ligger rundt bildet. Det er den som holder styr på figurens posisjon på skjermen.

Den har mange forskjellige attributter som kan manipuleres for å flytte figuren rundt.

Alle rect sine attributter
x,y
top, left, bottom, right
topleft, bottomleft, topright, bottomright
midtop, midleft, midbottom, midright
center, centerx, centery
size, width, height
w,h
class Spiller(pygame.sprite.Sprite):
def __init__(self) -> None:
super().__init__()
self.image = pygame.image.load("yellow.png").convert_alpha()
self.rect = self.image.get_rect()
# Plasserer figuren midt på skjermen i starten
self.rect.x = WIDTH // 2
self.rect.y = HEIGHT // 2
# Fart som skal brukes til å flytte på figuren
self.speed_x = 1
self.speed_y = -1
def update(self):
# Flytter figuren ved å endre på rect sin x og y
self.rect.x += self.speed_x
self.rect.y += self.speed_y
if self.rect.right > WIDTH or self.rect.left < 0:
self.speed_x *= -1
if self.rect.bottom > HEIGHT or self.rect.top < 0:
self.speed_y *= -1
Eksempel på bruk av sprite i en større kode
import pygame
from random import randint
# Constants
FPS = 60
WIDTH = 800
HEIGHT = 600
class Spiller(pygame.sprite.Sprite):
def __init__(self, x: int, y:int) -> None:
super().__init__()
self.image = pygame.image.load("yellow.png").convert_alpha()
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.speed_x = 1
self.speed_y = -1
def update(self):
self.rect.x += self.speed_x
self.rect.y += self.speed_y
if self.rect.right > WIDTH or self.rect.left < 0:
self.speed_x *= -1
if self.rect.bottom > HEIGHT or self.rect.top < 0:
self.speed_y *= -1
def accelerate(self):
self.speed_x += 1
self.speed_y += 1
def brake(self):
self.speed_x -= 1
self.speed_y -= 1
class Game:
def __init__(self) -> None:
pygame.init()
self.clock = pygame.time.Clock()
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("GAME TITLE")
# Game state
self.running = True
# Sprite groups
self.sprites = pygame.sprite.Group()
self.spiller = Spiller(100,100, 25,25, "blue")
self.sprites.add(self.spiller)
def handle_events(self) -> None:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
self.spiller.accelerate()
if keys[pygame.K_DOWN]:
self.spiller.brake()
def update(self) -> None:
self.sprites.update()
def draw(self) -> None:
self.screen.fill("white")
self.sprites.draw(self.screen)
pygame.display.flip()
def run(self) -> None:
while self.running:
self.handle_events()
self.update()
self.draw()
self.clock.tick(FPS)
pygame.quit()
if __name__ == "__main__":
game = Game()
game.run()

Group-klassen (pygame.sprite.Group()) kan brukes til å samle sprite-objekter. Den kommer med metodene draw og update som kjører henholdsvis draw- og update-metodene til alle sprite-objektene som er i gruppen. I tillegg kan grupper også brukes for å kollisjoner med samlinger av sprites (se pygame/kollisjoner).

Under er et eksempel på bruk av grupper.

class Game:
def __init__(self) -> None:
(...)
# Sprite groups
self.players = pygame.sprite.Group() # oppretter en sprite-gruppe for spillere
self.enemies = pygame.sprite.Group() # oppretter en sprite-gruppe for fiender
# legger til en spiller i players-gruppen
self.players.add(Player())
# legger til 10 fiender i enemies-gruppen
for i in range(10):
self.enemies.add(Enemy())
def update(self) -> None:
self.players.update() # kjører update-metoden på alle sprites i players-gruppen
self.enemies.update() # kjører update-metoden på alle sprites i enemies-gruppen
def draw(self) -> None:
self.screen.fill("white")
self.players.draw(self.screen) # tegner alle sprites i players-gruppen på vinduet
self.enemies.draw(self.screen) # tegner alle sprites i enemies-gruppen på vinduet
pygame.display.flip()
(...)