# PyGame - Top down shooter mechanics

I'm currently developing a game for some school work using the PyGame library for Python. I'm almost done with most of the game's core mechanics, but have gotten hung up on the shooting mechanics. My current code is too long to post fully, but I'll put excerpts of it and explain what I have so far.

all_sprites_list = pygame.sprite.Group()

bullets = []
bullet_list = pygame.sprite.Group()
bullet_speed = 10

class Bullet(pygame.sprite.Sprite):
def __init__(self):
super().__init__()

self.image = pygame.Surface([4,10])
self.image.fill(red)
self.rect = self.image.get_rect()

def update(self):
if self.rect.x > chx:
self.rect.x -= bullet_speed
elif self.rect.x < chx:
self.rect.x += bullet_speed
if self.rect.y > chy:
self.rect.y -= bullet_speed
elif self.rect.y < chy:
self.rect.y += bullet_speed


This code shows the class I have for my bullets and their movement. The problems with this right now are that A) the bullets get stuck around the crosshair position, of which the chx and chy variables show the x and y position of the mouse.

    if event.type == pygame.MOUSEBUTTONDOWN:
bullet = Bullet()
if weapon == "hg" and hg_move == True:
bullet.rect.x = hgrect.x
bullet.rect.y = hgrect.y


This code shows an example of one of the firing commands later in the main game loop. hg, hg_move, and hgrect.x/y are all variables used for the movement of the character depending on the type of weapon he is holding.

Some of the main issues are seemingly caused by the fact that I can't find a way store a static value of the likes of the crosshair positions, or to keep the bullets going on a trajectory until they leave the screen or hit an object.

Any help would be greatly appreciated!

• Hello, Do you have any screenshots of the game? – Juanpa Jan 23 '19 at 21:14

# Bullet Class

class Bullet(pygame.sprite.Sprite):
def __init__(self, vx, vy):
super().__init__()

self.image = pygame.Surface([4,10])
self.image.fill(red)
self.rect = self.image.get_rect()
self.velocity_x = vx
self.velocity_y = vy

def update(self):
self.rect.x += self.velocity_x
self.rect.y += self.velocity_y

# Spawning the Bullet

# 1. You need to determine the direction from the player to the crosshair

# X distance from player to crosshair
dx = (chx - hgrect.x)
# Y distance from player to crosshair
dy = (chy - hgrect.y)
# Direction from player to crosshair in radians
dir = math.atan2(dy, dx)

# 2. Calculate a velocity vector with a given speed and the direction above
speed = 20 # units: pixels/update
vx = speed * math.cos(dir)
vy = speed * math.sin(dir)

# 3. Create the bullet with the calculated X and Y velocity
bullet = new Bullet(vx, vy)

`
• That works great for getting them from the character to the crosshair (thank you!), the only problems from there however is the actual movement of the bullets themselves, as the code means that they will move at 45 degree angles to where they were fired from, find themselves on the correct place in one axis, and move along that axis until they find the others, so they essentially bend, and also the bullets don't continue going if they get to where the crosshair was, as ideally they would continue until they go off the screen. – Mingy Jan 23 '19 at 20:57
• I have edited my answer to also fix your bullet direction issue. I wasn't sure if you intended to have the bullets snap to 45° directions (like some arcade games). – Romen Jan 23 '19 at 21:56