Can't figure out why my image wont move in pygame - python

I'm just messing around with Pygame and I can't see what I'm doing incorrectly to make the red circle move with the arrow keys. I can't tell if it's in my main loop. I also haven't been able to find very many tutorials on sprite or looping animations with Pygame. If I for example wanted to make a square oscillate for example like a moving platform how would I do that?
import pygame
import time
## event handling varibles
player_x = 0
player_y = 0
x = 250
y = 250
## screen display
display_width = 500
display_height = 500
pygame.init()
game_screen = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("test")
# player
def player():
pygame.draw.circle(game_screen,red,(x,y),15)
# colors
white = (255,255,255)
red = (255,0,0)
black = (0,0,0)
### main loop
dead = False
while dead != True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
dead = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_x = -1
elif event.key == pygame.K_RIGHT:
player_x = +1
if event.key == pygame.K_UP:
player_y = +1
elif event.key == pygame.K_DOWN:
player_y = -1
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or pygame.K_RIGHT:
player_x = 0
if event.key == pygame.K_UP or pygame.K_DOWN:
player_y = 0
game_screen.fill(black)
player()
pygame.display.update()
x -= player_x
y -= player_y
pygame.quit()
quit()

Your indendation is all messed up.
Your code won't do anything unless the event is QUIT... which then makes it quit.
Your boolean logic is wrong.
This is not proper syntax event.key == pygame.K_UP or pygame.K_DOWN. The order of precedence here is as follows (event.key == pygame.K_UP) or (K_DOWN). Since K_DOWN is truthy, it is always true and thus this entire statement is always true.
I think you mean: event.key == pygame.K_UP or event.key == pygame.K_DOWN
Lastly, it wont' keep moving as you say you want.
It will only move when there is an event in the queue. You can make it keep moving by generating events. Perhaps with an event timer.
Here is a fixed version, hope this helps:
import pygame
import time
## event handling varibles
player_x = 0
player_y = 0
x = 250
y = 250
## screen display
display_width = 500
display_height = 500
pygame.init()
game_screen = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("test")
# player
def player(game_screen, red, point): # Use parameters not globals
pygame.draw.circle(game_screen, red, point, 15)
# colors
white = (255,255,255)
red = (255,0,0)
black = (0,0,0)
### main loop
pygame.time.set_timer(pygame.USEREVENT, 1) # 1 per second
dead = False
while not dead:
for event in pygame.event.get():
if event.type == pygame.QUIT:
dead = True
elif event.type == pygame.USEREVENT:
pygame.time.set_timer(pygame.USEREVENT, 1) # Set another timer for another 1 second
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_x = +10
elif event.key == pygame.K_RIGHT:
player_x = -10
elif event.key == pygame.K_UP:
player_y = +10
elif event.key == pygame.K_DOWN:
player_y = -10
elif event.type == pygame.KEYUP:
if event.key in [pygame.K_LEFT, pygame.K_RIGHT]:
player_x = 0
elif event.key in [pygame.K_UP, pygame.K_DOWN]:
player_y = 0
game_screen.fill(black)
player(game_screen,red,(x,y))
pygame.display.update()
x -= player_x
y -= player_y
pygame.quit()

Related

Can you make the game display appear in the centre of your screen once the run is pressed. If yes how?

#enable pygame mode
import pygame
pygame.init()
#create screen
screen = pygame.display.set_mode((1000,600))
#Title + Logo
pygame.display.set_caption("Space Invader")
icon = pygame.image.load("chicken.png")
pygame.display.set_icon(icon)
#Player icon
player_icon = pygame.image.load("spaceship.png")
playerX = 400
playerY = 500
player_changeX = 0
player_changeY = 0
def player(x, y):
screen.blit(player_icon, (x, y))
surface.blit(image,((1920/2)-(image.get_width()/2),(1080/2)-
(image.get_height()/2)))
#game loop
running = True
while running:
# backround colour RGB
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#If key pressed check wether its right or left
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player_changeX = -1
if event.key == pygame.K_RIGHT:
player_changeX = 1
if event.key == pygame.K_UP:
player_changeY = -1
if event.key == pygame.K_DOWN:
player_changeY = 1
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key ==pygame.K_RIGHT:
player_changeX = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
player_changeY = 0
# If player reaches boarder
if playerX >= 936:
player_changeX = -1
if playerX <= 0:
player_changeX = 1
if playerY <= 0:
player_changeY = 1
if playerY >= 550:
player_changeY = -1
#Player change in coordinates
playerX += player_changeX
playerY += player_changeY
player(playerX, playerY)
pygame.display.update()
I am creating a simple game as i just got into programing and I was wondering if you could make the game screen appear in the centre of your own screen as when I run it it keeps appearing on the bottom of my screen and I then have to manually move it into the centre. If you can please tell me how. Hope my question was formated good enough. Thank you for any help.
It depends; if it's a image you can do:
surface.blit(image,((screenwidth/2)-(image.get_width()/2),(screenheight/2)-(image.get_height()/2)))
Please tell me it it's different

