1

So Ive been at this one problem for more than a week now and i feel like Ive tried everything. Nothing works, Ive looked it up, but at the same time I don't want to just copy code i would like to actually understand it.

    def x_collision(self):
        for tile in tiles:
            self.rect = pygame.Rect(self.x, self.y, self.size, self.size)
            if tile.colliderect(self.rect):
                if self.x_vel > 0:
                    self.x = tile.right
                if self.x_vel < 0:
                    self.x = tile.left - self.size
                
    def y_collision(self):
        for tile in tiles:
            self.rect = pygame.Rect(self.x, self.y, self.size, self.size)
            if tile.colliderect(self.rect):
                if self.y_vel > 0:
                    self.y = tile.bottom
                if self.y_vel < 0:
                    self.y = tile.top

This is just the two main functions for the collision located inside the player class.

Ive gotten the collisions to work on each axis but when i merge the two together it just goes insane, I'm guessing this has something to do with the position of the player being set in the wrong place but that shouldn't be the problem considering im not checking for the collision in one function but instead in two different for each the x and y.

Just, it's probably because of some stupid reason and it shouldn't be that hard if you're not dumb like me but i just can't seem to figure it out

Also if you're testing the code just delete everything that has something to do with sound!

Here is the entire code for reference (i know it's messy but im very new to this so good luck!)

import pygame
import random
import math
import time

# Initialize Pygame
pygame.init()
pygame.mixer.init()

# Set the size of the window
size = (900, 600)
screen = pygame.display.set_mode(size)

# Set the title of the window
pygame.display.set_caption("Classes testing")

clock = pygame.time.Clock()
fps = 60

pygame.mixer.music.load('PewPewProject/Retro Platform.wav')
pygame.mixer.music.set_volume(0.1)
pygame.mixer.music.play(-1)

pop_sound = pygame.mixer.Sound("PewPewProject/vine-boom.wav")
pop_sound.set_volume(0.5)

level = [
    ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
    ['1','E','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','E','0','0','0','1'],
    ['1','0','0','0','1','1','1','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','1','0','1','0','0','0','0','0','0','0','0','E','0','0','0','0','1'],
    ['1','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','E','1','1','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','E','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','1','1','1','0','1','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','1','0','0','0','1','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','1','0','1','1','1','0','E','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','1','0','1','S','1','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','1','0','0','0','1','0','0','0','0','0','1'],
    ['1','0','0','E','0','0','0','0','0','1','1','1','1','1','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1'],
    ['1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'],
    ]


tilex, tiley = [0, 0]
tilex_offset, tiley_offset = [0, 0]
tile_size = 50
tilemap = pygame.image.load('PewPewProject/tilemap.png')
tiles = []
collision_tiles = []
enemy_spawns = []


def build_level():
    for tiley, rows in enumerate(level):
        for tilex, tile in enumerate(rows):
            if tile == '1':
                tile_rect = pygame.Rect(tilex*tile_size+tilex_offset, tiley*tile_size+tiley_offset, tile_size, tile_size)  
                tiles.append(tile_rect)
            elif tile == '0':
                pass
            elif tile == 'E':
                enemy_spawns.append([tilex, tiley])
            elif tile == 'S':
                pass
            elif tile == 'R':
                pass
            else:
                print("Wrong Map Input")

def rebuild_level():
    global tiles, enemy_spawns
    tiles = []
    enemy_spawns = []
    build_level()


def draw_level():
    for tiley, rows in enumerate(level):
        for tilex, tile in enumerate(rows):
            color = None
            if tile == '1':
                color = (100, 100, 100)
            elif tile == 'S':
                color = (50, 255, 100)
            elif tile == 'R':
                color = (255, 50, 50)
            if color:
                pygame.draw.rect(screen, color, (tilex*tile_size+tilex_offset, tiley*tile_size+tiley_offset, tile_size, tile_size))

def random_except(start, end, exception_start, exception_end):
    num = random.randint(start, end)
    while num >= exception_start and num <= exception_end:
        num = random.randint(start, end)
    return num

class Player:
    def __init__(self, x, y):
        global projectiles
        self.speed = 5
        self.x = x
        self.y = y
        self.x_vel = 0
        self.y_vel = 0
        self.px_vel = 0
        self.py_vel = 0
        self.size = tile_size
        self.gunsurface = pygame.Surface((90, 25), pygame.SRCALPHA)
        self.healthboost = 1
        self.health = 100 * 1
        self.rotated_gunsurface = self.gunsurface
        self.gunsurface.fill((150, 150, 150))
        self.gunrect = self.gunsurface.get_rect()
        projectiles = [Projectile(-100, 0, 0)]
        self.last_shot_time = 0
        self.cooldown = 0.5
        self.is_slowed = False
        dx = 0
        dy = 0
        self.angle = math.atan2(dy, dx)
        self.force = 72
        self.forceCounterCuzIAmBadAtPython = self.force
        self.rect = pygame.Rect(self.x, self.y, self.size, self.size)

        self.alive = True
        

        self.colliding = False
    

    def x_collision(self):
        for tile in tiles:
            self.rect = pygame.Rect(self.x, self.y, self.size, self.size)
            if tile.colliderect(self.rect):
                if self.x_vel > 0:
                    self.x = tile.right
                if self.x_vel < 0:
                    self.x = tile.left - self.size
                
    
    def y_collision(self):
        for tile in tiles:
            self.rect = pygame.Rect(self.x, self.y, self.size, self.size)
            if tile.colliderect(self.rect):
                if self.y_vel > 0:
                    self.y = tile.bottom
                if self.y_vel < 0:
                    self.y = tile.top
                    


    def Movement(self):
        global tiley_offset, tilex_offset
        self.keys = pygame.key.get_pressed()


        tilex_offset += self.x_vel
        self.x_collision()
        if self.x_vel != 0:
            self.x_vel -= self.px_vel
            self.forceCounterCuzIAmBadAtPython -= 1
            if self.forceCounterCuzIAmBadAtPython <= 0:
                self.x_vel = 0

        
        tiley_offset += self.y_vel
        self.y_collision()
        if self.y_vel != 0:
            self.y_vel -= self.py_vel
            if self.forceCounterCuzIAmBadAtPython <= 0:
                self.y_vel = 0
        
        rebuild_level()
    


    def Alive(self):
        if self.health <= 0:
            self.alive = False



    def GUI(self):
        self.empty_health_bar = pygame.draw.rect(screen, (200, 20, 20), (screen.get_width()/4, 10,466, 25))
        self.health_bar = pygame.draw.rect(screen, (20, 200, 20), (screen.get_width()/4, 10, self.health*4.66/self.healthboost, 25))
        pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4, 10),(screen.get_width()/4+466, 10), 2)
        pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4, 35),(screen.get_width()/4+466, 35), 2)
        pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4, 10), (screen.get_width()/4, 35), 2)
        pygame.draw.line(screen, (0, 0, 0), (screen.get_width()/4+466, 10), (screen.get_width()/4+466, 35), 2)


    def Gun(self):
        cursor_x, cursor_y = pygame.mouse.get_pos()
        dx = cursor_x - (self.x + self.size)
        dy = cursor_y - (self.y + self.size)
        angle = math.atan2(dy, dx)
        self.rotated_gunsurface = pygame.transform.rotate(self.gunsurface, math.degrees(angle * -1))
        self.gunrect = self.rotated_gunsurface.get_rect(center = (self.x+self.size/2, self.y+self.size/2))
        screen.blit(self.rotated_gunsurface, (self.gunrect.x, self.gunrect.y))



    def Shoot(self):
        global dx, dy
        if pygame.key.get_pressed()[pygame.K_e]:
            current_time = time.time()
            if current_time - self.last_shot_time > self.cooldown:
                self.forceCounterCuzIAmBadAtPython = self.force
                pop_sound.play()
                cursor_x, cursor_y = pygame.mouse.get_pos()
                dx = cursor_x - (self.x + self.size/2)
                dy = cursor_y - (self.y + self.size/2)
                self.angle = math.atan2(dy, dx)
                projectiles.append(Projectile(self.x+self.size/2, self.y+self.size/2, self.angle))
                self.last_shot_time = current_time
                self.x_vel = math.cos(self.angle) * self.speed
                self.y_vel = math.sin(self.angle) * self.speed
                self.px_vel = self.x_vel / self.force
                self.py_vel = self.y_vel / self.force

    

        
    def Render(self):
        self.rect = pygame.Rect(self.x, self.y, self.size, self.size)
        pygame.draw.rect(screen, (230, 100, 100), self.rect)
        self.Gun()




