Python小型太空侵略者游戏中玩家移动后子弹发射位置错误的问题
Python小型太空侵略者游戏中玩家移动后子弹发射位置错误的问题
嘿,我看到你的问题了——子弹总是从玩家初始位置发射,而不是当前位置对吧?这其实是因为你的代码里有个小坑:你在bullet.py里重新创建了一个全新的Player实例,而不是用main.py里你实际控制的那个玩家对象!下面我一步步给你解决这个问题,顺便优化下代码的小问题~
问题根源
你在bullet.py的全局作用域里写了player = Player(),这会创建一个完全独立的玩家对象,它的位置永远是初始的(0, -180),所以不管你在main.py里怎么移动玩家,子弹获取的都是这个“假玩家”的位置,自然不会跟着动啦。
另外,main.py里的while True循环会阻塞turtle的事件处理机制,导致你的按键响应可能会延迟或者不流畅,我们也一起改掉这个问题。
修改步骤
1. 修复bullet.py的引用问题
把bullet.py里的全局变量都删掉,让Bullet类接收实际的玩家对象作为参数,这样它就能获取到玩家的实时位置了:
from turtle import Turtle BULLET_SPEED = 10 class Bullet(Turtle): def __init__(self, player): super().__init__() self.player = player # 保存实际的玩家对象引用 self.color("red") self.shape("circle") self.penup() self.speed(0) self.setheading(90) self.shapesize(.5, .5) self.hideturtle() def fire_bullet(self): # 获取当前玩家的实时位置 x_pos = self.player.xcor() y_pos = self.player.ycor() self.setposition(x_pos, y_pos) self.showturtle()
2. 调整main.py的代码
- 创建
Bullet实例时,把main.py里的player传进去 - 把阻塞的
while True换成turtle的ontimer方法,避免卡按键:
from turtle import Turtle, Screen from player import Player from bullet import Bullet, BULLET_SPEED screen = Screen() screen.setup(width=800, height=800) screen.title("Shmup Test") screen.bgcolor("black") player = Player() bullet = Bullet(player) # 把实际玩家传给子弹 screen.listen() screen.onkey(key="Up", fun=player.go_up) screen.onkey(key="Down", fun=player.go_down) screen.onkey(key="Left", fun=player.go_left) screen.onkey(key="Right", fun=player.go_right) screen.onkey(key="space", fun=bullet.fire_bullet) def update_game(): # 只有当子弹显示的时候才移动它 if bullet.isvisible(): bullet.forward(BULLET_SPEED) # 可以加个判断,子弹飞出屏幕就隐藏 if bullet.ycor() > 400: bullet.hideturtle() # 每隔10毫秒刷新一次游戏 screen.ontimer(update_game, 10) # 启动游戏更新循环 update_game() screen.mainloop() # 不要忘了加这个,保持窗口运行
3. 优化player.py(可选,但更规范)
把player.py里的全局screen去掉,改用self.getscreen()获取当前屏幕,避免重复创建:
from turtle import Turtle MOVE_DISTANCE = 10 class Player(Turtle): def __init__(self): super().__init__() self.image = "penguin.gif" # 用self.getscreen()获取当前屏幕,不用全局创建 self.getscreen().register_shape(self.image) self.shape(self.image) self.penup() self.speed(0) self.setposition(0, -180) self.setheading(90) def go_up(self): new_y = self.ycor() + MOVE_DISTANCE if new_y > 330: new_y = 330 self.goto(self.xcor(), new_y) def go_down(self): new_y = self.ycor() - MOVE_DISTANCE if new_y < -330: new_y = -330 self.goto(self.xcor(), new_y) def go_left(self): new_x = self.xcor() - MOVE_DISTANCE if new_x < -330: new_x = -330 self.goto(new_x, self.ycor()) def go_right(self): new_x = self.xcor() + MOVE_DISTANCE if new_x > 330: new_x = 330 self.goto(new_x, self.ycor())
这样修改后,子弹就会从玩家当前的位置发射啦!而且按键响应也会更流畅,不会因为while True卡顿。
备注:内容来源于stack exchange,提问作者Needle_Kane
相关产品推荐
相关产品推荐