Pygame Game Development shoot functionality

My question is how can I better my shooting functionality in my game. I am trying to make it to where the player can shoot in the direction it is moving (ex.shoot up,down,left,right) as well as shoot while moving and shoot while idle.
The player and missile are both rectangular using pygame shapes to make it easier for me to understand the logic behind game development.
def player(px,py):
pygame.draw.rect(gameWindow,black,[px,py,30,30])
def missile(mx,my):
pygame.draw.rect(gameWindow,black,[mx,my,10,10])
Here is the code of the game to help better understand what I'm talking about. The small section I have commented out is what I have tried. I only have it currently set to move in the x direction going left from its initial starting point.
import pygame #####IMPORTING PYGAME MODULE###########################
pygame.init() #####INITIALIZING PYGAME##################################
gameWindow = pygame.display.set_mode((800,600)) ###Screen Width and Height###
clock = pygame.time.Clock() ## FRAMES PER SECOND ##
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
def player(px,py):
pygame.draw.rect(gameWindow,black,[px,py,30,30])
def missile(mx,my):
pygame.draw.rect(gameWindow,black,[mx,my,10,10])
def enemies():
return
def gameloop():
px = 700
py = 300
mx = 700
my = 300
px_change = 0
py_change = 0
mx_change = 0
my_change = 0
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
mx_change = -10
if event.key == pygame.K_RIGHT:
mx_change = 10
if event.key == pygame.K_UP:
my_change = -10
if event.key == pygame.K_DOWN:
my_change = 10
if event.key == pygame.K_SPACE:
mx_change = -6
#if event.key == pygame.K_SPACE and pygame.K_RIGHT:
#mx_change = 6
if event.key == pygame.K_LEFT:
px_change = -10
if event.key == pygame.K_RIGHT:
px_change = 10
if event.key == pygame.K_UP:
py_change = -10
if event.key == pygame.K_DOWN:
py_change = 10
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
px_change = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
py_change = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
mx_change = 0
mx = px
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
my_change = 0
my = py
if event.key == pygame.K_SPACE:
mx_change = 0
my_change = 0
mx = px
my = py
px += px_change
py += py_change
mx += mx_change
my += my_change
gameWindow.fill(white)
player(px,py)
missile(mx,my)
pygame.display.update()
clock.tick(100)
pygame.quit()
quit()
gameloop()
I would suggest using different objects for your player and missile. The way you have things set up right now, there can only be 1 player and 1 missile. Only having 1 player might be fine but 1 missile makes for a dull game. I suggest using a class, such as this simple example:
class Projectile():
def init(self,x,y,vx,vy):
self.x = x
self.y = y
self.vx = vx
self.vy = vy
def update(self):
self.x += self.vx
self.y += self.vy
Now that you have a class you can start doing great things! Want to have spacebar fire a new missile instead of moving the one missile on screen? ezpz! All you need is a list of your missile objects to keep track of, say my_missile_list:
if event.key == pygame.K_SPACE:
my_missile_list.append(Projectile(px,py,missile_x_velocity,missile_y_velocity))
This creates an entirely new instance of the class Projectile based on the input position and speeds.
Finally, we need to have all these missiles move! This is where the class definition makes our life easier! Once per frame we just have to update the bullets:
for b in my_missile_list:
b.update()
There are more advantages to using classes here but this is a start. If you read through this and make a few changes your game will work much more like what you are looking for.
You should set missille only when you KEYDOWN space, and not use other keys to change it. Player may have variable direction so you will know in which direction it is looking when it stay and you will know in which direction move misille.
import pygame
# --- constants --- (UPPER_CASE_NAMES)
WHITE = (255,255,255)
BLACK = (0,0,0)
RED = (255,0,0)
# --- classes --- (CamelCaseNames)
# empty
# --- functions ---- (lower_case_names_
def player(screen, x, y):
pygame.draw.rect(screen, BLACK, (x, y, 30, 30))
def missile(screen, x, y):
pygame.draw.rect(screen, RED, (x, y, 10, 10))
def enemies():
pass
def gameloop(screen):
px = 700
py = 300
mx = 700
my = 300
px_change = 0
py_change = 0
p_direction = 'left'
mx_change = 0
my_change = 0
#m_direction = 'left'
game_exit = False
clock = pygame.time.Clock() ## FRAMES PER SECOND ##
while not game_exit:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_exit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
px_change = -10
p_direction = 'left'
if event.key == pygame.K_RIGHT:
px_change = 10
p_direction = 'right'
if event.key == pygame.K_UP:
py_change = -10
p_direction = 'top'
if event.key == pygame.K_DOWN:
py_change = 10
p_direction = 'down'
if event.key == pygame.K_SPACE:
mx = px
my = py
if p_direction == 'left':
mx_change = -16
my_change = 0
elif p_direction == 'right':
mx_change = 16
my_change = 0
elif p_direction == 'top':
mx_change = 0
my_change = -16
elif p_direction == 'down':
mx_change = 0
my_change = 16
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
px_change = 0
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
py_change = 0
# --- changes/updates ---
px += px_change
py += py_change
mx += mx_change
my += my_change
# --- draws ----
screen.fill(WHITE)
player(screen, px, py)
missile(screen, mx, my)
pygame.display.update()
# --- FPS ---
clock.tick(30)
# --- main ---
pygame.init()
screen = pygame.display.set_mode((800,600))
gameloop(screen)
pygame.quit()
#quit()
Instead of px, py and mx,my you should use pygame.Rect() - it can be used to draw() and blit() and it has methods to check collisions.

