Why can't I shoot with pygame? - python

I've been trying to make something cool with Python and Pygame for fun. I know a thing or two about Python in general but I'm quite a beginner with Pygame.
So the problem is: I have created a movable player and a moving enemy. I want to make the player shoot when I press the spacebar. I loaded a .png image, defined a function for shooting, and made so that the bullet keeps moving once shot. For some reason when I call the function, it just does nothing. It doesn't even give an error. I know I can shoot only one bullet with the current code and whatnot, but I would like to just get the current code working as a start.
"""
player and enemy functions are defined above and work well, I didn't include
them in this post for the sake of saving everyone's time
"""
# bullet
bullet_pic = pygame.image.load("bullet.png")
bullet_pic_reverse = pygame.image.load("bullet reverse.png")
bullet_state = "nope"
def shoot(pic, x, y):
global bullet_state
bullet_state = "jes"
screen.blit(pic, (x, y + 30))
player_dir = player_pic # direction of the player (left or right)
enemy_dir = enemy_pic # direction of the enemy
enemyX_change = 2.5
running = True
while running:
screen.blit(back, (0, 0)) # background picture
player(player_dir, playerX, playerY)
enemy(enemy_dir, enemyX, enemyY)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key == K_ESCAPE:
running = False
elif event.type == pygame.KEYDOWN:
# shooting
if event.key == K_SPACE:
if player_dir == player_pic:
bulletX = playerX + 100
bulletX_change = 20
bullet_dir = bullet_pic
else:
bulletX = playerX
bulletX_change = -20
bullet_dir = bullet_pic_reverse
shoot(bullet_dir, bulletX, playerY)
# player movement
hold = pygame.key.get_pressed()
if hold[K_LEFT] and playerX > 0:
playerX -= 7
player_dir = player_pic_reverse
if hold[K_RIGHT] and playerX < 1100:
playerX += 7
player_dir = player_pic
# enemy movement
enemyX += enemyX_change
if enemyX >= 1125:
enemyX_change = -2.5
enemy_dir = enemy_pic_reverse
elif enemyX <= 900:
enemyX_change = 2.5
enemy_dir = enemy_pic
# bullet constant movement
if bullet_state == "jes":
shoot(bullet_dir, bulletX, playerY)
bulletX += bulletX_change

I think the problem is with pygame.display.update(), you should put it always in the end of while running: loop. If you update display before calling shoot() background picture will be over bullet picture and you won't see it.
Another thing, you write K_ESCAPE instead of pygame.K_ESCAPE same with spacebar key. Does it work correctly for you? I didn't do anything with pygame for some time, maybe it's fine, but check it :)

Related

space invader pygame make enemy disappear when shot

