importrandomimportarcadeSPRITE_SCALING_PLAYER=0.5SPRITE_SCALING_COIN=0.2SPRITE_SCALING_LASER=0.8COIN_COUNT=50SCREEN_WIDTH=800SCREEN_HEIGHT=600BULLET_SPEED=5classMyGame(arcade.Window):""" Main application class. """def__init__(self):""" Initializer """# Call the parent class initializersuper().__init__(SCREEN_WIDTH,SCREEN_HEIGHT,"Sprites and Bullets Demo")# Variables that will hold sprite listsself.player_list=Noneself.coin_list=None# Set up the player infoself.player_sprite=Noneself.score=0# Don't show the mouse cursorself.set_mouse_visible(False)arcade.set_background_color(arcade.color.AMAZON)defsetup(self):""" Set up the game and initialize the variables. """# Sprite listsself.player_list=arcade.SpriteList()self.coin_list=arcade.SpriteList()# Set up the playerself.score=0# Image from kenney.nlself.player_sprite=arcade.Sprite("character.png",SPRITE_SCALING_PLAYER)self.player_sprite.center_x=50self.player_sprite.center_y=70self.player_list.append(self.player_sprite)# Create the coinsforiinrange(COIN_COUNT):# Create the coin instance# Coin image from kenney.nlcoin=arcade.Sprite("coin_01.png",SPRITE_SCALING_COIN)# Position the coincoin.center_x=random.randrange(SCREEN_WIDTH)coin.center_y=random.randrange(SCREEN_HEIGHT)# Add the coin to the listsself.coin_list.append(coin)# Set the background colorarcade.set_background_color(arcade.color.AMAZON)defon_draw(self):""" Render the screen. """# This command has to happen before we start drawingarcade.start_render()# Draw all the sprites.self.coin_list.draw()self.player_list.draw()# Render the textarcade.draw_text(f"Score: {self.score}",10,20,arcade.color.WHITE,14)defon_mouse_motion(self,x,y,dx,dy):""" Called whenever the mouse moves. """self.player_sprite.center_x=xself.player_sprite.center_y=ydefon_mouse_press(self,x,y,button,modifiers):""" Called whenever the mouse button is clicked. """passdefupdate(self,delta_time):""" Movement and game logic """# Call update on all spritesself.coin_list.update()defmain():window=MyGame()window.setup()arcade.run()if__name__=="__main__":main()

If you run this program, the player should move around the screen, and their
should be coins. But not much else is happening yet.

Next, we need a ‘shooting’ image:

laserBlue01.png

Download this image (originally from Kenney.nl) and make sure it is in the same
folder as your code.

We want all the coins above the player. So we can adjust the starting y locations
to have a starting point of 150 instead of 0. That will keep them above the player.

# Create the coinsforiinrange(COIN_COUNT):# Create the coin instance# Coin image from kenney.nlcoin=arcade.Sprite("coin_01.png",SPRITE_SCALING_COIN)# Position the coincoin.center_x=random.randrange(SCREEN_WIDTH)coin.center_y=random.randrange(150,SCREEN_HEIGHT)# Add the coin to the listsself.coin_list.append(coin)

