小能豆

贪吃蛇小游戏只在按下键盘时移动

python

我是一位python的初学者。我在写一个贪吃蛇的小游戏时发现小蛇并不能像我设想那样始终向当前方向移动,相反,它只会在我按下改变方向的按键(w,a,s,d)时移动在松开这些按键时静止

我的希望的结果

在我多次检查代码无果后,我决定在这里提问,希望会有一些在编程领域的大神们帮助我解决这个问题。使w,a,s,d仅用于改变方向,小蛇应始终向前

我的编写代码的环境

操作系统:Arch Linux
Python版本:3.11.8(Pipenv)

我的代码

在尝试之前,您应先在您的终端执行sudo pacman -S python-keyboard或者类似的安装这个三方库的命令

gluttonous_snake.py

from snake import Snake
from keyboard import read_key
from os import system
from time import sleep

class Game:
    """游戏主类在这里"""

    def __init__(self, screen_width, screen_height):
        """初始化"""
        self.screen_width = screen_width
        self.screen_height = screen_height
        self.snake = Snake(length = 3, skin_char = "O", drct = "left")

    def run(self):
        """一个游戏的循环"""
        while True:
            self.update_drct()
            self.update_position()
            self.update_screen()
            sleep(0.2)

    def update_screen(self):
        """方法用于更新屏幕"""
        system("clear") #清屏
        #循环打印每行
        for y in range(self.screen_height):
            #循环打印每行的每个字符
            for x in range(self.screen_width):
                #获取当前字符的坐标
                position_now = [x, y]
                #判断是否是边界以及打印边界对应的字符
                if position_now[0] == 0 or position_now[0] == self.screen_width-1:
                    print("#", end="")
                elif position_now[1] == 0 or position_now[1] == self.screen_height-1:
                    print("#", end="")
                #判断如果不是边界,那么是什么
                else:
                    #声明一个判断当前位置是否是蛇的变量并赋值
                    is_snake = False
                    #取得小蛇身体位置的每个坐标并分别判断是否在当前坐标上
                    for c in self.snake.position:
                        if c == position_now:
                            is_snake = True
                    #根据是否是小蛇身体判断打印哪种字符
                    if is_snake == True:
                        print(self.snake.skin_char, end="")
                    else:
                        print(" ", end="")
            #在打印每行的每个字符后换行来打印下一行
            print()
            #print(f"{self.snake.drct} | {self.snake.position}") #括号里内容为开发时调试用

    def update_drct(self):
        """更新方向"""
        #获得当前按下的按键
        r = read_key()
        #根据当前按键判断方向的更改
        if r == "w" and self.snake.drct != "down":
            self.snake.make_a_turn("up")
        elif r == "a" and self.snake.drct != "right":
            self.snake.make_a_turn("left")
        elif r == "s" and self.snake.drct != "up":
            self.snake.make_a_turn("down")
        elif r == "d" and self.snake.drct != "left":
            self.snake.make_a_turn("right")
        #q键退出
        elif r == "q":
            exit(0)
        #如果没有按键就不变
        else:
            self.snake.make_a_turn(self.snake.drct)

    def update_position(self):
        """更新坐标"""
        self.snake.creep()

if __name__ == "__main__":
    print("欢迎来到Python贪吃蛇小游戏!")
    game = Game(screen_width = 90, screen_height = 30)
    game.run()

snake.py

class Snake:
    """一个模拟小蛇的类"""

    def __init__(self, length, skin_char, drct):
        """初始化属性length和skin_char等"""
        self.length = length
        self.skin_char = skin_char
        self.drct = drct
        self.position = [[80, 20], [81, 20], [82, 20]]

    def make_a_turn(self, new_drct):
        """一个使小蛇转向指定方向的方法"""
        self.drct = new_drct


    def creep(self):
        """一个使小蛇爬动的方法"""
        if self.drct == "up":
            self.position.insert(0, [self.position[0][0], self.position[0][1] - 1])
            del self.position[-1]
        elif self.drct == "down":
            self.position.insert(0, [self.position[0][0], self.position[0][1] + 1])
            del self.position[-1]
        elif self.drct == "left":
            self.position.insert(0, [self.position[0][0] - 1, self.position[0][1]])
            del self.position[-1]
        elif self.drct == "right":
            self.position.insert(0, [self.position[0][0] + 1, self.position[0][1]])
            del self.position[-1]

总结

以上就是我遇到的问题以及我对它的描述。希望有这方面的高手可以帮我解决问题。谢谢。


阅读 54

收藏
2024-06-01

共1个答案

小能豆

你的代码已经很接近预期的行为了,但是需要稍作调整才能让小蛇始终向前移动。

问题在于在 update_drct 方法中,你检查按键输入后,如果没有按键按下,你仍然调用了 self.snake.make_a_turn(self.snake.drct) 来改变方向,这导致了小蛇在没有按键按下时也会改变方向。为了解决这个问题,你可以在没有按键按下时不做任何操作,让小蛇继续沿着当前方向移动。

下面是修改后的 update_drct 方法:

def update_drct(self):
    """更新方向"""
    # 获得当前按下的按键
    r = read_key()
    # 根据当前按键判断方向的更改
    if r == "w" and self.snake.drct != "down":
        self.snake.make_a_turn("up")
    elif r == "a" and self.snake.drct != "right":
        self.snake.make_a_turn("left")
    elif r == "s" and self.snake.drct != "up":
        self.snake.make_a_turn("down")
    elif r == "d" and self.snake.drct != "left":
        self.snake.make_a_turn("right")
    # q键退出
    elif r == "q":
        exit(0)
    # 如果没有按键按下就不变
    # else:
    #     self.snake.make_a_turn(self.snake.drct)

注释掉 else 分支,这样在没有按键按下时,就不会改变小蛇的方向,它会沿着当前方向继续移动。

2024-06-01