This is my Code:
import pygame
pygame.init()
win = pygame.display.set_mode((500,500))
pygame.display.set_caption("Test")
x = 50
y = 50
width = 40
height = 60
vel =5
run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
win.fill((0,0,0))
pygame.draw.rect(win, (255,255,255), (x,y,width,height))
pygame.display.update()
pygame.quit()
I would like the rectangle move continuously when you hold down one of the buttons but it only moves once per press.
I'm just starting to learn Python and Pygame (as you may see) so I'm thankful for any help.
What's happening here, is that you put the code to update the position in the event loop which means that your code ment to move the object is only run when pygame detects an event like a key press. But if you keep a key pressed down pygame does not register that as an event.
Simply remove all the code from keys = pygame.key... to display.update() from the for loop and put it in the while loop.
As such:
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
win.fill((0,0,0))
pygame.draw.rect(win, (255,255,255), (x,y,width,height))
pygame.display.update()
pygame.quit()
The object that needs to move will now move continuously as long as the keys are held down!
Related
I tried to make a boundary and it didn't work so I deleted it however now it just doesn't want to work. It is a code with an image and uses keys to move it. I am a beginner at coding so I don't know much so I would appreciate some edits or recommendations on what I should do.
This is my code:
#Imports Pygame module
import pygame
#Initializing/ Starting Pygame module
pygame.init()
#Setting the background and starting location of logo
dvdLogoSpeed = [1, 1]
backgroundColor = 0, 0, 0
#Screen size display variable
screen = pygame.display.set_mode(600, 600)
#Variable for logo and made rectangle for logo
dvdLogo = pygame.image.load("dvd-logo-white.png")
dvdLogoRect = dvdLogo.get_rect()
#Variables
x = 200
y = 200
vel = 10
width = 20
height = 20
def dvdwKeys ():
run = True
while run == True:
pygame.time.delay(10)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
screen.fill (backgroundColor)
screen.blit(dvdLogo, dvdLogoRect)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x>0:
dvdLogoRect.x -= vel
if keys[pygame.K_RIGHT] and x<600-width:
dvdLogoRect.x += vel
if keys[pygame.K_UP] and y>0:
dvdLogoRect.y -= vel
if keys[pygame.K_DOWN] and y<600-height:
dvdLogoRect.y += vel
pygame.display.flip()
dvdwKeys()
You need to test dvdLogoRect.x and dvdLogoRect.y instead of x and y:
while run == True:
# [...]
if keys[pygame.K_LEFT] and dvdLogoRect.x>0:
dvdLogoRect.x -= vel
if keys[pygame.K_RIGHT] and dvdLogoRect.right<600:
dvdLogoRect.x += vel
if keys[pygame.K_UP] and dvdLogoRect.y>0:
dvdLogoRect.y -= vel
if keys[pygame.K_DOWN] and dvdLogoRect.bottom<600:
dvdLogoRect.y += vel
However, you can simplify the code with pygame.Rect.clamp_ip:
def dvdwKeys ():
clock = pygame.time.Clock()
run = True
while run == True:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
dvdLogoRect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel
dvdLogoRect.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel
dvdLogoRect.clamp_ip(screen.get_rect())
screen.fill(backgroundColor)
screen.blit(dvdLogo, dvdLogoRect)
pygame.display.flip()
See also Setting up an invisible boundary for my sprite and How can I make a sprite move when key is held down and
This question already has answers here:
How can i shoot a bullet with space bar?
(1 answer)
How do I stop more than 1 bullet firing at once?
(1 answer)
Closed 1 year ago.
import pygame
# initialize the pygame
pygame.init()
# create the screen
screen = pygame.display.set_mode((800, 600))
# Title and icon
pygame.display.set_caption("Space Invaders")
icon = pygame.image.load('Invader2.xcf')
pygame.display.set_icon(icon)
# Player
playerImg = pygame.image.load('Player.xcf')
player_big = pygame.transform.scale(playerImg, (48, 48))
playerX = 370
playerY = 480
vel = 0.15
# Player Bullets
playerBulletImg = pygame.image.load('Player_bullet.xcf')
playerBulletX = playerX + 16
playerBulletY = playerY + 10
bulletVel = 0.3
def player(x, y):
screen.blit(player_big, (playerX, playerY))
def bullet(x, y):
screen.blit(playerBulletImg, (playerBulletX, playerBulletY))
# Game Loop
running = True
while running:
# RGB
screen.fill((18.8, 83.5, 78.4))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and playerX > 0:
playerX -= vel
playerBulletX -= vel
if keys[pygame.K_RIGHT] and playerX < 800 - 48:
playerX += vel
playerBulletX += vel
if keys[pygame.K_SPACE]:
playerBulletY -= 0.5
if playerBulletY == 0:
playerBulletY = 480
bullet(playerBulletX, playerBulletY)
player(playerX, playerY)
pygame.display.update()
Hi! I'm a beginner who has just started using Pygame. I'm making a Space Invaders / Galaga type game. When I press the space bar, the bullet goes up the y-axis, but only when I hold it down. I want the bullet to continue to move up the screen, even when I'm not holding down the space bar. Also, another problem is that when the bullet is in the air it still follows the x-value for the player. So when the bullet shoots up, It moves around depending on where the player is.
you should run your game as a class it is much more easier to code pygame with classes you can change your b.move to where else
import pygame
# initialize the pygame
pygame.init()
# create the screen
screen = pygame.display.set_mode((800, 600))
# Title and icon
pygame.display.set_caption("Space Invaders")
icon = pygame.image.load('Invader2.xcf')
pygame.display.set_icon(icon)
# Player
class Player:
def __init__(self):
self.Img = pygame.image.load('Player.xcf')
self.big = pygame.transform.scale(playerImg, (48, 48))
self.x = 370
self.y = 480
self.vel = 0.15
def draw(self,screen):
screen.blit(self.big, (self.x, self.y))
class Bullet:
def __init__(self):
self.Img = pygame.image.load('Player_bullet.xcf')
self.x = playerX + 16
self.y = playerY + 10
self.vel = 0.3
def draw(screen):
screen.blit(self.Img, (self.y, self.y))
def move():
self.y -= self.vel
def draw(p,b):
p.draw()
for i in b:
i.draw()
# Game Loop
def main():
running = True
p = Player()
b = []
while running:
screen.fill((18.8, 83.5, 78.4))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and p.x > 0:
p.x -= p.vel
if keys[pygame.K_RIGHT] and p.x < 800 - 48:
p.x += p.vel
if keys[pygame.K_SPACE]:
b.append(Bullet())
draw(p,b)
for bullet in b:
bullet.move()
pygame.display.update()
Use the keyboard event instead of pygame.key.get_pressed() to shoot a bullet.
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.
Add a shootBullet variable that indicates when the bullet will be fired. Set the state when SPACE is pressed. Move and draw the bullet depending on this state. Set the starting position of the bullet when the bullet is fired.
shootBullet = False
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_SPACE:
shootBullet = True
playerBulletX = playerX
playerBulletY = 480
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and playerX > 0:
playerX -= vel
if keys[pygame.K_RIGHT] and playerX < 800 - 48:
playerX += vel
if shootBullet:
playerBulletY -= 1
if playerBulletY <= 0:
shoot_bullet = False
screen.fill((18.8, 83.5, 78.4))
if shootBullet:
bullet(playerBulletX, playerBulletY)
player(playerX, playerY)
pygame.display.update()
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.
My character movement is bugging and i don't know why at all
When i run it it moves forward and like bugs backwards
Ive changed velocity and framerate to no avail and an scared to touch the code coz i just got it to work when the backgound is visible
import pygame
import os
WIDTH, HEIGHT = 1920, 1080
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Gaem")
WHITE = (255, 255, 255)
FPS = 60
Vel = 5
CHARACTER = pygame.image.load('MAN.png')
def draw_window(CHARACTERM):
WIN.fill((WHITE))
WIN.blit(CHARACTER, (CHARACTERM.x, CHARACTERM.y))
pygame.display.update()
def main():
CHARACTERM = pygame.Rect(100, 300, 850, 450)
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
##########CHARACTER MOVMENT####################
draw_window(CHARACTERM)
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_a]: #Left
CHARACTERM.x -= Vel
draw_window(CHARACTERM)
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_d]: #Right
CHARACTERM.x += Vel
draw_window(CHARACTERM)
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_w]: #Up
CHARACTERM.y -= Vel
draw_window(CHARACTERM)
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_s]: #Down
CHARACTERM.y += Vel
################################################
draw_window(CHARACTERM)
pygame.quit()
if __name__ == "__main__":
main()
Thank you Zatando1
It is sufficient to call pygame.key.get_pressed() and draw_window() once:
def main():
CHARACTERM = pygame.Rect(100, 300, 850, 450)
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_a]: #Left
CHARACTERM.x -= Vel
if keys_pressed[pygame.K_d]: #Right
CHARACTERM.x += Vel
if keys_pressed[pygame.K_w]: #Up
CHARACTERM.y -= Vel
if keys_pressed[pygame.K_s]: #Down
CHARACTERM.y += Vel
draw_window(CHARACTERM)
pygame.quit()
If you call draw_window() multiple times, pygame.display.update() will be executed multiple times in each frame. An update of the display at the end of the application loop is sufficient. Multiple calls to pygame.display.update() or pygame.display.flip() cause flickering.
This question already has an answer here:
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 2 years ago.
I have tried to make a Zelda clone, and now I'm wondering how to calculate collision, can anyone tell me how to do that? I have tried colliderct and it simply won't work here is my code:
import pygame
pygame.init()
display = pygame.display.set_mode((800,600))
white=(255,255,255)
black=(0,0,0)
x=50
y=50
width = 40
height = 60
vel = 5
playerimg= pygame.image.load('link1.jpg').convert()
def player(x,y):
display.blit(playerimg,(x,y))
while True:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
keys = pygame.key.get_pressed()
if keys[pygame.K_a]:
x -= vel
if keys[pygame.K_d]:
x += vel
if keys[pygame.K_w]:
y -= vel
if keys[pygame.K_s]:
y += vel
display.fill(white)
player(x,y)
pygame.draw.rect(display, (255,0,0), hitbox,2)
pygame.display.update()
pygame.quit()
you can use 'hitboxes' to do this, one you must know the dimensions of your image
now that you got them, you can do
hitbox=(x,y, 102,131)
hitbox1=pygame.draw.rect(display, (255,0,0), hitbox,2)
if the_thing_it_hits.colliderect(hitbox) == True:
print('ouch')
put this in the while True: loop and it should be good
You can do a collision test by using pygame.Rect and colliderect(). For instance you can define an obstacle and get the rectangle from playerimg by get_rect(). Test if the 2 rectangles are colliding:
while True:
# [...]
hitbox = pygame.Rect(100, 100, 100, 100)
player_rect = playerimg.get_rect(topleft = (x, y))
if player_rect.colliderect(hitbox):
print("hit")
display.fill(white)
player(x,y)
pygame.draw.rect(display, (255,0,0), hitbox,2)
pygame.display.update()
Anyway, I recommend to use pygame.sprite.Sprite, pygame.sprite.Group and pygame.sprite.spritecollide().
Furthermore, your implementation of the QUIT event will not quit the game
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
because the break statement will just break the event loop, but not the application loop.
Use a variable instead:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
I've been watching a pygame tutorial on youtube on player movement, and by using this code below, the guy making the video was able to hold down a key and the character would keep moving, but when i hold down a key the character will move once and then stop. Any ideas on how to fix this?
Code:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("huge honkabonkaros")
x = 50
y = 440
width = 40
height = 60
vel = 5
run = True
while run:
pygame.time.delay(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.display.update()
pygame.quit()
It is a matter of Indentation. The continuous movement must be in the application loop and not in the event loop. The application loop runs once per frame, but the event loop only runs once per event. When a key is pressed a KEYDOWN event occurs and when a key is released a KEYUP event occurs, but there is no event when a key is held down:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("huge honkabonkaros")
x = 50
y = 440
width = 40
height = 60
vel = 5
run = True
while run:
pygame.time.delay(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# INDENTATION
#<--|
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.display.update()
pygame.quit()