How can I make directional movement in pygame smooth? - python

I am making a game in pygame where you are a jellyfish and you can swim around. I've managed to being able to turn and go in the direction the jellyfish is rotated towards. But when I go in that direction the player image is shaking. Can I fix this somehow?
Where self.list[int(self.current)] is the current image of the animation and dt delta time.
if pygame.key.get_pressed()[pygame.K_UP]:
self.rotr = math.radians(self.rot)
self.ysp = math.cos(self.rotr)
self.xsp = math.sin(self.rotr)
self.x -= self.xsp*dt*20
self.y -= self.ysp*dt*20
self.image = pygame.transform.rotate(self.list[int(self.current)], self.rot)
self.rect = self.image.get_rect(center = (x, y))
if pygame.key.get_pressed()[pygame.K_LEFT]:
self.rot += math.pi*dt*7
if pygame.key.get_pressed()[pygame.K_RIGHT]:
self.rot -= math.pi*dt*7

You may have seen tutorials for how to move objects in PyGame, which rely on integer X and Y values. This is not a great way to achieve smooth motion. An example of NOT smooth motion is below - notice how the velocity and position values are integers:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("Moving rectangle")
x = 200 #integer value
y = 200 #integer value
width = 20
height = 20
vel = 10 # integer value
run = True
while run:
pygame.time.delay(10)
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))
#int values are directly used for screen position
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.display.update()
pygame.quit()
This is a simple fix, though:
x = 200.0 #now a float
y = 200.0 #now a float
width = 20
height = 20
vel = 10.0 #now a float
run = True
while run:
pygame.time.delay(10)
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))
#now converting X and Y from floats to integers, rounding first
pygame.draw.rect(win, (255, 0, 0), (int(round(x)), int(round(y)), width, height))
Notice how when we draw the rect, we round the X and Y coordinates. The rounded coordinates are the display coordinates. Your X and Y values that you use internally don't even have to correspond to pixel values 1:1; you're in control of how the conversion from position coordinates to screen coordinates happens. This is just the simplest case.
Even smoother motion can be achieved using acceleration, friction, etc. There are many tutorials on that though.

Related

Move two rects seperately with wasd and arrow keys in pygame?

I am new to programming with pygame and python itself. I was trying to make a simple local multiplayer game using pygame. I wrote my code while watching a tutorial on moving only one rectangle because I did not find anything on what I am trying to do. When I finished, I copied the part of the script with the variables and the movement for the rectangle and then pasted it and changed the variable names so it does not crash or something. Now, here comes my problem: because the movement is simple, it would print a new rectangle, if I press the buttons to move. Because of that, the background is refreshing its color all the time (or something like that) so only the one rectangle I want to move is shown. But if there is a second rect, the color covers it, and only one is visible all the time. How can I fix that?
Here is the code:
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("local multiplayer")
#variables player 1
X = 200
Y = 200
Width = 40
Height = 60
Vel = 5
#variables player 2
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()
#player 1
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
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), (X, Y, Width, Height))
pygame.display.update()
#player 2
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()
When you call win.fill((0, 0, 0)) the entire display is cleared. You have to draw the rectangles at once after clearing the display.
Update of the display at the end of the application loop. Multiple calls to pygame.display.update() or pygame.display.flip() cause flickering (see Why is the PyGame animation is flickering).
Simplify the code and use pygame.Rect objects to represent the players. Use pygame.Rect.clamp_ip to prevent the player from leaving the screen.
import pygame
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("local multiplayer")
clock = pygame.time.Clock()
player1 = pygame.Rect(200, 200, 40, 60)
vel1 = 1
player2 = pygame.Rect(50, 40, 40, 60)
vel2 = 1
run = True
while run:
clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
player1.x += (keys[pygame.K_d] - keys[pygame.K_a]) * vel1
player1.y += (keys[pygame.K_s] - keys[pygame.K_w]) * vel1
player2.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel2
player2.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel2
player1.clamp_ip(win.get_rect())
player2.clamp_ip(win.get_rect())
win.fill((0, 0, 0))
pygame.draw.rect(win, (255, 255, 255), player1)
pygame.draw.rect(win, (255, 255, 255), player2)
pygame.display.update()
pygame.quit()
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()
You are doing win.fill((0, 0, 0)) right after displaying player 1. Remove this code before you display the second character. Also, keep the fill line at the top of your app loop. This would give:
pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("local multiplayer")
#variables player 1
X = 200
Y = 200
Width = 40
Height = 60
Vel = 5
#variables player 2
x = 50
y = 50
width = 40
height = 60
vel = 5
run = True
while run:
win.fill((0, 0, 0))
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
#player 1
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
pygame.draw.rect(win, (255, 255, 255), (X, Y, Width, Height))
#player 2
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
pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
pygame.display.update()
pygame.quit()
It is also good practice to only update the screen once per loop. Another thing I would do is put the input all in the same if block (but that is not necessary). To further improve your code- consider making a player class that has a render function to display itself, along with an update function to handle control.

