Posted by: Xalthorn | February 6, 2008

Scrolling Map Display Tests

Sometimes, playing with a concept and coding things to prove it will work can take a heck of a long time and prove to be a major distraction, bringing progress on the main project to a grinding halt.

I’ve hit one of those.

One thing that has been bugging me for a while is how I want to display the player and their surrounding area, giving as much control of the view as possible to the player.

The current test generates a 50×50 tile map and displays it in a flat rectangle (no isometric yet). The viewport is set to 400×400 pixels with a thumbnail of 100×100 beside it. The map can be scrolled by dragging on the viewport, or moving the highlighted area on the thumbnail.

The plan was always to allow the user to select the zoom level which would determine the size of the images used to draw the map. Currently the three variations are 25×25, 50×50, and 100×100.

Displaying the map and thumbnail in the first place, with accurate and smooth scrolling was a hard and annoying process even though looking back at the code now, it all seems so easy. This was mainly due to the method used to actually move the map around.

Initially, I followed the generally accepted approach of changing the style of the map container to move it around (element.style.left and element.style.top). This worked but I found that the map juddered and was just not responsive enough.

The eventual solution was to use element.scrollLeft and element.scrollTop which made a huge difference when you’re moving a couple of thousand DIVs around.

Misha3D and I came to the conclusion that this was because rather than just moving an element on the page, we were modifying a style which could have had implications on every child within that element, which caused the delay. We could be wrong, but it made sense at the time.

Once the map was being displayed and could be scrolled around, the next step was to allow the size of the images to be changed by the user. Diving straight in, I placed three buttons on the page and had each one run some code that would essentially destroy and recreate the map display by setting the innerHTML of the map DIV.

In hindsight it wasn’t a very clever plan. Sure enough it worked, but the time it took to rebuild the map was irritating and I was only messing around with a test. I dread to think how many potential players would run away screaming after trying to use it in a game.

I considered doing some tests with a more reasonable map size. Something smaller than 50×50 and more the sort of size that the game would actually use. Thankfully I stopped myself, realising that I was trying to avoid the problem by changing the test parameters rather than make the code work properly.

So I knuckled down and had another think. After a bit of messing around, I found a nice workable solution that only had a brief delay when changing the size of the images. The solution I’m currently uses modifies the style of the map tiles rather than rebuilding them.

After all, all we’re doing is changing the appearance of the tiles rather than the content, so why should be have to rebuild the structure.

Now that works to an acceptable standard, I still have more work to do on the map display routines. I need to give the option to view the map in isometric view at the push of a button and I need to plan and test some actual content on the map beyond a few people.

After that I can then tidy the routines up and throw a test together that allows the user to move around a map stored on the server, with some basic interaction.