Pygame not checking keyevents after another happens

I am moving a sprite on the x-axis. It is properly moving left and right. When I press both LEFT and RIGHT at the same time it stop moving properly.
I am trying to make it when a user presses both keys and then lets go of one, for it to continue moving in the direction still pressed.
Weirdly it works while I holding right and letting go of left. It continues moving right.
When I hold left and tap right it stops moving until I press right again.
I commented out some ideas I had to make this work, but they failed me.
I am sure its a simple fix or a logic failure on my part.
I have worked a couple hours on this.
Thanks for responses ahead of time.
import pygame
import time
import random
import sys
import math
pygame.init()
displayWidth = 1200
displayHeight = 800
white = (255,255,255)
black = (0,0,0)
gameDisplay = pygame.display.set_mode((displayWidth, displayHeight))
pygame.display.set_caption('Game 3')
clock = pygame.time.Clock()
class firstSquare:
def __init__(self,player_x,player_y):
self.x = player_x
self.y = player_y
self.width = 100
self.height = 100
def render(self):
pygame.draw.rect(gameDisplay, white,(self.x, self.y, self.width, self.height))
class secondSquare:
def __init__(self,cpu_x,cpu_y):
self.x = cpu_x
self.y = cpu_y
self.width = 100
self.height = 100
def render(self):
pygame.draw.rect(gameDisplay, white,(self.x, self.y, self.width, self.height))
player = firstSquare(300,300)
cpu = secondSquare(100,100)
def gameLoop():
### variables##
player_x = 100
player_y = 100
x = 100
y = 100
movement_x = 0
movement_y = 0
frame_rate = 0
frame_table = 0
inGame = True
while inGame:
for event in pygame.event.get():
if event.type == pygame.QUIT:
inGame = False
pygame.quit()
sys.exit()
keyPressed= pygame.key.get_pressed()
#### this is moving the player on x-axis##
if keyPressed[pygame.K_LEFT]:
movement_x = -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
movement_x = 0
if keyPressed[pygame.K_RIGHT]:
movement_x = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
movement_x = 0
### two keys at once won't move the player###
if keyPressed[pygame.K_LEFT] and keyPressed[pygame.K_RIGHT]:
movement_x = 0
### pressing one key and letting go the other will continue movement
## if keyPressed[pygame.K_LEFT] and keyPressed[pygame.K_RIGHT]:
## if event.type == pygame.KEYUP:
## if event.key == pygame.K_LEFT:
## movement_x = 5
## print("left dropped")
## if keyPressed[pygame.K_RIGHT] and keyPressed[pygame.K_LEFT]:
## if event.type == pygame.KEYUP:
## if event.key == pygame.K_RIGHT:
## movement_x = -5
## print("Right dropped")
gameDisplay.fill(black)
player.render()
cpu.render()
player.x += movement_x
pygame.display.update()
clock.tick(60)
gameLoop()
pygame.quit()
quit()
I think what you need is this:
if keyPressed[pygame.K_LEFT]:
movement_x = -5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT and movement_x < 0:
movement_x = 0
if keyPressed[pygame.K_RIGHT]:
movement_x = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT and movement_x > 0:
movement_x = 0
And that would be it... Hope it helps.
Try to use the following code in your movement:
if keyPressed[pygame.K_LEFT]:
movement_x = -5
elif keyPressed[pygame.K_RIGHT]:
movement_x = +5
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
movement_x = 0
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
movement_x = 0