class Projectile:
    def __init__(self, x, y, angle):
        self.x = x
        self.y = y
        self.angle = angle
        self.speed = 8
        self.hitbox = pygame.Rect(self.x, self.y, 5,5)

    
    def Move(self):
        self.x += math.cos(self.angle) * self.speed
        self.y += math.sin(self.angle) * self.speed   
        

    def Render(self):
        self.hitbox = pygame.draw.circle(screen, (255, 255, 0), (int(self.x), int(self.y)), 7)

class Enemy:
    def __init__(self, health, main_speed, tag, size, player, x, y):
        self.health = health
        #self.main_speed = 3
        self.tag = tag
        self.size = size
        self.player = player
        self.speed = 3

        self.x = x
        self.y = y

        self.alive = True

    def Destroy(self):
        self.alive = False
    
    def Spawning(self):
        self.hitbox = pygame.draw.rect(screen, (100, 240, 100), (self.x + tilex_offset, self.y + tiley_offset, self.size, self.size))

    def Movement(self):
        dx = self.player.x - self.x
        dy = self.player.y - self.y
        angle = math.atan2(dy - tiley_offset, dx - tilex_offset)

        self.x += self.speed * math.cos(angle)
        self.y += self.speed * math.sin(angle)
        
    
projectiles = [Projectile(-100, 0, 0)]
def main():
    player = Player(screen.get_width()/2-tile_size/2, screen.get_height()/2-tile_size/2)

    enemies = []
    def Spawn_enemies(num_enemies, player):
        for i in range(num_enemies):
            x, y = random.choice(enemy_spawns)
            enemy = Enemy(1, 1, i, 25, player, x*tile_size, y*tile_size)
            enemies.append(enemy)


    build_level()
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
        # Main Loop
        screen.fill((100, 100, 200))

        # usage 
        spawn_enemies_chance = random.randint(0, 250)
        number_of_enemies = len(enemies)
        if spawn_enemies_chance == 1 and number_of_enemies <= 4:
            Spawn_enemies(1,player)
        draw_level()
        
        # enemy
        for enemy in enemies:
            if enemy.alive:
                enemy.Movement()
                enemy.Spawning()

                for projectile in projectiles:
                    if enemy.hitbox.colliderect(projectile.hitbox):
                        enemy.health -= 1
                        pop_sound.play()
                        if enemy.health <= 0:
                            try:
                                enemy.alive = False
                                enemies.remove(enemy)
                            except:
                                print("list.remove(x): x not in list... Enemy moment")
                        projectiles.remove(projectile)



        # Get Hurt
        for enemy in enemies:
            if enemy.hitbox.colliderect(player):
                player.health -= 10
                enemies.remove(enemy)
                    
        
        
        # Projectiles
        for i, projectile in enumerate(projectiles):
            projectile.Move()        
            projectile.Render()
            if projectiles != []:
                if projectile.x < 0 or projectile.x > screen.get_width() or projectile.y < 0 or projectile.y > screen.get_height():
                    projectiles.pop(i)
            for tile in tiles:
                if projectiles != []:
                    if tile.colliderect(projectile.hitbox):
                        try:
                            projectiles.pop(i)
                        except:
                            print(i," pop index out of range, don't mind it :)")

        # player
        player.Alive()
        player.Shoot()
        player.Movement()
        player.Render()

        # Renders the UI ontop of everything
        player.GUI()
        

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

    pygame.quit()

# DO NOT DISTURB!
if __name__ == "__main__":
    main()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Xseis
  • 65
  • 4
  • 1
    *" if you're testing the code just delete everything that has something to do with sound!"* - No. You have to provide a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). – Rabbid76 Feb 03 '23 at 19:08

0 Answers0