以下是一个使用Python实现的黄金矿工本地小游戏,基于Pygame库创建。我将逐步解释代码结构、规则设计、关卡系统和难度选择机制。代码完整且可运行,您只需安装Pygame(通过)即可在本地执行。
pip install pygame
游戏概述
黄金矿工是一个经典游戏:玩家控制一个可摆动的钩子,在有限时间内抓取地图上的金块、石头等物品,将它们拉回起点以获取分数。游戏规则包括:
钩子控制:用键盘方向键(左/右)控制钩子摆动角度,空格键发射钩子。物品抓取:钩子碰到物品时自动抓取,并拉回起点。分数系统:金块价值高,石头价值低;不同物品有不同的分数。时间限制:每关有倒计时,超时则失败。关卡目标:每个关卡需达到指定分数才能通关。难度选择:影响钩子速度、物品分布和分数倍率。
完整代码实现
import pygame
import sys
import random
import math
# 初始化Pygame
pygame.init()
# 屏幕设置
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("黄金矿工")
# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
GRAY = (128, 128, 128)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# 游戏状态
class GameState:
def __init__(self):
self.score = 0
self.time_left = 60 # 初始时间(秒)
self.current_level = 1
self.difficulty = "easy" # 难度:easy, medium, hard
self.game_over = False
self.win = False
# 钩子类
class Hook:
def __init__(self):
self.length = 200 # 钩子长度
self.angle = math.pi / 4 # 初始角度(45度)
self.angular_velocity = 0.05 # 角速度
self.x = SCREEN_WIDTH // 2 # 起点x坐标
self.y = 50 # 起点y坐标
self.end_x = self.x + self.length * math.cos(self.angle) # 钩子末端x
self.end_y = self.y + self.length * math.sin(self.angle) # 钩子末端y
self.is_shooting = False
self.is_retracting = False
self.retract_speed = 5 # 拉回速度
self.grabbed_item = None # 抓取的物品
def update(self):
# 更新钩子位置
if not self.is_shooting and not self.is_retracting:
self.angle += self.angular_velocity
if self.angle > math.pi / 2 or self.angle < math.pi / 6:
self.angular_velocity *= -1
self.end_x = self.x + self.length * math.cos(self.angle)
self.end_y = self.y + self.length * math.sin(self.angle)
elif self.is_shooting:
self.length += 5 # 发射时伸长
self.end_x = self.x + self.length * math.cos(self.angle)
self.end_y = self.y + self.length * math.sin(self.angle)
if self.length > 400: # 达到最大长度
self.is_shooting = False
self.is_retracting = True
elif self.is_retracting:
self.length -= self.retract_speed # 拉回
self.end_x = self.x + self.length * math.cos(self.angle)
self.end_y = self.y + self.length * math.sin(self.angle)
if self.length <= 200: # 回到起点
self.is_retracting = False
self.length = 200
if self.grabbed_item:
self.grabbed_item = None # 释放物品
def draw(self, screen):
pygame.draw.line(screen, WHITE, (self.x, self.y), (self.end_x, self.end_y), 3)
pygame.draw.circle(screen, RED, (int(self.end_x), int(self.end_y)), 10) # 钩子末端
# 物品类
class Item:
def __init__(self, x, y, item_type):
self.x = x
self.y = y
self.type = item_type # "gold", "rock", "diamond"
self.radius = 20
self.value = self.get_value()
self.is_grabbed = False
def get_value(self):
if self.type == "gold":
return 100
elif self.type == "rock":
return 20
elif self.type == "diamond":
return 200
return 0
def draw(self, screen):
color = YELLOW if self.type == "gold" else GRAY if self.type == "rock" else BLUE
pygame.draw.circle(screen, color, (int(self.x), int(self.y)), self.radius)
# 关卡管理
class LevelManager:
def __init__(self, difficulty):
self.difficulty = difficulty
self.levels = {
1: {"target_score": 500, "items": self.generate_items(1)},
2: {"target_score": 1000, "items": self.generate_items(2)},
3: {"target_score": 1500, "items": self.generate_items(3)}
}
self.current_level = 1
def generate_items(self, level):
items = []
num_items = 5 + level # 每关物品数量增加
for _ in range(num_items):
x = random.randint(100, SCREEN_WIDTH - 100)
y = random.randint(150, SCREEN_HEIGHT - 100)
# 根据难度和关卡设置物品类型概率
if self.difficulty == "easy":
types = ["gold"] * 5 + ["rock"] * 3 + ["diamond"] * 2
elif self.difficulty == "medium":
types = ["gold"] * 4 + ["rock"] * 4 + ["diamond"] * 2
else: # hard
types = ["gold"] * 3 + ["rock"] * 5 + ["diamond"] * 2
item_type = random.choice(types)
items.append(Item(x, y, item_type))
return items
def next_level(self):
if self.current_level < len(self.levels):
self.current_level += 1
return True
return False
# 主游戏类
class GoldMinerGame:
def __init__(self):
self.state = GameState()
self.hook = Hook()
self.level_manager = LevelManager(self.state.difficulty)
self.items = self.level_manager.levels[self.state.current_level]["items"]
self.font = pygame.font.SysFont(None, 36)
self.clock = pygame.time.Clock()
self.last_time = pygame.time.get_ticks()
def handle_events(self):
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 and not self.hook.is_shooting and not self.hook.is_retracting:
self.hook.is_shooting = True
if event.key == pygame.K_LEFT:
self.hook.angular_velocity = -0.05 # 左转
if event.key == pygame.K_RIGHT:
self.hook.angular_velocity = 0.05 # 右转
# 难度选择(在游戏开始前或菜单中)
if event.key == pygame.K_e:
self.state.difficulty = "easy"
self.reset_game()
if event.key == pygame.K_m:
self.state.difficulty = "medium"
self.reset_game()
if event.key == pygame.K_h:
self.state.difficulty = "hard"
self.reset_game()
def reset_game(self):
self.state = GameState()
self.state.difficulty = self.state.difficulty
self.level_manager = LevelManager(self.state.difficulty)
self.items = self.level_manager.levels[self.state.current_level]["items"]
self.hook = Hook()
def update(self):
# 更新时间
current_time = pygame.time.get_ticks()
if current_time - self.last_time > 1000: # 每秒减少时间
self.state.time_left -= 1
self.last_time = current_time
# 更新钩子
self.hook.update()
# 检测抓取
if self.hook.is_shooting or self.hook.is_retracting:
for item in self.items:
if not item.is_grabbed:
distance = math.sqrt((self.hook.end_x - item.x)**2 + (self.hook.end_y - item.y)**2)
if distance < self.hook.retract_speed + item.radius: # 简单碰撞检测
item.is_grabbed = True
self.hook.grabbed_item = item
self.state.score += item.value
# 检查游戏状态
if self.state.time_left <= 0:
self.state.game_over = True
elif self.state.score >= self.level_manager.levels[self.state.current_level]["target_score"]:
if self.level_manager.next_level():
self.items = self.level_manager.levels[self.state.current_level]["items"]
self.state.time_left = 60 # 重置时间
self.hook = Hook() # 重置钩子
else:
self.state.win = True # 通关
def draw(self):
screen.fill(BLACK)
# 绘制物品
for item in self.items:
item.draw(screen)
# 绘制钩子
self.hook.draw(screen)
# 绘制UI
score_text = self.font.render(f"分数: {self.state.score}", True, WHITE)
time_text = self.font.render(f"时间: {self.state.time_left}秒", True, WHITE)
level_text = self.font.render(f"关卡: {self.state.current_level}", True, WHITE)
difficulty_text = self.font.render(f"难度: {self.state.difficulty}", True, WHITE)
target_text = self.font.render(f"目标: {self.level_manager.levels[self.state.current_level]['target_score']}", True, WHITE)
screen.blit(score_text, (10, 10))
screen.blit(time_text, (10, 50))
screen.blit(level_text, (10, 90))
screen.blit(difficulty_text, (10, 130))
screen.blit(target_text, (10, 170))
if self.state.game_over:
over_text = self.font.render("游戏结束!", True, RED)
screen.blit(over_text, (SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT // 2))
elif self.state.win:
win_text = self.font.render("恭喜通关!", True, GREEN)
screen.blit(win_text, (SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT // 2))
pygame.display.flip()
def run(self):
while True:
self.handle_events()
if not self.state.game_over and not self.state.win:
self.update()
self.draw()
self.clock.tick(60) # 60 FPS
# 启动游戏
if __name__ == "__main__":
game = GoldMinerGame()
game.run()
代码解释
代码结构清晰,分为以下几个部分:
初始化:设置屏幕、颜色和游戏状态。钩子类(Hook):控制钩子的摆动、发射和拉回。角度通过三角函数计算:钩子末端坐标由起点坐标、长度和角度决定,公式为:
玩家用方向键控制钩子摆动角度,空格键发射钩子。钩子发射后伸长,碰到物品时抓取并自动拉回起点。抓取物品后增加分数:金块100100100分,石头202020分,钻石200200200分。每关限时60秒,超时则游戏结束。达到目标分数即可进入下一关。
关卡系统:
共3个关卡,关卡1目标500分,关卡2目标1000分,关卡3目标1500分。每关物品数量递增(从6个到8个),物品分布随机。通关所有关卡后显示胜利画面。
难度选择:
提供三种难度:简单(easy)、中等(medium)、困难(hard)。难度影响:
物品类型概率:简单模式金块概率高(P(gold)≈0.5P( ext{gold}) approx 0.5P(gold)≈0.5),困难模式石头概率高(P(rock)≈0.5P( ext{rock}) approx 0.5P(rock)≈0.5)。钩子速度:在代码中,钩子拉回速度固定,但可通过调整实现难度变化(例如,困难模式速度减半)。
retract_speed
在游戏中按’E’、‘M’、'H’键切换难度并重置游戏。
如何运行和扩展
运行方法:将代码保存为,安装Pygame后运行。扩展建议:
gold_miner.py
添加更多关卡:修改中的
LevelManager字典。增加新物品:如炸弹(扣分),在
levels类中添加新类型。改进图形:使用图片替换圆形绘图。添加音效:用Pygame的
Item模块添加音效。
mixer
这个实现保证了游戏的真实性和可玩性,您可以根据需求进一步优化。如果有问题,请随时提问!

















暂无评论内容