I have made a simple pygame that should move a donkey image left and right with the arrow keys. The Donkey image is in the folder and already appears, but it does not move left and right. I am on python 3.7 if that helps.
I have look for more then half and hour and I don't understand why it is not working, please help.
This is My Code:
import pygame
from pygame.locals import*
charx = 1
chary = 1
vel = 10
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("Pygame")
char = pygame.transform.scale(pygame.image.load('donkey.jpg'), (128, 128))
keys = pygame.key.get_pressed()
clock = pygame.time.Clock()
run = True
while run:
clock.tick(10)
if keys[pygame.K_LEFT]:
charx = charx - vel
elif keys[pygame.K_RIGHT]:
charx = charx + vel
else:
run = False
run = True
win.blit(char,(charx, chary))
pygame.display.update()
When I run the program the window shows up and there is Donkey Kong in the top left corner. But he does not move with the arrow keys.
I'm not sure exactly why, but if you add the event loop it works.
You also need to move the keys = pygame.key.get_pressed() line inside the while loop.
while run:
#add the following 3 lines, to check over events
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
charx = charx - vel
elif keys[pygame.K_RIGHT]:
charx = charx + vel
else:
run = False
run = True
win.blit(char,(charx, chary))
pygame.display.update()
clock.tick(10)
I can only guess that pygame.key.get_pressed() doesn't work properly if pygame.event.get() is not consumed in the main loop.
Related
This question already has answers here:
How can I make a sprite move when key is held down
(6 answers)
Closed 1 year ago.
im a beginner in pygame, and i dont have any experience in programming,
im using pygame.key.get_pressed() :
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((400, 400))
pygame.display.set_caption('Hello World!')
green = (0,255,0)
FPS = 60
FpsClock = pygame.time.Clock()
playerY = 200
playerX = 200
while True:
BG = pygame.draw.rect(DISPLAYSURF,(255, 255,255),(0,0,400,400))
player = pygame.draw.rect(DISPLAYSURF,(green),(playerX, playerY,20, 20))
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if keys[pygame.K_z]:
playerY -= 5
if keys[pygame.K_s]:
playerY += 5
if keys[pygame.K_d]:
playerX += 5
if keys[pygame.K_q]:
playerX -= 5
pygame.display.update(player)
pygame.display.update()
FpsClock.tick(FPS)
when i click one time on s key for example everything works just fine the player moves, but
if i hold down s button there is a delay before the player move's down while im holding the button
(samething for w,a,d)
It is a matter of Indentation. You must evaluate the pressed keys in the application loop instead of the event loop:
while True:
BG = pygame.draw.rect(DISPLAYSURF,(255, 255,255),(0,0,400,400))
player = pygame.draw.rect(DISPLAYSURF,(green),(playerX, playerY,20, 20))
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# INDENTATION
#<--|
if keys[pygame.K_z]:
playerY -= 5
if keys[pygame.K_s]:
playerY += 5
if keys[pygame.K_d]:
playerX += 5
if keys[pygame.K_q]:
playerX -= 5
pygame.display.update(player)
pygame.display.update()
FpsClock.tick(FPS)
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.
This question already has an answer here:
How to make a character jump in Pygame?
(1 answer)
Closed last year.
hello i am currently trying to make a jumping game in pygame a lot like the chrome dino game. i have made some simple code to draw a square and make it jump. i will my code dow n bellow. my problem is with the jumping part. whenever i press w wichis the the jump button the square jumps multiple times(usauly 2 times). good people of stack overflow please help a man in need.
here is my code
import pygame
pygame.init()
screen_width = 500
screen_height = 400
isJump = False
y = 350
x = 50
BLUE=(0,0,255)
run = True
screen = pygame.display.set_mode((screen_width, screen_height))
screen.fill((0,0,0))
pygame.display.set_caption("syoma n9ot intelent")
pygame.draw.rect(screen,BLUE,(x,y,50,50))
while run:
pygame.display.flip()
for event in pygame.event.get():
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
for a in range (1,250):
y -= .5
screen.fill((0,0,0))
pygame.draw.rect(screen,BLUE,(x,y,50,50))
pygame.display.flip()
for a in range (1,250):
y += .5
screen.fill((0,0,0))
pygame.draw.rect(screen,BLUE,(x,y,50,50))
pygame.display.flip()
if event.type == pygame.QUIT:
run = False
pygame.quit()
Use the KEYDOWN event instead of pygame.key.get_pressed().
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.
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.
Use pygame.time.Clock to control the frames per second and thus the game speed.
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. See pygame.time.Clock.tick():
This method should be called once per frame.
That means that the loop:
clock = pygame.time.Clock()
run = True
while run:
clock.tick(100)
runs 100 times per second.
Do not control the game with an extra loop in the application or event loop. Use the application loop. Use the variables isJump and jumpCount to control the jump. Set the variable isJump = True and jumpCount = 20 when w is started pressed. Decrement jumpCount in the application loop and change the y position of the player. Set isJump = False if jumpCount == -20:
Complete example:
import pygame
pygame.init()
screen_width = 500
screen_height = 400
isJump = False
jumpCount = 0
y = 350
x = 50
BLUE=(0,0,255)
run = True
screen = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()
pygame.display.set_caption("syoma n9ot intelent")
pygame.draw.rect(screen,BLUE,(x,y,50,50))
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
isJump = True
jumpCount = 20
if isJump:
if jumpCount > 0:
y -= 5
elif jumpCount <= 0:
y += 5
jumpCount -= 1
if jumpCount == -20:
isJump = False
screen.fill((0,0,0))
pygame.draw.rect(screen,BLUE,(x,y,50,50))
pygame.display.flip()
I'm new to pygame and am fairly interested in it.
I followed a tutorial on YouTube just to get a window setup and object that moves on keyboard press but the code I have for the program closing on the close window button doesn't work.
import sys, pygame
pygame.init()
win = pygame.display.set_mode((800,800))
pygame.display.set_caption("Simple Shooter")
x = 400
y = 400
width = 20
height = width
vel = 1
run = True
while run == True:
pygame.time.delay(10)
for event in pygame.event.get():
if event == pygame.QUIT:
run = False
sys.exit()
pygame.quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and y > vel:
y -= vel
if keys[pygame.K_s] and y < 800 - height - vel:
y += vel
if keys[pygame.K_a] and x > vel:
x -= vel
if keys[pygame.K_d] and x < 800 - width:
x += vel
win.fill((0,0,0))
pygame.draw.rect(win, (255,0,0), (x,y,width,height))
pygame.display.flip()
I'm using pygame version 1.9.6 .
Any help would be great!
You have to compare the type attribute of the pygame.event.Event object to the type constant and not to the object itself:
if event == pygame.QUIT:
if event.type == pygame.QUIT:
Struggling to make my 'cowboy' image move across the screen in all 4 directions. Nothing happens whenever I press the keys. Help please. This is based off the exercise questions in Python Crash Course.
import pygame
pygame.init()
screen = pygame.display.set_mode((500,500))
pygame.display.set_caption("Move the Cowboy")
cowboy = pygame.image.load('images/cowboy.bmp')
cowboy = pygame.transform.scale(cowboy, (50, 50))
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
screen.fill((240,237,207))
cowboy_rect = cowboy.get_rect()
screen_rect = screen.get_rect()
screen_center = screen_rect.center
cowboy_rect.center = screen_rect.center
cowboy_rect.x = cowboy_rect.width
cowboy_rect.y = cowboy_rect.height
cowboy_x = float(cowboy_rect.x)
cowboy_y = float(cowboy_rect.y)
screen.blit(cowboy, screen_center)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
cowboy_x -= 5
elif keys[pygame.K_RIGHT]:
cowboy_x += 5
elif keys[pygame.K_UP]:
cowboy_y -= 5
elif keys[pygame.K_DOWN]:
cowboy_y += 5
pygame.display.update()
pygame.quit()
You are putting the image at the middle of the screen with screen.blit(cowboy, screen_center). Change screen_center to cowboy_rect as this stores the position of the image.
Also take the cowboy_rect = cowboy.get_rect() out of the loop as this resets it back to 0.
You are then putting the position of cowboy_rect to the center of the screen by doing cowboy_rect.center = screen_rect.center, take that out of the loop so it only happens once, not every frame. Then its getting changed to 50,50 by cowboy_rect.x = cowboy_rect.width and cowboy_rect.y = cowboy_rect.height, so take that out.
Then at the keys, change cowboy_x -= 5 to cowboy_rect.x -= 5 and do the same for the others.
By putting this in: screen.blit(cowboy, screen_center), you are saying that this image will appear at the center of the screen. You want it to appear at (cowboy_x, cowboy_y), as these are the positionment variables you defined. Here is a working version of your code:
import pygame
pygame.init()
screen = pygame.display.set_mode((500,500))
pygame.display.set_caption("Move the Cowboy")
cowboy = pygame.image.load('images/cowboy.bmp')
cowboy = pygame.transform.scale(cowboy, (50, 50))
cowboy_x, cowboy_y = 0, 0
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
screen.fill((240,237,207))
screen.blit(cowboy, (cowboy_x, cowboy_y))
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
cowboy_x -= 1
elif keys[pygame.K_RIGHT]:
cowboy_x += 1
elif keys[pygame.K_UP]:
cowboy_y -= 1
elif keys[pygame.K_DOWN]:
cowboy_y += 1
pygame.display.update()
pygame.quit()
I took the liberty of taking out some completely useless lines of code, and of bringing the stuff you didn't need to re-iterate out of the loop, to save processing space.
Currently, I am stuck on trying to get my tank to move when the user presses "a" and "d". The lines involving pressing a key to move the tank seem correct and I believe should work. This is also my first time using one of these forums. Please provide feedback so I can improve. Thank you for your help.
I have asked my teacher and friends for help, but they are all wondering why the tank will not move. I also have searched over the internet and youtube for answers. A weird thing is that my friend and I directly copied a youtube video on user movement where the user can move a rectangle around. My friend can hold down "w","a","s",or "d" to move the rectangle, but I can not hold down "w","a","s",or "d" to move it but need to spam the button. What is weird is that when you move your mouse around, I can then hold down "w","a","s",or "d".
import pygame
from pygame.locals import *
import math
import random
width = 640
height = 480
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("2 Player Tanks")
def gameloop():
pygame.init()
time = pygame.time.get_ticks()
screen.fill(white)
tankx = 100
tanky = 100
tankwidth = 40
tankheight = 20
turretwidth = 5
wheelwidth = 5
tankmove = 5
def tank(x,y):
x = int(x)
y = int(y)
pygame.draw.circle(screen,black,(x,y),10)
pygame.draw.rect(screen,black,(x-tankheight,y,tankwidth,tankheight))
pygame.draw.line(screen,black,(x,y),(x-20,y-20), turretwidth)
startx = 15
for i in range(7):
pygame.draw.circle(screen,black,(x-startx,y+20),wheelwidth)
startx -= 5
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
keys= pygame.key.get_pressed()
if keys[pygame.K_a]:
tankx -= tankmove
if keys[pygame.K_d]:
tankx += tankmove
if keys[pygame.K_w]:
tanky -= tankmove
if keys[pygame.K_s]:
tanky += tankmove
tank(tankx,tanky)
pygame.display.update()
gameloop()
I want the player to be able to use "a" and "d" to move the tank horizontally.
The event loop is executed only when an event occurs. This means it is executed when a key is pressed or a key is released — however, when a key is held down, no event occurs and the event loop is not executed.
You've got to evaluate the key presses in the main loop (in scope of gameloop) rather than in the event loop:
e.g.
def gameloop():
# [...]
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
# <--
keys= pygame.key.get_pressed()
if keys[pygame.K_a]:
tankx -= tankmove
if keys[pygame.K_d]:
tankx += tankmove
if keys[pygame.K_w]:
tanky -= tankmove
if keys[pygame.K_s]:
tanky += tankmove
tank(tankx,tanky)
pygame.display.update()
Note: pygame.key.get_pressed() returns the current states of the keys and the states are evaluated and updated when pygame.event.get() is called.
The position of the tank is reset at the begin of the frame, because the variables tankx and tanky are set at the begin of gameloop:
def gameloop():
#[...]
tankx = 100
tanky = 100
Define the variables in global scope, and use the global statement to access them.
Decrease the speed of the tank, because it would move very rapidly (tankmove = 1).
The pygame.init() should be called once only, at the begin of application.
e.g.
def gameloop():
global tankx, tanky, tankmove
tankwidth = 40
tankheight = 20
turretwidth = 5
wheelwidth = 5
time = pygame.time.get_ticks()
screen.fill(white)
# [...]
pygame.init()
tankx = 100
tanky = 100
tankmove = 1
run = True
while run:
gameloop()
I can move the tank with a randomized background, but the program keeps on drawing a new tank. To fix this, I added a screen.fill(white). That fixes the drawing problem, but now I have no background.
Don't draw the random background to the window. Create a pygame.Surface and draw the random background to the surface.
.blit the background surface to the screen in every frame:
background_surface = pygame.Surface((widht, height))
# draw background to "background_surface" rather then "screen"
# [...]
def gameloop():
# [...]
# blit background instead of screen.fill(white)
screen.blit(background_surface, (0, 0))
# [...]