Image not moving for the life of me

import pygame
# Some colors
GREEN = ( 0,255,0)
BLUE = ( 0, 0, 255)
WHITE = ( 255, 255, 255)
BLACK = ( 0, 0, 0)
pygame.init()
clock = pygame.time.Clock()
#Screen
SCREEN = pygame.display.set_mode([1000,700])
#Title
pygame.display.set_caption("Trying to move things")
#Variables
x_position = 100
y_position = 100
x_speed = 0
y_speed = 0
#Positions
image_image_positions = [x_position,y_position]
#Graphics
image_image = pygame.image.load("izzat.png").convert()
image_image.set_colorkey(BLACK)
#Main loop ____
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Keyboard commands.
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_speed = -5
elif event.key == pygame.K_DOWN:
y_speed = 5
elif event.key == pygame.K_w:
x_speed = -5
elif event.key == pygame.K_s:
x_speed = 5
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_speed = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_speed = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
x_speed += 0
if y_position + y_speed >=0 and y_position + y_speed + 60 <=500:
y_position += y_speed
x_position += x_speed
SCREEN.fill(GREEN)
SCREEN.blit(image_image, image_image_positions)
print(x_position)
print(y_position)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Hello, I have been having a problem which I'm really not happy at because I have been trying to fix it for a while now. So basically I have a image, and I wish to move the image based on the keyboard inputs, yet whatever I try nothing works. I then wondered maybe the y and x position aren't changing at all which is why the images positions are not changing, well I did print( those positions) but it the positions are definitely changing, the variables, so I do not get how the image positions do not change at all. Then I thought maybe because it's a tuple, so I changed it to parenthesis, that also did not work. I just don't get why my image position doesn't move if the variables for the position of the image do change. Thank you if you could help me in any way. I have looked this up but I couldn't find any help. Thank you for your help if you help me!
Update__________
Ok so apparently the image_image_position stays the same despite the variables changing when I printed the positions of image_image_position. Is there any way to change them and not have them stay at 100,100 all the time and change with the variables being changed?
You haven't assigned the speeds.
image_image_positions[0] = xspeed
image_image_positions[1] = yspeed
You are only changing your variables yspeed and xspeed, but you are not setting the actual positions of the image. Add the following line before the blit:
image_image_positions = [x_position,y_position]
Full code:
import pygame
# Some colors
GREEN = ( 0,255,0)
BLUE = ( 0, 0, 255)
WHITE = ( 255, 255, 255)
BLACK = ( 0, 0, 0)
pygame.init()
clock = pygame.time.Clock()
#Screen
SCREEN = pygame.display.set_mode([1000,700])
#Title
pygame.display.set_caption("Trying to move things")
#Variables
x_position = 100
y_position = 100
x_speed = 0
y_speed = 0
#Positions
image_image_positions = [x_position,y_position]
#Graphics
image_image = pygame.image.load("izzat.png").convert()
image_image.set_colorkey(BLACK)
#Main loop ____
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Keyboard commands.
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_speed = -5
elif event.key == pygame.K_DOWN:
y_speed = 5
elif event.key == pygame.K_w:
x_speed = -5
elif event.key == pygame.K_s:
x_speed = 5
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_speed = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_speed = 0
elif event.key == pygame.K_w or event.key == pygame.K_s:
x_speed += 0
if y_position + y_speed >=0 and y_position + y_speed + 60 <=500:
y_position += y_speed
x_position += x_speed
image_image_positions = [x_position,y_position]
SCREEN.fill(GREEN)
SCREEN.blit(image_image, image_image_positions)
print(x_position)
print(y_position)
pygame.display.flip()
clock.tick(60)
pygame.quit()
While you ARE updating the x/y positions, this isn't changing where the image is being drawn:
SCREEN.blit(image_image, image_image_positions)
image_image_positions, is never changed throughout the life-span of your application (besides startup).
To fix this simply add the update into your loop:
image_image_positions = [x_position,y_position]

