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
Related
This question already has answers here:
How to get keyboard input in pygame?
(11 answers)
How can I make a sprite move when key is held down
(6 answers)
Closed 2 days ago.
I'm trying to get a rectangle to move on screen, but the keyboard presses aren't working, and I can't solve it. Can someone help?
import pygame
WIN = pygame.display.set_mode((900, 500))
pygame.display.set_caption("coolioso")
FPS = 60
keys_pressed = pygame.key.get_pressed()
vel = 10
player = pygame.Rect(450, 250, 50, 50)
def draw_window():
WIN.fill((255, 255, 255))
pygame.draw.rect(WIN, (255, 0, 0), (player))
def main():
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if keys_pressed[pygame.K_w]:
player.y += vel
draw_window()
pygame.display.update()
pygame.quit()
if __name__ == "__main__":
main()
I tried using multiple different methods like functions, putting the key press statement elsewhere, but nothing worked and nothing changed.
This question already has answers here:
How can I make a sprite move when key is held down
(6 answers)
How to get keyboard input in pygame?
(11 answers)
Closed last month.
I'm trying to create a game in pygame where the character moves while animating, I tired using sprites but got the same results, however I did notice that pygame wasn't detecting that I pressed the right arrow key, I tried to get it to work but alas.
here's my code
:
import pygame
from sys import exit
def player_animation():
global player_current_sprite, player_frames, player_image
player_current_sprite += 0.01
player_image = player_frames[int(player_current_sprite)]
if player_current_sprite >= 1.3:
player_current_sprite = 0.7
pygame.display.set_caption('pausing has consequences')
pygame.init()
screen = pygame.display.set_mode((1000, 700))
clock = pygame.time.Clock()
player_frame_1 = pygame.image.load('graphics/player_frame_1.png')
player_frame_2 = pygame.image.load('graphics/player_frame_2.png')
player_current_sprite = 0
player_frames = [player_frame_1, player_frame_2]
player_image = player_frames[player_current_sprite]
player_rect = player_image.get_rect(center=(450, 250))
move = False
background_surface = pygame.image.load('graphics/background.png')
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.KEYDOWN:
move = True
if event.type == pygame.K_RIGHT and move == True:
player_rect.x += 10
if event.type == pygame.KEYUP:
move = False
screen.blit(background_surface, (0, 0))
player_animation()
screen.blit(player_image, player_rect)
pygame.display.flip()
clock.tick(60)
The x value does not change when I pressed the button, I did notice that pygame did not detect my button press
import pygame
import sys
pygame.init()
weight=550
height=400
screen = pygame.display.set_mode((weight,height))
image=pygame.image.load("Capture.jpg").convert()
ix= 70
iy = 80
speed =10
imageplace = screen.blit(image,(ix,iy))
pygame.display.update()
running=True
while running:
for event in pygame.event.get():
pygame.time.delay(10)
if event.type == pygame.QUIT:
running=False
keys=pygame.key.get_pressed()
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
pos_x = pos[0]
pos_y = pos[1]
if (keys[pygame.K_LEFT] or keys[pygame.K_a]) and ix > 0:
ix-=speed
if (keys[pygame.K_RIGHT] or keys[pygame.K_d]) and ix > 0:
ix+=speed
if (keys[pygame.K_UP] or keys[pygame.K_w]) and ix > 0:
iy-=speed
if (keys[pygame.K_DOWN] or keys[pygame.K_s]) and ix > 0:
iy+=speed
if imageplace.collidepoint(pos_x,pos_y):
print("You have clicked on button")
else:
print("Wrong Direction")
I tried to move an image with pygame but it didn't work. I am new at this. I couldn't find anything on internet and I didn't understand it.
See How can I make a sprite move when key is held down and you must redraw the scene in ever frame. The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
Example based on your code:
import pygame
pygame.init()
width, height = 550, 400
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
image = pygame.image.load("Capture.jpg").convert()
imageplace = image.get_rect(topleft = (70, 80))
speed = 5
running=True
while running:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running=False
if event.type == pygame.MOUSEBUTTONDOWN:
if imageplace.collidepoint(event.pos):
print("You have clicked on button")
else:
print("Wrong Direction")
keys = pygame.key.get_pressed()
if (keys[pygame.K_LEFT] or keys[pygame.K_a]) and imageplace.left > 0:
imageplace.x -= speed
if (keys[pygame.K_RIGHT] or keys[pygame.K_d]) and imageplace.right < width:
imageplace.x += speed
if (keys[pygame.K_UP] or keys[pygame.K_w]) and imageplace.top > 0:
imageplace.y -= speed
if (keys[pygame.K_DOWN] or keys[pygame.K_s]) and imageplace.bottom < height:
imageplace.y += speed
screen.fill((0, 0, 0))
screen.blit(image, imageplace)
pygame.display.update()
pygame.quit()
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!
I am new to pygame and I am trying to make pong in order to learn it. I am trying to make smooth controls so that holding down an arrow will work, but it is not working right now.
import sys, pygame
pygame.init()
size = (500, 350)
screen = pygame.display.set_mode(size)
x = 1
xwid = 75
yhei = 5
pygame.key.set_repeat(0, 500)
while True:
vector = 0
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
vector = 4
elif event.key == pygame.K_LEFT:
vector = -4
pygame.draw.rect(screen,(255,255,255),(x,size[1] - yhei,xwid,yhei),0)
pygame.display.update()
screen.fill((0,0,0))
x += vector
if x <= 0:
x = 0
elif x >= size[0] - xwid:
x = size[0] - xwid
why does this not work for holding down the left or right arrows?
pygame.key.set_repeat(0, 500)
If you set the delay parameter to 0, key repeat will be disabled. The documentation isn't quite clear about that:
pygame.key.set_repeat()
control how held keys are repeated
set_repeat() -> None
set_repeat(delay, interval) -> None
When the keyboard repeat is enabled, keys that are held down will generate
multiple pygame.KEYDOWN events. The delay is the number of
milliseconds before the first repeated pygame.KEYDOWN will be sent.
After that another pygame.KEYDOWN will be sent every interval
milliseconds. If no arguments are passed the key repeat is disabled.
When pygame is initialized the key repeat is disabled.
Emphasis mine.
You could set the delay to 1, and it would work as expected:
pygame.key.set_repeat(1, 10) # use 10 as interval to speed things up.
But note that you should not use set_repeat and the pygame.KEYDOWN event to implement movement. If you do, you won't be able to observe real single key strokes, since if the player presses a key, a whole bunch of pygame.KEYDOWN events would be created.
Better use pygame.key.get_pressed(). Have a look at his minimal example:
import pygame
pygame.init()
screen = pygame.display.set_mode((680, 460))
clock = pygame.time.Clock()
# use a rect since it will greatly
# simplify movement and drawing
paddle = pygame.Rect((0, 0, 20, 80))
while True:
if pygame.event.get(pygame.QUIT): break
pygame.event.pump()
# move up/down by checking for pressed keys
# and moving the paddle rect in-place
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]: paddle.move_ip(0, -7)
if keys[pygame.K_DOWN]: paddle.move_ip(0, 7)
# ensure the paddle rect does not go out of screen
paddle.clamp_ip(screen.get_rect())
screen.fill((0,0,0))
pygame.draw.rect(screen, (255,255,255), paddle)
pygame.display.flip()
clock.tick(60)
try it !
pygame.key.set_repeat(1,500)
I know what do you mean. Try this:
import sys, pygame
from pygame.locals import *
pygame.init()
size = (500, 350)
screen = pygame.display.set_mode(size)
x = 1
xwid = 75
yhei = 5
clock = pygame.time.Clock()
while True:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
key_pressed = pygame.key.get_pressed()
if key_pressed[K_LEFT]:
x -= 4
if x <= 0:
x = 0
if key_pressed[K_RIGHT]:
x += 4
if x >= size[0] - xwid:
x = size[0] - xwid
pygame.draw.rect(screen,(255,255,255),(x,size[1] - yhei,xwid,yhei),0)
pygame.display.update()
screen.fill((0,0,0))