0

I'm trying to make this game but whenever I try to implement making the player unable to just phase/walk through blocks it just disables user input. The section I'm talking about has a comment above it.

import pygame, sys
from pygame.math import Vector2

#Block Collisions
#Block Types
#
pygame.init()
tile_size = 16
tile_number = 32
screen = pygame.display.set_mode((tile_size * tile_number, tile_size * tile_number))
clock = pygame.time.Clock()
background = pygame.image.load("background.png").convert_alpha()

class MAIN:
    def __init__(self):
        self.pos = Vector2(0,0)
        self.blocks = []
        self.player = pygame.Rect(int(self.pos.x * tile_size), int(self.pos.y * tile_size), tile_size, tile_size)
        self.movement = True
    
    def draw_player(self):
        self.player = pygame.Rect(int(self.pos.x * tile_size), int(self.pos.y * tile_size), tile_size, tile_size)
        pygame.draw.rect(screen,(255,0,0), self.player)

    def place_block(self):
        mouse_pos = Vector2(pygame.mouse.get_pos()[0]//16,pygame.mouse.get_pos()[1]//16)
        block_rect = pygame.Rect(mouse_pos.x*16, mouse_pos.y*16, tile_size, tile_size)
        self.blocks.append(block_rect)
    
    def break_block(self):
        for block in self.blocks:
            if block.collidepoint(pygame.mouse.get_pos()[0],pygame.mouse.get_pos()[1]):
                self.blocks.remove(block)
                self.check_collisions()
        
    def draw_blocks(self):
        for block in self.blocks:
            pygame.draw.rect(screen,(0,0,0), block)

    def check_collisions(self):
        for block in self.blocks:
            if block.collidepoint(self.player.x,self.player.y):
                self.movement = False
                break
            else:
                self.movement = True
        

game = MAIN()

while True:
    game.check_collisions()
    keys = pygame.key.get_pressed()
    if game.movement == True:
        if keys[pygame.K_d]:
            #how im trying to implement collisions  vvv
            for block in game.blocks:
                if block.collidepoint((game.player.x)+1,game.player.y):
                    game.pos.x += 1
        if keys[pygame.K_a]:
            game.pos.x -= 1
        if keys[pygame.K_w]:
            game.pos.y -= 1
        if keys[pygame.K_s]:
            game.pos.y += 1
    mouse = pygame.mouse.get_pressed()
    if mouse[2]:
        game.place_block()
    if mouse[0]:
        game.break_block()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
       

    screen.blit(background,(0,0))  
    game.draw_blocks()  
    game.draw_player()

    pygame.display.update()
    clock.tick(30)

It looks like your post is mostly code; please add some more details.It looks like your post is mostly code; please add some more details.

1 Answers1

0

The reason why it stops receiving user inputs is because of the following code blocks (disabling the game.movement):

Code block 1:

def check_collisions(self):
    for block in self.blocks:
        if block.collidepoint(self.player.x,self.player.y):
            self.movement = False
            break
        else:
            self.movement = True

Code block 2:

if game.movement == True:
    if keys[pygame.K_d]:
    ...

To answer your concern, let's remove the collision redundancy by commenting out the game.check_collisions() method call and implement as follows:

while True:
    # game.check_collisions()
    keys = pygame.key.get_pressed()
    if game.movement == True:
        if keys[pygame.K_d]:
            has_collision = False
            for block in game.blocks:
                if block.collidepoint((game.player.x + tile_size, game.player.y + tile_size)):
                    has_collision = True
                    break
            if not has_collision:
                game.pos.x += 1

However, the collision implementation is inefficient as you need to redo the same collision checks for every keyboard input. You can implement it like this instead:

while True:
    # game.check_collisions()
    keys = pygame.key.get_pressed()
    if game.movement == True:
        dx, dy = 0, 0
        if keys[pygame.K_d]:
            dx = 1
        if keys[pygame.K_a]:
            dx = -1
        if keys[pygame.K_w]:
            dy = -1
        if keys[pygame.K_s]:
            dy = 1

        for block in game.blocks:
            # check x-collision
            if block.collidepoint((game.player.x + dx * tile_size, game.player.y)):
                dx = 0
            # check y-collision
            if block.collidepoint((game.player.x, game.player.y + dy * tile_size)):
                dy = 0
        game.pos.x += dx
        game.pos.y += dy
Jobo Fernandez
  • 905
  • 4
  • 13