Reputation: 21
I am creating a game in python using pygame where two spaceships (red & yellow) shoot projectiles at each other. When it came to writing the code which fired the projectiles for red, I binded the shoot key to the letter "u" on my keyboard. However, when I press "u", the projectile doesn't fire.
Later on in debugging, I noticed that you have to be holding down the "l" key (which makes red move to the right) and the spaceship has to have a velocity to the right for the bullet to fire.
I also downloaded some files for the spaceship images and background, which can be found here (after clicking link, click "Code", then "Download ZIP", then move it to your python files): https://github.com/techwithtim/PygameForBeginners
Code:
import pygame
import os
WIDTH, HEIGHT = 900, 500
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Spaceship Game")
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
FPS = 60
VEL = 5
BULLET_VEL = 7
MAX_BULLETS = 3
BORDER = pygame.Rect(WIDTH//2 - 5, 0, 10, HEIGHT)
SPACESHIP_WIDTH, SPACESHIP_HEIGHT = 55, 40
YELLOW_HIT = pygame.USEREVENT + 1
RED_HIT = pygame.USEREVENT + 2
YELLOW_SPACESHIP_IMAGE = pygame.image.load(
os.path.join("Assets", "spaceship_yellow.png"))
YELLOW_SPACESHIP = pygame.transform.rotate(
pygame.transform.scale(YELLOW_SPACESHIP_IMAGE, (SPACESHIP_WIDTH, SPACESHIP_HEIGHT)), 90)
RED_SPACESHIP_IMAGE = pygame.image.load(
os.path.join("Assets", "spaceship_red.png"))
RED_SPACESHIP = pygame.transform.rotate(pygame.transform.scale(RED_SPACESHIP_IMAGE, (55, 40)), 270)
SPACE = pygame.transform.scale(pygame.image.load(
os.path.join("Assets", "space.png")), (WIDTH, HEIGHT))
def draw_window(red, yellow, red_bullets, yellow_bullets):
WIN.blit(SPACE, (0, 0))
pygame.draw.rect(WIN, BLACK, BORDER)
WIN.blit(YELLOW_SPACESHIP, (yellow.x, yellow.y))
WIN.blit(RED_SPACESHIP, (red.x, red.y))
for bullet in red_bullets:
pygame.draw.rect(WIN, RED, bullet)
for bullet in yellow_bullets:
pygame.draw.rect(WIN, YELLOW, bullet)
pygame.display.update()
def yellow_handle_movement(keys_pressed, yellow):
if keys_pressed[pygame.K_w] and yellow.y - VEL > 0: # UP KEY YELLOW
yellow.y -= VEL
if keys_pressed[pygame.K_a] and yellow.x - VEL > 0: # LEFT KEY YELLOW
yellow.x -= VEL
if keys_pressed[pygame.K_s] and yellow.y + VEL + yellow.height < HEIGHT - 15: # DOWN KEY YELLOW
yellow.y += VEL
if keys_pressed[pygame.K_d] and yellow.x + VEL + yellow.width < BORDER.x: # RIGHT KEY YELLOW
yellow.x += VEL
def red_handle_movement(keys_pressed, red):
if keys_pressed[pygame.K_i] and red.y - VEL > 0: # UP KEY RED
red.y -= VEL
if keys_pressed[pygame.K_j] and red.x - VEL > BORDER.x + BORDER.width: # LEFT KEY RED
red.x -= VEL
if keys_pressed[pygame.K_k] and red.y + VEL + red.height < HEIGHT - 15: # DOWN KEY RED
red.y += VEL
if keys_pressed[pygame.K_l] and red.x + VEL + red.width < WIDTH: # RIGHT KEY RED
red.x += VEL
def handle_bullets(yellow_bullets, red_bullets, yellow, red):
for bullet in yellow_bullets:
bullet.x += BULLET_VEL
if yellow.colliderect(bullet):
pygame.event.post(pygame.event.Event(RED_HIT))
yellow_bullets.remove(bullet)
elif bullet.x > WIDTH:
yellow_bullets.remove(bullet)
for bullet in red_bullets:
bullet.x -= BULLET_VEL
if red.colliderect(bullet):
pygame.event.post(pygame.event.Event(YELLOW_HIT))
red_bullets.remove(bullet)
elif bullet.x < 0:
red_bullets.remove(bullet)
def main(): # Main Game Loop
red = pygame.Rect(700, 300, SPACESHIP_WIDTH, SPACESHIP_HEIGHT)
yellow = pygame.Rect(100, 300, SPACESHIP_WIDTH, SPACESHIP_HEIGHT)
red_bullets = []
yellow_bullets = []
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q and len(yellow_bullets) < MAX_BULLETS:
bullet = pygame.Rect(yellow.x + yellow.width, yellow.y + yellow.height//2 - 2, 10, 5)
yellow_bullets.append(bullet)
if event.key == pygame.K_u and len(red_bullets) < MAX_BULLETS:
bullet = pygame.Rect(red.x, red.y + red.height//2 - 2, 10, 5)
red_bullets.append(bullet)
keys_pressed = pygame.key.get_pressed()
yellow_handle_movement(keys_pressed, yellow)
red_handle_movement(keys_pressed, red)
handle_bullets(yellow_bullets, red_bullets, yellow, red)
draw_window(red, yellow, red_bullets, yellow_bullets)
if __name__ == "__main__": # Makes sure that the code won't run if imported
main()
You can run the code and see the problem for yourself, as I explain things very badly.
Upvotes: 2
Views: 79
Reputation: 210909
You have to check if the yellow bullet collides with the red spaceship and the red bullet collides with the yellow spaceship and not the other way around.
Read also How to remove items from a list while iterating? and iterate through a shallow copy of the bulleted lists.
def handle_bullets(yellow_bullets, red_bullets, yellow, red):
for bullet in yellow_bullets[:]: # <---
bullet.x += BULLET_VEL
if red.colliderect(bullet): # <---
pygame.event.post(pygame.event.Event(RED_HIT))
yellow_bullets.remove(bullet)
elif bullet.x > WIDTH:
yellow_bullets.remove(bullet)
for bullet in red_bullets[:]: # <---
bullet.x -= BULLET_VEL
if yellow.colliderect(bullet): # <---
pygame.event.post(pygame.event.Event(YELLOW_HIT))
red_bullets.remove(bullet)
elif bullet.x < 0:
red_bullets.remove(bullet)
Upvotes: 2