1
\$\begingroup\$

So I basically want to load another map once the player collides with a object, specifically a "Portal" in my game. Which is really making the player move onto other levels. I don't want to jumble up my code with a bunch of function like "go_to_level_9" or something so I'm planning to use a list or dictionary or something. So how to those game devs out there do that? Code for main.py is here: https://pastebin.com/rpddq1MP. The part with the portal stuff, walls and a few others:

    for tile_object in self.map.tmxdata.objects:
        obj_center = vec(tile_object.x + tile_object.width / 2,
                         tile_object.y + tile_object.height / 2)
        if tile_object.name == 'player':
            self.player = Player(self, obj_center.x, obj_center.y)
        if tile_object.name == 'zombie':
            Mob(self, obj_center.x, obj_center.y)
        if tile_object.name == '#':
            Obstacle(self, tile_object.x, tile_object.y,
                     tile_object.width, tile_object.height)
        if tile_object.name in ['health', 'shotgun']:
            Item(self, obj_center, tile_object.name)
        if tile_object.name == 'portal':
            self.map = TiledMap(path.join(self.map_folder, tile_object.type))

how do you do it? I'm currently using Tiled and pygame so I'm also using pytmx.

Edit: When I run the code, it just gives me an error about my other file, tilemap.py.

Error: File "D:\coding\my_coding_stuff\python\games\pygames\little rpg\tilemap.py", line 49, in apply return entity.rect.move(self.camera.topleft) AttributeError: 'TiledMap' object has no attribute 'rect'

Tilemap.py:

import pygame as pg
import pytmx
from settings import *

def collide_hit_rect(one, two):
    return one.hit_rect.colliderect(two.rect)

class Map:
    def __init__(self, filename):
        self.data = []
        with open(filename, 'rt') as f:
            for line in f:
                self.data.append(line.strip())

        self.tilewidth = len(self.data[0])
        self.tileheight = len(self.data)
        self.width = self.tilewidth * TILESIZE
        self.height = self.tileheight * TILESIZE

class TiledMap:
    def __init__(self, filename):
        tm = pytmx.load_pygame(filename, pixelalpha=True)
        self.width = tm.width * tm.tilewidth
        self.height = tm.height * tm.tileheight
        self.tmxdata = tm

    def render(self, surface):
        ti = self.tmxdata.get_tile_image_by_gid
        for layer in self.tmxdata.visible_layers:
            if isinstance(layer, pytmx.TiledTileLayer):
                for x, y, gid, in layer:
                    tile = ti(gid)
                    if tile:
                        surface.blit(tile, (x * self.tmxdata.tilewidth,
                                            y * self.tmxdata.tileheight))

    def make_map(self):
        temp_surface = pg.Surface((self.width, self.height))
        self.render(temp_surface)
        return temp_surface

class Camera:
    def __init__(self, width, height):
        self.camera = pg.Rect(0, 0, width, height)
        self.width = width
        self.height = height

    def apply(self, entity):
        return entity.rect.move(self.camera.topleft)

    def apply_rect(self, rect):
        return rect.move(self.camera.topleft)

    def update(self, target):
        x = -target.rect.centerx + int(WIDTH / 2)
        y = -target.rect.centery + int(HEIGHT / 2)

        # limit scrolling to map size
        x = min(0, x)  # left
        y = min(0, y)  # top
        x = max(-(self.width - WIDTH), x)  # right
        y = max(-(self.height - HEIGHT), y)  # bottom
        self.camera = pg.Rect(x, y, self.width, self.height)
\$\endgroup\$
0
0
\$\begingroup\$

Sorry everyone for wasting your time, but I figured out I would just make new() take a extra parameter, map, and whenever player touches a portal, it will just load the map that's in the portal's type slot like this:

def new(self, map):
    # initialize all variables and do all the setup for a new game
    self.all_sprites = pg.sprite.LayeredUpdates()
    self.walls = pg.sprite.Group()
    self.mobs = pg.sprite.Group()
    self.bullets = pg.sprite.Group()
    self.items = pg.sprite.Group()
    self.map = TiledMap(path.join(self.map_folder, map))
    self.map_img = self.map.make_map()
    self.map.rect = self.map_img.get_rect()
    for tile_object in self.map.tmxdata.objects:
        obj_center = vec(tile_object.x + tile_object.width / 2,
                         tile_object.y + tile_object.height / 2)
        if tile_object.name == 'player':
            self.player = Player(self, obj_center.x, obj_center.y)
        if tile_object.name == 'zombie':
            Mob(self, obj_center.x, obj_center.y)
        if tile_object.name == '#':
            Obstacle(self, tile_object.x, tile_object.y,
                     tile_object.width, tile_object.height)
        if tile_object.name in ['health', 'shotgun']:
            Item(self, obj_center, tile_object.name)
        if tile_object.name == 'portal':
            self.new(tile_object.type)
    self.camera = Camera(self.map.width, self.map.height)
    self.draw_debug = False
    self.paused = False
    self.effects_sounds['level_start'].play()
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.