小游戏

import pygame
import sys
import random

Initialize pygame

pygame.init()

Game constants

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 400
GROUND_HEIGHT = 350
GRAVITY = 1
JUMP_FORCE = -18
GAME_SPEED = 5
OBSTACLE_FREQUENCY_INITIAL = 1500 # Initial obstacle frequency (ms)

Color definitions

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (50, 168, 82)
BROWN = (139, 69, 19)
SKY_BLUE = (135, 206, 235)
GROUND_COLOR = (222, 184, 135)
RED = (255, 50, 50)

Create game window

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Pixel Dino Runner")
clock = pygame.time.Clock()

Fonts

font = pygame.font.SysFont(None, 36)
big_font = pygame.font.SysFont(None, 72)

class Dinosaur:
def init(self):
self.x = 80
self.y = GROUND_HEIGHT - 40
self.width = 40
self.height = 60
self.velocity = 0
self.is_jumping = False
self.color = GREEN
self.eye_radius = 5
self.leg_width = 10
self.leg_height = 15

def jump(self):
if not self.is_jumping:
self.velocity = JUMP_FORCE
self.is_jumping = True

def update(self):
# Apply gravity
self.velocity += GRAVITY
self.y += self.velocity

Check if landed

if self.y >= GROUND_HEIGHT - self.height:
self.y = GROUND_HEIGHT - self.height
self.velocity = 0
self.is_jumping = False

def draw(self):
# Draw dino body
pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height), border_radius=8)

Draw dino head

head_width = 30
pygame.draw.rect(screen, self.color, (self.x + self.width - 5, self.y - 15, head_width, 25), border_radius=5)

Draw eyes

pygame.draw.circle(screen, WHITE, (self.x + self.width + head_width - 10, self.y - 5), self.eye_radius)
pygame.draw.circle(screen, BLACK, (self.x + self.width + head_width - 10, self.y - 5), self.eye_radius // 2)

Draw legs

pygame.draw.rect(screen, self.color, (self.x + 5, self.y + self.height - 5, self.leg_width, self.leg_height))
pygame.draw.rect(screen, self.color,
(self.x + self.width - 15, self.y + self.height - 5, self.leg_width, self.leg_height))

def get_rect(self):
return pygame.Rect(self.x + 10, self.y, self.width - 20, self.height - 10)

class Obstacle:
def init(self, x):
self.x = x
self.width = random.randint(20, 40)
self.height = random.randint(40, 70)
self.y = GROUND_HEIGHT - self.height
self.color = BROWN
self.passed = False

def update(self, speed):
self.x -= speed

def draw(self):
# Draw cactus body
pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height), border_radius=5)

Draw cactus thorns

for i in range(3):
pygame.draw.rect(screen, self.color,
(self.x - 5, self.y + 10 + i * 15, self.width + 10, 5),
border_radius=2)

def get_rect(self):
return pygame.Rect(self.x + 5, self.y, self.width - 10, self.height)

def draw_ground():
pygame.draw.rect(screen, GROUND_COLOR, (0, GROUND_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - GROUND_HEIGHT))

Draw ground texture

for i in range(0, SCREEN_WIDTH, 30):
pygame.draw.line(screen, (200, 160, 120), (i, GROUND_HEIGHT), (i, SCREEN_HEIGHT), 1)

def draw_clouds(cloud_positions):
for pos in cloud_positions:
pygame.draw.ellipse(screen, WHITE, (pos[0], pos[1], 60, 30))
pygame.draw.ellipse(screen, WHITE, (pos[0] + 20, pos[1] - 10, 70, 35))
pygame.draw.ellipse(screen, WHITE, (pos[0] + 40, pos[1], 60, 30))

def draw_score(score, high_score):
score_text = font.render(f"Score: {score}", True, BLACK)
high_score_text = font.render(f"High Score: {high_score}", True, BLACK)
screen.blit(score_text, (20, 20))
screen.blit(high_score_text, (20, 60))

def draw_game_over(score, high_score):
game_over_text = big_font.render("GAME OVER!", True, BLACK)
score_text = font.render(f"Final Score: {score}", True, BLACK)
high_score_text = font.render(f"High Score: {high_score}", True, BLACK)
restart_text = font.render("@~@", True, BLACK)

