超低质自制小游戏
开始界面:

运行界面;

结束界面:

代码:
点击查看代码
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()
浙公网安备 33010602011771号