Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bullets shooting from wrong position after player moved in small "Space Invaders" game

I'm a beginner in Python and trying to code a game such as Space Invaders.

I created everything but when I move my character and fire, the bullet will remain shooting from the character's original position.

I need it the be shot from the character's actual position at every time.

main.py

from turtle import Turtle, Screen
from player import Player
from bullet import Bullet, BULLET_SPEED

turtle = Turtle()


screen = Screen()
screen.setup(width=800, height=800)
screen.title("Shmup Test")
screen.bgcolor("black")

player = Player()
bullet = Bullet()


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)

while True:
    bullet.forward(BULLET_SPEED)

player.py

from turtle import Turtle, Screen

MOVE_DISTANCE = 10

screen = Screen()


class Player(Turtle):

    def __init__(self):
        super().__init__()
        self.image = "penguin.gif"
        screen.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())

bullet.py

from turtle import Turtle, Screen
from player import Player

BULLET_SPEED = 10

self = Turtle()
player = Player()
screen = Screen()


class Bullet(Turtle):

    def __init__(self):
        super().__init__()
        self.color("red")
        self.shape("circle")
        self.penup()
        self.speed(0)
        self.setposition(player.xcor(), player.ycor())
        self.setheading(90)
        self.shapesize(.5, .5)
        self.hideturtle()

    def fire_bullet(self):
        x_pos = player.xcor()
        y_pos = player.ycor()
        self.setposition(x_pos, y_pos)
        self.showturtle()
like image 887
Needle_Kane Avatar asked Oct 20 '25 23:10

Needle_Kane


1 Answers

The Bullet class uses a separate instance of the Player class to determine from where to shoot.

So it does not notice if the Player instance used in main.py has moved.

You should use only one instance of Player that is shared between main.py and Bullet. A typical way to achieve that would be to create it in main.py and pass it as argument to Bullet.

There are several changes needed:

In main.py:

player = Player()
bullet = Bullet()

becomes

player = Player()
bullet = Bullet(player)

In bullet.py:

player = Player()

class Bullet(Turtle):
    def __init__(self):
        super().__init__()

becomes

class Bullet(Turtle):
    def __init__(self, player):
        super().__init__()
        self.player = player

and

    def fire_bullet(self):
        x_pos = player.xcor()
        y_pos = player.ycor()

becomes

    def fire_bullet(self):
        x_pos = self.player.xcor()
        y_pos = self.player.ycor()
like image 143
mkrieger1 Avatar answered Oct 23 '25 12:10

mkrieger1