reading and writing tile maps

reading and writing tile maps

Postby metulburr » Tue May 27, 2014 5:15 pm

ive been trying to understand tile maps, and ive put it off for a long time now. now i think i am interested in figuring this out. I am quite confused though. Ive checked out a couple games that use it, PyTMX, and tiled. I was also watching the latest video on pygame.org about tile sets as well.

I am assuming different games handle things differently. For example, some games might use tilesets as visual only while another might contain the collision info, triggers, etc. within the tile set? Then you load the trigger from the map? Is this accurate?

I dont know, i am just confused on where to start. I looked at pytmx and i almost wanting to recreate it as for some reason not liking using it when i dont understand what it is doing. But then is it worth it? If that does not account for visual tile sets along with triggers/collisions, etc. Then would i have to recreate it to account for that if i want triggers within the tilesets?

I think i need an idiots guide to tile sets or something lol. For some reason even after researching tile maps, i am still quite confused as when i first started, or even more.

I was tinkering with https://pyweek.org/e/Justinmeister/ pyweek entry to try to change the map. I edited the level via tiled, and when i play the game, the edited tiles exist, but do have any coliision detection for them. I checked out hte rest of the code, but i cnat fiond where the detection comes into play.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1420
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: reading and writing tile maps

Postby justinmeister » Fri May 30, 2014 12:33 am

Hey, I think PyTmx is super great. Me and Leif (the guy who wrote the library) planned on making a tutorial, but neither of us really had the time.

The way I use tile maps is to create a giant level surface object (although only blitting the portion that is in the viewport), as well as using tile objects to store information.. Here's a method in the levels.py that creates collideable rects that can collide with the player:

Code: Select all
def make_blockers(self, blocker_name):
        """
        Make the collideable blockers the player can collide with.
        """
        blockers = pg.sprite.Group()
        for object in self.renderer.tmx_data.getObjects():
            properties = object.__dict__
            if properties['name'] == blocker_name:
                x = properties['x']
                y = properties['y'] - 70
                width = height = 70
                blocker = pg.sprite.Sprite()
                blocker.state = None
                blocker.rect = pg.Rect(x, y, width, height)
                blockers.add(blocker)

        return blockers


The object layer in the tmx file is where I put these objects with names like 'blocker'. The logic for creating the level's surface is in tilerender.py. I just use normal pygame methods to detect collisions. All the data is loaded when the level starts, after which I don't rely on the tmx file.

The collision logic is in collision.py
justinmeister
 
Posts: 9
Joined: Fri Jan 31, 2014 5:01 am

Re: reading and writing tile maps

Postby metulburr » Fri May 30, 2014 1:10 am

Me and Leif (the guy who wrote the library) planned on making a tutorial

That would be awesome. It would make it a lot easier for those whom never made a tilemap yet, including me.

The way I use tile maps is to create a giant level surface object

Would this work with movable platforms? You would have to recreate the level every time a platform moves, or a changing wall disappears, etc. Is this current?

If figured i would start out by just adding a platform to your current level, and then attempt to make a level with Tiled, PyTMX and implement it into my own game/structure.

If i edit your default level tmx file with Tiled, and add an extra platform...
http://www.mediafire.com/view/ozp1ch4l9 ... level1.tmx
When you run the game, it displays the platform, but it is not collidable. Doesnt the tmx contain that data in which you get from:
Code: Select all
for object in self.renderer.tmx_data.getObjects():

So how come that object is not pulled in that loop?

EDIT:
ok i just figured out that your level does have the blockers by accidently grabbing a blocker. OK So now it makes a little more sense. Now i think i just need to research Tiled as i have no idea what i am doing in this thing. How exactly would you load a tilemap into Tiled, as it auto does it when i load your tmx file. And how do you create a new blocker with a fresh map?

EDIT2:
OK so after checking out TIled more...For a more complex game, would you just have your tile set layer for viewing, your blocker layer for collision, your starting points (for player and enemy) position layer, and a trigger layer? Everything as a layer in the map, in which is loaded by key into the game?
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1420
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: reading and writing tile maps

Postby justinmeister » Fri May 30, 2014 5:41 am

This was a good resource to learn more about tiled: http://gamedevelopment.tutsplus.com/tut ... medev-2838

Anything that has to move (whether an item box, moving platform, enemy, or player) should be sprite that has an object marking it's start location. You can also have objects that act as triggers that when collided with, create the enemy at the location you designated. Anything that is part of the background or doesn't move can just be part of the background surface. You still need to add tile objects to designate where you want the rects to be for the player to collide with.

One thing that's annoying about Tiled is that, as far as I can tell, once you start making the tile map, you can't move the files into different directories (that includes the tmx file, as well as the tile sets). Maybe there is a way do that, but I'm not aware of it.

The key thing is to use tmx to store data that you load all at once into your program. Once you parse the tmx file with PyTmx, you should no longer have to refer to it, because all that info is now in a Python data structure.
justinmeister
 
Posts: 9
Joined: Fri Jan 31, 2014 5:01 am

Re: reading and writing tile maps

Postby metulburr » Fri May 30, 2014 11:10 am

