Lucky38i
Lucky38i

Reputation: 135

Shoot bullet in the direction my ship is pointing

I want to get my bullet shooting in the direction that my ship is facing. I managed to get a bullet in the game using this very useful code: How to create bullets in pygame?

Let me provide some code for reference. Below is the set of codes used to rotate my ship as-well as get it to move in said direction. Also, Offset = 0.

'''Directional commands for the sprite'''
if pressed[pygame.K_LEFT]: offset_change += 4
if pressed[pygame.K_RIGHT]: offset_change -= 4
if pressed[pygame.K_UP]:
    y_change -= cos(spaceship.angle) * 8
    x_change -= sin(spaceship.angle) * 8    
if pressed[pygame.K_DOWN]:
    y_change += 5
if event.type == pygame.KEYUP:
    if event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT or event.key == pygame.K_UP or event.key == pygame.K_DOWN:
        x_change = 0
        y_change = 0
        offset_change = 0

'''changes X/Y based on the value of X/Y_Change'''

spaceship.angle += offset_change        
spaceship.startY += y_change
spaceship.startX += x_change

Below is the class the spaceship code is in.

class Spaceship():
'''Class attributed to loading the spaceship'''
    def __init__(self, char, startX, startY, Angle):
        '''Loads in the image and sets variables'''
        self.char = char
        self.startX = startX
        self.startY = startY
        self.angle = Angle
        self.space = load_item(self.char)
        self.drawChar()

    def drawChar(self):
        '''Draws the image on the screen'''
        #Code is from Pygame documentation 
        #Due to limitations of Pygame the following code had to be used with a few of my own manipulations
        rot_image = pygame.transform.rotate(self.space,self.angle)
        rot_rect = self.space.get_rect()
        rot_rect.center = rot_image.get_rect().center
        rot_image = rot_image.subsurface(rot_rect).copy()
        gameDisplay.blit(rot_image,(self.startX,self.startY))

Now as part of the "How to create bullets..." link I previously mentioned I was thinking of changing

for b in range(len(bullets)):
    bullets[b][1] -= 8

to bullets[spaceship.startX][spaceship.startY] -= 8 As it was my belief that that line of code represented bullets[x][y]. However I was presented with TypeError: list indices must be integers, not float.

I'm guessing my assumption is wrong. Any ideas you can suggest to get my bullet moving according to how I'd like it to be?

Upvotes: 1

Views: 406

Answers (1)

CodenameLambda
CodenameLambda

Reputation: 1496

b is the index of the bullet in the list bullets, and 0 or 1 are the x and y coordinates.

You can update them as follows, with angle and speed changed to their values:

for bullet in bullets:  # as 'bullets' is a list of lists
    bullet[0] += math.cos(angle) * speed
    bullet[1] += math.sin(angle) * speed

Another, more object oriented, approach:

class Vector(tuple):
    def __new__(cls, *args):
        if len(args) == 1 and hasattr(args[0], "__iter__"):
            return super().__new__(cls, args[0])
        else:
            return super().__new__(cls, args)

    def __add__(self, other):
        return Vector(a + b for a, b in zip(self, other))

    def __sub__(self, other):
        return Vector(a - b for a, b in zip(self, other))

    def __neg__(self):
        return Vector(-i for i in self)

    def __mul__(self, other):
        return Vector(i * other for i in self)

    def __rmul__(self, other):
        return self.__mul__(other)

    def __div__(self, other):
        return Vector(i / other for i in self)

    def __truediv__(self, other):
        return self.__div__(other)


class Bullet(object):
    def __init__(self, position, angle, speed):
        self.position = Vector(position)
        self.speed = Vector(math.cos(angle), math.sin(angle)) * speed

    def tick(self, tdelta=1):
        self.position += self.speed * tdelta

    def draw(self):
        pass  # TODO


# Construct a bullet
bullets.append(Bullet(position, angle, speed)

# To move all bullets
for i in bullets:
    i.tick()  # or i.tick(tdelta)

Upvotes: 1

Related Questions