I can't move my player in pygame, can you figure why? - python

I'm trying to make a little game, and I came across a problem which I can't seem to figure out. The problem is that my sprite isn't moving after creating the game loop and the if statements with the keyup's and what not. Can you guys figure it out and tell me why it's not working?
Here's my code so far:
import pygame, sys, random
from pygame.locals import *
pygame.init()
mainClock = pygame.time.Clock()
windowWidth = 600
windowHeight = 400
windowSize = (600, 400)
windowSurface = pygame.display.set_mode((windowWidth, windowHeight), 0, 32)
display = pygame.Surface((300, 200))
black = (0, 0, 0)
white = (225, 225, 255)
green = (0, 255, 0)
moveRight = False
moveLeft = False
moveSpeed = 6
level= [['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','2','2','2','2','2','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['2','2','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','2'],
['1','1','2','2','2','2','2','2','2','2','2','2','0','0','2','2','2','1','1'],
['1','1','1','1','1','1','1','1','1','1','1','1','0','0','1','1','1','1','1'],
['1','1','1','1','1','1','1','1','1','1','1','1','0','0','1','1','1','1','1'],
['1','1','1','1','1','1','1','1','1','1','1','1','0','0','1','1','1','1','1'],
['1','1','1','1','1','1','1','1','1','1','1','1','0','0','1','1','1','1','1'],
['1','1','1','1','1','1','1','1','1','1','1','1','0','0','1','1','1','1','1']]
grass = pygame.image.load('grass.png')
dirt = pygame.image.load('dirt.png')
player = pygame.image.load('player.png').convert()
playerRect = pygame.Rect(100, 100, 5, 13)
player.set_colorkey((255,255,255))
while True:
display.fill((214, 42, 78))
#display.blit(player,(playerRect.x,playerRect.y))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_RIGHT or event.key == pygame.K_d:
moveRight = True
if event.type == pygame.K_LEFT or event.key == pygame.K_a:
moveLeft = False
if event.type == pygame.KEYUP:
if event.type == pygame.K_RIGHT or event.key == pygame.K_d:
moveRight = False
if event.type == pygame.K_LEFT or event.key == pygame.K_a:
moveLeft = False
display.blit(player,(playerRect.x,playerRect.y))
playerMovement = [0, 0]
if moveRight == True:
playerMovement[0] += 2
if moveLeft == True:
playerMovement[0] -= 2
tileRect = []
y = 0
for row in level:
x = 0
for col in row:
if col == '2':
display.blit(grass, (x*16, y*16))
if col == '1':
display.blit(dirt, (x*16, y*16))
if col != '0':
tileRect.append(pygame.Rect(x*16,y*16,16,16))
x += 1
y += 1
#pygame.draw.rect(windowSurface, black, player)
windowSurface.blit(pygame.transform.scale(display, windowSize),(0,0))
pygame.display.update()
mainClock.tick(60)

I've restructured your main loop to fix the problems. I change the playerMovement (velocity) in the event loop now and use it to update the playerRect in the main loop with the pygame.Rect.move_ip method.
By the way, you can pass the playerRect to blit to blit the image at the topleft (x, y) coords.
# The player's velocity. Define it outside of the main loop.
playerMovement = [0, 0]
while True:
# Handle events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_RIGHT or event.key == pygame.K_d:
playerMovement[0] = 2 # Set the x-velocity to the desired value.
if event.type == pygame.K_LEFT or event.key == pygame.K_a:
playerMovement[0] = -2
if event.type == pygame.KEYUP:
if event.type == pygame.K_RIGHT or event.key == pygame.K_d:
playerMovement[0] = 0 # Stop the player when the button is released.
if event.type == pygame.K_LEFT or event.key == pygame.K_a:
playerMovement[0] = 0
# Game logic.
playerRect.move_ip(playerMovement)
# Draw everything.
display.fill((214, 42, 78))
tileRect = []
y = 0
for row in level:
x = 0
for col in row:
if col == '2':
display.blit(grass, (x*16, y*16))
if col == '1':
display.blit(dirt, (x*16, y*16))
if col != '0':
tileRect.append(pygame.Rect(x*16,y*16,16,16))
x += 1
y += 1
display.blit(player, playerRect)
windowSurface.blit(pygame.transform.scale(display, windowSize), (0, 0))
pygame.draw.rect(windowSurface, black, playerRect)
pygame.display.update()
mainClock.tick(60)

Related

Rect not moving in Pygame

I am trying to make a pong game in pygame. So I needed to make a rectangle controlled by player. I defined some variables for this purpose.
The variables
player = pygame.Rect(s_width - 10, s_height/2 - 35, 5, 70)
player_speed = 0
In the loop
player.y += player_speed
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if pygame.key == pygame.K_DOWN:
player_speed += 5
if pygame.key == pygame.K_UP:
player_speed -= 5
if event.type == pygame.KEYUP:
if pygame.key == pygame.K_DOWN:
player_speed = 0
if pygame.key == pygame.K_UP:
player_speed = 0
There is just one problem in your code; you don't check
if pygame.key == pygame.K_...
You need to replace the pygame.key to event.key:
if event.key == pygame.K_...
import pygame
pygame.init()
s_width, s_height = 600, 600
wn = pygame.display.set_mode((s_width, s_height))
player = pygame.Rect(s_width - 10, s_height/2 - 35, 5, 70)
player_speed = 0
clock = pygame.time.Clock()
while True:
clock.tick(60)
player.y += player_speed
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
player_speed += 5
print(player_speed)
if event.key == pygame.K_UP:
player_speed -= 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
player_speed = 0
if event.key == pygame.K_UP:
player_speed = 0
wn.fill((0, 0, 0))
pygame.draw.rect(wn, (255, 0, 0), player)
pygame.display.update()
Output:

How to make a bullet animation in pygame? [duplicate]

This question already has an answer here:
How do I continuously trigger an action at certain time intervals? Enemy shoots constant beam instead of bullets in pygame [duplicate]
(1 answer)
Closed 2 years ago.
So I wrote my code and everything works how I want it to for now.
The only problem is that my bullet or fireball teleports to the location I set it to.
I am wondering if there is a way to make it look like its actually moving towards the destination using pygame and whatnot.
Thanks a ton!
(width, height) = (1300,800)
screen = pygame.display.set_mode((width, height))
playerImage = pygame.image.load('player.png')
fireballImage = pygame.image.load('fireball.png')
pygame.display.set_caption('Game')
transparent = (0, 0, 0, 0)
#Fireball stats
def player(x ,y):
screen.blit(playerImage, (x, y))
pygame.display.flip()
def fireball(x, y):
screen.blit(fireballImage, (fb_x,fb_y))
pygame.display.flip()
fireball_state = "ready"
print('created')
fb_x = x = width * 0.45
fb_y = y = height * 0.8
x_change = 0
y_change = 0
fb_x_change = 0
fb_y_change = 0
pressed = pygame.key.get_pressed()
#mainloop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_d:
x_change = 1
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
x_change = -1
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d:
x_change = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
y_change = -2
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
y_change = 2
if event.type == pygame.KEYUP:
if event.key == pygame.K_w or event.key == pygame.K_s:
y_change = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
fb_y_change = -400
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
fb_y_change = 0
x += x_change
y += y_change
fireball(x,y)
fb_x = x
fb_y = y
screen.fill((255,255,255))
player(x,y)
fb_x += fb_x_change
fb_y += fb_y_change
fireball(fb_x,fb_y)
pygame.display.update()
First of all remove pygame.display.flip() from player and fireball. That casuse flickering. A single pygame.display.update() at the end of the application loop is sufficient.
Note, the fireballs have to be blit at (x, y) rather than (fb_x, fb_y)
def player(x ,y):
screen.blit(playerImage, (x, y))
def fireball(x, y):
screen.blit(fireballImage, (x, y))
fireball_state = "ready"
Further more use pygame.time.Clock() / tick() to control the flops per second (FPS):
clock = pygame.time.Clock()
#mainloop
running = True
while running:
clock.tick(FPS)
Add a list for the fire balls:
fireballs = []
Spawn a new fireball when space is pressed:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
fireballs.append([x, y, 0, -2])
Update and draw the fireballs in a loop:
for fb in fireballs:
fb[0] += fb[2]
fb[1] += fb[3]
for fb in fireballs:
fireball(fb[0],fb[1])
See the example:
fireballs = []
FPS = 60
clock = pygame.time.Clock()
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
fireballs.append([x, y, 0, -2])
pressed = pygame.key.get_pressed()
if pressed[pygame.K_w]:
y -= 2
if pressed[pygame.K_s]:
y += 2
if pressed[pygame.K_a]:
x -= 2
if pressed[pygame.K_d]:
x += 2
for i in range(len(fireballs)-1, -1, -1):
fb = fireballs[i]
fb[0] += fb[2]
fb[1] += fb[3]
if fb[1] < 0:
del fireballs[i]
screen.fill((255,255,255))
player(x,y)
for fb in fireballs:
fireball(fb[0],fb[1])
pygame.display.update()

Why wont this blit on my screen?

I know this is going to be (hopefully) an easy fix, but I cannot get the gameover screen to blit on my screen. I have thought through this for the past two hours, and none of my tweaks are working. Any help would be greatly appreciated!
This file contains the main file loop as while as sprite group
updates and general updates/renders for the program
import pygame, sys
import player
import random
import math
from constants import *
from bullet import *
from block import *
pygame.init()
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption("Open")
clock = pygame.time.Clock()
def main():
moveX = 0
moveY = 0
sprite_list = pygame.sprite.Group()
bullet_list = pygame.sprite.Group()
block_list = pygame.sprite.Group()
main_player = player.Player()
sprite_list.add(main_player)
main_player.rect.x = 400
main_player.rect.y = 550
for i in range(1,10):
blocks = Block()
blocks.center_x = random.randrange(760)
blocks.center_y = random.randrange(400)
blocks.radius = random.randrange(10,200)
blocks.angle = random.random() * 4 * math.pi
blocks.speed = 0.04
block_list.add(blocks)
sprite_list.add(blocks)
font = pygame.font.Font(None, 36)
game_over = False
score = 0
level = 1
gameLoop = True
while gameLoop:
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_RIGHT:
moveX = 5
if event.key == pygame.K_LEFT:
moveX = -5
if event.key == pygame.K_DOWN:
moveY = 5
if event.key == pygame.K_UP:
moveY = -5
if event.key == pygame.K_SPACE:
bullets = Bullet()
bullets.rect.x = main_player.rect.x + 16
bullets.rect.y = main_player.rect.y + 16
sprite_list.add(bullets)
bullet_list.add(bullets)
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT and moveX >= 0:
moveX = 0
if event.key == pygame.K_LEFT and moveX <= 0:
moveX = 0
if event.key == pygame.K_DOWN and moveY >= 0:
moveY = 0
if event.key == pygame.K_UP and moveY <= 0:
moveY = 0
for bullets in bullet_list:
block_hit_list = pygame.sprite.spritecollide(bullets, block_list, True)
for block in block_hit_list:
score += 1
bullet_list.remove(bullets)
sprite_list.remove(bullets)
if bullets.rect.y < 0:
bullet_list.remove(bullets)
sprite_list.remove(bullets)
if pygame.sprite.spritecollide(main_player, block_list, True):
gameLoop = False
game_over = True
sprite_list.update()
screen.fill(BLACK)
sprite_list.draw(screen)
main_player.rect.x += moveX
main_player.rect.y += moveY
score_text = font.render("Score: "+str(score), True, WHITE)
screen.blit(score_text,[10,10])
level_text = font.render("Level: "+str(level), True, WHITE)
screen.blit(level_text,[115,10])
if game_over == True:
you_lose_text = font.render("YOU SUCK", True, RED)
screen.blit(you_lose_text, [300,300])
pygame.time.wait(1000)
break
clock.tick(60)
pygame.display.update()
pygame.quit()
if __name__ == "__main__":
main()
HERE IS MY ISSUE:
if game_over == True:
you_lose_text = font.render("YOU SUCK", True, RED)
screen.blit(you_lose_text, [300,300])
pygame.time.wait(1000)
break
I am getting no error, and the pygame.time.wait function is working correctly? Why is it just skipping over displaying the text?
Maybe it is not the best solution but your code doesn't need better.
blit draws in buffer. You have to use update before wait to send data from buffer to screen.
if game_over == True:
you_lose_text = font.render("YOU SUCK", True, RED)
screen.blit(you_lose_text, [300,300])
pygame.display.update() # send on screen
pygame.time.wait(1000)
break
clock.tick(60)
pygame.display.update()
pygame.quit()

pygame - Key pressed

I am kinda stuck with a supposed to be simple code to check if the user has pressed "w" or "s".
Below you can see my code:
import pygame
pygame.init()
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_w:
print('Forward')
elif event.type == pygame.KEYDOWN and event.key == pygame.K_s:
print('Backward')
Am I forgetting something here?
Thanks!
A window needs to be created to receive key presses, the following works.
import pygame
import sys
pygame.init()
pygame.display.set_mode((100, 100))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
print('Forward')
elif event.key == pygame.K_s:
print('Backward')
This is what seems to me the most simple and understandable way to do it:
import pygame
pygame.init()
pygame.display.set_mode((300, 300))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
print('Forward')
elif event.key == pygame.K_s:
print('Backward')
Instead of using the sys.exit() method I prefer to just use pygame.quit()
it is no good to ask the gamer to keep hitting w to get the response. If you want to read the "pressed" state. You could consider the followings:
from pygame import *
import time
flag = False # The flag is essential.
DONE = False
screen = display.set_mode((500,500)) # 1180, 216
count=0
while not DONE:
event.pump() # process event queue
keys = key.get_pressed() # It gets the states of all keyboard keys.
#print("%d"%count,keys)
count+=1
if keys[ord('w')]: # And if the key is K_DOWN:
print("%d w down"%count)
if keys[ord('s')]: # And if the key is K_DOWN:
print("%d s down"%count)
time.sleep(0.1)
Try this:
import pygame
pygame.init()
key = pygame.key.get_pressed()
while True:
for event in pygame.event.get():
if event.type == KEYDOWN and event.key == pygame.K_w:
print('Forward')
elif event.type == KEYDOWN and event.key == pygame.K_s:
print('Backward')
Sample code to understand how key press events work.
import pygame
from pygame.locals import *
def main():
pygame.init()
pygame.display.set_caption("Move Box With Arrow Keys")
wndsize = (320, 240)
display = pygame.display.set_mode(wndsize)
x = 5
y = 5
black = (0, 0, 0)
white = (255, 255, 255)
rectpos = (x, y)
rectdim = (50, 50)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
x += 5
print("K_RIGHT")
if event.key == pygame.K_LEFT:
x -= 5
print("K_LEFT")
if event.key == pygame.K_UP:
y -= 5
print("K_UP")
if event.key == pygame.K_DOWN:
y += 5
print("K_DOWN")
# Don't allow coords below 0
if 0 > x:
x = 5
if 0 > y:
y = 5
# Don't allow overflow
if x + rectdim[0] > wndsize[0]:
x = wndsize[0] - rectdim[0] - 5
if y + rectdim[1] > wndsize[1]:
y = wndsize[1] - rectdim[1] - 5
rectpos = (x, y)
display.fill(white)
rect = pygame.draw.rect(display, black, ((rectpos), (rectdim)))
pygame.display.update()
main()
This might work:
from pygame import *
init()
if key.get_pressed()[K_w] == True:
print('Forwards')
if key.get_pressed()[K_s] == True:
print('Backwards')`

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