我用python turtle开发这个简单的射击游戏已经有几天了,我遇到了一个我找不到答案的错误。
我想要的是,玩家每杀死5次,就会出现一个额外的敌人。但是当我被杀死5次时,无数的错误信息开始涌入。
错误消息是:isvisible() missing 1 required positional argument: 'self'
它指向我的enemy_attack
函数,在该函数中,我使用isvisible()
命令测试敌人是否被射杀,以使其从另一个随机位置重生。提前谢谢你的帮助。
我为没有评论而道歉
import turtle
import time
import random
from random import randint
game_over = False
kill_counter = 0
enemy_spawn_number = 5
def close():
turtle.bye()
speed = 10
enemy_speed = 0.5
lives = 3
wn = turtle.Screen()
wn.title("Defend.")
wn.bgcolor("black")
wn.setup(width=600, height=600)
wn.tracer(0)
player = turtle.Turtle()
player.speed(0)
player.shape("triangle")
player.color("white")
player.penup()
player.goto(0,0)
life1 = turtle.Turtle()
life1.speed(0)
life1.shape("triangle")
life1.color("yellow")
life1.penup()
life1.goto(265,-260)
life1.setheading(-90)
life2 = life1.clone()
life2.goto(240,-260)
life3 = life2.clone()
life3.goto(215,-260)
over_message = turtle.Turtle()
over_message.speed(0)
over_message.shape("square")
over_message.color("white")
over_message.penup()
over_message.goto(0,0)
over_message.ht()
killcount = over_message.clone()
killcount.goto(250,250)
killcount.ht()
killcount.write("Kill Count: 0", align="right", font=("Courier", 15, "normal"))
def go_up():
player.setheading(90)
player.forward(speed)
def go_right():
player.setheading(0)
player.forward(speed)
def go_left():
player.setheading(180)
player.forward(speed)
def go_down():
player.setheading(-90)
player.forward(speed)
wn.listen()
wn.onkeypress(go_up, "w")
wn.onkeypress(go_right, "d")
wn.onkeypress(go_left, "a")
wn.onkeypress(go_down, "s")
wn.onkeypress(close, "Escape")
collectible = turtle.Turtle()
collectible.speed(0)
collectible.shape("square")
collectible.color("blue")
collectible.penup()
collectible.goto(0,100)
bullet = turtle.Turtle()
bullet.shape("square")
bullet.color("grey")
bullet.shapesize(0.5,1)
bullet.hideturtle()
bullet.penup()
bullet.goto(500,500)
shooting = False
def shoot():
global shooting
if bullet.isvisible() == False:
player_x = player.xcor()
player_y = player.ycor()
player_facing = player.heading()
bullet.goto(player_x,player_y)
bullet.setheading(player_facing)
shooting = True
bullet.showturtle()
enemies = []
enemies.append(turtle.Turtle())
for enemy in enemies:
enemy.speed(0)
enemy.shape("circle")
enemy.color("red")
enemy.penup()
enemy.goto(0,350)
def enemy_attack():
global game_over
for enemy in enemies:
if enemy.isvisible() == True:
enemy.setheading(enemy.towards(player))
enemy.forward(enemy_speed)
wn.ontimer(enemy_attack, 10)
else:
if game_over == False:
rand_direction = randint(0,3)
if rand_direction == 0:
x = randint(-240, 200)
enemy.goto(x,450)
enemy.st()
enemy_attack()
elif rand_direction == 1:
x = randint(-240, 200)
enemy.goto(x,-450)
enemy.st()
enemy_attack()
elif rand_direction == 2:
y = randint(-210, 210)
enemy.goto(-450,y)
enemy.st()
enemy_attack()
elif rand_direction == 3:
y = randint(-210, 210)
enemy.goto(450,y)
enemy.st()
enemy_attack()
enemy_attack()
wn.onkey(shoot, "space")
while True:
wn.update()
if player.distance(collectible) < 20:
x = randint(-290, 290)
y = randint(-290, 290)
collectible.goto(x,y)
if bullet.xcor()>310 or bullet.xcor()<-310 or bullet.ycor()>310 or bullet.ycor()<-300:
shooting = False
bullet.hideturtle()
if shooting == True:
bullet.forward(0.2)
if player.xcor()>285:
playerX = player.xcor()
playerX = playerX-5
playerY = player.ycor()
player.goto(playerX,playerY)
elif player.xcor()<-285:
playerX = player.xcor()
playerX = playerX+5
playerY = player.ycor()
player.goto(playerX,playerY)
elif player.ycor()>285:
playerY = player.ycor()
playerY = playerY-5
playerX = player.xcor()
player.goto(playerX,playerY)
elif player.ycor()<-285:
playerY = player.ycor()
playerY = playerY+5
playerX = player.xcor()
player.goto(playerX,playerY)
for enemy in enemies:
if bullet.distance(enemy) < 20:
bullet.hideturtle()
enemy.hideturtle()
enemy.goto(0,350)
kill_counter = kill_counter+1
killcount.clear()
killcount.write("Kill Count: {}".format(kill_counter), align="right", font=("Courier", 15, "normal"))
if kill_counter == enemy_spawn_number:
enemies.append(turtle.Turtle)
for enemy in enemies:
enemy.speed(0)
enemy.shape("circle")
enemy.color("red")
enemy.penup()
enemy.goto(0,350)
enemy_spawn_number += 5
if enemy.distance(player) < 20:
enemy.ht()
player.goto(0,0)
lives = lives-1
if lives == 2:
life3.ht()
elif lives == 1:
life2.ht()
elif lives == 0:
life1.ht()
time.sleep(0.1)
if lives == 0:
game_over = True
collectible.ht()
player.ht()
for enemy in enemies:
enemy.ht()
over_message.write("Game Over! Press Esc to exit.", align="center", font=("Courier", 24, "normal"))```
我运行代码,大部分时间都能正常工作
在某个时刻它出错了
我开始思考为什么
enemy
(也就是turtle
)没有_speed
?为什么它将其视为整数?所有的enemy
都在列表上enemies
,所以我开始检查您添加到这个列表中的内容,我发现您在其中一个Turtle()
中忘记了()
所以它添加了类Turtle而不是Turle的实例
添加
()
后,我没有这个错误,但似乎还有其他问题,因为在杀死5个敌人后,它会冻结。它需要一些调试(或使用print()
)来找出问题所在编辑:如果我在开始时添加两个敌人,我会遇到同样的问题。问题可能是它可能会运行两次
wn.ontimer
,而这可能会运行另外两次wn.ontimer
,所以最后它可能没有时间执行它们EDIT:如果我在函数末尾只使用
wn.ontimer(enemy_attack, 10)
并删除其他enemy_attack()
代码,效果会更好。但这一次,敌人大多同时出现,当我杀死其中一个敌人时,它就会将他们全部移除。它可能需要更多的改变我看到的主要问题是@furas所指的:
enemy_attack()
通过递归和计时器调用自身turtle.Turtle
调用时不带括号。我不认为以任何方式调用enemy_attack()
都是一个好主意,相反,应该在主程序循环中调用它使用
ontimer()
的一个问题是,您需要确保使用的超时时间大于执行函数所需的时间。除非它被设计为同时运行自身的多个实例。如果它写的是一个全局变量,那么它可能一次只能写一个在基于事件的环境(如turtle)中,不应该有
while True:
(或time.sleep()
)。ontimer()
方法应该同时处理这两个问题在Python方面,您不应该执行以下操作:
相反,你应该:
下面,我把你的代码拆开,按照我期望的海龟游戏的设计方式重新组装。可能还有bug,但现在似乎可以玩了:
我认为您应该解决的下一个问题是代码中阻止您调整屏幕大小的所有数字常量:
这些都应根据屏幕大小进行定义:
以及他们操纵的对象。(即代码中没有大数字!)
相关问题 更多 >
编程相关推荐