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()
How to shoot bullets when space bar is pressed using LibGDX?
Took a look at the documentation for the library, and it doesn't seem to expose any other way of getting key presses (particularly key down/release). In such a case you can keep track of keep changes yourself with a spaceAlreadyPressed
variable that persists between frames.
...
boolean spaceIsPressed = Gdx.input.isKeyPressed(Keys.SPACE);
if (spaceIsPressed && !spaceAlreadyPressed) {
shoot();
}
...
spaceAlreadyPressed = spaceIsPressed;
It may be safer to use a spaceIsPressed
variable in case the input state changes unexpectedly.
Alternatively, if you want to make it shorter, you can use logical laws to reduce to the following, where canShoot
also persists between frames and has an initial value of false
.
...
canShoot = !canShoot && Gdx.input.isKeyPressed(Keys.SPACE);
if (canShoot) {
shoot();
}
...
I have created bullets for my car sprite to shoot but when I press space bar the bullet sprite comes out but disappears
Add a bullet list to the Car
class:
class Car(pygame.sprite.Sprite):
def __init__(self, scale, speed):
# [...]
self.bullet_list = []
Add a the position of the bullet to the list when SPACE is pressed. The starting position of the bullet is the position of the car:
class Car(pygame.sprite.Sprite):v
# [...]
def shoot(self):
self.bullet_list.append([self.rect.x, self.rect.y])
Move the bullets:
class Car(pygame.sprite.Sprite):
# [...]
def bullet_update(self):
for bullet_pos in self.bullet_list[:]:
bullet_pos[0] += self.vel
if bullet_pos[0] > 1000:
self.bullet_list.remove(bullet_pos)
Draw the bullets with the car:
class Car(pygame.sprite.Sprite):
# [...]
def draw(self):
for bullet_pos in self.bullet_list:
screen.blit(self.bullet, bullet_pos)
screen.blit(self.image, self.rect.center)
how to shoot bullets in pygame?
You just need to set bulletX = characterX + 20
once - when the bullet is fired. Currently you set it to that with each while run
loop iteration, which is why its position is getting updated constantly. So, if you removed that, and updated the X position only when needed, this is how that part of your code could look:
if event.key == pygame.K_SPACE:
y_speed_bullet = y_speed * -1 * 2.3
bulletX = characterX + 20
Although you'll want something to keep track of if the bullet is currently fired or not, so that holding down or repeatedly pressing space doesn't reset the bullet's position.
animating a player bullet when hitting the space bar inside html5 canvas
You need to handle an auto-fire by yourself.
Add two properties to your tank object
lastShootTime : 0, // time when we last shoot
shootRate : 300, // time between two bullets. (in ms)
Then, shoot only if enough time elapsed since last shoot :
shoot: function () {
var now = Date.now() ;
if (now - this.lastShootTime < this.shootRate) return;
this.lastShootTime = now ;
Missiles.collection.push(playerMissile({
x: this.x,
y: this.y,
radius: 2,
rot: this.rotation
}));
}
Rq1 : handle a speed for each missile, and have tank speed added to the missile to avoid the tank marching on its own missile (or speed the missile quite a bit for a quick fix. )
Rq 2 : you do not destroy missile when they are too far : do it.
Just an idea : you might improve the shootRate if the player gets an upgrade or so. You might also handle the heat of the canon, and have the shoot rate drop / stops on overheat.
I updated your fiddle, see here :
http://jsfiddle.net/gamealchemist/B2nUs/27/
I also modified a few things, as you will see, so that the game is smooth and there's no blinking now.
( It works with requestAnimationFrame, i corrected a few var missing, update of tank is within the tank class, playerMissile is a proper class, and the update is time-based, so your game will behave the same on any device. )
Happy coding !!!
pygame shooting multiple bullets
To reload, just reset the shoot flag and bullet position.
Try this update:
if shoot:
draw()
if b_x > 1300: # off screen
b_x = 0
shoot=False # wait for space to re-shoot
For rapid fire, use a list to store the bullet positions. The space key adds to the bullet list. When the bullet goes off screen, remove it from the list.
import pygame
import sys
pygame.init()
bg=pygame.display.set_mode((1300,640))
FPS=pygame.time.Clock()
p=x,y,width,height=(0,0,100,100)
b=b_x,b_y,b_width,b_height=(x,y,25,25)
bullets=[] # all active bullets
shoot=False
def draw():
global bullets,bullet,b_x,shoot,m
#b_x+=50
m=b_y+50
for i in range(len(bullets)):
b_x = bullets[i] # x position of bullets
bullet=pygame.draw.rect(bg,(0,0,255),(b_x+100,m,b_width,b_height))
bullets[i] += 50 # move each bullet
bullets = [b for b in bullets if b < 1300] # only keep bullets on screen
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
sys.exit()
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_LEFT:
x-=50
if event.key==pygame.K_RIGHT:
x+=50
if event.key==pygame.K_SPACE:
bullets.append(0) # add new bullets
bg.fill((0,0,0))
player1=pygame.draw.rect(bg,(255,0,0),(x,y,width,height))
if len(bullets): # if any active bullets
draw()
pygame.display.update()
FPS.tick(30)
Related Topics
How to Organize My Tkinter Appllication
Gunicorn Command Not Found, But It's in My Requirements.Txt
Command 'X86_64-Linux-Gnu-Gcc' Failed with Exit Status 1
How to Control the Keyboard and Mouse with Python
Datastax Python Cassandra Driver Build Fails on Ubuntu
Maltparser Giving Error in Nltk
Python: When to Use Pty.Fork() Versus Os.Fork()
How Can Python Handle Systemctl Stop
Importerror: No Module Named 'Pysqlite2'
How to Shoot a Bullet With Space Bar
Fetching the Output of a Command Executed Through Os.System() Command
Pip Install Unable to Find Ffi.H Even Though It Recognizes Libffi
A Function Callback Every Time a Key Is Pressed (Regardless of Which Window Has Focus)
Python Not Displaying Executable Output Properly
Pairing Bluetooth Devices with Passkey/Password in Python - Rfcomm (Linux)