I have a list with all my enemies and when the distance between the players bullet and the enemy is close enough, I can make a enemy disappear but its never the right one that was hit with the bullet, its always the enemy with the greatest x value(in my case the one at the end of the list) so my questions is how do I make the specific enemy disappear. here is my code for reference.
import pygame
import random
import math
# initalize pygame
pygame.init()
# creates game screen to display game
game_window = pygame.display.set_mode((800, 570))
# Title and icon for window
pygame.display.set_caption("Power of the Doctor")
icon = pygame.image.load('tardisShooter.png')
pygame.display.set_icon(icon)
# backgroun picture
background = pygame.image.load('SpaceTardissmall.png')
# player info
Playerimg = pygame.image.load('tardisShooter.png')
playerx = 370 # players x axis
playery = 470 # players y axis
playerx_change = 0 # adds constant change while added in loop
def player(x, y):
# blit draws image on screen: x axis y axis
game_window.blit(Playerimg, (x, y))
# enemy info
Enemyimg = []
enemyx = []
enemyy = []
enemyx_change = 1
enemyy_change = 0
num_enemies = 2
enemyspawnx = 50
enemyspawny = 200
for i in range(num_enemies):
Enemyimg.append(pygame.image.load('CybermanShooter.png'))
enemyx.append(enemyspawnx) # random x axis for enemy
enemyy.append(enemyspawny) # random y axis for enemy
enemyspawnx += 70
def enemy(x, y, i):
game_window.blit(Enemyimg[i], (x, y))
# bullet info
bulletimg = pygame.image.load('torpedo32.png')
bullety = playery
bulletx = playerx
bulletstate = "idle"
bullety_change = 5
def bullet(x, y):
global bulletstate
bulletstate = "FIRE"
game_window.blit(bulletimg, (x + 15.5, y - 25))
def collision(enemyx, enemyy, bulletx, bullety):
distance = math.sqrt((math.pow(bulletx - enemyx, 2)) + (math.pow(bullety - enemyy, 2)))
if distance < 27:
return True
else:
return False
rand = random.randint(0, num_enemies)
# timer info
bulletevent = pygame.USEREVENT
pygame.time.set_timer(bulletevent, 2000)
# get a rabdom number
# when the timer hits 2 secodsn spawsn bomb at the index of the random number that corresponds witht the enemy
# enemy bomb
bombimg = []
bombx = []
bomby = []
bomby_change = 1
bombstate = "idle"
num_bombs = 2
for i in range(num_bombs):
bombimg.append(pygame.image.load('bomb.png'))
bombx.append(enemyx[i])
bomby.append(enemyy[i])
def bomb(x, y, i):
global bombstate
bombstate = "fire"
game_window.blit(bombimg[i], (x + 15, y + 65))
# player hit detection
def enemyhit(bombx, bomby, x, y):
distance2 = math.sqrt((math.pow(bombx - x, 2)) + (math.pow(bomby - (y - 50), 2)))
if distance2 < 20:
return True
else:
return False
# loop to keep screen running
Running = True
while Running:
# background color
game_window.fill((0, 0, 0))
# background image in loop
game_window.blit(background, (0, 0))
# checks anything typed while game is running
for event in pygame.event.get():
# if they click x to quit close window
if event.type == pygame.QUIT:
Running = False
if event.type == bulletevent:
if bombstate == 'idle':
bomb(bombx[rand], bomby[rand], i)
bombx[rand] = enemyx[rand]
bomby[rand] = enemyy[rand]
# means key has been pressed(not released)
if event.type == pygame.KEYDOWN:
# escape key closes game
if event.key == pygame.K_ESCAPE:
Running = False
# right key moves player 5 spaces
if event.key == pygame.K_RIGHT:
playerx_change = 5
# left key moves players back 5 spaces
if event.key == pygame.K_LEFT:
playerx_change = -5
if event.key == pygame.K_SPACE:
bulletx = playerx
if bulletstate == "idle":
bullet(bulletx, bullety)
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT:
playerx_change = 0
playerx += playerx_change # constantly adds user input to player model
# player bounds
if playerx >= 740:
playerx = 740
if playerx <= 0:
playerx = 0
# player fucntion draws image
player(playerx, playery)
# loops through all the items in the lists named
for i in range(num_enemies):
# draws all enemies
enemy(enemyx[i], enemyy[i], i)
enemyx[i] += enemyx_change
if enemyx[i] >= 735:
enemyx_change = -.8
enemyy[i] += 10
if enemyx[i] <= 0:
enemyx_change = .8
enemyy[i] += 10
# is state is fire
if bulletstate == "FIRE":
# draws torpepd at coordinates
bullet(bulletx, bullety)
bullety -= bullety_change # decreases y axis moving bullet
if bullety <= 0: # if goes past border
bulletstate = "idle" # ittl switch back to idle
bullety = playery # moves bullet y back to player y
for i in range(num_enemies):
collided = collision(enemyx[i], enemyy[i], bulletx, bullety)
if collided == True:
bulletstate = 'idle'
bullety = playery
Enemyimg.remove(Enemyimg[i])
num_enemies -= 1
# when enemy fires
if bombstate == 'fire':
bomb(bombx[rand], bomby[rand], i)
bomby[rand] += bomby_change
if bomby[rand] > 570:
bombstate = 'idle'
bomby[rand] = enemyy[rand]
rand = random.randint(0, 1)
# enemy bullets hit player
enemyhits = enemyhit(bombx[rand], bomby[rand], playerx, playery)
if enemyhits == True:
playerx = 370
bombstate = 'idle'
bomby[rand] = enemyy[rand]
# updates the screen in loop
pygame.display.update()
A big problem with your code is having different lists for each attribute of your enemies.
You wrote this :
Enemyimg = []
enemyx = []
enemyy = []
Meaning that you always need to sync those three lists at all time to get coherent results. Which you are not doing, when you "remove" an enemy, you just remove the img from Enemyimg and not removing its coords in enemyy and enemyx.
While you could manage to make it work with three lists, you are just overcomplicating things. Let me show you what you may want to do to make your life way easier :)
I'm going to assume, you don't know about OOP (Object Oriented Programming) yet ? I Would be a great time to use it but it can be a little complexe if you are just starting out with programming.
So let's introduce python's dict !
What you really want to do is have one single list :
enemies = []
But how to store everything in one list you might wonder ?
Well, it will be a list of dict. A dict looks something like that :
example = {'image': pygame.image.load('CybermanShooter.png'), 'x': enemyspawnx, 'y': enemyspawny}
(Note that if you always use the same image, you don't need to put it here, you can just draw your image at the position)
Now if you do something like :
print(example['x'])
It will print your enemy's x value.
So, to sum up :
You want to have one single list : enemies = []
To add an enemy you will do :
enemies.append({'image': pygame.image.load('CybermanShooter.png'), 'x': enemyspawnx, 'y': enemyspawny})
To detect your collisions :
# Your collision function
def collision(enemy, bulletx, bullety):
distance = math.sqrt((math.pow(bulletx - enemy['x'], 2)) + (math.pow(bullety - enemy['y'], 2)))
if distance < 27:
return True
return False
# Your loop (in 2 steps: 1 - find enemies to remove, 2 - actually remove them)
enemies_to_remove = []
for enemy in enemies :
if collision(enemy, bulletx, bullety):
bulletstate = 'idle'
bullety = playery
enemies_to_remove.append(enemy)
num_enemies -= 1
for enemy in enemies_to_remove:
enemies.remove(enemy)
To draw your enemies:
# Your draw_enemy function (which you called `enemy(...)` for some reason)
def draw_enemy(enemy):
game_window.blit(enemy['image'], (enemy['x'], enemy['y']))
# Inside the main loop
for enemy in enemies:
draw_enemy(enemy)
To update the position of enemies:
# Make a move_enemy function
def move_enemy(enemy):
# put your moving logic here
# Inside the main loop:
for enemy in enemies:
move_enemy(enemy)
Do you get the principle ?
I've tried to stay as close as your original code as possible so it's not too many information to take in at once.
But technically you should apply the same principle for your bullets and to some extend to your player.

How to use time and make a timer in Pygame? [duplicate]

This question already has answers here:
Countdown timer in Pygame
(8 answers)
Spawning multiple instances of the same object concurrently in python
(1 answer)
Closed 5 months ago.
I am new to pygame programming and I am making a game with the help of tutorials. I finished the tutorial and want to add a new feature to my game.
Game Overview
I have created a space invader game where there are enemies moving on the x-axis and slowly coming down. In bottom there is a space ship which can move on the x axis and can shoot bullets to destroy or kill the enemies. The enemies respawn after being killed and if an enemy reaches the bottom, it is game over
Code
# importing modules
import pygame
import random
import math
from pygame import mixer
# initialize pygame
pygame.init()
# creating a window
screen = pygame.display.set_mode((800, 600))
# Background Music
mixer.music.load('background.wav')
mixer.music.play(-1)
# Background
bg_img = pygame.image.load("background3.png")
bg = pygame.transform.scale(bg_img, (800, 600))
# Title and Icon
pygame.display.set_caption("Space Shooters")
icon = pygame.image.load('spaceship.png')
pygame.display.set_icon(icon)
# Player
player = pygame.image.load('spaceship2.png')
playerX = 370
playerY = 500
playerX_change = 0
# Enemy
enemyImg = []
enemyX = []
enemyY = []
enemyX_change = []
enemyY_change = []
num_of_enemies = 6
for i in range(num_of_enemies):
enemyImg.append(pygame.image.load('enemy.png'))
enemyX.append(random.randint(6, 730))
enemyY.append(random.randint(45, 150))
enemyX_change.append(0.3)
enemyY_change.append(40)
# Bullet
# Ready - The bullet can't be seen
# Fire - The bullet has been shot
bulletImg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
bulletX_change = 0
bulletY_change = 1.5
bullet_state = "Ready"
# Score
score_value = 0
font = pygame.font.Font('freesansbold.ttf', 32)
textX = 10
textY = 10
# Game Over
over_font = pygame.font.Font('freesansbold.ttf', 64)
# Function for displaying text
def show_score(x, y):
score = font.render("Score : " + str(score_value), True, (255, 255, 255))
screen.blit(score, (x, y))
def game_over_text():
over_text = over_font.render("GAME OVER", True, (255, 255, 255))
screen.blit(over_text, (200, 250))
# Defining and drawing spaceship
def spaceship(x, y):
screen.blit(player, (x, y))
# Defining and drawing enemy
def enemy(x, y, i):
screen.blit(enemyImg[i], (x, y))
def fire_bullet(x, y):
global bullet_state
bullet_state = "Fire"
screen.blit(bulletImg, (x + 16, y + 10))
def Iscollision(enemyX, enemyY, bulletX, bulletY):
distance = math.sqrt((math.pow(enemyX - bulletX, 2)) + (math.pow(enemyY - bulletY, 2)))
if distance < 27:
return True
else:
return False
# making the game window run endlessly and game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Keystroke check (right, left)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -0.3
if event.key == pygame.K_RIGHT:
playerX_change = 0.3
if event.key == pygame.K_SPACE:
# Checking whether bullet is there on screen, if not making it ready, if yes disabling spacebar
if bullet_state == "Ready":
# Get the current X cordinate of spaceship
bulletX = playerX
fire_bullet(bulletX, bulletY)
bullet_sound = mixer.Sound('laser.wav')
bullet_sound.play()
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# Changing X coordinates to move spaceship
playerX += playerX_change
if playerX <= 6:
playerX = 6
elif playerX >= 730:
playerX = 730
screen.fill(0)
screen.blit(bg, (0, 0))
# Enemy Movement
for i in range(num_of_enemies):
# Game Over
if enemyY[i] > 440:
for j in range(num_of_enemies):
enemyY[j] = 2000
game_over_text()
break
for i in range(num_of_enemies):
enemyX[i] += enemyX_change[i]
if enemyX[i] <= 6:
enemyX_change[i] = 0.3
enemyY[i] += enemyY_change[i]
elif enemyX[i] >= 730:
enemyX_change[i] = -0.3
enemyY[i] += enemyY_change[i]
# Collision
collision = Iscollision(enemyX[i], enemyY[i], bulletX, bulletY)
# if collision and if collision is true are both the same
if collision:
collision_sound = mixer.Sound('explosion.wav')
collision_sound.play()
bulletY = 480
bullet_state = "Ready"
score_value += 1
enemyX[i] = random.randint(6, 730)
enemyY[i] = random.randint(45, 150)
enemy(enemyX[i], enemyY[i], i)
# Deleting each frame of enemy moving so that it runs smoothly
# Bullet Movement
if bulletY <= 0:
bulletY = 480
bullet_state = "Ready"
if bullet_state == "Fire":
fire_bullet(bulletX, bulletY)
bulletY -= bulletY_change
spaceship(playerX, playerY)
show_score(textX, textY)
# updating display
pygame.display.update()
New Feature
I want to add a feature that when a laser ( I have a picture) hits the spaceship, shot by the enemies, the spaceship can't move for 10 seconds. I have already tryed other stack overflow questions but they don't match my needs.
If you only have one cooldown to manage, a simple and clean way to do it is by using a custom event :
# Custom event
COOLDOWN_END = pg.USEREVENT
When you detect a collision you simply start a timer :
# Custom event
pg.time.set_timer(COOLDOWN_END, 1000, 1)
The first parameter is the event you are going to send to your event handler, the 2nd is the time in ms (so 1 sec here) and last one is the number of iteration. Here you just want to send the event once, so put 1.
The last step is to do catch this event in your handler and do what you want with it :
for evt in pg.event.get():
if evt.type == pg.QUIT:
exit()
if evt.type == COOLDOWN_END:
print(evt)
# Your logic goes here
Let's put everything together :
(Here, I simply used this technique to have a COOLDOWN_END event 1 sec after I clicked)
# General imports
import pygame as pg
import sys
# Init
pg.init()
# Vars
screen = pg.display.set_mode((500, 500))
pg.display.set_caption("name")
# Clock
FPS = 60
clock = pg.time.Clock()
# Custom event
COOLDOWN_END = pg.USEREVENT
# Main functions
def update():
pass
def draw():
# Clear screen
screen.fill((0,0,0))
def handle_evt():
for evt in pg.event.get():
if evt.type == pg.QUIT:
exit()
if evt.type == pg.KEYDOWN:
if evt.key == pg.K_ESCAPE:
exit()
if evt.type == pg.MOUSEBUTTONDOWN:
if evt.button == 1:
on_click()
if evt.type == COOLDOWN_END:
print(evt)
def on_click():
pg.time.set_timer(COOLDOWN_END, 1000, 1)
def exit():
pg.quit()
sys.exit()
# Main loop
if __name__ == '__main__':
while True:
handle_evt()
update()
draw()
clock.tick(FPS)
pg.display.flip()
You may use custom event with from pygame.locals import USEREVENT.
An alternative is to keep track of time of when you got hit using pygame.time.get_ticks() + some stun cooldown system, and applying only to the portion of the code involved with player movement.
stun_duration = 10000 # milliseconds
damaged_timestamp = -stun_duration # allows to get stunned starting from pygame.init() call
running = True
while running:
for event in pygame.event.get():
# preceding code
# check if beyond stun cooldown
if pygame.time.get_ticks() - damaged_timestamp > stun_duration:
damaged_timestamp = pygame.time.get_ticks()
# Keystroke check (right, left)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -0.3
if event.key == pygame.K_RIGHT:
playerX_change = 0.3
if event.key == pygame.K_SPACE:
# Checking whether bullet is there on screen, if not making it ready, if yes disabling spacebar
if bullet_state == "Ready":
# Get the current X cordinate of spaceship
bulletX = playerX
fire_bullet(bulletX, bulletY)
bullet_sound = mixer.Sound('laser.wav')
bullet_sound.play()
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# Changing X coordinates to move spaceship
playerX += playerX_change
if playerX <= 6:
playerX = 6
elif playerX >= 730:
playerX = 730
# proceeding code

How to move an image smoothly in pygame

I have searched other related questions on stack overflow but can't find the right solution.
Code Overview
basically I am trying to make a space invader game here at the bottom there is a space ship shooting down enemies and the enemies constantly move making the game hard and fun. while I am trying to make the enemies move, they paint lines which doesn't look good.
Code
# importing modules
import pygame
import random
# initialize pygame
pygame.init()
# creating a window
screen = pygame.display.set_mode((800, 600))
# Title and Icon
pygame.display.set_caption("Space Shooters")
icon = pygame.image.load('spaceship.png')
pygame.display.set_icon(icon)
# Player
player = pygame.image.load('spaceship2.png')
playerX = 370
playerY = 500
playerX_change = 0
# Enemy
enemyImg = pygame.image.load('enemy.png')
enemyX = random.randint(6, 730)
enemyY = random.randint(45, 150)
enemyX_change = 0.3
enemyY_change = 0
# Defining and drawing spaceship
def spaceship(x, y):
screen.blit(player, (x, y))
# Defining and drawing enemy
def enemy(x, y):
screen.blit(enemyImg, (x, y))
# making the game window run endlessly and game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Keystroke check (right, left)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -0.25
if event.key == pygame.K_RIGHT:
playerX_change = 0.25
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
# Changing X coordinates to move spaceship
playerX += playerX_change
if playerX <= 6:
playerX = 6
if playerX >= 730:
playerX = 730
enemyX += enemyX_change
if enemyX <= 6:
enemyX = 6
enemyX_change = 0.3
if enemyX >= 730:
enemyX = 730
enemyX_change = -0.3
spaceship(playerX, playerY)
enemy(enemyX, enemyY)
# updating display
pygame.display.update()
Expected Results vs Received Results
Expected Results: The enemy moves on the x axis at a constant speed and bounces back when a boundary has been hit. No trail should be formed.
Received Results: The enemy is moving as expected ,but painting a trail where it is and was going.
The display is redrawn in every frame, therefore the display must be cleared before drawing the objects in the scene:
while running:
# [...]
# clear the display
screen.fill(0) # <-- clear display
# draw the scene
spaceship(playerX, playerY)
enemy(enemyX, enemyY)
# update the display
pygame.display.update()
The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()

Why does "Game over" text not appear?

I am currently attempting to programm a small game. An enemy is supposed to chase the player, the actual chasing is not implemented yet. I still need to figure out how to do that, but that's not the question.
I have made it so that the player returns to the start point once they collide with the enemy. In addition to that, a text 'Game over' is supposed to appear. The function for that is called at the end of the game loop and while the text appeared briefly(it actually only appeared once, I have tried it multiple times), it does not stay. I was planing on making it appear and then disappear after a few seconds so that the player can play again, but I'm not sure why it disappears instantly.
If this is the wrong place to post this, please tell me, I will delete this post. This is my code, would be amazing if somebody could help me out:
import pygame #imports pygame
import math
pygame.init()
#screen
screen = pygame.display.set_mode((800,600)) #width and height
#title and icon
pygame.display.set_caption("The Great Chase") #changes title
icon = pygame.image.load('game-controller.png')
pygame.display.set_icon(icon) #setting icon
#player
playerImg = pygame.image.load('scary-monster.png')
playerX = 370
playerY = 480
playerX_change = 0
playerY_change = 0
#enemy
enemyImg = pygame.image.load('caterpillar.png')
enemyX = 370
enemyY = 50
enemyX_change = 0
enemyY_change = 0
#GAME OVER
game_over_font = pygame.font.Font('Bubblegum.ttf',64)
def game_over_text():
game_over_text = game_over_font.render("GAME OVER", True, (255, 0, 0))
screen.blit(game_over_text, (200, 250))
def player(x, y): #function for player
screen.blit(playerImg, (x, y)) #draws image of player, blit -> means to draw
def enemy(x, y): #function for enemy
screen.blit(enemyImg,(x,y))
def isCollision(playerX, playerY, enemyX, enemyY):
distance = math.sqrt((math.pow(playerX-enemyX,2)) + (math.pow(playerY - enemyY,2)))
if distance < 25:
return True
else:
return False
def chase():
distance = math.sqrt((math.pow(playerX-enemyX,2)) + (math.pow(playerY - enemyY,2)))
#Game loop
running = True
while running:
screen.fill((255,255,0)) #0-255 RGB-> red, green & blue
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# if keystroke check whether right or left or up or down
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerX_change = -0.2
if event.key == pygame.K_RIGHT:
playerX_change = 0.2
if event.key == pygame.K_UP:
playerY_change = -0.2
if event.key == pygame.K_DOWN:
playerY_change = 0.2
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerX_change = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
playerY_change = 0
playerX += playerX_change
playerY += playerY_change
#creating borders so that player won't leave screen
if playerX <=0:
playerX = 0
elif playerX >=768:
playerX = 768
if playerY <= 0:
playerY = 0
elif playerY >=568:
playerY = 568
#collision
collision = isCollision(playerX, playerY, enemyX, enemyY)
if collision:
playerY = 480
game_over_text()
player(playerX, playerY)
enemy(enemyX, enemyY)
pygame.display.update()
The collision only occurs for a moment and the game over text is only shown when the object collides. If you want to persist the text, set a gameover variable when the collision is detected and display the text based on the state of the variable:
gameover = False
running = True
while running:
# [...]
collision = isCollision(playerX, playerY, enemyX, enemyY)
if collision:
playerY = 480
gameover = True
player(playerX, playerY)
enemy(enemyX, enemyY)
if gameover:
game_over_text()
pygame.display.update()
Note, collision is set in every frame depending on the position of the objects. However, gameover is set once when a collision occurs and then maintains its state.

Shooting in Pygame

I am trying to make a shooter in pygame. I am able to have the player move around, and when space is pressed, the bullet will go to its position. I am wondering how i can get it to move away from the player, until it hits the edge of the screen. Here is what i have so far:
if AMMO > 0:
if event.type == pygame.KEYDOWN and Gun.image == NOGUN:
if event.key == pygame.K_SPACE and Gun.image == NOGUN:
Bullet.rect.center = Player.rect.center
if Player.direction == 0:
Bullet.direction = 0 #WHERE THE BULLET WILL MOVE
shot.play()
print "BANG"
AMMO = AMMO - 1
time.sleep(0.09)
We'd need more code here.
In pseudocode:
def frameUpdate( timeBetweenFrame, bulletSpeed, playerDirectionVector ):
bullet.position = bullet.position + playerDirectionVector.MultiplyByScalar(bulletSpeed * timeBetweenFrame);
Where playerDirectionVector is a normalized vector in the direction the player is facing.
Try this
if AMMO > 0:
if event.type == pygame.KEYDOWN and Gun.image == NOGUN:
if event.key == pygame.K_SPACE and Gun.image == NOGUN:
#Initialize Bullet so it's not null and do the rest
Bullet.rect.center = Player.rect.center
if Player.direction == 0:
Bullet.direction = 0
if Bullet != null
Bullet.X += 10
if Bullet.X > ScreenWidth()
Bullet = null
#These are all examples so you can understand the logic, I don't remember exactly how pygame works, but since you can move a character around you can find this :P
Keep in mind that this code allows only one bullet!
What I use when I make bullet instances in psudocode
#making your starting bullet cords
Bulletx = playerx
Bullety = playery
#this stores the angle the bullet was shot from
Bulletangle = degreesplayerisrotated
This converts the angle to a radian
Bulletangle = Bulletangle×pi/180
#this line updates the cords speed is a set value of how fast you want the bullet to move
Bulletx = bulletx-cos(bulletangle)×speed
Bullety = bullety-sin (bulletangle)×speed
Screen.blit (bullet, (bulletx, bullety))
Or draw a circle with the cords
If you have a question be sure to ask hope this cleared things up

Categories

Resources