首页 新闻 会员 周边

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

0
[待解决问题]

问题描述

大家好,我是一位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]

总结

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

烈火天机的主页 烈火天机 | 菜鸟二级 | 园豆:202
提问于:2024-04-27 12:51
< >
分享
所有回答(3)
0

单独给update_drct函数开一个线程

jiajinzhao | 园豆:460 (菜鸟二级) | 2024-04-28 10:32
0

没有看到贪吃蛇前行的代码

每天一个bug小技巧 | 园豆:204 (菜鸟二级) | 2024-04-28 11:26
0

根本原因在于你使用的 read_key()方法,这个方法是阻塞运行的,所以你只有在按键盘后,才会触发一次此方法
调整如下:
from snake import Snake
from keyboard import read_key
import keyboard
from os import system
from time import sleep
import threading
current_key = None
def key_event(e):
global current_key
current_key = e.name
keyboard.hook(key_event)
class Game:
"""游戏主类在这里"""

old_action = ""
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:
        print('update_drct')
        self.update_drct()
        print('update_position')
        self.update_position()
        print('update_screen')
        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):
    global current_key
    """更新方向"""
    #获得当前按下的w按键
    # r = read_key()
    r = current_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):
    """更新坐标"""
    print(" 更新 坐标 ")
    self.snake.creep()

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

人间春风意 | 园豆:2368 (老鸟四级) | 2024-04-29 08:46

代码格式乱掉了,不过是直接在你的代码基础上调整的,你应该能知道正确的格式

支持(0) 反对(0) 人间春风意 | 园豆:2368 (老鸟四级) | 2024-04-29 08:52
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册