My character won't move in python - 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()

Related

Python pygame's keyboard move command does not operate

I'm currently trying to build a game through vscode using pygame lib.
My code to move character around with keyboard arrow keys won't apply to my module.
My module won't close even though I click exit button or esc.
Any thoughts why its not working?
import pygame
import os
pygame.init()
screen_width = 480
screen_height = 640
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption("June's Game")
background = pygame.image.load("D:/Python/pygame_basic/background.png")
character = pygame.image.load("D:/Python/pygame_basic/character.png")
character_size = character.get_rect().size
character_width = character_size[0]
character_height = character_size[1]
character_x_position = (screen_width / 2) - (character_width / 2)
character_y_position = screen_height - character_height
to_x = 0
to_y = 0
running = True #게임이 진행중인가
while running:
for event in pygame.event.get():
if event == pygame.QUIT:
running = False
if event == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
to_x -= 5
elif event.key == pygame.K_RIGHT:
to_x += 5
elif event.key == pygame.K_UP:
to_y -= 5
elif event.key == pygame.K_DOWN:
to_y += 5
if event == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
to_x = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
to_y = 0
character_x_position += to_x
character_y_position += to_y
#screen.fill((0,0,255))
screen.blit(background, (0,0))
screen.blit(character, (character_x_position,character_y_position))
pygame.display.update()
pygame.quit()
i coudln't get it to work
event is an object. You have to get the type of the event, e.g.:
if event == pygame.KEYDOWN
if event.type == pygame.KEYDOWN:
You have to limit the frames per second to limit CPU usage with pygame.time.Clock.tick and to control the speed of the game. Otherwise, the player moves much too fast and immediately disappears from the screen. The method tick() of a pygame.time.Clock object, delays the game in that way, that every iteration of the loop consumes the same period of time.
clock = pygame.time.Clock()
running = True
while running:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
to_x -= 5
elif event.key == pygame.K_RIGHT:
to_x += 5
elif event.key == pygame.K_UP:
to_y -= 5
elif event.key == pygame.K_DOWN:
to_y += 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
to_x = 0
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
to_y = 0
character_x_position += to_x
character_y_position += to_y
#screen.fill((0,0,255))
screen.blit(background, (0,0))
screen.blit(character, (character_x_position,character_y_position))
pygame.display.update()
However, there is a better method to move an object when a key is held down (See How can I make a sprite move when key is held down):
to_x = 0
to_y = 0
speed = 5
clock = pygame.time.Clock()
running = True
while running:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
to_x = (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * speed
to_y = (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * speed
character_x_position += to_x
character_y_position += to_y
screen.blit(background, (0,0))
screen.blit(character, (character_x_position,character_y_position))
pygame.display.update()

how do i make the snake constantly go in the direction the user inputted [duplicate]

This question already has answers here:
How can I make a sprite move when key is held down
(6 answers)
Closed 1 year ago.
right now it just moves in the direction i tell it to put it just stops. How do i go about making it KEEP going in the direction I inputted by? And make it constantly go in the direction, but be able to control how fast it moves, right now i want it to move every 4 minutes
import pygame
from pygame.locals import *
pygame.init()
surface = pygame.display.set_mode((600, 600))
background = pygame.image.load('back.png')
surface.blit(background, (0, 0))
block = pygame.image.load('block.png').convert()
block_y = 0
block_x = 0
surface.blit(block, (block_x, block_y))
def draw():
surface.blit(background, (0, 0))
surface.blit(block, (block_x, block_y))
pygame.display.flip()
direction = ''
pygame.display.flip()
running = True
while running:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
if event.key == K_UP:
block_y -= 10
draw()
if event.key == K_DOWN:
block_y += 10
draw()
if event.key == K_LEFT:
block_x -= 10
draw()
if event.key == K_RIGHT:
block_x += 10
draw()
elif event.type == QUIT:
running = False
```
Here's an option with minimal changes to your program. I changed the event handlers to update speed variables, which update the position in an added update() function. The speeds are zeroed when the key is released. I've also removed the duplicated draw() functions. Note this code is untested.
import pygame
from pygame.locals import *
pygame.init()
surface = pygame.display.set_mode((600, 600))
background = pygame.image.load('back.png')
surface.blit(background, (0, 0))
block = pygame.image.load('block.png').convert()
block_y = 0
block_x = 0
speed_x = 0
speed_y = 0
surface.blit(block, (block_x, block_y))
def draw():
surface.blit(background, (0, 0))
surface.blit(block, (block_x, block_y))
pygame.display.flip()
def update():
"""Update game state"""
block_x += speed_x
block_y += speed_y
direction = ''
pygame.display.flip()
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
elif event.key == K_UP:
speed_y -= 10
elif event.key == K_DOWN:
speed_y += 10
elif event.key == K_LEFT:
speed_x -= 10
elif event.key == K_RIGHT:
speed_x += 10
elif event.type == KEYUP:
if event.key in (K_DOWN, K_UP):
speed_y = 0
elif event.key in (K_LEFT, K_RIGHT):
speed_x = 0
elif event.type == QUIT:
running = False
update()
draw()
clock.tick(60) # limit frame rate to 60 FPS
EDIT: Added frame rate limiting
Use pygame.key.get_pressed() instead of the KEYDOWN event.
The keyboard events (see pygame.event module) occur only once when the state of a key changes. The KEYDOWN event occurs once every time a key is pressed. KEYUP occurs once every time a key is released. Use the keyboard events for a single action or a step-by-step movement.
pygame.key.get_pressed() returns a sequence with the state of each key. If a key is held down, the state for the key is True, otherwise False. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement
running = True
while running:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
elif event.type == QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
block_y -= 10
if keys[pygame.K_DOWN]:
block_y += 10
if keys[pygame.K_LEFT]:
block_x -= 10
if keys[pygame.K_RIGHT]:
block_x += 10
draw()
The code can be further simplified:
running = True
while running:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
elif event.type == QUIT:
running = False
keys = pygame.key.get_pressed()
block_x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * 10
block_y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * 10
draw()

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()

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

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()

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()

Categories