My character won't move in python

This is the code I used.
import pygame, sys
from pygame.locals import *
pygame.init()
def game():
width, height = 1000, 600
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption('My game far now :P') #This command allows you make a title.
background=pygame.image.load('AE.jpg')
background = pygame.transform.scale(background, (width,height))
screen.blit(background, (0,0))
#Load target image and player
player = pygame.image.load('little.png')
player = pygame.transform.scale(player, (40,40))
px,py = width/2,height/2
screen.blit(player, (px,py))
movex = movey = 0
#Running of the game loop
while True:
screen.blit(background, (0,0))
#screen.blit(target,targetpos)
screen.blit(player, (px,py))
pygame.display.update()
#keyboard an/or mouse movements
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == K_RIGHT:
movex = 2
if event.key == K_LEFT:
movex = -2
if event.key == K_UP:
movey = -2
if event.key == K_DOWN:
movey = 2
elif event.type == pygame.KEYUP:
if event.key == K_RIGHT:
movex = 0
if event.key == K_LEFT:
movex = 0
if event.key == K_UP:
movey = 0
if event.key == K_DOWN:
movey = 0
px = px + movex
py = py + movey
#Python 's way of running the main routine
if __name__=='__main__':
game()
When I run the program it all starts right, the screen opens with background and player spawning in the middle of the screen, but when I try to move nothing happends, no errors nothing.
Would apriciate any help I can get :)
Thx for taking time to help me.
You seem to have code indentation problem in last two lines which may be causing the bug.
Your curent code is equivalent to this if code block:
elif event.type == pygame.KEYUP:
if event.key == K_RIGHT:
movex = 0
if event.key == K_LEFT:
movex = 0
if event.key == K_UP:
movey = 0
if event.key == K_DOWN # IF BLOCK STARTS
movey = 0
px = px + movex # THIS FALLS IN THE PREVIOUS IF BLOCK
py = py + movey
Correct code would be :
elif event.type == pygame.KEYUP:
if event.key == K_RIGHT:
movex = 0
if event.key == K_LEFT:
movex = 0
if event.key == K_UP:
movey = 0
if event.key == K_DOWN # IF BLOCK STARTS
movey = 0 #IF BLOCK ENDS
px = px + movex # NOW THIS IS OUT OF THE IF BLOCK
py = py + movey
Take this code, the movement is optimized. Useles code removed.
I hope you understand it ;)
import pygame, sys
from pygame.locals import *
pygame.init()
width, height = 1000, 600
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption('My game far now :P')
background=pygame.image.load('AE.png')
background = pygame.transform.scale(background, (width,height))
player = pygame.image.load('little.png')
player = pygame.transform.scale(player, (40,40))
px,py = width/2,height/2
movex = movey = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]: px -= 2
if keys[pygame.K_RIGHT]: px += 2
if keys[pygame.K_UP]: py -= 2
if keys[pygame.K_DOWN]: py += 2
screen.blit(background, (0,0))
screen.blit(player, (px,py))
pygame.display.update()
Two problems.
You don't render in your loop
You are updating the location only in the if statement.
fixed:
while True:
# input
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
# ...snip...
# physics
px += movex
py += movey
# drawing
screen.blit(background, (0,0))
screen.blit(player, (px,py))
pygame.display.update()

Categories