1

Update:

So I fiddled with the level files and added a new level to go to because I might as well keep going even if my question wasn't answered, and it turns out that the issue wasn't with spawnmethod but with the level tiling code itself. The code won't generate any levels besides the one declared at the start of the script. What's the problem?

Original post:

I'm making a tile-based platformer game. It uses a tiling script to determine what goes where.

for row_index,row in enumerate(layout):
    for col_index,cell in enumerate(row):
        x = col_index * 50
        y = row_index * 50
        if cell == 'G':
            tile = Asphalt((x,y))
            self.tiles.add(tile)
        elif cell == 'c' and spawnmethod == 0:
            player_sprite = Player((x,y))
            self.player.add(player_sprite)
        elif cell == 'l' and spawnmethod == 1:
            player_sprite = Player((x,y))
            self.player.add(player_sprite)
        elif cell == 'r' and spawnmethod == 2:
            player_sprite = Player((x,y))
            self.player.add(player_sprite)

In this game I have 3 spawn points on the map.

level_map = [
'                ',
'                ',
'                ',
'                ',
'                ',
'l              r',
'    G   c       ',
'G   G          G',
'GGGGGGGGGGGGGGGG']

The c spawn point is where the player spawns by default if he didn't get to the level by scrolling. The l and r spawn points are where the player spawns if he gets to the level by scrolling to the left or right, respectively. This is the code that determines that:

def scroll(self):
    if self.rect.x < -50:
        exec(open(leveltotheleft).read())
        level = Level(level_map,screen)
        spawnmethod = 2
        Level.setup_level(Level,level_map)
    elif self.rect.x > 800:
        exec(open(leveltotheright).read())
        level = Level(level_map,screen)
        spawnmethod = 1
        Level.setup_level(Level,level_map)

My problem is that when the player does scroll to the left or right, he still spawns in the c spawn point. If you need the full script, well here it is:

#import modules
import pygame, os
spawnmethod = 0
exec(open('levels/world1spawn.py').read())

#definitions
def import_folder(path):
    surface_list = []
    
    for _,__,img_files in os.walk(path):
        for image in img_files:
            full_path = path + '/' + image
            image_surf = pygame.image.load(full_path).convert_alpha()
            surface_list.append(image_surf)
    return surface_list

#classes
class Asphalt(pygame.sprite.Sprite):
    def __init__(self,pos):
        super().__init__()
        self.image = pygame.image.load('asphalt.png')
        self.rect = self.image.get_rect(topleft = pos)

class Player(pygame.sprite.Sprite):
    def __init__(self,pos):
        super().__init__()
        self.import_character_assets()
        self.frame_index = 0
        self.animation_speed = 0.25
        self.image = self.animations['idle'][self.frame_index]
        self.rect = self.image.get_rect(topleft = pos)
        
        self.direction = pygame.math.Vector2(0,0)
        self.speed = 8
        self.gravity = 0.8
        self.jump_speed = -13
        self.jumped = False
        self.state = 'idle'

    def import_character_assets(self):
        character_path = 'noodle/'
        self.animations = {'idle':[], 'run':[], 'fall':[]}
        
        for animation in self.animations.keys():
            full_path = character_path + animation
            self.animations[animation] = import_folder(full_path)
        
    def animate(self):
        if self.direction.y < 0 or self.direction.y > 1:
            self.jumped = True
            animation = self.animations['fall']
        else:
            if self.direction.x != 0:
                animation = self.animations['run']
            else:
                animation = self.animations['idle']
        self.frame_index += self.animation_speed
        if self.frame_index >= len(animation):
            self.frame_index = 0
        
        self.image = animation[int(self.frame_index)]
    
    def get_input(self):
        keys = pygame.key.get_pressed()
        
        if keys[pygame.K_RIGHT]:
            self.direction.x = 1
        elif keys[pygame.K_LEFT]:
            self.direction.x = -1
        else:
            self.direction.x = 0
        
        if keys[pygame.K_z] and not self.jumped:
            self.jump()
        
    def apply_gravity(self):
        self.direction.y += self.gravity
        self.rect.y += self.direction.y
    
    def jump(self):
        self.direction.y = self.jump_speed
    
    def scroll(self):
        if self.rect.x < -50:
            exec(open(leveltotheleft).read())
            level = Level(level_map,screen)
            spawnmethod = 2
            Level.setup_level(Level,level_map)
        elif self.rect.x > 800:
            exec(open(leveltotheright).read())
            level = Level(level_map,screen)
            spawnmethod = 1
            Level.setup_level(Level,level_map)
    def update(self):
        self.get_input()
        self.animate()
        self.scroll()

class Level:
    def __init__(self,level_data,surface):
        self.display_surface = surface
    def setup_level(self,layout):
        self.tiles = pygame.sprite.Group()
        self.player = pygame.sprite.GroupSingle()
        for row_index,row in enumerate(layout):
            for col_index,cell in enumerate(row):
                x = col_index * 50
                y = row_index * 50
                if cell == 'G':
                    tile = Asphalt((x,y))
                    self.tiles.add(tile)
                elif cell == 'c' and spawnmethod == 0:
                    player_sprite = Player((x,y))
                    self.player.add(player_sprite)
                elif cell == 'l' and spawnmethod == 1:
                    player_sprite = Player((x,y))
                    self.player.add(player_sprite)
                elif cell == 'r' and spawnmethod == 2:
                    player_sprite = Player((x,y))
                    self.player.add(player_sprite)
    
    def horizontal_movement_collision(self):
        player = self.player.sprite
        player.rect.x += player.direction.x * player.speed
        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.x < 0:
                    player.rect.left = sprite.rect.right
                elif player.direction.x > 0:
                    player.rect.right = sprite.rect.left
    
    def vertical_movement_collision(self):
        player = self.player.sprite
        player.apply_gravity()
        for sprite in self.tiles.sprites():
            if sprite.rect.colliderect(player.rect):
                if player.direction.y > 0:
                    player.rect.bottom = sprite.rect.top
                    player.jumped = False
                    player.direction.y = 0
                elif player.direction.y < 0:
                    player.rect.top = sprite.rect.bottom
        
    def run(self):
        screen.fill((174,237,255))
        self.tiles.draw(self.display_surface)
        self.horizontal_movement_collision()
        self.vertical_movement_collision()
        self.player.update()
        self.player.draw(self.display_surface)

#pygame
pygame.init()
screen = pygame.display.set_mode((800,450))
clock = pygame.time.Clock()
level = Level(level_map,screen)
Level.setup_level(Level,level_map)

#the game loop
running = True
while running:
    #check for inputs
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    #next frame
    level.run()
    pygame.display.update()
    clock.tick(24)

And the level:

level_map = [
'                ',
'                ',
'                ',
'                ',
'                ',
'l              r',
'    G   c       ',
'G   G          G',
'GGGGGGGGGGGGGGGG']

leveltotheleft = 'levels/world1spawn.py'
leveltotheright = 'levels/world1spawn.py'
Oxnvat
  • 49
  • 4
  • Why are you passing spawnmethod to the setup_level method by setting a global, rather than by passing it as a parameter? I don't know if that's your problem or not but it's certainly not making your life easier to do it. – Daniel McLaury Jul 23 '22 at 21:05

0 Answers0