import pygame
import random
from itertools import cycle
# Window dimensions
DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 400
GROUND_LEVEL = 280
class Player:
def __init__(self):
self.animation_cycle = cycle([0, 1, 2])
self.frames = (
pygame.image.load("image/zyp1.png").convert_alpha(),
pygame.image.load("image/zyp1.png").convert_alpha(),
pygame.image.load("image/zyp1.png").convert_alpha(),
)
self.jump_sound = pygame.mixer.Sound('audio/zyp.mp3')
self.rect = self.frames[0].get_rect()
self.x_pos = 50
self.y_pos = GROUND_LEVEL
self.rect.topleft = (self.x_pos, self.y_pos)
self.is_jumping = False
self.velocity_y = 0
self.jump_power = 13
self.gravity = 0.8
def start_jump(self):
if not self.is_jumping:
self.is_jumping = True
self.velocity_y = -self.jump_power
self.jump_sound.play()
def update_position(self):
if self.is_jumping:
self.rect.y += self.velocity_y
self.velocity_y += self.gravity
if self.rect.y >= GROUND_LEVEL:
self.rect.y = GROUND_LEVEL
self.is_jumping = False
self.velocity_y = 0
def render(self, surface):
frame_index = next(self.animation_cycle)
surface.blit(self.frames[frame_index], (self.x_pos, self.rect.y))
class ScrollingBackground:
def __init__(self, offset_x, offset_y):
self.texture = pygame.image.load("image/bg.png").convert_alpha()
self.x = offset_x
self.y = offset_y
def shift(self, speed):
self.x -= speed
if self.x <= -DISPLAY_WIDTH:
self.x = DISPLAY_WIDTH
def render(self, surface):
surface.blit(self.texture, (self.x, self.y))
class Hazard:
SPEED_BASE = 5
GROUND_OFFSET = 150
def __init__(self):
self.dino_sprite = pygame.image.load("image/konglong1.png").convert_alpha()
self.beast_sprite = pygame.image.load("image/daguaishou.png").convert_alpha()
self.digit_sprites = tuple(
pygame.image.load(f"image/{n}.png").convert_alpha() for n in range(10)
)
self.collect_audio = pygame.mixer.Sound("audio/zyp22.mp3")
variant = random.randint(0, 1)
if variant == 0:
self.sprite = self.dino_sprite
self.speed = 15
self.y_offset = 100
else:
self.sprite = self.beast_sprite
self.speed = self.SPEED_BASE
self.y_offset = self.GROUND_OFFSET
self.rect = self.sprite.get_rect()
self.rect.center = (DISPLAY_WIDTH + 50, self.y_offset)
def advance(self):
self.rect.x -= self.speed
def render(self, surface):
surface.blit(self.sprite, (self.rect.x, self.rect.y))
@property
def off_screen(self):
return self.rect.x < -self.rect.width
def run_game():
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
pygame.display.set_caption("Dino Runner")
player = Player()
bg_layer1 = ScrollingBackground(0, 0)
bg_layer2 = ScrollingBackground(DISPLAY_WIDTH, 0)
obstacles = []
spawn_timer = 0
score = 0
game_active = True
scrolling_speed = 5
while True:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return
if game_active and event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
player.start_jump()
if event.key == pygame.K_r and not game_active:
# restart
obstacles.clear()
player.rect.y = GROUND_LEVEL
player.is_jumping = False
player.velocity_y = 0
score = 0
spawn_timer = 0
game_active = True
if game_active:
bg_layer1.shift(scrolling_speed)
bg_layer2.shift(scrolling_speed)
bg_layer1.render(screen)
bg_layer2.render(screen)
player.update_position()
player.render(screen)
spawn_timer += dt
if spawn_timer >= 1300 and random.randint(0, 100) > 40:
obstacles.append(Hazard())
spawn_timer = 0
for hazard in obstacles[:]:
hazard.advance()
hazard.render(screen)
if hazard.off_screen:
obstacles.remove(hazard)
score += 1
if player.rect.colliderect(hazard.rect):
game_active = False
font = pygame.font.Font(None, 36)
score_surf = font.render(f"Score: {score}", True, (255, 255, 255))
screen.blit(score_surf, (10, 10))
else:
screen.fill((30, 30, 30))
font_large = pygame.font.Font(None, 64)
msg = font_large.render("GAME OVER", True, (200, 0, 0))
screen.blit(msg, (DISPLAY_WIDTH // 2 - 120, DISPLAY_HEIGHT // 2 - 30))
prompt = pygame.font.Font(None, 28).render("Press R to restart", True, (200, 200, 200))
screen.blit(prompt, (DISPLAY_WIDTH // 2 - 80, DISPLAY_HEIGHT // 2 + 30))
pygame.display.flip()
if __name__ == "__main__":
run_game()
Building a Side-Scrolling Runner Game Using Pygame
Posted on Thu, 13 Aug 2026 16:26:27 +0000 by SCook