Space Invaders - Pygame - Make enemy shoot
The problem is here:
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
player.shootPlayer()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_TAB:
enemy.shootEnemy()
Once event.type == KEYDOWN one time, the second evaluation is ignored.
Try this
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
player.shootPlayer()
elif event.key == pygame.K_TAB:
enemy.shootEnemy()
This checks for a KEYDOWN event, then for the specific key that's pressed.
Bullets Not Appearing in Simple Space Invader Game
I believe that you need to update your screen at the end of the while-loop, not at the beginning:
while True:
#fill screen
for event in pygame.event.get():
#get user input
pygame.display().flip()
Pygame - Enemy shoot, problem with groups
You can get a list of the Sprties in a pygame.sprite.Group
with the method sprites()
. The sprites in the list cam be accessed by subscription.
If bosss
contains exactly 1 Sprite, you can get the rect
attribute of the Sprite with:
rect = bosss.sprites()[0].rect
How can i shoot a bullet with space bar?
The general approach to firing bullets is to store the positions of the bullets in a list (bullet_list
). When a bullet is fired, add the bullet's starting position ([start_x, start_y]
) to the list. The starting position is the position of the object (player or enemy) that fires the bullet. Use a for
-loop to iterate through all the bullets in the list. Move position of each individual bullet in the loop. Remove a bullet from the list that leaves the screen (bullet_list.remove(bullet_pos)
). For this reason, a copy of the list (bullet_list[:]
) must be run through (see How to remove items from a list while iterating?). Use another for
-loop to blit
the remaining bullets on the screen:
bullet_list = []
while run == True:
# [...]
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bullet_list.append([start_x, start_y])
for bullet_pos in bullet_list[:]:
bullet_pos[0] += move_bullet_x
bullet_pos[1] += move_bullet_y
if not screen.get_rect().colliderect(bullet_image.get_rect(center = bullet_pos))
bullet_list.remove(bullet_pos)
# [...]
for bullet_pos in bullet_list[:]
screen.blit(bullet_image, bullet_image.get_rect(center = bullet_pos))
# [...]
See also Shoot bullet.
Please note, that class names should normally use the CapWords convention.
(See Style Guide for Python Code - Class names)
That means it has to be Player
and Bullet
rather than player
and bullet
You have an application loop, so use it. All the objects are continuously updated and drawn in the main application loop, in each frame.
The class Bullet
do not need any loop. The constructor has to have parameters for the position (x
, y
). Further it needs on method which changes the position and one which draws the bullet:
class Bullet:
def __init__(self, x, y):
self.radius = 10
self.speed = 10
self.x = x
self.y = y
def update(self):
self.y -= self.speed#
def draw(self):
pygame.draw.circle(d, (255, 0, 0), (self.x, self.y), self.radius)
Use a list of bullets
. Create a new bullet when space is pressed. Move the bullets (update
) in every frame an remove
a bullet if it is out of the window. Draw the remaining bullets in every frame:
bullets = []
# [...]
while run:
for event in pygame.event.get():
# [...]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bullets.append(Bullet(p.x+p.width//2, p.y))
# [...]
for b in bullets:
b.update()
if b.y < 0:
bullets.remove(b)
# [...]
for b in bullets:
b.draw()
Furthermore use pygame.key.get_pressed()
use to get the state of the keys in every frame and to update the position of the player:
while run:
# [...]
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
p.move_left()
if keys[pygame.K_RIGHT]:
p.move_right()
Complete example:
import pygame, os
os.environ["SDL_VIDEO_CENTERED"] = "1"
pygame.init()
win = pygame.display
d = win.set_mode((1200, 600))
clock = pygame.time.Clock()
class Player:
def __init__(self, x, y, height, width):
self.x = x
self.y = y
self.height = height
self.width = width
self.speed = 2
def draw(self):
pygame.draw.rect(d, (0, 0, 0), (self.x, self.y, self.width, self.height))
def move_left(self):
self.x -= self.speed
def move_right(self):
self.x += self.speed
class Bullet:
def __init__(self, x, y):
self.radius = 10
self.speed = 10
self.x = x
self.y = y
def update(self):
self.y -= self.speed#
def draw(self):
pygame.draw.circle(d, (255, 0, 0), (self.x, self.y), self.radius)
bullets = []
p = Player(600, 500, 50, 30)
run = True
while run:
clock.tick(100)
# handel events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bullets.append(Bullet(p.x+p.width//2, p.y))
# update objects
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
p.move_left()
if keys[pygame.K_RIGHT]:
p.move_right()
for b in bullets:
b.update()
if b.y < 0:
bullets.remove(b)
# clear display
d.fill((98, 98, 98))
# draw scene
for b in bullets:
b.draw()
p.draw()
# update display
win.update()
Python Pygame: Fire multiple bullets for Space Invader game
You should separate your game into a loop that contains 3 different functions:
LOOP
UPDATE_LOGIC
INPUT_HANDLING
DRAW_ELEMENTS
END-LOOP
In the input_handling, put a bullet into a list of bullets if the player is not in cool-down.
In the update_logic, iterate of the bullet list calculating the positions through time, and cool-down time of the player.
In the draw_elements, simply draw every thing on your scene. (iterate over the bullet list)
and you can use different timers for the draw and update_logic. That way will help you to add new elements to your game easily
Related Topics
How to Do Row-To-Column Transposition of Data in CSV Table
Find the Indexes of All Regex Matches
Matplotlib: Adding an Axes Using the Same Arguments as a Previous Axes
Unicodeencodeerror: 'Ascii' Codec Can't Encode Character at Special Name
How to Change My Desktop Background with Python
Loop Over a List Containing Path to Sound Files
Password Authentication in Python Paramiko Fails, But Same Credentials Work in Ssh/Sftp Client
How to Select Rows with One or More Nulls from a Pandas Dataframe Without Listing Columns Explicitly
Fastest Way to Search a List in Python
Python Regular Expression Pattern * Is Not Working as Expected
Why am I Getting a Nameerror When I Try to Call My Function
Monkey Patching a Class in Another Module in Python
How Would I Make a Method Which Is Run Every Time a Frame Is Shown in Tkinter
Pygame Tic Tak Toe Logic? How Would I Do It
What Does "Error: Option --Single-Version-Externally-Managed Not Recognized" Indicate