Python 海龟未记录碰撞
Collisions aren't registering with Python Turtles
我正在按照在线教程创建一个简单的 2D 射击游戏,敌人精灵(除 1 个外,共有 5 个)不遵守我的碰撞代码。一切正常,除了玩家控制的子弹对象直接穿过敌人的精灵。我收到的错误消息:
Traceback (most recent call last):
File "C:\Python\Python36\pygame projects\space invaders.py", line 163, in <module>
bullet.hideturtle()
File "C:\Python\Python36\lib\turtle.py", line 2322, in hideturtle
self.pen(shown=False)
File "C:\Python\Python36\lib\turtle.py", line 2459, in pen
self._update()
File "C:\Python\Python36\lib\turtle.py", line 2660, in _update
self._update_data()
File "C:\Python\Python36\lib\turtle.py", line 2646, in _update_data
self.screen._incrementudc()
File "C:\Python\Python36\lib\turtle.py", line 1292, in _incrementudc
raise Terminator
turtle.Terminator
如果你浏览一半代码,你会发现我用于碰撞数学的毕达哥拉斯理论,不确定它是否正确:
enemies = []
number_of_enemies = 5
for i in range(number_of_enemies):
enemies.append(turtle.Turtle())
for enemy in enemies:
enemy.color("green")
enemy.shape("circle")
enemy.penup()
enemy.speed(0)
x = random.randint(-200, 200)
y = random.randint(100, 250)
enemy.setposition(x, y)
enemyspeed = 2
def isCollision(t1, t2):
distance = math.sqrt(math.pow(t1.xcor() - t2.xcor(), 2)+ math.pow(t1.ycor() - t2.ycor(), 2))
if distance < 15:
return True
else:
return False
while True:
for enemy in enemies:
x = enemy.xcor()
x += enemyspeed
enemy.setx(x)
if enemy.xcor() > 280:
for e in enemies:
y = enemy.ycor()
y -= 40
enemy.sety(y)
enemyspeed *= -1
if enemy.xcor() < -280:
for e in enemies:
y = enemy.ycor()
y -= 40
enemy.sety(y)
enemyspeed *= -1
if bulletstate == "fire":
y = bullet.ycor()
y += bulletspeed
bullet.sety(y)
if isCollision(bullet, enemy):
#reset the bullet
bullet.hideturtle()
bulletstate = "ready"
bullet.setposition(0, -400)
#reset the enemy
x = random.randint(-200, 200)
y = random.randint(100, 250)
enemy.setposition(x, y)
if isCollision(player, enemy):
player.hideturtle()
enemy.hideturtle()
print ("Get To The Doctors! You're Riddled!")
break
如果答案显而易见,我们深表歉意。如果有人花时间解释错误,我将不胜感激。其他人也发布了类似的问题,但每个人都有适用于他们的例子,而我仍处于很难想象别人的例子的阶段。任何帮助将不胜感激。
我认为您的主要问题是您在每次敌人更新之间更新子弹,而不是针对所有敌人更新一次。这会在视觉效果和实际发生的事情之间造成偏差。另外,你不需要定义毕达哥拉斯公式,海龟们已经知道了!以下是我对您的代码进行的修改,以解决上述问题并稍微修改编码风格和效率:
from turtle import Turtle, Screen
from random import randint
NUMBER_OF_ENEMIES = 5
ENEMY_JUMP = 40
BULLET_SPEED = 20
PLAYER_SPEED = 15
SAFETY_DISTANCE = 15
GALLERY_WIDTH, GALLERY_HEIGHT = 560, 550
GALLERY_BORDER = 80
# player movement
def move_left():
x = player.xcor() - PLAYER_SPEED
if x < -GALLERY_WIDTH / 2:
x = -GALLERY_WIDTH / 2
player.setx(x)
def move_right():
x = player.xcor() + PLAYER_SPEED
if x > GALLERY_WIDTH / 2:
x = GALLERY_WIDTH / 2
player.setx(x)
def fire_bullet():
global bulletstate
if bulletstate == 'ready':
bulletstate = 'fire'
bullet.setposition(player.position())
bullet.forward(BULLET_SPEED / 2)
bullet.showturtle()
def isCollision(t1, t2):
return t1.distance(t2) < SAFETY_DISTANCE
def move():
global enemy_speed, bulletstate
screen.tracer(False)
for enemy in enemies:
x = enemy.xcor() + enemy_speed
enemy.setx(x)
if x > GALLERY_WIDTH / 2:
for e in enemies:
y = e.ycor() - ENEMY_JUMP
e.sety(y)
enemy_speed *= -1
elif x < -GALLERY_WIDTH / 2:
for e in enemies:
y = e.ycor() - ENEMY_JUMP
e.sety(y)
enemy_speed *= -1
if isCollision(player, enemy):
player.hideturtle()
enemy.hideturtle()
print("Get To The Doctors! You're Riddled!")
screen.update()
return
if isCollision(bullet, enemy):
# reset the bullet
bullet.hideturtle()
bullet.setposition(0, -GALLERY_HEIGHT)
bulletstate = 'ready'
# reset the enemy
enemy.hideturtle()
x = randint(GALLERY_BORDER - GALLERY_WIDTH / 2, GALLERY_WIDTH / 2 - GALLERY_BORDER)
y = randint(GALLERY_HEIGHT / 2 - 175, GALLERY_HEIGHT / 2 - 25)
enemy.setposition(x, y)
enemy.showturtle()
if bulletstate == 'fire':
bullet.forward(BULLET_SPEED)
# check to see if the bullets has gone to the top
if bullet.ycor() > GALLERY_HEIGHT / 2:
bullet.hideturtle()
bulletstate = 'ready'
screen.tracer(True)
screen.ontimer(move, 25)
screen = Screen()
screen.setup(GALLERY_WIDTH + GALLERY_BORDER, GALLERY_HEIGHT + GALLERY_BORDER)
screen.bgcolor('black')
player = Turtle('turtle', visible=False)
player.speed('fastest')
player.color('red')
player.penup()
player.setheading(90)
player.sety(-250) # need to define this
player.showturtle()
enemies = []
enemy_speed = 1
for _ in range(NUMBER_OF_ENEMIES):
enemy = Turtle('circle', visible=False)
enemy.speed('fastest')
enemy.color('green')
enemy.penup()
x = randint(GALLERY_BORDER - GALLERY_WIDTH / 2, GALLERY_WIDTH / 2 - GALLERY_BORDER)
y = randint(GALLERY_HEIGHT / 2 - 175, GALLERY_HEIGHT / 2 - 25) # define these!
enemy.setposition(x, y)
enemy.showturtle()
enemies.append(enemy)
# create the player's spunk shots
bullet = Turtle('triangle', visible=False)
bullet.speed('fastest')
bullet.shapesize(0.5)
bullet.color('white')
bullet.penup()
bullet.setheading(90)
# define bullet state
# ready - ready to fire
# fire - bullet is firing
bulletstate = 'ready'
screen.onkey(move_left, 'Left')
screen.onkey(move_right, 'Right')
screen.onkey(fire_bullet, 'space')
screen.listen()
move()
screen.mainloop()
我猜到了缺失的部分。看看这对您有何影响。
我正在按照在线教程创建一个简单的 2D 射击游戏,敌人精灵(除 1 个外,共有 5 个)不遵守我的碰撞代码。一切正常,除了玩家控制的子弹对象直接穿过敌人的精灵。我收到的错误消息:
Traceback (most recent call last):
File "C:\Python\Python36\pygame projects\space invaders.py", line 163, in <module>
bullet.hideturtle()
File "C:\Python\Python36\lib\turtle.py", line 2322, in hideturtle
self.pen(shown=False)
File "C:\Python\Python36\lib\turtle.py", line 2459, in pen
self._update()
File "C:\Python\Python36\lib\turtle.py", line 2660, in _update
self._update_data()
File "C:\Python\Python36\lib\turtle.py", line 2646, in _update_data
self.screen._incrementudc()
File "C:\Python\Python36\lib\turtle.py", line 1292, in _incrementudc
raise Terminator
turtle.Terminator
如果你浏览一半代码,你会发现我用于碰撞数学的毕达哥拉斯理论,不确定它是否正确:
enemies = []
number_of_enemies = 5
for i in range(number_of_enemies):
enemies.append(turtle.Turtle())
for enemy in enemies:
enemy.color("green")
enemy.shape("circle")
enemy.penup()
enemy.speed(0)
x = random.randint(-200, 200)
y = random.randint(100, 250)
enemy.setposition(x, y)
enemyspeed = 2
def isCollision(t1, t2):
distance = math.sqrt(math.pow(t1.xcor() - t2.xcor(), 2)+ math.pow(t1.ycor() - t2.ycor(), 2))
if distance < 15:
return True
else:
return False
while True:
for enemy in enemies:
x = enemy.xcor()
x += enemyspeed
enemy.setx(x)
if enemy.xcor() > 280:
for e in enemies:
y = enemy.ycor()
y -= 40
enemy.sety(y)
enemyspeed *= -1
if enemy.xcor() < -280:
for e in enemies:
y = enemy.ycor()
y -= 40
enemy.sety(y)
enemyspeed *= -1
if bulletstate == "fire":
y = bullet.ycor()
y += bulletspeed
bullet.sety(y)
if isCollision(bullet, enemy):
#reset the bullet
bullet.hideturtle()
bulletstate = "ready"
bullet.setposition(0, -400)
#reset the enemy
x = random.randint(-200, 200)
y = random.randint(100, 250)
enemy.setposition(x, y)
if isCollision(player, enemy):
player.hideturtle()
enemy.hideturtle()
print ("Get To The Doctors! You're Riddled!")
break
如果答案显而易见,我们深表歉意。如果有人花时间解释错误,我将不胜感激。其他人也发布了类似的问题,但每个人都有适用于他们的例子,而我仍处于很难想象别人的例子的阶段。任何帮助将不胜感激。
我认为您的主要问题是您在每次敌人更新之间更新子弹,而不是针对所有敌人更新一次。这会在视觉效果和实际发生的事情之间造成偏差。另外,你不需要定义毕达哥拉斯公式,海龟们已经知道了!以下是我对您的代码进行的修改,以解决上述问题并稍微修改编码风格和效率:
from turtle import Turtle, Screen
from random import randint
NUMBER_OF_ENEMIES = 5
ENEMY_JUMP = 40
BULLET_SPEED = 20
PLAYER_SPEED = 15
SAFETY_DISTANCE = 15
GALLERY_WIDTH, GALLERY_HEIGHT = 560, 550
GALLERY_BORDER = 80
# player movement
def move_left():
x = player.xcor() - PLAYER_SPEED
if x < -GALLERY_WIDTH / 2:
x = -GALLERY_WIDTH / 2
player.setx(x)
def move_right():
x = player.xcor() + PLAYER_SPEED
if x > GALLERY_WIDTH / 2:
x = GALLERY_WIDTH / 2
player.setx(x)
def fire_bullet():
global bulletstate
if bulletstate == 'ready':
bulletstate = 'fire'
bullet.setposition(player.position())
bullet.forward(BULLET_SPEED / 2)
bullet.showturtle()
def isCollision(t1, t2):
return t1.distance(t2) < SAFETY_DISTANCE
def move():
global enemy_speed, bulletstate
screen.tracer(False)
for enemy in enemies:
x = enemy.xcor() + enemy_speed
enemy.setx(x)
if x > GALLERY_WIDTH / 2:
for e in enemies:
y = e.ycor() - ENEMY_JUMP
e.sety(y)
enemy_speed *= -1
elif x < -GALLERY_WIDTH / 2:
for e in enemies:
y = e.ycor() - ENEMY_JUMP
e.sety(y)
enemy_speed *= -1
if isCollision(player, enemy):
player.hideturtle()
enemy.hideturtle()
print("Get To The Doctors! You're Riddled!")
screen.update()
return
if isCollision(bullet, enemy):
# reset the bullet
bullet.hideturtle()
bullet.setposition(0, -GALLERY_HEIGHT)
bulletstate = 'ready'
# reset the enemy
enemy.hideturtle()
x = randint(GALLERY_BORDER - GALLERY_WIDTH / 2, GALLERY_WIDTH / 2 - GALLERY_BORDER)
y = randint(GALLERY_HEIGHT / 2 - 175, GALLERY_HEIGHT / 2 - 25)
enemy.setposition(x, y)
enemy.showturtle()
if bulletstate == 'fire':
bullet.forward(BULLET_SPEED)
# check to see if the bullets has gone to the top
if bullet.ycor() > GALLERY_HEIGHT / 2:
bullet.hideturtle()
bulletstate = 'ready'
screen.tracer(True)
screen.ontimer(move, 25)
screen = Screen()
screen.setup(GALLERY_WIDTH + GALLERY_BORDER, GALLERY_HEIGHT + GALLERY_BORDER)
screen.bgcolor('black')
player = Turtle('turtle', visible=False)
player.speed('fastest')
player.color('red')
player.penup()
player.setheading(90)
player.sety(-250) # need to define this
player.showturtle()
enemies = []
enemy_speed = 1
for _ in range(NUMBER_OF_ENEMIES):
enemy = Turtle('circle', visible=False)
enemy.speed('fastest')
enemy.color('green')
enemy.penup()
x = randint(GALLERY_BORDER - GALLERY_WIDTH / 2, GALLERY_WIDTH / 2 - GALLERY_BORDER)
y = randint(GALLERY_HEIGHT / 2 - 175, GALLERY_HEIGHT / 2 - 25) # define these!
enemy.setposition(x, y)
enemy.showturtle()
enemies.append(enemy)
# create the player's spunk shots
bullet = Turtle('triangle', visible=False)
bullet.speed('fastest')
bullet.shapesize(0.5)
bullet.color('white')
bullet.penup()
bullet.setheading(90)
# define bullet state
# ready - ready to fire
# fire - bullet is firing
bulletstate = 'ready'
screen.onkey(move_left, 'Left')
screen.onkey(move_right, 'Right')
screen.onkey(fire_bullet, 'space')
screen.listen()
move()
screen.mainloop()
我猜到了缺失的部分。看看这对您有何影响。