I cant move my sprite unless I shoot first?


I cant move my sprite unless I shoot first?



I'm developing a basic game, where you can move around and shoot projectiles to kill randomly spawned enemies, but if I boot the game and I try to move before I do anything else, the game crashes. If I shoot a projectile first, however, the game runs perfectly and I can move around without any problems, but I can't seem to figure out why this is.


import pygame
import random


BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

#Classes

class Player(pygame.sprite.Sprite):

def __init__(self, filename, x, y):

super().__init__()

self.image = pygame.image.load(filename).convert()
self.image.set_colorkey(BLACK)

self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x

self.change_x = 0
self.change_y = 0
self.walls = None


def changespeed(self, x, y):
self.change_x += x
self.change_y += y

def update(self):
self.rect.x += self.change_x

block_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
for block in block_hit_list:
if self.change_x > 0:
self.rect.right = block.rect.left
else:
self.rect.left = block.rect.right

self.rect.y += self.change_y

block_hit_list = pygame.sprite.spritecollide(self, self.walls, False)
for block in block_hit_list:
if self.change_y > 0:
self.rect.bottom = block.rect.top
else:
self.rect.top = block.rect.bottom


class Wall(pygame.sprite.Sprite):

def __init__(self, x, y, width, height):

super().__init__()

self.image = pygame.Surface([width, height])
self.image.fill(BLACK)

self.rect = self.image.get_rect()
self.rect.y = y
self.rect.x = x



class Enemy(pygame.sprite.Sprite):

def __init__(self, filename):

super().__init__()

self.image = pygame.image.load(filename).convert()
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()

class ProjectileUp(pygame.sprite.Sprite):

def __init__(self, filename):

super().__init__()

self.image = pygame.image.load(filename).convert()
self.image.set_colorkey(BLACK)

self.rect = self.image.get_rect()


def update(self):
self.rect.y -= 5


class ProjectileDown(pygame.sprite.Sprite):

def __init__(self, filename):

super().__init__()

self.image = pygame.image.load(filename).convert()
self.image.set_colorkey(BLACK)

self.rect = self.image.get_rect()


def update(self):
self.rect.y += 5

class ProjectileLeft(pygame.sprite.Sprite):

def __init__(self, filename):

super().__init__()

self.image = pygame.image.load(filename).convert()
self.image.set_colorkey(BLACK)

self.rect = self.image.get_rect()


def update(self):
self.rect.x -= 5


class ProjectileRight(pygame.sprite.Sprite):

def __init__(self, filename):

super().__init__()

self.image = pygame.image.load(filename).convert()
self.image.set_colorkey(BLACK)

self.rect = self.image.get_rect()


def update(self):
self.rect.x += 5


# --- Create the window

#Initialise pygame
pygame.init()

#Window dimensions
screen_width = 1080
screen_height = 607
screen = pygame.display.set_mode([screen_width, screen_height])

#Window display name
pygame.display.set_caption('Labyrinth')


#Sprite Lists
all_sprite_list = pygame.sprite.Group()
block_list = pygame.sprite.Group()
wall_list = pygame.sprite.Group()
projectile_list = pygame.sprite.Group()


#Define game borders
wall = Wall(-32, 0, 10, 607)
wall_list.add(wall)
all_sprite_list.add(wall)

wall = Wall(0 , -64, 1080, 10)
wall_list.add(wall)
all_sprite_list.add(wall)

wall = Wall(1100, 0, 10, 607)
wall_list.add(wall)
all_sprite_list.add(wall)

wall = Wall(0 , 600, 1080, 10)
wall_list.add(wall)
all_sprite_list.add(wall)


#Create player sprite
player = Player("Isaac.png", 420, 150)
all_sprite_list = pygame.sprite.Group()
all_sprite_list.add(player)
player.walls = wall_list


#Create enemies
for i in range(7):
block = Enemy("Judas.png")
block.rect.x = random.randrange(50, 950)
block.rect.y = random.randrange(50, 450)
block_list.add(block)
all_sprite_list.add(block)





#Manage screen updates
clock = pygame.time.Clock()

#Load background image
background_position = [0, 0]
background_image = pygame.image.load("Floor.png").convert()

#Loop until game_exit
done = False



#---------- MAIN PROGRAM LOOP ----------#