Responses

  1. Hey, thanks for mentioning me πŸ™‚

    Good to see you managed the map part. Changing the style of a tile was also my solution of choice since my tiles are objects rather than simple images. These objects contain any information about a tile from it’s movement cost to the order in which it should be drawn (stackable tile graphics).

    There are other nice solutions, such as having a style sheet for each tile size and when changing the tile size, just load in the matching stylesheet. That way you would reduce a huge number of object accesses to just one.

    Another speed improvement is also to load tile images not as tiles but rather as tile mosaic and using css to clip the contents of each individual tile. Though I need to run some more tests to see how this impacts ram for 20k+ tiles.

  2. Hehe, no worries about the mention πŸ˜€

    I’m curious about the information you’re putting in the tile objects. Are you fully loading each tile object with everything it needs, or are you also having a list of ‘core’ objects and each tile object refers to it’s core for the static information? It would mean more processing overhead but much less memory.

    I will certainly be using CSS sprites for some parts of the site and I will probably use it to hold the various images used to ‘rotate’ each tile or object.

  3. Your approach sounds pretty intriguing too. I’d be interested most in how you handled the mini map. Do you use scaled graphics or do you just use a colored div (e.g. 3×3 px) to represent each tile.

    The good thing about Javascript is that you can inherit from instances. As you said, you can easily make all the base instances that you know you are going to need and then just make instances (copies if you will) from those objects. Good thing, if you then make a runtime change to the base object, it will be reflected in all instances.

    I have hardcoded a base Tile object that has all the necessary methods, variables and constants. Each tile on the map is instanced from that. Only if a certain tile has special properties (e.g. mana spring) it gets all extra properties added.
    Base properties are for example
    next – tile that comes above the current one (stacking)
    north, east, south, west – adjacent tiles
    pos – position in the map array
    offset – the local offset from the base grid of the image
    … and more …

    Each tile in turn contains a TileGfx object that offers a few accessor functions to easily get to the image or it’s properties. This will later also handle animated tiles.

    This is where I got the idea from: http://www.geocities.com/SiliconValley/Pines/1672/tiletech.html

    Or do a google search on “Jason McIntosh Tile Graphics”.

    For basic functionality, dom and some effects I am using a heavily customized version of AJS ( http://www.orangoo.com/labs/AJS/ ).

    If you are interested in some code to look at, just send me an email and I’ll send you some files.

  4. My mini map is simply an image drawn with PHP using the same data as the map drawing routine.

    Over the top of this, I place a simple DIV which can be dragged around.

  5. Thanks for the info.
    Yes that makes sense πŸ™‚

    I wasn’t really thinking about the server side when I posted the question.

  6. I can get away with such a simple method because of the map size I’m dealing with. The ‘world’ is always the same size and the thumbnail won’t need to show just a portion of the world.

    When I code up the level designer I’ll need a more dynamic image. I’ll probably kick the data back to the server and refresh the thumbnail.

    Also, when the map gets larger (the RPG for example) then I’ll probably throw some variables at the image script to let it display a section of the map, letting the display zoom in and out.

  7. This is weird, but I just recently started toying with this same idea. I put together a pretty simple js library that I’ve tried to keep generic enough that you can drop it into some existing code pretty easily. It doesn’t zoom or anything, and it relies on having the content of the viewport fully loaded in the page (so it’s not like Google Maps where it will pull more content from the server when you scroll in a direction). You should check it out – I’m going to write a tutorial around using it, but you can probably get a pretty good idea of it from these examples and by looking at the source:
    http://offtheline.net/examples/map/simplemap.html
    http://offtheline.net/examples/map/worldmap.html
    http://offtheline.net/examples/map/tablemap.html
    (hope the spam filter doesn’t reject me for these links)

    For my current purposes, it works great (so far in testing – haven’t pushed it to the live server yet). Now I can make battle maps without worrying about them becoming too large for those unfortunate 1024×768 resolutions…

  8. Man you are giving me ideas here πŸ™‚

    My original intention was to do everything completely independent from a server side so the games would be useful offline too.

    I think for multiplayer it could be essential to keep server communication besides the actual multiplayer data to a minimum.

    What could work with the mini map is just preloading 3 or 4 sizes of the mini-map and then have them scroll when you move the div which represents the actual viewing area.

    But this is all put back until I have the simpler games done and the library out to public.

  9. @Ranger Sheck : Very slick as usual. I figure I’ll worry about the google map system when I have a world big enough to warrant it. At the moment, I’m keeping myself focussed on my simpler project which is always going to have maps that are 45×45. It’s annoying because on one hand, I’m really keen to mess with the fringe loading map system but I know it’ll just distract me.

    @Misha3D : Your offline approach explains why you are building such a dynamic and detailed object based system.

    My intention is to strip as much as I can from the bandwidth, which is why a lot of my scripts utilise javascript to build rich content from a relatively simple set of data.

    My current test, for example, uses a simple map of two tile types (stone and grass) and as it builds the map to display, it does all the fringing checks. This means that not only does the server only have to worry about the actual content of a tile rather than the display, the maps can be compressed with RLE, letting javascript unpack it.

    I really need to tidy up my code and pop it online for people to tear to pieces πŸ™‚

  10. @Ranger Sheck: Very good concept and very detailed approach. Since it’s an MIT license I might use it.

    @Xalthorn: In my recent version I am doing the map transitions(fringing) in JS too. It seems JS can handle (relatively) huge calculations with no problem. It’s the DOM and Style modifications that really bogs the browser down.

    I have planned to save the object state optionally as yaml and xml. At creation time I can output straight JS code too. RLE is a nice thought to compress this.
    I have even seen some guy implement zip in JS. But I wanted to leave this until I get the basic framework down.

    The object based approach actually comes naturally when you try to create something that has similar data sets that are almost but not quite the same. Objects and inheritance saves a lot of recoding for shared properties and functions.

    I am using AJS classes for this, so it’s not as powerful as true prototyping in terms of access control, but I can use JSON for the classes and save a whole lot of code that just leaves my code all messed up.

    Can’t wait for the code to check it out and learn… πŸ™‚

  11. Hehe, or check it out and laugh πŸ˜‰

  12. Hey, if you’d like to get a laugh or investigate my code – I posted my sprite animation classes for anyone to use.

    Later today I’ll post a performance comparison (with example code and demos) between plain html, svg and canvas. Be prepared for a little surprise concerning svg…

    Cheers

  13. I’ll certainly go and check it out πŸ™‚

    Whilst tidying my code up ready to throw onto the web, I went off on a tangent again and figured I might as well throw a demo together that uses the basic game mechanics and lets you see what I’m aiming for and why my map scroller isn’t a fully featured thing.

    Of course, this opened up a huge can of worms. I figured whilst I was at it, I might as well throw the web interface together in a way that I expect it to work later. This meant banging my head through a few more walls to get a layout I like.

  14. I hear what you saying… Once you get started, there’s almost noway back…

    But since it was your own decision with no one forcing you I don’t feel pity for you :p

    And while I am here, might I do a little advertisement on behalf of my very own site πŸ˜‰
    I was chatting with some Firefox developers lately which caused me to heavily streamline my Graphics handling. I am now able to animate 250+ Sprites with no visual impact. Of course this only works in canvas…
    I’ve put together an in depth review of each possibility to animate sprites in a browser yesterday. The scrolling property technique isn’t actually that much of an advantage.

    Go check it out and while you’re at it, be nice and say hello and let me know what you think :):
    Choosing the right Graphics Technique for a Browser based Game

  15. Hehe, I’m well aware that most of my problems are of my own creation.

    My main concern with canvas is the cross browser compatibilty issue again. I don’t want the user to have to download anything, install plugins, and so on. I just want them to load the page and see it all working. I appreciate that canvas isn’t a plugin and *can* work on IE, but I figured I’d go off on a tangent again πŸ˜‰

    I’m interested in canvas as it appears to simply be an area on the page that you can treat as an output device of fixed dimensions which you can mess around with to your hearts content with more traditional programming methods. As a result, I’ll probably pick it up and play with it later.

    However, I really mustn’t let myself get even more distracted right yet.

  16. Greetings,

    I’ve recently discovered the YABASIC PS2 demo and had a lot of fun typing some of the old listings on my PS3.

    One advantage, the PS3 can export/import the saves!

    You were a prolific user of YABASIC back then

    Even made a little program to test controllers.

    Did I give you a blast from the past?

    Cheers!

    Wenlock
    Bacchus Marsh
    Australia

  17. Hello Wenlock,

    That’s certainly a blast from the past, but Yabasic isn’t dead yet, there is a great Forum where people code in all sorts of languages and offer help and advice. It’s definitely worth a visit.

    http://www.dbfinteractive.com/index.php

  18. pbbgs are the future of work procrastination πŸ˜€


Leave a reply to Misha3d Cancel reply

Categories