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  阅读(17)  评论(0)    收藏  举报