Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
pygame setting borders?
#1
# I am having trouble with the borders around the castle walls?
import pygame

pygame.init() #Initialize

#==============================INITIALIZING==============================

screen = pygame.display.set_mode((600,500)) # (x, y)

#=============================== (R,G,B) ================================

red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
black = (0,0,0)
white = (255,255,255)
yellow = (255,255,0)
grey = (128,128,128)

x = 290
y = 400
width = 20
height = 20
vel = 10




 
# ========================================Game Loop=============================
while True:
    pygame.time.delay(100)
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
        
        

    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

# player stops at the sidewalls and top and bottom walls
    if x <= 30:
        x = 30
    if x >= 550:
        x = 550
    if y <= 31:
        y = 31
    if x <= 250 and y >= 450:
        y = 450
    if x >= 350 and y >= 450:
        y = 450

# player stops at castle walls

    if x >= 140 and y <= 260:
        x = 140
    
    
    
            




    screen.fill(grey)
    pygame.draw.rect(screen,yellow,[0,0,30,500])
    pygame.draw.rect(screen,yellow,[570,0,30,500])
    pygame.draw.rect(screen,yellow,[0,470,250,30])
    pygame.draw.rect(screen,yellow,[350,470,250,30])
    pygame.draw.rect(screen,yellow,[0,0,200,30])
    pygame.draw.rect(screen,yellow,[400,0,200,30])
    pygame.draw.rect(screen,yellow,[210,0,10,30])
    pygame.draw.rect(screen,yellow,[230,0,10,30])
    pygame.draw.rect(screen,yellow,[250,0,10,30])
    pygame.draw.rect(screen,yellow,[380,0,10,30])
    pygame.draw.rect(screen,yellow,[360,0,10,30])
    pygame.draw.rect(screen,yellow,[340,0,10,30])
    pygame.draw.rect(screen,yellow,[160,30,100,200])
    pygame.draw.rect(screen,yellow,[340,30,100,240])
    pygame.draw.rect(screen,yellow,[160,130,200,140])
    pygame.draw.rect(screen,yellow,[180,130,100,240])
    pygame.draw.rect(screen,yellow,[320,130,100,240])
    pygame.draw.rect(screen,yellow,[x,y,20,20])

    pygame.display.update()
Reply
#2
Line 68 is giving you trouble. If you want to go this route you'll need to make this a lot more complex.

if x >= 140 and x <= 340 and y <= 260 and y >= ?????..... etc, etc
basically, outer boundaries are easy to do this way because you only come at them from one side. The way you are doing it, you'll basically have to write big ifs for every side of every object.

The real solution to the problem is to use the pygame sprite class for your player and walls. Then it is easy to see if they hit and to stop your player from moving.

Here is a tutorial for pygame:
https://www.youtube.com/watch?v=3UxnelT9...5EMxUWPm2i

Here is a simpler one that used the Turtle module.
https://www.youtube.com/watch?v=inocKE13...q9RzORkQWP

Both these will show you how to draw your map with a .txt file, which you will find a lot better and easy to modify. Moreover, if you want enemies in your game or shooting, your will have a hell of at time without using some of these other tools.
Reply
#3
1. Need to learn rects. This will do a lot of the work for you.
2. Vector2 will keep your floats and handle different math for you.
3. pygame has over 400 builtin colors.
4. Use pygame.time.Clock over pygame.time.delay. This will lead to smoother movement and constant movement
5. Use delta from pygame.time.Clock to move player smoothly. delta = clock.tick(fps)

Example how I would do it.
import pygame