One thing that's annoying about Tiled is that, as far as I can tell, once you start making the tile map, you can't move the files into different directories (that includes the tmx file, as well as the tile sets). Maybe there is a way do that, but I'm not aware of it.


After you said this i had to try it....It looks like tiled expects the data structure to stay the same even after the file is moved. So if the tileset for the tmx is up two directories and down another one, then that has to persist for it to find it. That makes sense. What tile manager do you use that does allow it?

Ill have to play around with PyTMX, in trying to load the tmx into my game. Thanks for the link by the way.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1420
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: reading and writing tile maps

Postby metulburr » Fri May 30, 2014 1:06 pm

OK i started peeling away your code to try to understand it. A lot of it i just copied. Ill change it later to my liking after i understand it.

So here is a zip that i compressed of what i was trying. It contains the example tileset, pytmx, the tmx file i created, and the code. I tried to keep it small as possible.

I filled the screen with white. What i get when i run the program is a black screen when i render the map. I am not sure what i am missing?

Thanks for all your help.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1420
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: reading and writing tile maps

Postby justinmeister » Fri May 30, 2014 3:29 pm

Code: Select all
def make_viewport(self, map_image):
    map_rect = map_image.get_rect()
    return self.screen.get_rect(bottom=map_rect.bottom)

So the viewport is just the rect that represents what part of the screen is going to blitted every cycle. When you set bottom=map_rect.bottom, it means that the level starts at the very bottom of your tile map. Your tilemap is 100 tiles wide, 100 tiles high, but the only part of it that has tiles on it are on the top left corner. So what you did worked fine, it's just that you can't see it. If there is no tile and no background color, PyTmx seems to default to black (hence not seeing white. If you set the viewport to start at 0,0 (by deleting bottom=map_rect.bottom) or by resizing your tmx map (in the menu: Map > Resize Map), you should see your blitted tiles.
justinmeister
 
Posts: 9
Joined: Fri Jan 31, 2014 5:01 am

Re: reading and writing tile maps

Postby justinmeister » Fri May 30, 2014 3:31 pm

metulburr wrote:What tile manager do you use that does allow it?

When I start a tile map, I just make sure everything is in the right directory from the start to avoid any problems. I haven't really experimented with any work arounds.
justinmeister
 
Posts: 9
Joined: Fri Jan 31, 2014 5:01 am

Re: reading and writing tile maps

Postby metulburr » Fri May 30, 2014 4:00 pm

So the viewport is just the rect that represents what part of the screen is going to blitted every cycle. When you set bottom=map_rect.bottom, it means that the level starts at the very bottom of your tile map. Your tilemap is 100 tiles wide, 100 tiles high, but the only part of it that has tiles on it are on the top left corner. So what you did worked fine, it's just that you can't see it. If there is no tile and no background color, PyTmx seems to default to black (hence not seeing white. If you set the viewport to start at 0,0 (by deleting bottom=map_rect.bottom) or by resizing your tmx map (in the menu: Map > Resize Map), you should see your blitted tiles.


ahh ok. thanks.

So now im confused on how to handle collision blocks, how to store them with tiled, and how to retrieve them wiht pytmx.

For the collision blocks that you use in the object layer...Do you just use a random block from the tileset that you dont use elsewhere to indicate that its a blocker?

In your code data.states.level.Level in make player(), make sprites(), and make_doors(), make_item_boxes()... you have:
Code: Select all
...
]if properties['name'] == 'player start point':
...
f properties['type'] == 'enemy':
...
if properties['name'] == 'door':
...
if properties['name'] == 'item box':

Are the strings door, enemy, and player start point, and item box individual layers within the tmx file? If i open your tmx file for that game, i see an object layer and two tile layers, so i am not sure where the tmx file and the code intervene.

EDIT:
If i open your tmx file and view the xml code, i see attribute name. I think i am starting to make sense of it. wow, this is taking quite a long time just to comprehend.

EDIT2:
Currently i am having a hell of a time implementing what i got working there within my game as the structure needs adjusting. Kind of at a stand still with that for the moment. Going crazy with relative imports.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1420
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: reading and writing tile maps

Postby justinmeister » Fri May 30, 2014 5:29 pm

I just use a random but distinct image to indicate different objects. The orange square was just arbitrary. After I made one blocker object, I just copy and pasted it all over the map.

Are the strings door, enemy, and player start point, and item box individual layers within the tmx file? If i open your tmx file for that game, i see an object layer and two tile layers, so i am not sure where the tmx file and the code intervene.


If you double click an object while the object layer is selected in Tiled, you'll get a little window that shows the various properties of an object. Some default properties are 'Name', 'Type', 'x', and 'y' but you can add your own custom properties as well if you want.

Code: Select all
def make_player(self):
        for object in self.renderer.tmx_data.getObjects():
            properties = object.__dict__
            if properties['name'] == 'player start point':
                x = properties['x']
                y = properties['y']
                return player.Player(x, y, self)


For this method, there's a blue object with the name 'player start point' that is used to store the start location of the player. The x and y properties are used to create a Player object. To be honest, I'm not sure why I needed to use __dict__ to access the properties, but it was the only way I could get it to work.

I use basically the same process to load the blocker rects, and everything else stored in the object layer.
justinmeister
 
Posts: 9
Joined: Fri Jan 31, 2014 5:01 am

Re: reading and writing tile maps

Postby justinmeister » Fri May 30, 2014 5:38 pm

metulburr wrote:EDIT2:
Currently i am having a hell of a time implementing what i got working there within my game as the structure needs adjusting. Kind of at a stand still with that for the moment. Going crazy with relative imports.

Yeah, maybe I just don't understand how to import packages, but I find it works if your tilerender.py is in your data folder, with your PyTmx folder at the top. Relative imports on a .py is easy.
justinmeister
 
Posts: 9
Joined: Fri Jan 31, 2014 5:01 am

Re: reading and writing tile maps

Postby metulburr » Fri May 30, 2014 5:47 pm

yeah, thanks....i think ill just have to play around with tiled and coding a little bit to figure out more. THanks for the help

Yeah, maybe I just don't understand how to import packages, but I find it works if your tilerender.py is in your data folder, with your PyTmx folder at the top. Relative imports on a .py is easy.

Yeah i didnt like the fact that the pytmx directory was in root, so i put it in the data directory along with renderer and that really just caused a bunch of headaches for importing. If i have to i would, but would rather not.

To be honest, i dont even remember why, but i emptied out PyTMX/__init__.py because that was causing some traceback that i dont even remember what it was at this point. I think i might have to clear out all tmx stuff in my program, redownload his repo again, because I modified some of his code that i cant remember how to revert. Really turned into a big mess quickly.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1420
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: reading and writing tile maps

Postby justinmeister » Fri May 30, 2014 5:50 pm

For some reason I put the PyTmx directory in data for The Stolen Crown, but I used:

Code: Select all
from . import PyTMX


in the tilerender.py and it seems to work fine. Again, no idea what I'm doing or why that works. Maybe someone who knows more can chime in.
justinmeister
 
Posts: 9
Joined: Fri Jan 31, 2014 5:01 am

Re: reading and writing tile maps

Postby metulburr » Fri May 30, 2014 6:48 pm

ok figured it out. It wasnt importing because I messed with his __init__.py file. I often refer to my own tutorial here, because i mess things up from time to time with relative imports. http://www.python-forum.org/viewtopic.php?f=25&t=3963

I finally got it to work entangled with my structure. There are a few things that i want to modify structure-wise, but at least the tilemap is loading and rendering ok. Sweet. That took all day to figure that out. Whew!!!

EDIT:
I forgot about both python versions. I attempted python3.x and i get:
Code: Select all
metulburr@ubuntu ~/repos/platformer $ python game.py
{u'fullscreen': False, u'resizable': False, u'difficulty': u'medium', u'caption': u'Flood It', u'save': {u'won': 0, u'lost': 0, u'shortest': None, u'points': 0}, u'size': [800, 600]}
metulburr@ubuntu ~/repos/platformer $ python3 game.py
Traceback (most recent call last):
  File "game.py", line 4, in <module>
    from data.main import main
  File "/home/metulburr/repos/platformer/data/main.py", line 3, in <module>
    from .control import Control
  File "/home/metulburr/repos/platformer/data/control.py", line 4, in <module>
    from .states import menu, splash, title, game, options
  File "/home/metulburr/repos/platformer/data/states/game.py", line 2, in <module>
    from .. import tools, player, block, powerup, renderer
  File "/home/metulburr/repos/platformer/data/renderer.py", line 1, in <module>
    from . import pytmx
  File "/home/metulburr/repos/platformer/data/pytmx/__init__.py", line 1, in <module>
    from pytmx import *
ImportError: No module named 'pytmx'
metulburr@ubuntu ~/repos/platformer  $

Apparently he has different version of tmx for python2 and python3?

EDIT2:
I checked out his pytmx for python3 branch and experiemental branch, but both of those caused problems. The only one i can get to work is the regular repo for python2.x That bothers me that i cannot get it to run in python3.x if using that.

If you see anything wrong let me know:
https://github.com/metulburr/platformer

I couldnt find how to modify the location of the tilemap within Tiled. However i was able to manually change it.
because it was created looking for hte tileset in the same directory it was:
Code: Select all
  <image source="grass-tiles-2-small.png" width="384" height="192"/>

and now i put the tmx file within resources.tmx directory and moved the tileset in resources.graphics I had to change it to:
Code: Select all
  <image source="../graphics/grass-tiles-2-small.png" width="384" height="192"/>

which worked fine, but it would be nice to have that option within TIled.

I think i had my fill with this today, lol.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1420
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: reading and writing tile maps

Postby justinmeister » Fri May 30, 2014 11:57 pm

It might be worthwhile to check out the library's code and see why it's not working with Python 3. I'm sure Leif would appreciate any fixes you can make.
justinmeister
 
Posts: 9
Joined: Fri Jan 31, 2014 5:01 am


Return to Game Development

Who is online

Users browsing this forum: No registered users and 2 guests