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.
Related
i created a snake game and i have one problem in function food() it keep adding food on screen and removing it i don't know how to fix this i tried with food_statement like = "wait" when there's a food in screen and draw when it's not food can you help me code is working properly until hit food function?
import pygame
import time
import random
pygame.init()
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption('Snake Game by Joelinton')
blue=(0,0,255)
x_change = 0.2
y_change = 0.2
x = 400
y = 250
def creatingsnake():
pygame.draw.rect(screen,blue,[x,y,20,20])
def gameover():
font = pygame.font.SysFont('freesansbold.ttf', 100)
text = font.render('Game Over', True,(255,255,255))
screen.blit(text, (250, 250))
def food():
foodx = random.randint(0,750)
foody = random.randint(0,550)
pygame.draw.rect(screen,blue,[foodx,foody,20,20])
running = True
while running:
screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= x_change
if keys[pygame.K_RIGHT]:
x += x_change
if keys[pygame.K_UP]:
y -= y_change
if keys[pygame.K_DOWN]:
y += y_change
if x < 0 or x > 780 or y < 0 or y > 580:
gameover()
running = False
time.sleep(1)
food()
creatingsnake()
pygame.display.update()
food is called in each frame. Thus, when the coordinates are generated in the function 'food', new random coordinates are generated in each frame. You must set the coordinates of the food once before the application loop:
foodx = random.randint(0,750)
foody = random.randint(0,550)
def food():
pygame.draw.rect(screen,blue,[foodx,foody,20,20])
running = True
while running:
# [...]
food()
creatingsnake()
pygame.display.update()
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.
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.
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))
# [...]
I'm trying to create a "player" - black square - which moves when you hold down WASD. I tried looking around here, on google and on youtube on how to make this work, but every solution I've tried has the same problem: instead of moving it while I hold down the key, I have to tap the key constantly to make it move in small bits. I've no clue what I'm doing wrong. Here's the code (using python 3.3 - pygame 1.9):
import pygame
from pygame.locals import *
from pygame.time import *
import sys
pygame.init()
velX = 0
velY = 0
running = True
clock = pygame.time.Clock()
def draw():
global velX
global velY
playerx = 20
playery = 20
screen = pygame.display.set_mode((700,300))
pygame.display.set_caption('something')
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((255,255,255))
screen.blit(background, (0,0))
playerx = playerx + velX
playery = playery + velY
player_filename = 'player.png'
player = pygame.image.load(player_filename)
screen.blit(player, (playerx,playery))
pygame.display.flip()
def main():
global velX
global velY
global running
while running:
keys_down = pygame.key.get_pressed()
pygame.key.set_repeat(1, 50)
time = 50/1000
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running=False
if keys_down[K_d]:
velX += 50*time
if keys_down[K_w]:
velY -= 50*time
if keys_down[K_s]:
velY += 50*time
if keys_down[K_a]:
velX -= 50*time
clock.tick(50)
draw()
if __name__ == '__main__':
main()
I already tried the set repeat command, but it didn't seem to do much anything. I also tried directly copying from a few solutions I found here on stackoverflow, but none of them worked. I suppose there is something else wrong in the code.
There are two problems with your code. First to your question. The reason the player never moves more than one step is that you reset the player position in every call to draw() when you do
playerx = 20
playery = 20
Instead, you should put that code above the draw()function and add
global playerx
global playery
at the top of draw(). Now, the player position is not reset every frame.
The second problem is that you create a new screen in every call to draw() when you do
screen = pygame.display.set_mode((700,300))
pygame.display.set_caption('something')
instead you should move those to lines above draw() and just use the same screen for every draw.
Also, like elyase points out, what you probably want is to set the velocities to fixed values, not increase them. Like so
velX = 0
velY = 0
if keys_down[K_d]:
velX = 10
if keys_down[K_w]:
velY = -10
if keys_down[K_s]:
velY = 10
if keys_down[K_a]:
velX = -10
This way the player will move around with a constant speed in the direction you steer it.
Hope that clear some stuff up. :)
You are resetting the position inside draw(). Also you should put the code that changes the direction, inside the event.type == pygame.KEYDOWN condition. Something like this:
if event.type == KEYDOWN:
if event.key == K_d:
velX += 50*time
elif event.key == K_w:
velY -= 50*time
...
if event.type == KEYUP:
# set velocity to 0