大家好,我是一位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]
以上就是我遇到的问题以及我对它的描述。希望有这方面的高手可以帮我解决问题。谢谢。
单独给update_drct函数开一个线程
没有看到贪吃蛇前行的代码
根本原因在于你使用的 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()
代码格式乱掉了,不过是直接在你的代码基础上调整的,你应该能知道正确的格式