Nu använder vi grunderna för att bygga ett spel med Pygame. Styr spelaren med piltangenterna, ta dig genom hålen i de fallande väggarna och försök slå ditt rekord.
Exemplet använder funktioner för att dela upp logiken. Pygame skapar bland annat objekt för fönster, klocka och text. Du kan senare bygga vidare med egna klasser för spelare och väggar.
Förberedelser
Installera Pygame i din Python-miljö från terminalen:
python -m pip install pygamePå vissa system heter kommandot python3. Spelet körs som en vanlig Python-fil på datorn och kräver ett grafiskt skrivbord. Det ritas med rektanglar, så du behöver inte leta efter några extra bildfiler.
1. Skapa spelplanen och en game-loop
Ett spel behöver läsa händelser, uppdatera tillståndet och rita nästa bild om och om igen. Följande minimala program öppnar ett fönster och stänger det korrekt när du klickar på krysset.
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 512))
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((242, 246, 239))
pygame.display.flip()
clock.tick(60)
pygame.quit()clock.tick(60) begränsar loopen till högst ungefär 60 bilder per sekund. I det kompletta spelet använder vi även den uppmätta tiden mellan bilder, dt, så att hastigheten uttrycks i pixlar per sekund.
2. Läs piltangenterna och flytta spelaren
pygame.key.get_pressed() berättar vilka tangenter som hålls nere. Rörelsen måste begränsas så att hela spelaren ligger inom fönstret, även vid kanterna. Funktionen move_player sköter både det och att diagonal rörelse inte blir snabbare.
3. Skapa en fallande vägg med ett hål
Spelplanen är tio block bred och varje block är 64 pixlar. Slumpa hålets startkolumn från 0 till och med 8, och hoppa över den kolumnen och nästa när väggen byggs. Då finns alltid ett hål på två block.
Öka väggens y-position med wall_speed * dt. När den lämnat spelplanen börjar en ny vägg ovanför fönstret och poängen ökar.
4. Kontrollera hela spelarens kollision
Det räcker inte att testa spelarens övre vänstra hörn. Funktionen overlaps jämför hela spelarens rektangel med varje väggblock. Om ytorna överlappar tar omgången slut. Spelarens kanter kan ligga precis intill ett block utan att ytorna överlappar.
5. Starta om en omgång
Variabeln playing avgör om spelet pågår eller visar startmenyn. Enter återställer position, poäng, hastighet och vägg. Escape eller fönstrets kryss avslutar programmet.
Hela spelet
Spara koden som fallande-vaggar.py och kör den:
python fallande-vaggar.pyVisa hela spelets kod
"""Undvik fallande väggar. Installera pygame och kör filen med Python 3."""
import math
import random
WIDTH, HEIGHT = 640, 512
BLOCK_SIZE = 64
PLAYER_SIZE = 32
PLAYER_SPEED = 260
def move_player(x, y, dx, dy, dt):
"""Flytta spelaren och håll hela spelaren innanför spelplanen."""
length = math.hypot(dx, dy)
if length > 1:
dx, dy = dx / length, dy / length
x = max(0, min(WIDTH - PLAYER_SIZE, x + dx * PLAYER_SPEED * dt))
y = max(0, min(HEIGHT - PLAYER_SIZE, y + dy * PLAYER_SPEED * dt))
return x, y
def wall_blocks(y, gap_start):
"""Ett hål på två block, med startindex från 0 till och med 8."""
return [
(column * BLOCK_SIZE, y, BLOCK_SIZE, BLOCK_SIZE)
for column in range(10)
if column not in (gap_start, gap_start + 1)
]
def overlaps(first, second):
"""True när två rektanglar överlappar med en positiv area."""
x1, y1, w1, h1 = first
x2, y2, w2, h2 = second
return x1 < x2 + w2 and x1 + w1 > x2 and y1 < y2 + h2 and y1 + h1 > y2
def main():
import pygame
pygame.init()
try:
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Fallande väggar – Programmera Python")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 28)
player_x, player_y = 304.0, 440.0
wall_y = -float(BLOCK_SIZE)
gap_start = random.randint(0, 8)
wall_speed = 120
score = 0
playing = False
running = True
while running:
# Begränsa bildfrekvens och undvik stora hopp efter en paus.
dt = min(clock.tick(60) / 1000, 0.05)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_RETURN and not playing:
player_x, player_y = 304.0, 440.0
wall_y = -float(BLOCK_SIZE)
gap_start = random.randint(0, 8)
wall_speed = 120
score = 0
playing = True
if not running:
break
if playing:
keys = pygame.key.get_pressed()
dx = int(keys[pygame.K_RIGHT]) - int(keys[pygame.K_LEFT])
dy = int(keys[pygame.K_DOWN]) - int(keys[pygame.K_UP])
player_x, player_y = move_player(player_x, player_y, dx, dy, dt)
wall_y += wall_speed * dt
player = (player_x, player_y, PLAYER_SIZE, PLAYER_SIZE)
if any(overlaps(player, block) for block in wall_blocks(wall_y, gap_start)):
playing = False
elif wall_y > HEIGHT:
score += 1
wall_y = -float(BLOCK_SIZE)
gap_start = random.randint(0, 8)
wall_speed = min(wall_speed + 8, 300)
screen.fill((242, 246, 239))
for block in wall_blocks(wall_y, gap_start):
pygame.draw.rect(screen, (36, 91, 76), block)
pygame.draw.rect(screen, (215, 165, 47), (player_x, player_y, PLAYER_SIZE, PLAYER_SIZE))
score_text = font.render(f"Klarade väggar: {score}", True, (34, 49, 44))
screen.blit(score_text, (16, 12))
if not playing:
message = font.render("Enter: nytt spel | Esc: avsluta", True, (34, 49, 44))
screen.blit(message, (170, 230))
pygame.display.flip()
finally:
pygame.quit()
if __name__ == "__main__":
main()
Bygg vidare själv
- Ändra spelarens storlek och jämför svårighetsgraden.
- Lägg till en andra vägg.
- Skapa egna klasser för spelaren och väggen.
- Byt rektanglarna mot bilder när logiken fungerar.