Arrow Key Movement in Pygame

I am starting with pygame and can't seem to figure out how to implement continuous movement. This is my current code:
import pygame
pygame.init()
window = pygame.display.set_mode(((500, 500)))
pygame.display.set_caption(("First Game"))
x = 50
y = 50
width = 40
height = 60
vel = 10
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
window.fill((0, 0, 0))
pygame.draw.rect(window, (200, 23, 255), (350, 350, width, height))
pygame.display.update()
pygame.quit()
As I have just started, I can't think of any possible solutions. Would be really nice of you if you can resolve this issue of mine. I know there is going to be some really stupid bug.
You need to draw the rectangle x, y instead of constant 350, 350:
pygame.draw.rect(window, (200, 23, 255), (350, 350, width, height))
pygame.draw.rect(window, (200, 23, 255), (x, y, width, height))
For a smooth movement you need to set vel to 1 and decrease the delay in the application loop.
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():
import pygame
pygame.init()
window = pygame.display.set_mode(((500, 500)))
pygame.display.set_caption(("First Game"))
x, y = 50, 50
width, height = 40, 60
vel = 1
clock = pygame.time.Clock()
run = True
while run:
clock.tick(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
window.fill((0, 0, 0))
pygame.draw.rect(window, (200, 23, 255), (x, y, width, height))
pygame.display.update()
pygame.quit()
Draw your rectangle at x and y coordinates as origin.

How to make the snake continue in that direction until another arrow key is pressed

I've tried many ideas like importing pynput but it kept on crashing and making my computer messed up. I've tried putting it in a loop but that didn't work as well and kept crashing
import sys
import pygame
import random
import os
import time
pygame.init()
#assigns thingys to window adjustments
size = width, height = 750, 750
white = 255, 255, 255
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Snake Game")
#The coordinates and size of the snake square thingy
x = 350
y = 350
w = 25
h = 25
ax = range(30,700)
ay = range(40,700)
aw = 15
ah = 15
vel = 10
vertical1 = 9000
vertical2 = 0
score_value = 0
font = pygame.font.Font('freesansbold.ttf', 32)
textx = 10
testy = 10
def show_score(x, y):
score = font.render("Score: "+ str(score_value), True, (255,0,0))
screen.blit(score, (x, y))
def divisible_random(a,b,n):
if b-a < n:
raise Exception('{} is too big'.format(n))
result = random.randint(a, b)
while result % n != 0:
result = random.randint(a, b)
return result
def apple(x,y):
pygame.draw.rect(screen, (255, 0, 0), (arx, ary, aw, ah))
arx = divisible_random(30,700,10)
ary = divisible_random(40,700,10)
while 1:
#Delays the movement so you can see snake thingy fps
pygame.time.delay(25)
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit()
#gets the presses to move the snake
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
while True:
x= x - vel
if keys[pygame.K_RIGHT] or keys[pygame.K_DOWN] or keys[pygame.K_UP]:
break
if keys[pygame.K_RIGHT]:
while True:
x= x + vel
if keys[pygame.K_LEFT] or keys[pygame.K_DOWN] or keys[pygame.K_UP]:
break
if keys[pygame.K_DOWN]:
while True:
y = y + vel
if keys[pygame.K_LEFT] or keys[pygame.K_RIGHT] or keys[pygame.K_UP]:
break
if keys[pygame.K_UP]:
while True:
y = y - vel
if keys[pygame.K_LEFT] or keys[pygame.K_RIGHT] or keys[pygame.K_DOWN]:
break
screen.fill(white)
#The snake thingy and apple thingy
apple(arx, ary)
snake = pygame.draw.rect(screen, (0, 0, 0), (x, y, w, h))
diffrencex = abs(arx-x)
diffrencey = abs(ary-y)
if ((x == arx and y == ary) or ((diffrencex == 10 and x < arx) and (diffrencey == 10 and y < ary)) or ((diffrencex==10 and x< arx) and (y == ary)) or ((x == arx) and (diffrencey==10 and y< ary))):
score_value += 1
arx = divisible_random(30,700,10)
ary = divisible_random(40,700,10)
#Borders for the frame thingy
pygame.draw.line(screen, (0,0,0), (14, 10), (14, 800), 30)
pygame.draw.line(screen, (0,0,0), (734, 10), (734, 800), 30)
pygame.draw.line(screen, (0,0,0), (9000, 734), (0 , 734), 30)
pygame.draw.line(screen, (0,0,0), (9000, 24), (0 , 24), 30)
if x < 30:
x = 700
if x > 700:
x = 30
if y > 700:
y = 40
if y < 40:
y = 700
show_score(textx, testy)
print(arx,ary,x,y)
pygame.display.update()
pygame.quit
I know the code isn't neat not organized but I'm working on it as soon as I finish making the game
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
while True:
x= x - vel
if keys[pygame.K_RIGHT] or keys[pygame.K_DOWN] or keys[pygame.K_UP]:
break
if keys[pygame.K_RIGHT]:
while True:
x= x + vel
if keys[pygame.K_LEFT] or keys[pygame.K_DOWN] or keys[pygame.K_UP]:
break
if keys[pygame.K_DOWN]:
while True:
y = y + vel
if keys[pygame.K_LEFT] or keys[pygame.K_RIGHT] or keys[pygame.K_UP]:
break
if keys[pygame.K_UP]:
while True:
y = y - vel
if keys[pygame.K_LEFT] or keys[pygame.K_RIGHT] or keys[pygame.K_DOWN]:
break
I encounter problems here to be exact
Use the keyboard events (KEYDOWN, KEYUP - see pygame.event) rather than pygame.key.get_pressed(). Add a variable direction and change the state tof the variable when LEFT, RIGHT, UP respectively DOWN is pressed. Change the player's position according to the direction:
direction = (0, 0)
while 1:
#Delays the movement so you can see snake thingy fps
pygame.time.delay(25)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
direction = (-1, 0)
elif event.key == pygame.K_RIGHT:
direction = (1, 0)
elif event.key == pygame.K_UP:
direction = (0, -1)
elif event.key == pygame.K_DOWN:
direction = (0, 1)
x += vel * direction[0]
y += vel * direction[1]
You want continuous movement, but you don't want to hold down the button. You want to move the snake even if no key is pressed. Therefore, you need to save the direction of movement in a variable and change the direction once when a key is pressed. The keyboard event occurs once when a key is pressed and is the right choice to change direction.
Use a variable to store the direction of movement. Have key presses affect that variable. Then, check that variable every loop iteration, and move the snake according to the direction.

Image rotation not working as expected

I am very new to python/pygame, and would like some help. I am trying to make two cars automatically move forward(which I have completed successfully) however I cannot manage to make the cars turn left/right when a certain key is pressed. I would love someone to help me with this. As I said, I am new to this, so if anyone was kind enough to help, please can you edit my code so it is successful as well as an explanation to what is going wrong, thank you so very much in advance. https://i.stack.imgur.com/zrlUT.png
https://i.stack.imgur.com/q6Hb9.png
https://i.stack.imgur.com/MGR3N.jpg
P.S. There is no error message to my code, as there is no wrong in it, the rotate function is simply not working
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((1150, 800))
pygame.display.set_caption("Car Football")
degrees = 180
x = 70
y = 70
x1 = 1000
y1 = 400
width = 70
height = 70
vel = 15
vel1 = 15
def rotatedleft():
pygame.transform.rotate(redcar, (15))
def rotatedright():
pygame.transform.rotate(redcar, (-15))
run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
screen.fill((0, 0, 0))
bgImg = pygame.image.load("Football_pitch.png").convert()
screen.blit(bgImg, [0,0])
redcar = pygame.image.load("redcar.png")
screen.blit(redcar, (x, y))
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
rotatedleft = True
if run:
x += vel
if keys[pygame.K_RIGHT]:
rotatedright = True
pygame.display.flip()
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if run:
x1 -= vel1
if keys[pygame.K_d] and x1 < 1150:
x1 += vel1
if keys[pygame.K_w]:
y1 -= vel1
if keys[pygame.K_s]:
y1 += vel1
bluecar = pygame.image.load("Bluecarss.png")
screen.blit(bluecar, (x1, y1))
circleball = pygame.draw.circle(screen, (255, 255, 255), (300, 140), 50, 0)
pygame.display.update()
pygame.display.flip()
pygame.quit()
sys.exit()
You need to know trigonometry or vectors if you want to rotate a car in your game and move it in the direction it is facing (I'm using vectors in the following example). The position and the velocity should be vectors and you have to add the vel to the pos vector every frame to move the car forward. You also need a pygame.Rect which is used as the blit position (the rect makes it easier to center the car and can be used for collision detection).
When the user presses ← or →, you have to rotate the angle and the vel vector (vel is also the direction) and then use the angle to rotate the image/pygame.Surface. As for the image rotation, you should keep a reference to the original image in order to preserve the quality of the image. Pass it to pygame.transform.rotate together with the current angle of the car and you'll get a rotated surface. This surface will have different dimensions, so you need to create a new rect (with pygame.Surface.get_rect) to update the blit position (top left coordinates).
import pygame
from pygame.math import Vector2
pygame.init()
screen = pygame.display.set_mode((1150, 800))
clock = pygame.time.Clock() # A clock to limit the frame rate.
# Load your images once at the beginning of the program.
REDCAR_ORIGINAL = pygame.Surface((50, 30), pygame.SRCALPHA)
pygame.draw.polygon(
REDCAR_ORIGINAL, (200, 0, 0), [(0, 0), (50, 10), (50, 20), (0, 30)])
redcar = REDCAR_ORIGINAL
# Use vectors for the position and the velocity.
pos = Vector2(70, 70) # Center position of the car.
vel = Vector2(2, 0)
# This rect serves as the blit position of the redcar image.
rect = redcar.get_rect(center=pos)
angle = 0 # Current angle of the car.
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
# When a key gets pressed, increment the angle, rotate
# the vector and create a new rotated car image.
# The angle is rotated in the opposite direction because
# pygame's y-axis is flipped.
angle += 3
vel.rotate_ip(-3)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, angle)
# Also, get a new rect because the image size was changed.
# Pass the pos vector as the `center` argument to keep the
# image centered.
rect = redcar.get_rect(center=pos)
elif keys[pygame.K_RIGHT]:
angle -= 3
vel.rotate_ip(3)
redcar = pygame.transform.rotate(REDCAR_ORIGINAL, angle)
rect = redcar.get_rect(center=pos)
# Move the car by adding the velocity to the position.
pos += vel
rect.center = pos # Update the rect as well.
screen.fill((30, 30, 30))
screen.blit(redcar, rect) # Blit the car at the `rect.topleft` coords.
pygame.display.flip()
clock.tick(60) # Limit the frame rate to 60 FPS.
pygame.quit()
if keys[pygame.K_LEFT]:
rotatedleft = True
You're assigning True to rotatedleft, which you've previously defined as a function, try calling the function, like so:
if keys[pygame.K_LEFT]:
rotatedleft()
Now it's kinda turning, I'm pretty sure it's still not quite what you're looking for but hey, baby steps. Best of luck with your game.
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((1150, 800))
pygame.display.set_caption("Car Football")
degrees = 180
x = 70
y = 70
x1 = 1000
y1 = 400
width = 70
height = 70
vel = 15
vel1 = 15
run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
screen.fill((0, 0, 0))
bgImg = pygame.image.load("Football_pitch.png").convert()
screen.blit(bgImg, [0,0])
redcar = pygame.image.load("redcar.png")
screen.blit(redcar, (x, y))
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
redcar = pygame.transform.rotate(redcar, 15)
screen.blit(redcar, (x, y))
if run:
x += vel
if keys[pygame.K_RIGHT]:
redcar = pygame.transform.rotate(redcar, -15)
screen.blit(redcar, (x, y))
pygame.display.flip()
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if run:
x1 -= vel1
if keys[pygame.K_d] and x1 < 1150:
x1 += vel1
if keys[pygame.K_w]:
y1 -= vel1
if keys[pygame.K_s]:
y1 += vel1
bluecar = pygame.image.load("Bluecarss.png")
screen.blit(bluecar, (x1, y1))
circleball = pygame.draw.circle(screen, (255, 255, 255), (300, 140), 50, 0)
pygame.display.update()
pygame.display.flip()
pygame.quit()
sys.exit()

How can I stop a character in pygame from leaving the edge of the screen?

I have created a small program in pygame where the player controls a blue square moving around the screen, but I want to stop the player from moving past the edge of the screen. Here is the code I have so far, how can I do this?
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
done = False
x = 30
y = 30
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
is_blue = not is_blue
pressed = pygame.key.get_pressed()
if pressed[pygame.K_UP]: y -= 5
if pressed[pygame.K_DOWN]: y += 5
if pressed[pygame.K_LEFT]: x -= 5
if pressed[pygame.K_RIGHT]: x += 5
screen.fill((0, 0, 0))
color = (0, 128, 255)
pygame.draw.rect(screen, color, pygame.Rect(x, y, 60, 60))
pygame.display.flip()
clock.tick(60)
pygame.Rects have a clamp (and clamp_ip) method which you can use to limit the movement area. So create a rect with the size of the screen (called screen_rect here) and a rect for the player (player_rect) and call the clamp_ip method after each movement to keep it inside of the screen area.
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
BG_COLOR = pg.Color(30, 30, 50)
def main():
clock = pg.time.Clock()
image = pg.Surface((50, 30))
image.fill(pg.Color('dodgerblue'))
pg.draw.rect(image, pg.Color(40, 220, 190), (0, 0, 49, 29), 2)
player_rect = image.get_rect(topleft=(200, 200))
# This pygame.Rect has the dimensions of the screen and
# is used to clamp the player_rect to this area.
screen_rect = screen.get_rect()
speed = 5
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
return
pressed = pg.key.get_pressed()
if pressed[pg.K_UP]:
player_rect.y -= speed
if pressed[pg.K_DOWN]:
player_rect.y += speed
if pressed[pg.K_LEFT]:
player_rect.x -= speed
if pressed[pg.K_RIGHT]:
player_rect.x += speed
# Clamp the rect to the dimensions of the screen_rect.
player_rect.clamp_ip(screen_rect)
screen.fill(BG_COLOR)
screen.blit(image, player_rect)
pg.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()
pg.quit()
This should work
if pressed[pygame.K_UP] and y > 0: y -= 5
if pressed[pygame.K_DOWN] and y < 600 - 60: y += 5
if pressed[pygame.K_LEFT] and x > 0: x -= 5
if pressed[pygame.K_RIGHT] and x < 800 - 60: x += 5
Where 600 and 800 is the screen size and 60 the size of your rectangle
Something like:
if pressed[pygame.K_UP]:
if not (y > maxwidth or y < 0):
y += 5
And so on for the others. the maxwidth looks like 600 in your code but I'd put it at the top of your code so you dont keep having to change it in different places.
What you are trying to do is called edge detection, as in detect if you are at an edge, in this case you want the edges to be the screen's edges. what you should do, is check if your x or y are at an edge, if so don't go any further.
if pressed[pygame.K_UP]:
if 0 < y-5 < 600: #0 and 600 being the edges of your screen, you can use a variable to change it dynamically later one
y -= 5
Note this will only detect if the top left's square is going out of bounds, since x and y is the top and left coords for the rectangle, meaning the bottom right of the square will be able to still go out of bounds,
If you want to check the whole square, you will have to make adjustment calculations in the if statement, or base your x and y on the center (which you will still have to modify the if statement to something like below. (note I'm altering based on your current code for x and y being top left.
if pressed[pygame.K_UP]:
if (0 < y-5 < 600) or (0< y+60-5 <600) #0 and 600 being the edges of your screen, you can use a variable to change it dynamically later one
y -= 5
This checks the other side of the square. Note for x you will check for the horizontal limits which in this case is 800. Also we are checking including the -5 because we want to see where we are going, not where we are at.

Categories