while not done:

# --- Event processing
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True


#Projectile spawn
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
projectile = ProjectileUp("LightningUp.png")
projectile.rect.x = player.rect.x+65
projectile.rect.y = player.rect.y
elif event.key == pygame.K_DOWN:
projectile = ProjectileDown("LightningDown.png")
projectile.rect.x = player.rect.x+65
projectile.rect.y = player.rect.y+100
elif event.key == pygame.K_LEFT:
projectile = ProjectileLeft("LightningLeft.png")
projectile.rect.x = player.rect.x+35
projectile.rect.y = player.rect.y+100
elif event.key == pygame.K_RIGHT:
projectile = ProjectileRight("LightningRight.png")
projectile.rect.x = player.rect.x+115
projectile.rect.y = player.rect.y+100

all_sprite_list.add(projectile)
projectile_list.add(projectile)


#Movement controls
if event.type == pygame.KEYDOWN:
if event.key == ord('a'):
player.changespeed(-7, 0)
elif event.key == ord('d'):
player.changespeed(7, 0)
elif event.key == ord('w'):
player.changespeed(0, -7)
elif event.key == ord('s'):
player.changespeed(0, 7)

elif event.type == pygame.KEYUP:
if event.key == ord('a'):
player.changespeed(7, 0)
elif event.key == ord('d'):
player.changespeed(-7, 0)
elif event.key == ord('w'):
player.changespeed(0, 7)
elif event.key == ord('s'):
player.changespeed(0, -7)



# --- Game logic

#Update sprites
all_sprite_list.update()

#Projectile mechanics
for projectile in projectile_list:

block_hit_list = pygame.sprite.spritecollide(projectile, block_list, True)

for block in block_hit_list:
projectile_list.remove(projectile)

#Determine if player hits enemy
blocks_hit_list = pygame.sprite.spritecollide(player, block_list, True)

#Call on background image
screen.blit(background_image, background_position)

# --- Draw the window

all_sprite_list.draw(screen)

pygame.display.flip()

clock.tick(60)

pygame.quit()




1 Answer
1



It's because your if/elif/else logic is messed up a bit. You have two paths for the KEYDOWN event. If the first event happens to be a movement command, your code runs through the projectile code first (without finding a valid projectile command) and then tries to reference a projectile object that doesn't exist. Try this instead:


#---------- MAIN PROGRAM LOOP ----------#

while not done:

# --- Event processing
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True

elif event.type == pygame.KEYDOWN:
projectile = None # initialize
if event.key == pygame.K_UP:
projectile = ProjectileUp("LightningUp.png")
projectile.rect.x = player.rect.x+65
projectile.rect.y = player.rect.y
elif event.key == pygame.K_DOWN:
projectile = ProjectileDown("LightningDown.png")
projectile.rect.x = player.rect.x+65
projectile.rect.y = player.rect.y+100
elif event.key == pygame.K_LEFT:
projectile = ProjectileLeft("LightningLeft.png")
projectile.rect.x = player.rect.x+35
projectile.rect.y = player.rect.y+100
elif event.key == pygame.K_RIGHT:
projectile = ProjectileRight("LightningRight.png")
projectile.rect.x = player.rect.x+115
projectile.rect.y = player.rect.y+100
elif event.key == ord('a'):
player.changespeed(-7, 0)
elif event.key == ord('d'):
player.changespeed(7, 0)
elif event.key == ord('w'):
player.changespeed(0, -7)
elif event.key == ord('s'):
player.changespeed(0, 7)

if projectile: # did we create a valid projectile?
all_sprite_list.add(projectile)
projectile_list.add(projectile)


elif event.type == pygame.KEYUP:
if event.key == ord('a'):
player.changespeed(7, 0)
elif event.key == ord('d'):
player.changespeed(-7, 0)
elif event.key == ord('w'):
player.changespeed(0, 7)
elif event.key == ord('s'):
player.changespeed(0, -7)





Oh, that makes alot more sense, thatll help alot! thanks!
– Goose _
Jun 30 at 9:48





@Goose_, no problem. If this answered your question, please click on the check mark to accept it.
– OregonJim
Jun 30 at 16:18






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

how to run turtle graphics in Colaboratory

Export result set on Dbeaver to CSV