Page 1 of 1

Sokoban game-How to load map and more questions.

Posted: Sat Jun 25, 2016 9:32 am
by AltLock
Hey everyone,

I am making a game right now as a hobby that should (I would like to) be able to load as many maps as possible from text.
First I want it to load (and stay compatible with)Sokoban maps and later be able to add new features and twists such as the cliches (teleporters :crazy:, different colored blocks, etc.) but also experiment with never done before things. The kind of maps available here I would like to be able to load into the game: http://www.sourcecode.se/sokoban/levels.

So I already implemented tileset importing and have pre-planned a lot of classes and player movement, but I
can't completely get my head around how I would translate the text to a table or something similar to then assign the objects at the correct
locations to get the correct logic and tiles. If someone could give me a few pointers about this, I would be very grateful.

Thank you very much,

AltLock

EDIT: Clarification.

Re: Sokoban game-How to load map and more questions.

Posted: Sat Jun 25, 2016 5:03 pm
by pgimeno
It's hard to know where the difficulty lies. And in absence of a map structure, it's hard to give hints on how to turn it into actual code.

The basic idea is to read the file line by line, and then each of the lines character by character, and fill in the map according to the character found. But that's straightforward.

Note that I wouldn't recommend having the player and the boxes as part of the map, but better as separate entities. That would allow more flexibility like animating the character as it changes squares, rather than making it disappear from one square and appear on the next, for example.

Here's an example of how to read it into three structures: map, boxes, and player. The boxes table is assumed to have pairs {x=x, y=y} indicating where the boxes are. The player is just x and y.

Code: Select all

  boxes = {}
  local y = 1
  for line in love.filesystem.lines(levelfilename) do
    for x = 1, #line do
      c = line:sub(x, 1)
      if c == "#" then
        -- wall - store in map
        map[y][x] = wall_sprite
      elseif c == "." then
        -- target - store in map
        map[y][x] = target_sprite
      elseif c == "*" then
        -- box on target - store target in map, box in boxes
        map[y][x] = target_sprite
        boxes[#boxes+1] = {x=x, y=y}
      elseif c == "@" then
        map[y][x] = empty_sprite
        player = {x=x, y=y}
      -- and so on
      end
    end
    y = y + 1
  end
The complete level format is at http://sokobano.de/wiki/index.php?title=Level_format

I've omitted sanity checks, like having only one player, checking that the number of targets equals the number of boxes, and more sophisticated ones such as ensuring that the room is closed or that all boxes not already on a target are reachable. Checks for level separators are also omitted.

Re: Sokoban game-How to load map and more questions.

Posted: Sun Jun 26, 2016 9:09 am
by AltLock
Good day pgimeno!

This is some nice code you posted here! I'll try to incorporate this into my code. I believe it would make it easier for me to write a little 'import' program that runs at startup and will do all the checks to then transform them into compatible maps (and put them in a local database or something). This program should make it very easy to structure, categorize, clean up and add (of course) almost any map the player wants to add. When I implement a gui-based start menu I can separate maps on maker, difficulty, features, size, original vs exclusive for this game etc. Thank you very much pgimeno, you really got me thinking on this.

Cheers,

Altlock