当我在 tkinter 游戏中按下一个键时,敌人会停止
Posted
技术标签:
【中文标题】当我在 tkinter 游戏中按下一个键时,敌人会停止【英文标题】:Enemies stop when I press a key in tkinter game 【发布时间】:2019-05-28 17:08:03 【问题描述】:为了练习编程,我用 Python 制作了一个带有海龟图形和 tkinter 的游戏。我有一个问题:如果我按下一个键,游戏循环就会停止并且敌人不会移动。这个问题有什么解决办法吗?
import random
import time
import turtle
from tkinter import *
running = True
#window
wn = Tk()
wn.geometry("900x700")
canvas = Canvas(wn, width=750, height=600)
canvas.pack()
canvas.place(relx=0.5, rely=0.5, anchor=CENTER)
#player
player = turtle.RawTurtle(canvas)
player_speed = 3
#enemies
enemies = []
for enemy in range(5):
enemies.append((turtle.RawTurtle(canvas), 10))
for enemy in enemies:
enemy[0].penup()
enemy[0].speed(0)
enemy[0].setheading(90)
enemy[0].goto(enemy_position_x(), enemy_position_y())#random position
#move the player
def move_left(event):
player.setheading(180)
player.setx(player.xcor() - player_speed)
def move_right(event):
player.setheading(360)
player.setx(player.xcor() + player_speed)
def move_up(event):
player.setheading(90)
player.sety(player.ycor() + player_speed)
def move_down(event):
player.setheading(270)
player.sety(player.ycor() - player_speed)
def shoot(event):
#I don't write the shoot function, because it's long
print("shoot")
wn.bind('<Left>', move_left)
wn.bind('<Right>', move_right)
wn.bind('<Up>', move_up)
wn.bind('<Down>', move_down)
wn.bind('<space>', shoot)
#game loop
while running:
#move the enemy
for this_enemy in enemies:
if this_enemy[0].xcor() < player.xcor():
this_enemy[0].setx(this_enemy[0].xcor() + 3)
time.sleep(0.1)
if this_enemy[0].xcor() > player.xcor():
this_enemy[0].setx(this_enemy[0].xcor() - 3)
time.sleep(0.1)
if this_enemy[0].ycor() < player.ycor():
this_enemy[0].sety(this_enemy[0].ycor() + 3)
time.sleep(0.1)
if this_enemy[0].ycor() > player.ycor():
this_enemy[0].sety(this_enemy[0].ycor() - 3)
time.sleep(0.1)
wn.mainloop()
【问题讨论】:
【参考方案1】:您的程序的基本设计不正确。 Turtle(和 tkinter)是事件驱动的,但是使用带有 time.sleep()
的 while True:
循环可以解决此问题。我在下面重写了您的代码以使用计时器事件以及其他更改。当你用键盘控制玩家时,敌人应该保持移动。我扔掉了 tkinter 包装器代码,因为它没有做任何乌龟无法为自己做的事情:
from turtle import Screen, Turtle
from random import randint
def enemy_position_x():
return randint(-325, 325)
def enemy_position_y():
return randint(-300, 300)
# move the player
def move_left():
player.setheading(180)
player.setx(player.xcor() - player_speed)
def move_right():
player.setheading(360)
player.setx(player.xcor() + player_speed)
def move_up():
player.setheading(90)
player.sety(player.ycor() + player_speed)
def move_down():
player.setheading(270)
player.sety(player.ycor() - player_speed)
def move():
# move the enemy
for enemy in enemies:
enemy.setheading(enemy.towards(player))
if enemy.distance(player) > 10:
enemy.forward(enemy_speed)
screen.ontimer(move, 100)
# window
screen = Screen()
screen.setup(900, 700)
# player
player = Turtle()
player.speed('fastest')
player.color('green')
player.penup()
player_speed = 3
# enemies
enemies = []
for _ in range(5):
enemy = Turtle()
enemy.penup()
enemy.speed('fastest')
enemy.color('red')
enemy.goto(enemy_position_x(), enemy_position_y())
enemies.append(enemy)
enemy_speed = 3
screen.onkey(move_left, 'Left')
screen.onkey(move_right, 'Right')
screen.onkey(move_up, 'Up')
screen.onkey(move_down, 'Down')
screen.listen()
move()
screen.mainloop()
【讨论】:
抱歉,我会使用 onkeypress。玩家必须平稳移动。 @Laszlo,我不知道这意味着什么。或者你为什么后悔。但可以肯定。 玩家必须在按键时移动。使用onkey,如果我按下键,玩家就会移动一次。 @Laszlo,您可能误解了关键事件。当你按下一个键时,你会产生一个“按下”,当你放手时,一个“释放”。按住键本身不会产生更多的“按下”事件,而是操作系统会启动其自动按键重复,从而生成一系列“按下”和“释放”事件。我不相信在这种情况下从“新闻”切换到“发布”会产生重大影响。我尝试了onkeyrelease
和onkeypress
,我注意到的唯一区别是后者专门将它与 Python 3 联系起来,但不影响操作。
谢谢,现在我明白了,但是我的问题有什么解决办法吗?以上是关于当我在 tkinter 游戏中按下一个键时,敌人会停止的主要内容,如果未能解决你的问题,请参考以下文章
当我在 vba powerpoint 中按下一个键时调用一个 Sub