importrandomimportarcadeSPRITE_SCALING_PLAYER=0.5SPRITE_SCALING_COIN=0.2SPRITE_SCALING_LASER=0.8COIN_COUNT=50SCREEN_WIDTH=800SCREEN_HEIGHT=600BULLET_SPEED=5classMyGame(arcade.Window):""" Main application class. """def__init__(self):""" Initializer """# Call the parent class initializersuper().__init__(SCREEN_WIDTH,SCREEN_HEIGHT,"Sprites and Bullets Demo")# Variables that will hold sprite listsself.player_list=Noneself.coin_list=Noneself.bullet_list=None# Set up the player infoself.player_sprite=Noneself.score=0# Don't show the mouse cursorself.set_mouse_visible(False)arcade.set_background_color(arcade.color.AMAZON)defsetup(self):""" Set up the game and initialize the variables. """# Sprite listsself.player_list=arcade.SpriteList()self.coin_list=arcade.SpriteList()self.bullet_list=arcade.SpriteList()# Set up the playerself.score=0# Image from kenney.nlself.player_sprite=arcade.Sprite("character.png",SPRITE_SCALING_PLAYER)self.player_sprite.center_x=50self.player_sprite.center_y=70self.player_list.append(self.player_sprite)# Create the coinsforiinrange(COIN_COUNT):# Create the coin instance# Coin image from kenney.nlcoin=arcade.Sprite("coin_01.png",SPRITE_SCALING_COIN)# Position the coincoin.center_x=random.randrange(SCREEN_WIDTH)coin.center_y=random.randrange(150,SCREEN_HEIGHT)# Add the coin to the listsself.coin_list.append(coin)# Set the background colorarcade.set_background_color(arcade.color.AMAZON)defon_draw(self):""" Render the screen. """# This command has to happen before we start drawingarcade.start_render()# Draw all the sprites.self.coin_list.draw()self.player_list.draw()self.bullet_list.draw()# Render the textarcade.draw_text(f"Score: {self.score}",10,20,arcade.color.WHITE,14)defon_mouse_motion(self,x,y,dx,dy):""" Called whenever the mouse moves. """self.player_sprite.center_x=xdefon_mouse_press(self,x,y,button,modifiers):""" Called whenever the mouse button is clicked. """passdefupdate(self,delta_time):""" Movement and game logic """# Call update on all spritesself.coin_list.update()self.bullet_list.update()defmain():window=MyGame()window.setup()arcade.run()if__name__=="__main__":main()

We need to
create bullets when the user presses the mouse button. We can add an
on_mouse_press method to do something when the user presses the mouse button:

defon_mouse_press(self,x,y,button,modifiers):# Create a bulletbullet=arcade.Sprite("laserBlue01.png",SPRITE_SCALING_LASER)# Add the bullet to the appropriate listself.bullet_list.append(bullet)

This will create a bullet, but the bullet will default to the lower left corner.
You can just barely see it.

We can give the bullet a position:

defon_mouse_press(self,x,y,button,modifiers):# Create a bulletbullet=arcade.Sprite("laserBlue01.png",SPRITE_SCALING_LASER)bullet.center_x=xbullet.center_y=y# Add the bullet to the appropriate listself.bullet_list.append(bullet)

But this isn’t what we want either. The code above puts the laser where we click
the mouse. We want the laser to be where the player is. That’s easy:

defon_mouse_press(self,x,y,button,modifiers):# Create a bulletbullet=arcade.Sprite("laserBlue01.png",SPRITE_SCALING_LASER)bullet.center_x=self.player_sprite.center_xbullet.center_y=self.player_sprite.center_y# Add the bullet to the appropriate listself.bullet_list.append(bullet)

We can even start the bullet a bit ABOVE the player:

defon_mouse_press(self,x,y,button,modifiers):# Create a bulletbullet=arcade.Sprite("laserBlue01.png",SPRITE_SCALING_LASER)bullet.center_x=self.player_sprite.center_xbullet.center_y=self.player_sprite.center_y+30# Add the bullet to the appropriate listself.bullet_list.append(bullet)

We can make the bullet move up using the constant BULLET_SPEED which
we set to 5 at the top of the program:

defon_mouse_press(self,x,y,button,modifiers):# Create a bulletbullet=arcade.Sprite("laserBlue01.png",SPRITE_SCALING_LASER)bullet.center_x=self.player_sprite.center_xbullet.center_y=self.player_sprite.center_y+30bullet.change_y=BULLET_SPEED# Add the bullet to the appropriate listself.bullet_list.append(bullet)

We can rotate the bullet so it isn’t sideways using the angle attribute
built into the Sprite class:

defon_mouse_press(self,x,y,button,modifiers):# Create a bulletbullet=arcade.Sprite("laserBlue01.png",SPRITE_SCALING_LASER)bullet.center_x=self.player_sprite.center_xbullet.center_y=self.player_sprite.center_y+30bullet.change_y=BULLET_SPEEDbullet.angle=90# Add the bullet to the appropriate listself.bullet_list.append(bullet)

Now that we have bullets, how do we get them to collide with the coins?
We add the following to our applications update method:

