Jim
Jim

Reputation: 25

Adding boundaries in Pygame with movable characters/images

I have been creating a game where an image moves according to player input with Keydown and Keyup methods. I want to add boundaries so that the user cannot move the image/character out of the display (I dont want a game over kind of thing if boundary is hit, just that the image/character wont be able to move past that boundary)

import pygame
pygame.init()#initiate pygame
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
display_width = 1200
display_height = 800
display = pygame.display.set_mode((display_width,display_height))
characterimg_left = pygame.image.load(r'/Users/ye57324/Desktop/Make/coding/python/characterimg_left.png')
characterimg_right = pygame.image.load(r'/Users/ye57324/Desktop/Make/coding/python/characterimg_right.png')
characterimg = characterimg_left
def soldier(x,y):
    display.blit(characterimg, (x,y))
x = (display_width * 0.30)
y = (display_height * 0.2)
pygame.display.set_caption('No U')
clock = pygame.time.Clock()#game clock
flip_right = False
x_change = 0
y_change = 0
bg_x = 0
start = True
bg = pygame.image.load(r'/Users/ye57324/Desktop/Make/coding/python/bg.png').convert()

class player:
    def __init__(self, x, y):
        self.jumping = False

p = player(x, y)
while start:
    for event in pygame.event.get():
        if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
            start = False


        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change += -4
                if flip_right == True:
                    characterimg = characterimg_left
                    flip_right = False
                    x += -150
            elif event.key == pygame.K_RIGHT:
                x_change += 4
                if flip_right == False:
                    characterimg = characterimg_right
                    flip_right = True
                    x += 150
            elif event.key == pygame.K_UP:
                    y_change += -4
            elif event.key == pygame.K_DOWN:
                y_change += 4
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                x_change += 4
            elif event.key == pygame.K_RIGHT:
                x_change += -4
            elif event.key == pygame.K_UP:
                y_change += 4
            elif event.key == pygame.K_DOWN:
                y_change += -4

    x += x_change
    y += y_change
    display.fill(white)
    soldier(x,y)
    pygame.display.update()
    clock.tick(120)#fps
pygame.quit()

I have tried several times including switching to the key pressed method but they all failed. Help please, thank you.

Upvotes: 1

Views: 1299

Answers (2)

skrx
skrx

Reputation: 20438

Just clamp the x and y values between 0 and the display width and height.

# In the main while loop after the movement.
if x < 0:
    x = 0
elif x + image_width > display_width:
    x = display_width - image_width

if y < 0:
    y = 0
elif y + image_height > display_height:
    y = display_height - image_height

I also recommend checking out how pygame.Rects work. You could define a rect with the size of the display,

display_rect = display.get_rect()

and a rect for the character which will be used as the blit position:

rect = characterimg_left.get_rect(center=(x, y))

Then move and clamp the rect in this way:

rect.move_ip((x_change, y_change))
rect.clamp_ip(display_rect)

display.fill(white)
# Blit the image at the `rect.topleft` coordinates.
display.blit(characterimg, rect)

Upvotes: 1

Cribber
Cribber

Reputation: 2913

Basically you want to limit the player's movement.

So everytime you want to "move" the player (I'm guessing this is "x_change" / "y_change") you need to check whether they would still be inside your boundaries after the move.

Example: Your display x boundary is 0 pixels on the left of your screen and 500 to the right. I only allow the actual movement if the result of the movement is within my boundaries.

 boundary_x_lower = 0
 boundary_x_upper = 500

 if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                if boundary_x_lower < (x_change - 4): 
                    # I allow the movement if I'm still above the lower boundary after the move.
                    x_change -= 4
            elif event.key == pygame.K_RIGHT:
                if boundary_x_upper > (x_change +4): 
                     # I allow the movement if I'm still below the upper boundary after the move.
                     x_change += 4

PS: I am confused by your code as you subtract when you move to the right... I am used to 2D games where you increment the player's position if you move to the right... and subtract if you go to the left.

Feel free to adapt the code to fit your project. The basic principle applies also to the y-axis movement: with boundary_y_lower & _y_upper. if you have further questions, just ask!

Upvotes: 1

Related Questions