I can't move an image with pygame - python

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

Related

detecting invalid collision in python pygame [duplicate]

This question already has answers here:
How do I detect collision in pygame?
(5 answers)
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 1 year ago.
import pygame
pygame.init()
pygame.display.set_caption('...SHON...PONG...')
icon=pygame.image.load('icon.png')
pygame.display.set_icon(icon)
FPS=50
fpsClock=pygame.time.Clock()
screenh=500
screenw=300
screen=pygame.display.set_mode((screenh,screenw))
black =((0,0,0))
paddle1=pygame.image.load('paddle1.png')
paddle1_rect=paddle1.get_rect()
paddle1_y=100
paddle1_x=10
paddle2=pygame.image.load('paddle2.png')
paddle2_rect=paddle1.get_rect()
paddle2_y=100
paddle2_x=471
ball=pygame.image.load('player.png')
ball_rect=ball.get_rect()
ball_x=240
ball_y=130
ball_y_speed=2
ball_x_speed=2
speed=15
paddle1_rect.x=paddle1_x
paddle1_rect.y=paddle1_y
paddle2_rect.x=paddle2_x
paddle2_rect.y=paddle2_y
ball_rect.x=ball_x
ball_rect.y=ball_y
def ball_movement():
global ball_x, ball_y, ball_x_speed, ball_y_speed
ball_x -=ball_x_speed
ball_y +=ball_y_speed
def ball_collide_screen():
global ball_x, ball_y, ball_x_speed, ball_y_speed
if ball_y + screenw >= 600:
ball_y_speed = -2
if ball_y + screenw <= 300:
ball_y_speed = -2
def ball_collide_paddles():
global ball_rect, paddle1_rect, paddle2_rect
if paddle1_rect.right - ball_rect.left <= 0:
print('ho')
running=True
while running:
screen.fill((0,0,0))
screen.blit(paddle1, (paddle1_x,paddle1_y))
screen.blit(paddle2, (paddle2_x,paddle2_y))
screen.blit(ball, (ball_x, ball_y))
ball_collide_screen()
ball_movement()
ball_collide_paddles()
pygame.display.update()
fpsClock.tick(FPS)
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
pygame.quit()
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_w:
paddle1_y-= speed
if event.key==pygame.K_z:
paddle1_y+=speed
if event.key==pygame.K_UP:
paddle2_y-=speed
if event.key==pygame.K_DOWN:
paddle2_y+=speed
*i am getting problems with the pygame colliderect function. i put a print function whenever the ball collides with paddle and it continues print collide as long as the program is running.....i read somewhere that the rect position has to be matching with the balls initial position and i have tried doing that but all in vain .....i have been doing pygame for a while and i have encountered this problem trying to make this pong game *
You must update the location of the pygame.Rect objects, after moving the objects and before the collision detection:
def ball_movement():
global ball_x, ball_y, ball_x_speed, ball_y_speed
ball_x -=ball_x_speed
ball_y +=ball_y_speed
ball_rect.x=ball_x
ball_rect.y=ball_y
running=True
while running:
# [...]
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
pygame.quit()
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_w:
paddle1_y-= speed
if event.key==pygame.K_z:
paddle1_y+=speed
if event.key==pygame.K_UP:
paddle2_y-=speed
if event.key==pygame.K_DOWN:
paddle2_y+=speed
paddle1_rect.x=paddle1_x
paddle1_rect.y=paddle1_y
paddle2_rect.x=paddle2_x
paddle2_rect.y=paddle2_y
Note, you don't need the variables ball_x, ball_y, paddle1_x, paddle1_y, paddle2_x and paddle2_y at all.
Use ball_rect.x, ball_rect.y, paddle1_rect.x, paddle1_rect.y, paddle2_rect.x and paddle2_rect.y instead.
import pygame
pygame.init()
pygame.display.set_caption('...SHON...PONG...')
#icon = pygame.image.load('icon.png')
#pygame.display.set_icon(icon)
FPS = 50
fpsClock = pygame.time.Clock()
screenh = 500
screenw = 300
screen = pygame.display.set_mode((screenh,screenw))
black = ((0,0,0))
#paddle1 = pygame.image.load('paddle1.png')
paddle1 = pygame.Surface((5, 50))
paddle1.fill((255, 255, 255))
paddle1_rect = paddle1.get_rect(topleft = (10, 100))
#paddle2 = pygame.image.load('paddle2.png')
paddle2 = pygame.Surface((5, 50))
paddle2.fill((255, 255, 255))
paddle2_rect = paddle1.get_rect(topleft = (471, 100))
#ball = pygame.image.load('player.png')
ball = pygame.Surface((5, 5))
ball.fill((255, 255, 255))
ball_rect = ball.get_rect(topleft = (240, 130))
ball_x_speed = 2
ball_y_speed = 2
speed = 15
def ball_movement():
ball_rect.x += ball_x_speed
ball_rect.y += ball_y_speed
def ball_collide_screen():
global ball_x_speed, ball_y_speed
if ball_rect.left <= 0:
ball_x_speed = 2
if ball_rect.right >= screen.get_width():
ball_x_speed = -2
if ball_rect.top <= 0:
ball_y_speed = 2
if ball_rect.bottom >= screen.get_height():
ball_y_speed = -2
def ball_collide_paddles():
if paddle1_rect.right - ball_rect.left <= 0:
print('ho')
running=True
while running:
screen.fill((0,0,0))
screen.blit(paddle1, paddle1_rect)
screen.blit(paddle2, paddle2_rect)
screen.blit(ball, ball_rect)
pygame.display.update()
fpsClock.tick(FPS)
ball_collide_screen()
ball_movement()
ball_collide_paddles()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running=False
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
paddle1_rect.y -= speed
if event.key == pygame.K_s:
paddle1_rect.y += speed
if event.key == pygame.K_UP:
paddle2_rect.y -= speed
if event.key == pygame.K_DOWN:
paddle2_rect.y += speed