# Loop through each bulletforbulletinself.bullet_list:# Check this bullet to see if it hit a coinhit_list=arcade.check_for_collision_with_list(bullet,self.coin_list)# If it did, get rid of the bulletiflen(hit_list)>0:bullet.remove_from_sprite_lists()# For every coin we hit, add to the score and remove the coinforcoininhit_list:coin.remove_from_sprite_lists()self.score+=1# If the bullet flies off-screen, remove it.ifbullet.bottom>SCREEN_HEIGHT:bullet.remove_from_sprite_lists()

We loop through each bullet with a for loop. Then we check to see if the
bullet is hitting any of the coins. If it is, we get rid of the coin. We get
rid of the bullet.

We also check to see if the bullet flies off the top of the screen. If it does,
we get rid of the bullet. This is easy to forget, but if you do, it will cause
the computer to slow down because you are tracking thousands of bullets that
have long ago left the space we care about.

importrandomimportarcadeSPRITE_SCALING_PLAYER=0.5SPRITE_SCALING_COIN=0.2SPRITE_SCALING_LASER=0.8COIN_COUNT=50SCREEN_WIDTH=800SCREEN_HEIGHT=600BULLET_SPEED=5classMyGame(arcade.Window):""" Main application class. """def__init__(self):""" Initializer """# Call the parent class initializersuper().__init__(SCREEN_WIDTH,SCREEN_HEIGHT,"Sprites and Bullets Demo")# Variables that will hold sprite listsself.player_list=Noneself.coin_list=Noneself.bullet_list=None# Set up the player infoself.player_sprite=Noneself.score=0# Don't show the mouse cursorself.set_mouse_visible(False)arcade.set_background_color(arcade.color.AMAZON)defsetup(self):""" Set up the game and initialize the variables. """# Sprite listsself.player_list=arcade.SpriteList()self.coin_list=arcade.SpriteList()self.bullet_list=arcade.SpriteList()# Set up the playerself.score=0# Image from kenney.nlself.player_sprite=arcade.Sprite("character.png",SPRITE_SCALING_PLAYER)self.player_sprite.center_x=50self.player_sprite.center_y=70self.player_list.append(self.player_sprite)# Create the coinsforiinrange(COIN_COUNT):# Create the coin instance# Coin image from kenney.nlcoin=arcade.Sprite("coin_01.png",SPRITE_SCALING_COIN)# Position the coincoin.center_x=random.randrange(SCREEN_WIDTH)coin.center_y=random.randrange(120,SCREEN_HEIGHT)# Add the coin to the listsself.coin_list.append(coin)# Set the background colorarcade.set_background_color(arcade.color.AMAZON)defon_draw(self):""" Render the screen. """# This command has to happen before we start drawingarcade.start_render()# Draw all the sprites.self.coin_list.draw()self.bullet_list.draw()self.player_list.draw()# Render the textarcade.draw_text(f"Score: {self.score}",10,20,arcade.color.WHITE,14)defon_mouse_motion(self,x,y,dx,dy):""" Called whenever the mouse moves. """self.player_sprite.center_x=xdefon_mouse_press(self,x,y,button,modifiers):""" Called whenever the mouse button is clicked. """# Create a bulletbullet=arcade.Sprite("laserBlue01.png",SPRITE_SCALING_LASER)# The image points to the right, and we want it to point up. So# rotate it.bullet.angle=90# Position the bulletbullet.center_x=self.player_sprite.center_xbullet.bottom=self.player_sprite.top# Add the bullet to the appropriate listsself.bullet_list.append(bullet)defupdate(self,delta_time):""" Movement and game logic """# Call update on all spritesself.coin_list.update()self.bullet_list.update()# Loop through each bulletforbulletinself.bullet_list:# Check this bullet to see if it hit a coinhit_list=arcade.check_for_collision_with_list(bullet,self.coin_list)# If it did, get rid of the bulletiflen(hit_list)>0:bullet.remove_from_sprite_lists()# For every coin we hit, add to the score and remove the coinforcoininhit_list:coin.remove_from_sprite_lists()self.score+=1# If the bullet flies off-screen, remove it.ifbullet.bottom>SCREEN_HEIGHT:bullet.remove_from_sprite_lists()defmain():window=MyGame()window.setup()arcade.run()if__name__=="__main__":main()