class Player:
    def __init__(self, rect, color):
        # Player position
        self.rect = pygame.Rect(rect)
        # Hold floats since rects are only ints
        self.center = pygame.Vector2(self.rect.center)
        self.vel = 10 * 0.01
        self.color = color

    def collision(self, walls):
        collided = []
        for wall_rect in walls:
            if wall_rect.colliderect(self.rect):
                collided.append(wall_rect)

        if len(collided) > 0:
            # Keep smooth movement
            center = self.center - pygame.Vector2(int(self.center.x), int(self.center.y))
            for wall_rect in collided:
                # Get what over lapping
                clip_rect = self.rect.clip(wall_rect)
                # Check if wall is still overlapping.
                # Needed if collided with more than one wall.
                # Else player would start jumping up and down the walls
                if clip_rect.w > 0 or clip_rect.h > 0:
                    # Take the smallest overlap and move player over
                    if clip_rect.w < clip_rect.h:
                        center.x = 0
                        if self.rect.centerx < wall_rect.centerx:
                            self.rect.right = wall_rect.left
                        else:
                            self.rect.left = wall_rect.right
                    else:
                        center.y = 0
                        if self.rect.centery < wall_rect.centery:
                            self.rect.bottom = wall_rect.top
                        else:
                            self.rect.top = wall_rect.bottom

            self.center = pygame.Vector2(self.rect.center) + center

    def move(self, direction, delta, walls):
        self.center += direction * delta * self.vel
        self.rect.center = self.center
        self.collision(walls)

    def draw(self, surface):
        surface.fill(self.color, self.rect)

def main():
    pygame.init()
    # Basic pygame setup
    pygame.display.set_caption("Example")
    main_surface = pygame.display.set_mode((600,500))
    rect = main_surface.get_rect()
    clock = pygame.time.Clock()
    delta = 0
    fps = 60

    # Game varaibles
    player = Player((290, 400, 20, 20), pygame.Color("yellow"))
    walls = [pygame.Rect(0, 0, 30, 500),
             pygame.Rect(570, 0, 30, 500),
             pygame.Rect(0, 470, 250, 30),
             pygame.Rect(350, 470, 250, 30),
             pygame.Rect(0, 0, 200, 30),
             pygame.Rect(400, 0, 200, 30),
             pygame.Rect(210, 0, 10, 30),
             pygame.Rect(230, 0, 10, 30),
             pygame.Rect(250, 0, 10, 30),
             pygame.Rect(380, 0, 10, 30),
             pygame.Rect(360, 0, 10, 30),
             pygame.Rect(340, 0, 10, 30),
             pygame.Rect(160, 30, 100, 200),
             pygame.Rect(340, 30, 100, 240),
             pygame.Rect(160, 130, 200, 140),
             pygame.Rect(180, 130, 100, 240),
             pygame.Rect(320, 130, 100, 240)]

    # Create a map surface 
    map_surface = pygame.Surface(rect.size)
    map_surface.fill(pygame.Color('gray50'))
    for rect in walls:
        map_surface.fill(pygame.Color("yellow"), rect)

    # Main loop
    running = True
    while running:
        # Event loop

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        keys = pygame.key.get_pressed()
        direction = pygame.Vector2(0, 0)
        if keys[pygame.K_LEFT]:
            direction.x -= 1

        if keys[pygame.K_RIGHT]:
            direction.x += 1

        if keys[pygame.K_UP]:
            direction.y -= 1

        if keys[pygame.K_DOWN]:
            direction.y += 1

        if direction != pygame.Vector2(0, 0):
            # Normalize for player is moving in a circle instead of a square.
            direction.normalize_ip()
            player.move(direction, delta, walls)

        main_surface.blit(map_surface, (0, 0))
        player.draw(main_surface)

        pygame.display.update()
        # Idle. delta is time between frames in milliseconds.
        delta = clock.tick(fps)

main()

Less error prone way is just return player back to old position.

class Player:
    def __init__(self, rect, color):
        # Player position
        self.rect = pygame.Rect(rect)
        # Hold floats since rects are only ints
        self.center = pygame.Vector2(self.rect.center)
        self.vel = 10 * 0.01
        self.color = color

    def collision(self, rect, walls):
        for wall_rect in walls:
            if wall_rect.colliderect(rect):
                return True
        return False

    def move(self, direction, delta, walls):
        center = self.center + direction * delta * self.vel
        rect = self.rect.copy()
        rect.center = center
        if not self.collision(rect, walls):
            self.center = center
            self.rect.center = center

    def draw(self, surface):
        surface.fill(self.color, self.rect)
99 percent of computer problems exists between chair and keyboard.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyGame] Error setting up pygame wazee 10 13,286 Jun-14-2018, 11:19 PM
Last Post: wazee

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020