Python Forum

Full Version: Problems with pytmx
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Merry Christmas too all of you out there.

I have a problem with pytmx, as you can already say from the title of this thread.
So I have made a class to load the map, that I made with the application "Tiled":

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_grid
        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
I am loading it in the load section of my main.py file:

self.map = TiledMap(path.join(map_folder, 'outdoor.tmx'))
self.map_img = self.map.make_map()
self.map_rect = self.map_img.get_rect()
But still I get this error:

Traceback (most recent call last):
  File "/Users/.../Desktop/MyRPG/main.py", line 5172, in <module>
    g = Game()
  File "/Users/.../Desktop/MyRPG/main.py", line 16, in __init__
    self.load_data()
  File "/Users/.../Desktop/MyRPG/main.py", line 62, in load_data
    self.map = TiledMap(path.join(map_folder, 'outdoor.tmx'))
  File "/Users/.../Desktop/MyRPG/tilemap.py", line 22, in __init__
    tm = pytmx.load_pygame(filename, pixelalpha=True)
AttributeError: module 'pytmx.pytmx' has no attribute 'load_pygame'
Any idea how to fix this?
Merry Christmas.
Smile
I've never used it, but I see this in the docs:
Quote:Load with pygame surfaces:
>>> from pytmx.util_pygame import load_pygame
>>> tmxdata = load_pygame("map.tmx")

So instead of pytmx.load_pygame, try pytmx.util_pygame.load_pygame.

But also, the source for pytmx just imports submodules (source), so what you're doing should work. How are you importing the module?
(Dec-27-2019, 05:01 PM)nilamo Wrote: [ -> ]I've never used it, but I see this in the docs:
Quote:Load with pygame surfaces:
>>> from pytmx.util_pygame import load_pygame
>>> tmxdata = load_pygame("map.tmx")

So instead of pytmx.load_pygame, try pytmx.util_pygame.load_pygame.

But also, the source for pytmx just imports submodules (source), so what you're doing should work. How are you importing the module?

I have been importing it like this:

from pytmx import *
I tried what you said, but now I'm getting this error:

Traceback (most recent call last):
  File "/Users/.../Desktop/MyRPG/main.py", line 5172, in <module>
    g = Game()
  File "/Users/.../Desktop/MyRPG/main.py", line 16, in __init__
    self.load_data()
  File "/Users/.../Desktop/MyRPG/main.py", line 62, in load_data
    self.map = TiledMap(path.join(map_folder, 'outdoor.tmx'))
  File "/Users/.../Desktop/MyRPG/tilemap.py", line 22, in __init__
    tm = pytmx.util_pygame.load_pygame
NameError: name 'pytmx' is not defined
My code looks like this now:

import pygame as pg
from pytmx.util_pygame import load_pygame
from settings import *

class TiledMap:
    def __init__(self, filename):
        tm = pytmx.util_pygame.load_pygame
        self.width = tm.width * tm.tilewidth
        self.height = tm.height * tm.tileheight
        self.tmxdata = load_pygame("outdoor.tmx")

    def render(self, surface):
        ti = self.tmxdata.get_tile_image_by_grid
        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
And in the main.py file I use this to load the map: (still the same)

self.map = TiledMap(path.join(map_folder, 'outdoor.tmx'))
self.map_img = self.map.make_map()
self.map_rect = self.map_img.get_rect()
Do you know, how I could fix this? Thanks
Disclaimer: I havent used pytmx in awhile so i am out of the loop at this point. I might be out of date depending on how much he updated pytmx.

Quote:
Error:
AttributeError: module 'pytmx.pytmx' has no attribute 'load_pygame'
Did you put pytmx file in a pytmx directory? What is your file structure? I know at one point he had a pymtx directory with a pytmx file inside. If you copied that directory over you need 2 pytmx, whereas if you copied the file only you only need 1.

Personally i would not use star imports. But if you do, you are bypassing pytmx part of the line.

Assuming you copied only the file over and not the directory, you should be
import pytmx
pytmx.load_pygame()
Here is a game that uses that as an example:
https://github.com/justinmeister/bouncy-...der.py#L14

I have a feeling this is more of an module import issue than anything related specifically to pytmx.
Hey! It's the Kidscancode tile based game! I just had a problem with this exact thing yesterday and almost posted here with the problem.

I did figure it out. I'm I correct in guessing that you changed name of your "map_folder" or otherwise moved or changed something when you got your first error? I did. I had a type-o in my code so instead of fixing that I changed my "map_folder" name to match it. Mistake. Before the error you posted, did you maybe get "exception error"

I changed how I imported pytmx like was suggested. Nothing.

The actual fix was to make sure the path in my code the the "map" folder is correct and resave the Tiled file.

I used:
from pytmx import *

and

tm = load_pygame(filename, pixelalpha=True) 
In the map folder you'll see a .tsx file. If you changed anything since making that file it all becomes a nightmare. If you make sure your path is right and resave your tilemap in Tiled that might be the fix. It worked for me... after 2 hours of trying everything else.

He says in the video to make sure everything is where it needs to before going on or it leads to lots of problems... I'm sure this is what he meant.
I tried out what you said @metulburr and @michael1789 but it is not working.
Now I am getting this error:

Traceback (most recent call last):
  File "/Users/.../Desktop/MyRPG/main.py", line 5, in <module>
    from sprites import *
  File "/Users/.../Desktop/MyRPG/sprites.py", line 4, in <module>
    from tilemap import collide_hit_rect
  File "/Users/.../Desktop/MyRPG/tilemap.py", line 6, in <module>
    pytmx.load_pygame()
TypeError: load_pygame() missing 1 required positional argument: 'filename'
The code looks like this now:


import pygame as pg
#from pytmx.util_pygame import load_pygame
import pytmx
from settings import *

pytmx.load_pygame()

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

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

    def render(self, surface):
        ti = self.tmxdata.get_tile_image_by_grid
        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
In the sprites.py file I just imported that collide_hit_rect thing, because I need it there.
I don't know why it is not working.
I made a new map and didn't move any of the files.
Hope you guys can help me out.

Thanks. Happy New Year by the way. :-)
I'm at work so I don't have time to dig into this, but If you look up bitcraft on reddit and contact hin he is the author of pytmx. He use to hang out and on the pygame reddit forums years ago. Not sure now though


load_pygame takes the filename I believe of the tmx file as an argument
In my class Game, in Main.py I have:
self.map = TileMap(path.join(map_folder, 'map1.tmx'))
That is where the "file_name" argument in given to TileMap() then to pygame_load. Make sure what you put there is the new file you have.
(Jan-02-2020, 03:14 PM)michael1789 Wrote: [ -> ]In my class Game, in Main.py I have:
self.map = TileMap(path.join(map_folder, 'map1.tmx'))
That is where the "file_name" argument in given to TileMap() then to pygame_load. Make sure what you put there is the new file you have.

It is. But still I'm getting this error.
I just noticed that line 6 you have:
pytmx.load_pygame()
I don't have that, and it's not in his example. That might be the issue. Take it out and see if that works.
Pages: 1 2