1

As of now, my code will render the tilemap and the background. It will also render the player and will show its walking animations depending on what you press for the keys. If you hit a spike tile, you will get teleported back to the starting point. But thats it, the rest of the tiles do not have any physics/ground. My player will walk through the blocks and basically is just floating the whole time. I tried several different tutorials on youtube and some online sources but I couldn't find one that made any sense or was applicable to my code. I am also fairly new to pygame so what do you guys think I can/should do to incorporate some tile physics in my code? Here is a different method I tried to get there to be some form of a wall:

if key_press[pygame.K_LEFT] and player.x>player.velocity:
        if pygame.Rect.colliderect(player.rect, grasscliffleft1):
            player.x += 0
        else:
            player.left = True
            player.x-=player.velocity
            player.right=False
            player.left=True

Here is my main code:

   import pygame
    pygame.init()
        
    pygame.mixer.music.load('music.mp3')
    pygame.mixer.music.play(-1)
    
    window=pygame.display.set_mode((1200,800))
    background=pygame.image.load('background.png')
    background=pygame.transform.scale(background,(1200,800))
    
    #This loads the images for the walking right animation
    walk_right=[pygame.image.load('Right/Right (1).png'), pygame.image.load('Right/Right (2).png'),
    pygame.image.load('Right/Right (3).png'),pygame.image.load('Right/Right (4).png'),pygame.image.load('Right/Right (5).png'),
    pygame.image.load('Right/Right (6).png'),pygame.image.load('Right/Right (7).png'),pygame.image.load('Right/Right (8).png'),
    pygame.image.load('Right/Right (9).png'),pygame.image.load('Right/Right (10).png'),pygame.image.load('Right/Right (11).png'),
    pygame.image.load('Right/Right (12).png'),pygame.image.load('Right/Right (13).png'),pygame.image.load('Right/Right (14).png'),
    pygame.image.load('Right/Right (15).png')]
    #This loads the images for the walking left animation
    walk_left=[pygame.image.load('Left/Left (1).png'), pygame.image.load('Left/Left (2).png'),
    pygame.image.load('Left/Left (3).png'),pygame.image.load('Left/Left (4).png'),pygame.image.load('Left/Left (5).png'),
    pygame.image.load('Left/Left (6).png'),pygame.image.load('Left/Left (7).png'),pygame.image.load('Left/Left (8).png'),
    pygame.image.load('Left/Left (9).png'),pygame.image.load('Left/Left (10).png'),pygame.image.load('Left/Left (11).png'),
    pygame.image.load('Left/Left (12).png'),pygame.image.load('Left/Left (13).png'),pygame.image.load('Left/Left (14).png'),
    pygame.image.load('Left/Left (15).png')]
    
    idle=pygame.image.load('idle.png')
    
    fps=pygame.time.Clock()
    
    #This class saves information for the player such as their x,y,velocity 
    class Player(object):
        def __init__(self,x,y):
            self.velocity=4
            self.x = x
            self.y = y
            self.jumping=False
            self.right=False
            self.left=False
            self.jumptotal=10
            self.walkcount=0
            self.player_hitbox=(self.x+1,self.y,60,60)
        #This will be used to create the player walking animations
        def draw(self,window):
            if player.walkcount + 1 > 45:
                player.walkcount = 0
            if player.right:
                window.blit(walk_right[player.walkcount // 3], (player.x, player.y))
                player.walkcount += 1
            elif player.left:
                window.blit(walk_left[player.walkcount // 3], (player.x - 50, player.y))
                player.walkcount += 1
            else:
                window.blit(idle, (player.x, player.y))
        #This displays the players hitbox that will be used for collisions with the tiles
        def hitbox(self,window):
            self.player_hitbox = (self.x, self.y, 47, 83)
            self.rect=pygame.draw.rect(window,(255,255,255),self.player_hitbox,2)
    
    
    
    running=True
    
    player=Player(20,600)
    coin_visible=True
    #This draws the background, the player
    def draw_game():
        global player
        window.blit(background, (0, 0))
        player.draw(window)
        player.hitbox(window)
    
    #This will render and display the tiles onto the screen. It also gets each individual rect information and stores them in a list(incase I can use the list for something?)
    def draw_tiles():
        global dirt1
        global dirtdown1
        global grasscliffleft1
        global grasscliffright1
        global grasscliffmid1
        global grass1
        global coin1
        global spikerright1
        global spike_down1
        global spike_left1
        global spikeup1   
        global tile_list
        tile_list=[]
        y = 0
        for row in game_map:
            x = 0
            for tile in row:
                if tile == '1':
                    window.blit(dirt, (x * tile_size, y * tile_size))
                    dirt1=dirt.get_rect(topleft=(x * tile_size, y * tile_size))
                    tile=(dirt,dirt1)
                    tile_list.append(tile)
                elif tile == '2':
                    window.blit(dirtdown, (x * tile_size, y * tile_size))
                    dirtdown1=dirtdown.get_rect(topleft=(x * tile_size, y * tile_size))
                    tile = (dirtdown,dirtdown1)
                    tile_list.append(tile)
                elif tile == '3':
                    window.blit(grasscliffleft, (x * tile_size, y * tile_size))
                    grasscliffleft1=grasscliffleft.get_rect(topleft=(x * tile_size, y * tile_size))
                    tile = (grasscliffleft,grasscliffleft)
                    tile_list.append(tile)
                elif tile == '4':
                    window.blit(grasscliffright, (x * tile_size, y * tile_size))
                    grasscliffright1 = grasscliffright.get_rect(topleft=(x * tile_size, y * tile_size))
                    tile = (grasscliffright,grasscliffright1)
                    tile_list.append(tile)
                elif tile == '5':
                    window.blit(grasscliffmid, (x * tile_size, y * tile_size))
                    grasscliffmid1=grasscliffmid.get_rect(topleft=(x * tile_size, y * tile_size))
                    tile = (grasscliffmid,grasscliffmid1)
                    tile_list.append(tile)
                elif tile == '6':
                    window.blit(grass, (x * tile_size, y * tile_size))
                    grass1 =grass.get_rect(topleft=(x * tile_size, y * tile_size))
                    tile = (grass,grass1)
                    tile_list.append(tile)
                elif tile == '7':
                    if coin_visible:
                        window.blit(coin, (x * tile_size, y * tile_size))
                    coin1=coin.get_rect(topleft=(x * tile_size, y * tile_size))
                    tile = (coin,coin1)
                    tile_list.append(tile)
                elif tile == '8':
                    window.blit(spikerright, (x * tile_size, y * tile_size))
                    spikerright1=spikerright.get_rect(topleft=(x * tile_size, y * tile_size))
                    tile = (spikerright,spikerright1)
                    tile_list.append(tile)
                elif tile == '9':
                    window.blit(spike_down, (x * tile_size, y * tile_size))
                    spike_down1=spike_down.get_rect(topleft=(x * tile_size, y * tile_size))
                    tile = (spike_down,spike_down1)
                    tile_list.append(tile)
                elif tile == '10':
                    window.blit(spike_left, (x * tile_size, y * tile_size))
                    spike_left1=spike_left.get_rect(topleft=(x * tile_size, y * tile_size))
                    tile = (spike_left,spike_left1)
                    tile_list.append(tile)
                elif tile == '11':
                    window.blit(spikeup, (x * tile_size, y * tile_size))
                    spikeup1=spikeup.get_rect(topleft=(x * tile_size, y * tile_size))
                    tile = (spikeup,spikeup1)
                    tile_list.append(tile)
                x += 1
            y += 1
    #This will be used to detect collisions and create an impact. This is what isnt working. The only tiles that have any form of a physics are the spikes, when I hit the spikes, the player gets sent back to the starting point
    def collision():
        global dirt1
        global dirtdown1
        global grasscliffleft1
        global grasscliffright1
        global grasscliffmid1
        global grass1
        global coin1
        global spikerright1
        global spike_down1
        global spike_left1
        global spikeup1
        global tile_list
    
        if pygame.Rect.colliderect(player.rect,dirt1):
            player.x=dirt1.left-player.rect.left
        elif pygame.Rect.colliderect(player.rect,dirtdown1):
            player.rect.left=dirtdown1.right
        elif pygame.Rect.colliderect(player.rect, grasscliffleft1):
            player.rect.right=grasscliffleft1.left
            player.rect.top=grasscliffleft1.bottom
            player.rect.bottom=grasscliffleft1.top
        elif pygame.Rect.colliderect(player.rect, grasscliffright1):
            player.rect.left = grasscliffright1.right
            player.rect.top = grasscliffright1.bottom
            player.rect.bottom = grasscliffright1.top
        elif pygame.Rect.colliderect(player.rect, grasscliffmid1):
            player.rect.top = grasscliffmid1.bottom
            player.rect.bottom = grasscliffmid1.top
        elif pygame.Rect.colliderect(player.rect, grass1):
            player.rect.top=grass1.bottom
            player.rect.bottom = grass1.top
            player.rect.right = grass1.left
            player.rect.left = grass1.right
        elif pygame.Rect.colliderect(player.rect, coin1):
            coin_visible=False
        elif pygame.Rect.colliderect(player.rect, spikerright1):
            player.jumping=False
            player.jumptotal = 10
            player.x=20
            player.y=600
        elif pygame.Rect.colliderect(player.rect, spike_down1):
            player.jumping = False
            player.jumptotal = 10
            player.x=20
            player.y=600
        elif pygame.Rect.colliderect(player.rect, spike_left1):
            player.jumping = False
            player.jumptotal = 10
            player.x=20
            player.y=600
        elif pygame.Rect.colliderect(player.rect, spikeup1):
            player.jumping = False
            player.jumptotal = 10
            player.x=20
            player.y=600
    
    
    
    #We are loading all of the tile images and resizing them
    dirt=pygame.image.load('Tiles/Dirt.png')  # 1
    dirt=pygame.transform.scale(dirt,(40,40))
    
    dirtdown = pygame.image.load('Tiles/DirtDown.png')  # 2
    dirtdown=pygame.transform.scale(dirtdown,(40,40))
    
    grasscliffleft = pygame.image.load('Tiles/GrassCliffLeft.png')  # 3
    grasscliffleft=pygame.transform.scale(grasscliffleft,(40,40))
    
    grasscliffright = pygame.image.load('Tiles/GrassCliffMid.png')  # 4
    grasscliffright=pygame.transform.scale(grasscliffright,(40,40))
    
    grasscliffmid = pygame.image.load('Tiles/GrassCliffRight.png')  # 5
    grasscliffmid=pygame.transform.scale(grasscliffmid,(40,40))
    
    grass = pygame.image.load('Tiles/GrassJoinHillLeft.png')  # 6
    grass=pygame.transform.scale(grass,(40,40))
    
    coin = pygame.image.load('Tiles/image 1.png')  # 7
    coin=pygame.transform.scale(coin,(40,40))
    
    spike_left = pygame.image.load('Tiles/Spike_Left&down.png')  # 8
    spike_left=pygame.transform.scale(spike_left,(40,40))
    
    spikerright=pygame.transform.flip(spike_left,True,False)# 10
    spikerright=pygame.transform.scale(spikerright,(40,40))
    
    spike_down = pygame.image.load('Tiles/Spike_Down.png')  # 9
    spike_down=pygame.transform.scale(spike_down,(40,40))
    
    spikeup = pygame.image.load('Tiles/spikeup.png')  #  11
    spikeup=pygame.transform.scale(spikeup,(40,40))
    
    #This is the tilemap used to determine which tile is displayed where on the screen
    game_map=[['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
              ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','7','0','0','0'],
              ['0','0','0','0','0','0','0','0','3','5','4','0','0','0','0','7','0','0','0','0','6','0','8','6','0','8','4','5','0','0'],
              ['0','0','7','0','0','0','0','0','9','0','0','0','0','0','3','5','4','0','0','0','0','0','0','0','0','0','0','0','0','0'],
              ['6','6','6','6','6','6','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
              ['2','2','2','2','2','2','10','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
              ['0','0','0','0','0','0','0','6','0','0','0','0','0','0','0','0','0','0','0','0','7','0','0','0','0','0','0','0','0','0'],
              ['0','0','0','0','0','0','0','9','0','3','5','5','4','0','0','8','6','0','0','8','6','0','0','0','0','0','0','0','0','0'],
              ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','7','0','0','0','0','0'],
              ['0','0','0','0','0','0','7','0','0','0','0','0','0','0','0','0','0','0','7','0','0','0','0','3','5','4','0','0','0','0'],
              ['0','0','0','0','0','3','5','5','4','0','0','0','0','0','0','0','0','0','6','0','0','6','0','0','0','0','0','0','0','0'],
              ['0','0','0','0','0','0','0','0','0','0','6','0','0','0','11','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
              ['0','0','0','0','0','0','0','0','0','0','0','0','3','5','5','4','0','0','0','0','0','0','0','0','0','7','0','0','0','0'],
              ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','9','0','0','0','7','11','0','0','0','8','3','5','4','0','0','0'],
              ['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','3','5','5','5','0','0','0','0','0','0','0','0','0'],
              ['0','0','0','0','0','0','0','0','7','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
              ['0','0','0','0','0','0','0','3','5','4','0','0','0','3','5','4','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
              ['6','6','6','6','6','6','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','6','6','6','6','6','6','6'],
              ['1','1','1','1','1','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1','1','1','1','1','1','1'],
              ['2','2','2','2','2','2','11','11','11','11','11','11','11','11','11','11','11','11','11','11','11','11','11','2','2','2','2','2','2','2']]
    
    #This is the main loop that is being ran. 
    tile_size=dirt.get_width()
    while running:
        fps.tick(45)
        draw_game()
    
        draw_tiles()
    
        collision()
    
        for event in pygame.event.get():
          if event.type==pygame.QUIT:
            running=False
        #Moves the player in the designated direction depending on the key press
        key_press=pygame.key.get_pressed()
        if key_press[pygame.K_LEFT] and player.x>player.velocity:
            player.x-=player.velocity
            player.right=False
            player.left=True
        elif key_press[pygame.K_RIGHT] and player.x<2300-player.x-player.velocity:
            player.x+=player.velocity
            player.right = True
            player.left = False
        else:
            player.right=False
            player.left=False
            player.walkcount=0
    
        if key_press[pygame.K_UP]:
           player.jumping=True
        #This is used to make the player jump 
        if not (player.jumping):
            if key_press[pygame.K_UP]:
                player.isJump = True
    
        else:
            if player.jumptotal >= -10:
                neg = 1
                if player.jumptotal < 0:
                    neg = -1
    
                player.y -= (player.jumptotal ** 2) * 0.25 * neg
                player.jumptotal -= 1
            else:
                player.jumping = False
                player.jumptotal = 10
    
        pygame.display.update()
    
    
    pygame.quit()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Amir Yolo
  • 21
  • 2

1 Answers1

0

First of all, player.x = 0 does not set player.x to 0, but it adds 0 to the x-coordinate of player. Change:

player.x += 0

player.x = 0

Anyway I have a few suggestions to restructure the collison detection. Set the velocity depending on the pressed key (also see How can I make a sprite move when key is held down):

key_press = pygame.key.get_pressed()
velocity = (key_press[pygame.K_RIGHT] - key_press[pygame.K_LEFT]) * player.velocity

Change the position of the player depending on the velocity:

player.x += velocity 

Create a list of the bounding rectangles of the obstacles that cause the player to be moved back to the starting position:

spikes = [spike_left1, spikerright1, spike_down1, spikeup1]

Use pygame.Rect.collidelist to determine if the player collides with any of these obstacles and set the player back to the start position in case of a collision.

if player.collidelist(spikes) >= 0:
    player.x = 0
Rabbid76
  • 202,892
  • 27
  • 131
  • 174