How Do I Fix My Ball Animation In Pygame? [duplicate]

This question already has an answer here:
How can I move the ball instead of leaving a trail all over the screen in pygame?
(1 answer)
Closed 1 year ago.
So my ball animation for my multiplayer pong game is broken. Instead of moving and bouncing normally, the ball draws it self again after moving.
How do i fix the ball to not like clone itself after it moves 5 pixels? This is the animation code:
enter code here
import pygame
pygame.init()
#Creating the window
screen_width, screen_height = 1000, 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Pong")
#FPS
FPS = 60
clock = pygame.time.Clock()
#Game Variables
light_grey = (170,170,170)
#Paddles
paddle_1 = pygame.Rect(screen_width - 30, screen_height/2 - 70, 20,100)
paddle_2 = pygame.Rect(10, screen_height/2 - 70, 20, 100)
#Ball
ball = pygame.Rect(screen_width/2, screen_height/2, 30, 30)
ball_xVel = 5
ball_yVel = 5
def ball_animation():
global ball_xVel, ball_yVel
ball.x += ball_xVel
ball.y += ball_yVel
if ball.x > screen_width or ball.x < 0:
ball_xVel *= -1
if ball.y > screen_height or ball.y < 0:
ball_yVel *= -1
def draw():
pygame.draw.ellipse(screen, light_grey, ball)
pygame.draw.rect(screen, light_grey, paddle_1)
pygame.draw.rect(screen, light_grey, paddle_2)
def main():
#main game loop
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
draw()
ball_animation()
pygame.display.update()
clock.tick(FPS)
pygame.quit()
if __name__ == "__main__":
main()
You have to clear the display in every frame with pygame.Surface.fill:
screen.fill(0)
The typical PyGame application loop has to:
handle the events by 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 either pygame.display.update() or pygame.display.flip()
limit frames per second to limit CPU usage with pygame.time.Clock.tick
def main():
# main application loop
run = True
while run:
# event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# update and move objects
ball_animation()
# clear the display
screen.fill(0)
# draw the scene
draw()
# update the display
pygame.display.update()
# limit frames per second
clock.tick(FPS)
pygame.quit()
exit()

pygame image collsion trouble [duplicate]

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

How to move the background image with keys in pygame?

I am making a game in pygame. In this game, the background image is large. On the screen, player only sees about 1/20th of the background image. I want, when player presses the left, right, up or down arrow keys, the background image moves respectively, but, it stops moving when player reaches the end of the image. I have no idea how to do this.
My code up to this point :-
import pygame
FPS = 60
screen = pygame.display.set_mode((1000, 1000))
bg = pygame.image.load('map.png')
clock = pygame.time.Clock()
while True:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
Thanks in Advance :-
Get the sice of the background and the screen by get_size():
screen_size = screen.get_size()
bg_size = bg.get_size()
Define the initial start of the background in range [0, bg_size[0]-screen_size[0]]. e.g. center of the background:
bg_x = (bg_size[0]-screen_size[0]) // 2
Get the list of the key states by pygame.key.get_pressed():
keys = pygame.key.get_pressed()
Change bg_x dependent on the state of left and right:
if keys[pygame.K_LEFT]:
bg_x -= 10
if keys[pygame.K_RIGHT]:
bg_x += 10
Clamp bg_x to the range [0, bg_size[0]-screen_size[0]]:
bg_x = max(0, min(bg_size[0]-screen_size[0], bg_x))
blit the background at -bg_x on the screen:
screen.blit(bg, (-bg_x, 0))
See the example:
import pygame
FPS = 60
screen = pygame.display.set_mode((1000, 1000))
bg = pygame.image.load('map.png')
screen_size = screen.get_size()
bg_size = bg.get_size()
bg_x = (bg_size[0]-screen_size[0]) // 2
bg_y = (bg_size[1]-screen_size[1]) // 2
clock = pygame.time.Clock()
while True:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
bg_x -= 10
if keys[pygame.K_RIGHT]:
bg_x += 10
if keys[pygame.K_UP]:
bg_y -= 10
if keys[pygame.K_DOWN]:
bg_y += 10
bg_x = max(0, min(bg_size[0]-screen_size[0], bg_x))
bg_y = max(0, min(bg_size[1]-screen_size[1], bg_y))
screen.blit(bg, (-bg_x, -bg_y))
pygame.display.flip()

pygame key.set_repeat not working

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

Categories

Resources