Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
image = https://www.dropbox.com/s/nx6yzx8ddhu36m7/car.png?dl=0
when I rotate(press Left or Right Key) while I accelerate(press up key) my car moves in a strange way.
Also there is something wrong with the accelerating
speed doesn't increase the way I expect it to be. I think the speed should be increasing as the time goes on but it doesn't...
can anyone please help me by trying the code?
thank you
here's my code:
import pygame,math
pygame.init()
display_width = 1200
display_height = 800
white = (255,255,255)
black = (0,0,0)
car_image = pygame.image.load('car.png')
role_model = pygame.image.load('role_model.png')
clock = pygame.time.Clock()
FPS = 30
screen = pygame.display.set_mode([display_width,display_height])
car_width = 76
car_height = 154
def rotate(image, rect, angle):
rot_image = pygame.transform.rotate(image, angle)
rot_rect = rot_image.get_rect(center=rect.center)
return rot_image,rot_rect
def carRotationPos(angle):
x=1*math.cos(math.radians(angle-90))
y=1*math.sin(math.radians(angle-90))
return x,y
def gameloop():
running = True
angle = 0
angle_change = 0
changeX = 0
changeY=0
x=0
y=0
change_x=0
change_y=0
speed = 1
speed_change = 1
rect = role_model.get_rect()
while running == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
angle_change = 5
#changeX=0
#changeY=0
if event.key == pygame.K_RIGHT:
angle_change = -5
#changeX=0
#changeY=0
if event.key == pygame.K_UP:
#angle_change =0
changeX=-x
changeY=y
speed_change = speed_change**2 +1
if event.key == pygame.K_DOWN:
#angle_change =0
changeX=x
changeY=-y
speed_change = -(speed_change**2 + 1)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
angle_change = 0
if event.key == pygame.K_RIGHT:
angle_change = 0
if event.key == pygame.K_UP:
changeX=0
changeY=0
speed = 1
speed_change=1
if event.key == pygame.K_DOWN:
changeX=0
changeY=0
speed = 1
speed_change=1
if angle == -360 or angle == 360:
angle = 0
angle+=angle_change
change_x+=changeX
change_y+=changeY
speed+=speed_change
if speed > 20:
speed = 20
screen.fill(white)
x,y=carRotationPos(angle)
x=round(x,5)*speed
y=round(y,5)*speed
rot_image,rot_rect=rotate(car_image,rect,angle)
rot_rect=list(rot_rect)
rot_rect1=rot_rect[0]+display_width/2-car_width/2
rot_rect2=rot_rect[1]+display_height/2-car_height/2
rot_rect1+=change_x
rot_rect2+=change_y
del rot_rect[0]
del rot_rect[1]
rot_rect.insert(0,rot_rect1)
rot_rect.insert(1,rot_rect2)
screen.blit(rot_image,rot_rect)
pygame.display.update()
clock.tick(FPS)
gameloop()
pygame.quit()
When you press UP/DOWN then you set changeX = x , changeY = y and car moves using changeX, changeY.
When you press LEFT/DOWN then you change angle and calculate new x, y but this doesn't change changeX, changeY so car still moves the same direction (using the same changeX, changeY).
EDIT: now it turns correctly when you move forward but still there is problem with backward acceleration. I'm working on it.
I use moving_up/moving_down to update changeX and changeY when car is moving - so it use current angle and x, y to change direction.
EDIT: acceleration problem solve: you have to use speed_change = speed_change**2 + 1 when you go UP and DOWN. You don't need negative value when you go DOWN because x_change = x, y_change = -y will change direction.
New code:
BTW: I add ESC to quit program and BACKSPACE to center car on screen (reset position)
import pygame
import math
# --- constants --- (UPPER_CASE)
WHITE = (255, 255, 255)
BLACK = ( 0, 0, 0)
DISPLAY_WIDTH = 1200
DISPLAY_HEIGHT = 800
FPS = 30
CAR_WIDTH = 76
CAR_HEIGHT = 154
# --- functions --- (lower_case)
def rotate(image, rect, angle):
rot_image = pygame.transform.rotate(image, angle)
rot_rect = rot_image.get_rect(center=rect.center)
return rot_image, rot_rect
def rotate_car_pos(angle):
x = math.cos(math.radians(angle-90))
y = math.sin(math.radians(angle-90))
return x, y
def gameloop():
# start position - screen center - so I don't have to add center later
car_rect = role_model.get_rect(center=screen_rect.center)
# ---
angle = 0
angle_change = 0
x = 0
y = 0
x_change = 0
y_change = 0
speed = 0
speed_change = 0
# ---
pos_x = 0
pos_y = 0
#---
moving_up = False
moving_down = False
#recalculate = True
running = True
while running:
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_BACKSPACE:
# reset position [for test only]
pos_x = 0
pos_y = 0
angle = 0
elif event.key == pygame.K_LEFT:
angle_change = 5
elif event.key == pygame.K_RIGHT:
angle_change = -5
elif event.key == pygame.K_UP:
moving_up = True
x_change = -x
y_change = y
speed_change = speed_change**2 + 1
elif event.key == pygame.K_DOWN:
moving_down = True
x_change = x
y_change = -y
speed_change = speed_change**2 + 1
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
angle_change = 0
elif event.key == pygame.K_RIGHT:
angle_change = 0
elif event.key == pygame.K_UP:
moving_up = False
x_change = 0
y_change = 0
speed = 0
speed_change = 0
elif event.key == pygame.K_DOWN:
moving_down = False
x_change = 0
y_change = 0
speed = 0
speed_change = 0
# --- updates ---
# - pos -
if x_change or y_change:
pos_x += x_change
pos_y += y_change
print('[DEBUG]: pos_x, pos_y: ', pos_x, pos_y)
# - angle -
# rotate olny when moving
#if moving_up or moving_down:
if angle_change:
angle += angle_change
while angle > 360:
angle -= 360
while angle < -360:
angle += 360
print('[DEBUG]: angle: ', angle)
# - speed -
if speed_change:
speed += speed_change
if speed > 20:
speed = 20
print('[DEBUG]: speed: ', speed)
# - others -
x, y = rotate_car_pos(angle)
x = round(x*speed, 5)
y = round(y*speed, 5)
print('[DEBUG]: x, y: ', x, y)
if moving_up:
x_change = -x
y_change = y
elif moving_down:
x_change = x
y_change = -y
#if recalculate:
rot_image, rot_rect = rotate(car_image, car_rect, angle)
rot_rect.centerx += pos_x
rot_rect.centery += pos_y
# --- draws ---
screen.fill(WHITE)
screen.blit(rot_image, rot_rect)
pygame.display.update()
# --- clock ---
clock.tick(FPS)
# --- main ---
pygame.init()
car_image = pygame.image.load('car.png')
role_model = pygame.image.load('car.png')
screen = pygame.display.set_mode( (DISPLAY_WIDTH, DISPLAY_HEIGHT) )
screen_rect = screen.get_rect()
clock = pygame.time.Clock()
gameloop()
pygame.quit()
Related
This question already has an answer here:
How do I get the snake to grow and chain the movement of the snake's body?
(1 answer)
Closed 1 year ago.
Hi guys I started learning pygames, i started playing snake and came to an obstacle. I don't know how to make a function for my snake to grow when it eats an apple, I've looked at a lot of snake codes and I'm still not sure how to do it. I dont have idea how to do that, I realy hope you can give mi some advice to improve my game.
your help would do me good, thanks
import pygame
import random
import math
# Init
pygame.init()
# Screen
screen = pygame.display.set_mode((800, 600))
# Caption and Icon
pygame.display.set_caption("Snake Game")
icon = pygame.image.load('icon.png')
pygame.display.set_icon(icon)
# Background
background = pygame.image.load('background.jpg')
# Snake
snakeImg = pygame.image.load('snake.png')
snakeX = 300
snakeY = 300
snakeX_change = 0
snakeY_change = 0
# Apple
appleImg = pygame.image.load('apple.png')
appleX = random.randint(32, 768)
appleY = random.randint(32, 568)
def snake(x, y):
screen.blit(snakeImg, (x, y))
def apple(x, y):
screen.blit(appleImg, (x, y))
# Collision
def isCollision(appleX, appleY, snaketX, snakeY):
distance = distance = math.sqrt(math.pow(appleX - snakeX, 2) + (math.pow(appleY - snakeY, 2)))
if distance < 27:
return True
else:
return False
# Game Loop
score = 0
running = True
while running:
# Background Image
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Snake Movment
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
snakeX_change = -0.1
snakeY_change = 0
if event.key == pygame.K_UP:
snakeY_change = -0.1
snakeX_change = 0
if event.key == pygame.K_RIGHT:
snakeX_change = 0.1
snakeY_change = 0
if event.key == pygame.K_DOWN:
snakeY_change = 0.1
snakeX_change = 0
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
snakeX_change = -0.1
if event.key == pygame.K_RIGHT:
snakeX_change = 0.1
if event.key == pygame.K_DOWN:
snakeY_change = 0.1
if event.key == pygame.K_UP:
snakeY_change = -0.1
snakeX += snakeX_change
snakeY += snakeY_change
if snakeX <= 0:
snakeX = 0
elif snakeX >= 770:
snakeX = 770
if snakeY <= 0:
snakeY = 0
elif snakeY >= 570:
snakeY = 570
# Collision
collision = isCollision(appleX, appleY, snakeX, snakeY)
if collision:
score += 1
print(score)
appleX = random.randint(32, 768)
appleY = random.randint(32, 568)
snake(snakeX, snakeY)
apple(appleX, appleY)
pygame.display.flip()
When snake's head collide with the apple, add 1 element inside snake's body, you can interprete snake's body as a list of elements, containing tuples perhaps.
This question already has an answer here:
How to make enemies fall at random on pygame?
(1 answer)
Closed 2 years ago.
my enemy in my game is supposed to move up and down and every time it reaches the bottom of the screen it is supposed to re spawn in a different spot and go down again. Here it is explained in a video.
pygame.init()
screen_width = 800
screen_height = 600
window = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Test')
time = pygame.time.Clock()
bg_color1 = (135, 142, 142) # MAIN BG COLOR
bg_color2 = (255, 0, 0) # red
bg_color3 = (255, 255, 0) # yellow
UFO = pygame.image.load('ufo.png')
bg_pic = pygame.image.load('Letsgo.jpg')
clock = pygame.time.Clock()
playerImg = pygame.image.load('enemy.png')
playerX = random.randrange(0, screen_width)
playerY = -50
playerX_change = 0
player_speed = 5
def player(x, y):
window.blit(playerImg, (playerX, playerY))
crashed = False
rect = UFO.get_rect()
obstacle = pygame.Rect(400, 200, 80, 80)
menu = True
playerY = playerY + player_speed
if playerY > screen_height:
playerX = random.randrange(0,screen_width)
playerY = -25
def ufo(x, y):
window.blit(UFO, (x, y))
while menu:
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
menu = False
window.fill((0, 0, 0))
time.tick(30)
window.blit(bg_pic, (0, 0))
pygame.display.update()
x = (screen_width * 0.45)
y = (screen_height * 0.8)
x_change = 0
car_speed = 0
y_change = 0
while not crashed:
x += x_change
if x < 0:
x = 0
elif x > screen_width - UFO.get_width():
x = screen_width - UFO.get_width()
y += y_change
if y < 0:
y = 0
elif y > screen_height - UFO.get_height():
y = screen_height - UFO.get_height()
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
############SIDE TO SIDE################
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -5
elif event.key == pygame.K_RIGHT:
x_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x_change = 0
###########UP AND DOWN#################
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change = -5
elif event.key == pygame.K_DOWN:
y_change = 5
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
## if playerY > screen_height:
playerX = random.randrange(0,screen_width)
playerY = -10
x += x_change
y += y_change
##
window.fill(bg_color1)
ufo(x, y)
player(playerX, playerY)
pygame.display.update()
clock.tick(100)
pygame.quit()
quit()
this is my full code and the code i used to make it move up and down was this.
playerX = random.randrange(0,screen_width)
playerY = -10
Thanks for any help!...........................................................................
What you are doing at the moment seems to be setting the Y once, you need to create a loop to constantly update the Y
The line with the condition if playerY > screen_height: is actually a comment:
## if playerY > screen_height:
so you're setting playerX every frame. It should look more like this:
if playerY > screen_height: # when out of screen
playerX = random.randrange(0,screen_width) # new random X
playerY = 0 # also reset y back to top
playerY += 10 # move
I'm making a small test game on pygame where you need to fly a plane around the screen without touching the boundaries of the window, or the game will close down. Before I added the boundaries' code, I was able to make the plane's sprite change when it flew left or right, tilting in the respective direction. Now, although the "collision boundaries" code has nothing to do with the sprites code, the plane only remains in it's one, initial sprite and does not change (it still moves and the boundary code works fine, but the sprite itself wont change).
here's my code:
def game_loop():
x = display_width * 0.45
y = display_height * 0.8
x_change = 0
accel_x = 0
y_change = 0
accel_y = 0
max_speed_x = 2.5
max_speed_y = 2.5
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
elif event.type == pygame.KEYDOWN:
if event.key in (pygame.K_LEFT, pygame.K_a):
accel_x = -.2
img = pygame.image.load('PocketFlyer3.png')
img = pygame.transform.scale(img, (32, 32))
elif event.key in (pygame.K_RIGHT, pygame.K_d):
accel_x = .2
img = pygame.image.load('PocketFlyer2.png')
img = pygame.transform.scale(img, (32, 32))
if event.key in (pygame.K_UP, pygame.K_w):
accel_y = -.2
elif event.key in (pygame.K_DOWN, pygame.K_s):
accel_y = .2
elif event.type == pygame.KEYUP:
if event.key in (pygame.K_LEFT, pygame.K_RIGHT, pygame.K_a, pygame.K_d):
accel_x = 0
img = pygame.image.load('PocketFlyer1.png')
img = pygame.transform.scale(img, (32, 32))
if event.key in (pygame.K_UP, pygame.K_DOWN, pygame.K_w, pygame.K_s):
accel_y = 0
#accel script for X
x_change += accel_x
if abs(x_change) >= max_speed_x:
x_change = x_change/abs(x_change) * max_speed_x
if accel_x == 0:
x_change *= 0.92
x += x_change
#accel script for Y
y_change += accel_y
if abs(y_change) >= max_speed_y:
y_change = y_change/abs(y_change) * max_speed_y
if accel_y == 0:
y_change *= 0.92
y += y_change
display.fill(skyblue)
plane(x,y)
if x > display_width - plane_width or x < 0 or y > display_width - plane_width or y < 0:
gameExit = True
pygame.display.update()
clock.tick(60)
the width of the plane and the game's window is defined before this extract; nothing too important has been left out of this small extract either.
(the slight difference in the indentation of the code isn't the issue, only something that's occurred whilst posting this question)
Your boundary test is wrong (checks both x and y against width and ignores height), should be:
if (x > display_width - plane_width) \
or (x < 0) \
or (y > display_height - plane_height) \
or (y < 0):
I'm trying to learn python so I'm messing around with pygame. I'm a complete beginner.
so far I have made it so that I can control an image, moving it in 2d with the arrow keys.
However, I drew the image facing left and it is always facing left and I want to make it face the direction it's moving. I managed to make it rotate 180 degrees when I press right, but that was everytime I press right so I kept flipping the wrong way.
I need it to face right when moving right and left when moving left.
Image attached.
Thank you
import pygame
import time
pygame.init()
display_width = 1000
display_height = 800
black=(0,0,0)
white=(255,255,255)
gamedisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('metal gear python')
clock = pygame.time.Clock()
snakeimg= pygame.image.load('snake.png')
snake_width = 96
snake_height= 79
def snake(x,y):
gamedisplay.blit(snakeimg, (x,y))
discovered = False
while not discovered:
for event in pygame.event.get():
if event.type == pygame.QUIT:
discovered = TRUE
print (event)
x = (display_width * 0.45)
y = (display_height * 0.8)
x_change=0
y_change=0
snake_speed=0
gameExit= False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
print(event)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -3
elif event.key == pygame.K_RIGHT:
x_change = 3
elif event.key == pygame.K_RIGHT:
x_change = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
x_change = 0
elif event.key == pygame.K_RIGHT:
x_change = 0
x += x_change
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_change = -3
elif event.key == pygame.K_DOWN:
y_change = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y_change = 0
y += y_change
gamedisplay.fill(white)
snake(x,y)
if x > display_width-snake_width or x < 0:
gameExit=True
if y > display_height-snake_height or y < 0:
True
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
Mainly i change the snake function, so that it computes the correct rotation and then rotates the image. Also I change a little bit of the logic, especially at event handling so it is easier to read
import pygame
import time
pygame.init()
display_width = 1000
display_height = 800
black = (0, 0, 0)
white = (255, 255, 255)
gamedisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('metal gear python')
clock = pygame.time.Clock()
snakeimg = pygame.image.load('snake.png')
snake_width = 96
snake_height = 79
def snake(x, y):
if x_change == 0 and y_change == 0:
rotation = -90
elif x_change > 0 and y_change == 0:
rotation = 180
elif x_change < 0 and y_change == 0:
rotation = 0
elif x_change == 0 and y_change > 0:
rotation = 90
elif x_change == 0 and y_change < 0:
rotation = -90
elif x_change < 0 and y_change < 0:
rotation = -45
elif x_change < 0 and y_change > 0:
rotation = 45
elif x_change > 0 and y_change < 0:
rotation = -135
elif x_change > 0 and y_change > 0:
rotation = 135
gamedisplay.blit(pygame.transform.rotate(snakeimg, rotation), (x, y))
discovered = False
while not discovered:
for event in pygame.event.get():
if event.type == pygame.QUIT:
discovered = True
print(event)
x = (display_width * 0.45)
y = (display_height * 0.8)
x_change = 0
y_change = 0
snake_speed = 0
gameExit = False
while not gameExit:
for event in pygame.event.get():
print(event)
if event.type == pygame.QUIT:
gameExit = True
discovered = True # so you can actually quit the game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_change = -3
elif event.key == pygame.K_RIGHT:
x_change = 3
elif event.key == pygame.K_UP:
y_change = -3
elif event.key == pygame.K_DOWN:
y_change = 3
elif event.type == pygame.KEYUP:
if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
x_change = 0
elif event.key in (pygame.K_UP, pygame.K_DOWN):
y_change = 0
x += x_change
y += y_change
gamedisplay.fill(white)
snake(x, y)
if x > display_width - snake_width or x < 0:
gameExit = True
if y > display_height - snake_height or y < 0:
gameExit = True
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
And still i have the question: Why 2 game loops inside each other?
I would like to know how to create a border in Pygame to stop the user controlled object from exiting the screen. Right now, I only have it so python prints some text when the user controlled object has come near one of the 4 sides.
Here is my code so far.
import pygame
from pygame.locals import *
pygame.init()
#Display Stuff
screenx = 1000
screeny = 900
screen = pygame.display.set_mode((screenx,screeny))
pygame.display.set_caption('Block Runner')
clock = pygame.time.Clock()
image = pygame.image.load('square.png')
#Color Stuff
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
white = (255,255,255)
black = (0,0,0)
#Variables
x_blocky = 50
y_blocky = 750
blocky_y_move = 0
blocky_x_move = 0
#Animations
def Blocky(x_blocky, y_blocky, image):
screen.blit(image,(x_blocky,y_blocky))
#Game Loop
game_over = False
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
blocky_y_move = -3
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
blocky_y_move = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_DOWN:
blocky_y_move = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
blocky_y_move = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
blocky_x_move = 3
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
blocky_x_move = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
blocky_x_move = -3
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
blocky_x_move = 0
if x_blocky > 870 or x_blocky < 0:
print(' X Border')
if y_blocky > 750 or y_blocky < 2:
print(' Y Border')
y_blocky += blocky_y_move
x_blocky += blocky_x_move
screen.fill(white)
Blocky(x_blocky, y_blocky, image)
pygame.display.update()
clock.tick(60)
Don't use integers to store your position. Use a Rect.
So instead of
x_blocky = 50
y_blocky = 750
use
blocky_pos = pygame.rect.Rect(50, 750)
Now you can simply use
blocky_pos.move_ip(blocky_x_move, blocky_y_move)
to move your object.
After moving, you can simply call clamp/clamp_ip to ensure the blocky_pos Rect is always inside the screen.
blocky_pos.clamp_ip(screen.get_rect())
Also, you don't need to define basic colors yourself, you could simply use pygame.color.Color('Red') for example.
I also suggest you use pygame.key.get_pressed() to get all pressed keys to see how to move your object instead of creating 1000 lines of event handling code.
Well, simply don't increase your move variable any further, if you detect that the user object is near or at the border. Or reverse the move direction, depending on your general intent.
if x_blocky > 870 or x_blocky < 0:
print(' X Border')
blocky_x_move = 0
if y_blocky > 750 or y_blocky < 2:
print(' Y Border')
blocky_y_move = 0
Also, you have some redundant code with your keyboard movement. Instead of writing
if event.type == KEYDOWN:
over and over again, group the KEYUP if statements and KEYDOWN if statements.
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
blocky_y_move = -3
elif event.key == pygame.K_DOWN:
blocky_y_move = +3
etc, and:
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
blocky_y_move = 0
elif event.type == pygame.K_DOWN:
blocky_y_move = 0
etc
You can set the boundaries using the min and max functions.
Here is the concept:
We have a pygame object that moves in all four directions; lets say the user holds down the LEFT arrow key, so that the object reaches the top of the screen. The y-coordinate of the top of the screen will always be 0, so we want the object to come to a stop at y-coordinate 0.
This may seem as simple as:
if char.rect.y > 0:
char.rect.y -= char.speed
But this will result in a bug ig char.speed is greater than 1. Like when the object is at y-coordinate 5,
and its speed is 10; the condition still allows for one more step for the object, resulting in the object
coming 5 pixels out of the pygame window. What we want to do is more like:
if char.rect.y > 0:
char.rect.y -= char.speed
if char.rect.y < 0:
char.rect.y = 0
to push the object back into the boundaries. The above block of code can be simplified with the max function:
self.rect.y = max([self.rect.y - self.speed, 0])
For the object moving down:
if char.rect.y < HEIGHT - char.height:
char.rect.y += char.speed
if char.rect.y > HEIGHT - char.height:
char.rect.y = HEIGHT - char.height
or, the more efficient and clean method:
self.rect.y = min([self.rect.y + self.speed, HEIGHT - self.height])
For going left and right, simply replace the ys and height (and HEIGHT) from two lines above with xs and widths (and WIDTH).
All together:
import pygame
pygame.init()
WIDTH = 600
HEIGHT = 600
wn = pygame.display.set_mode((WIDTH, HEIGHT))
class Player:
def __init__(self):
self.speed = 1
self.width = 20
self.height = 20
self.color = (255, 255, 0)
self.rect = pygame.Rect((WIDTH - self.width) / 2, (HEIGHT - self.height) / 2, 20, 20)
def up(self):
self.rect.y = max([self.rect.y - self.speed, 0])
def down(self):
self.rect.y = min([self.rect.y + self.speed, HEIGHT - self.height])
def left(self):
self.rect.x = max([self.rect.x - self.speed, 0])
def right(self):
self.rect.x = min([self.rect.x + self.speed, WIDTH - self.width])
def draw(self):
pygame.draw.rect(wn, self.color, self.rect)
char = Player()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
char.up()
if keys[pygame.K_DOWN]:
char.down()
if keys[pygame.K_LEFT]:
char.left()
if keys[pygame.K_RIGHT]:
char.right()
wn.fill((0, 0, 0))
char.draw()
pygame.display.update()
Good luck!