screen.blit(game_over_text, (SCREEN_WIDTH // 2 - game_over_text.get_width() // 2, SCREEN_HEIGHT // 2 - 80))
screen.blit(score_text, (SCREEN_WIDTH // 2 - score_text.get_width() // 2, SCREEN_HEIGHT // 2))
screen.blit(high_score_text, (SCREEN_WIDTH // 2 - high_score_text.get_width() // 2, SCREEN_HEIGHT // 2 + 40))
screen.blit(restart_text, (SCREEN_WIDTH // 2 - restart_text.get_width() // 2, SCREEN_HEIGHT // 2 + 100))

def draw_start_screen():
# Draw title
title_text = big_font.render("DINO RUNNER", True, GREEN)
screen.blit(title_text, (SCREEN_WIDTH // 2 - title_text.get_width() // 2, 100))

Draw start instruction

start_text = font.render("Press SPACE to Start", True, BLACK)
screen.blit(start_text, (SCREEN_WIDTH // 2 - start_text.get_width() // 2, SCREEN_HEIGHT // 2))

Draw controls info

controls_text = font.render("Controls: SPACE to Jump | R to Restart", True, BLACK)
screen.blit(controls_text, (SCREEN_WIDTH // 2 - controls_text.get_width() // 2, SCREEN_HEIGHT // 2 + 50))

def reset_game():
"""完全重置游戏状态"""
dino = Dinosaur()
obstacles = []
score = 0
game_speed = GAME_SPEED
last_obstacle_time = pygame.time.get_ticks()
game_over = False
game_started = True # 直接进入游戏状态
obstacle_frequency = OBSTACLE_FREQUENCY_INITIAL

return dino, obstacles, score, game_speed, last_obstacle_time, game_over, game_started, obstacle_frequency

def main():
# 初始游戏状态
dino = Dinosaur()
obstacles = []
cloud_positions = [(100, 80), (400, 120), (650, 60)]
score = 0
high_score = 0
game_speed = GAME_SPEED
last_obstacle_time = pygame.time.get_ticks()
game_over = False
game_started = False # 游戏开始时未启动
obstacle_frequency = OBSTACLE_FREQUENCY_INITIAL

while True:
current_time = pygame.time.get_ticks()

处理事件

for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

if event.type == pygame.KEYDOWN:
# 空格键处理
if event.key == pygame.K_SPACE:
if not game_started: # 开始游戏
game_started = True
elif not game_over: # 游戏中的跳跃
dino.jump()

R键处理 - 游戏结束后重新开始

if event.key == pygame.K_r and game_over:
# 重置所有游戏状态
(dino, obstacles, score, game_speed,
last_obstacle_time, game_over, game_started,
obstacle_frequency) = reset_game()

填充背景色

screen.fill(SKY_BLUE)

绘制云朵

draw_clouds(cloud_positions)

绘制地面

draw_ground()

绘制恐龙

dino.draw()

绘制障碍物

for obstacle in obstacles:
obstacle.draw()

游戏逻辑 - 只在游戏已开始且未结束时运行

if game_started and not game_over:
# 更新恐龙位置
dino.update()

生成新障碍物

if current_time - last_obstacle_time > obstacle_frequency:
obstacles.append(Obstacle(SCREEN_WIDTH))
last_obstacle_time = current_time
# 随着分数增加,障碍物出现频率提高
obstacle_frequency = max(500, OBSTACLE_FREQUENCY_INITIAL - score // 10 * 100)

更新障碍物位置

for obstacle in obstacles[:]:
obstacle.update(game_speed)

移除屏幕外的障碍物

if obstacle.x + obstacle.width < 0:
obstacles.remove(obstacle)
continue

计分

if not obstacle.passed and obstacle.x < dino.x:
obstacle.passed = True
score += 1
# 每得10分增加游戏速度
if score % 10 == 0:
game_speed += 0.5

碰撞检测

dino_rect = dino.get_rect()
for obstacle in obstacles:
if dino_rect.colliderect(obstacle.get_rect()):
game_over = True
high_score = max(high_score, score)

绘制分数

if game_started:
draw_score(score, high_score)

绘制开始界面(如果游戏未开始)

if not game_started:
draw_start_screen()

绘制游戏结束界面(如果游戏已结束)

if game_over:
draw_game_over(score, high_score)

绘制操作提示(游戏进行中)

if game_started and not game_over:
help_text = font.render("SPACE: Jump", True, BLACK)
screen.blit(help_text, (SCREEN_WIDTH - help_text.get_width() - 20, SCREEN_HEIGHT - 40))

更新显示

pygame.display.flip()

控制帧率

clock.tick(60)

if name == "main":
main()

posted on 2025-06-22 13:20  986614  阅读(32)  评论(0)    收藏  举报