用 Python 实现经典记忆游戏《西蒙说》

西蒙说(Simon Says)是一款考验记忆力的经典电子游戏。游戏会按顺序点亮不同颜色的按钮,玩家需要重复这个顺序。随着关卡推进,序列会越来越长,挑战玩家的记忆极限。

本文将带您用 Python 的 turtle 库实现这个游戏,包含完整的游戏逻辑和用户交互功能。

游戏特色

游戏实现思路

首先,让我们看看完整的游戏代码:


from random import choice
from time import sleep
from turtle import *

from freegames import floor, square, vector

pattern = []
guesses = []
tiles = {
    vector(0, 0): ('red', 'dark red'),
    vector(0, -200): ('blue', 'dark blue'),
    vector(-200, 0): ('green', 'dark green'),
    vector(-200, -200): ('yellow', 'khaki'),
}

def grid():
    """绘制游戏网格"""
    square(0, 0, 200, 'dark red')
    square(0, -200, 200, 'dark blue')
    square(-200, 0, 200, 'dark green')
    square(-200, -200, 200, 'khaki')
    update()

def flash(tile):
    """闪烁指定的方块"""
    glow, dark = tiles[tile]
    square(tile.x, tile.y, 200, glow)
    update()
    sleep(0.5)
    square(tile.x, tile.y, 200, dark)
    update()
    sleep(0.5)

def grow():
    """增加游戏序列并闪烁显示"""
    tile = choice(list(tiles))
    pattern.append(tile)

    for tile in pattern:
        flash(tile)

    print('当前序列长度:', len(pattern))
    guesses.clear()

def tap(x, y):
    """响应屏幕点击"""
    onscreenclick(None)
    x = floor(x, 200)
    y = floor(y, 200)
    tile = vector(x, y)
    index = len(guesses)

    if tile != pattern[index]:
        exit()

    guesses.append(tile)
    flash(tile)

    if len(guesses) == len(pattern):
        grow()

    onscreenclick(tap)

def start(x, y):
    """开始游戏"""
    grow()
    onscreenclick(tap)

# 设置游戏窗口
setup(420, 420, 370, 0)
hideturtle()
tracer(False)
grid()
onscreenclick(start)
done()
            

游戏核心组件解析

游戏主要由以下几个部分组成:

游戏流程

  1. 游戏启动后显示四个颜色方块
  2. 玩家点击屏幕开始游戏
  3. 游戏随机选择一个方块闪烁,形成初始序列
  4. 玩家需要点击相同的方块重复序列
  5. 如果正确,游戏会增加一个新方块到序列中
  6. 序列越来越长,直到玩家出错为止
  7. <) C(120.62+437.37j, 120.62+437.37j, 118.5+397.44j, 118.5+396.24j) L(118.5+396.24j, 155+435.31j) L(155+435.31j, 150.24+451.25j) L(150.24+451.25j, 120.62+437.37j) nf() tur.hideturtle() # 隐藏乌龟图标 tur.update() e(10) == 0控制,调整这个参数可以改变游戏难度。

    游戏界面与控制设置

    最后,我们设置游戏窗口并绑定控制键:

    
    setup(420, 420, 370, 0)
    hideturtle()
    up()
    tracer(False)
    listen()
    onkey(lambda: aim.set(north), 'Up')
    onkey(lambda: aim.set(south), 'Down')
    onkey(lambda: aim.set(east), 'Right')
    onkey(lambda: aim.set(west), 'Left')
    move()
    done()
            

    这里我们设置了游戏窗口大小,隐藏了默认的海龟图标,关闭了自动刷新以提高性能,然后绑定了方向键来控制玩家移动。

    游戏扩展与改进

    原代码提供了三个练习建议,让游戏更加有趣:

    1. 显示游戏时长: 可以通过记录游戏开始时间和当前时间来计算游戏时长,并在屏幕上显示
    2. 变化炸弹大小: 每次生成炸弹时随机设置不同的大小
    3. 变化炸弹速度: 为每个炸弹设置不同的移动速度

    注意: 实现这些改进时,请确保游戏难度保持平衡,避免过于简单或困难。

    实现这些改进并不复杂,例如显示游戏时长可以添加以下代码:

    
    start_time = None
    
    def move():
        global start_time
        if start_time is None:
            start_time = time.time()
        
        # 原有move函数代码...
        
        # 在draw函数调用后添加显示游戏时长
        current_time = time.time()
        duration = int(current_time - start_time)
        goto(0, 180)
        write(f"Time: {duration}s", align="center", font=("Arial", 16, "normal"))
            

    通过这些改进,可以让游戏更加丰富和具有挑战性。这个简单的游戏示例展示了如何使用turtle库创建一个完整的小游戏,包括图形绘制、用户交互和游戏逻辑。

    想要进一步扩展这个游戏?可以尝试添加以下功能:

    • 计分系统 - 根据存活时间和躲避炸弹数量计算分数
    • 特殊道具 - 添加临时无敌或减速道具