Slick Forums

Discuss the Slick 2D Library
It is currently Wed Oct 17, 2018 10:22 pm

All times are UTC




Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: Fri Feb 06, 2009 6:02 pm 
Offline

Joined: Fri Feb 06, 2009 11:04 am
Posts: 6
Location: Poland
I've been thinking about adding generation of random map using defined tilesets to my game. My game is using TiledMap class because it's quite convenient. So far the only way to do it I've found is like that:

1. Create sample map and decode a string between <data> </data> compressed and coded in base64 just to work out how data is represented (what is the format after decoding).
2. Create generator class which will append .tmx document with defined tilesets with my own <data></data> containment which will clutter my tiles over the map in a random way. It will require that I generate data in the format I've worked out in step 1. and code it to base64.
3. Open generated .tmx document with Slick's TiledMap class that will decode my data again and make use of it.

Is there any easier/simplier solution to this problem before TilEd "libraries" feature will be added?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 07, 2009 5:47 pm 
Offline

Joined: Fri Feb 08, 2008 4:05 am
Posts: 7
There is probably a much easier way than that, but I defer to someone who has worked more with Slick.


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 22, 2009 12:24 pm 
Offline

Joined: Tue May 19, 2009 5:23 pm
Posts: 26
I know this is an old post but just curious if this is what you went with?

This is an editor v code thing I guess. A long time ago we set up our editor to handle this.

My first thought about doing it would be to set up my tileset so that first tile in each row was the random generator.

1234
5678
9101112

I would then replace the tile on initialization with the tile number +rand(0-3)

Or you could store a variable(s) in the tile itself to tell it which ones to replace it with if it is marked a boolean bRandom. This might be cleanest.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 12, 2009 2:57 pm 
Offline

Joined: Mon Jun 15, 2009 8:16 pm
Posts: 7
If you uncheck binary encoding and compression in the saving tab in the preferences menu, you will find the resulting file much easier to read.

I also disabled embedding of images.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 16, 2009 4:54 pm 
Offline
Regular

Joined: Sat Aug 16, 2008 7:04 pm
Posts: 119
I have implemented a random map generator based on tiled.

If somebody is interested I will post the source code here.

_________________
Gamedev link-collection (german page)
My Gamedev Blog
Play Cyber Dungeon Quest!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 17, 2009 12:07 pm 
Offline
Slick Zombie

Joined: Wed Apr 02, 2008 1:32 pm
Posts: 1340
Location: Italy
Hardcore wrote:
I have implemented a random map generator based on tiled.

If somebody is interested I will post the source code here.


always post useful code :D

_________________
Blog | Last game Drone Swarm


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 18, 2010 12:51 am 
Offline

Joined: Thu Sep 24, 2009 8:14 pm
Posts: 50
Resurrecting this old thread.

I would also like to use a programmatically generated tiled maps for my game. TiledMap has its advantages of having good performance, tested, and integrated with Slick, but having to generate the game map into the TiLED format first doesn't seem like idea. There also does not appear to be an easy way to add elements to the map at run time (e.g., imagine SimCity, where buildings sprouts up in real time, imagine new building graphics being added to the map at run time).

So has anyone had success using TiledMap for runtime generated maps? Was there any particularly tough problems that needed to be solved?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 18, 2010 10:29 am 
Offline
Regular

Joined: Sat Aug 16, 2008 7:04 pm
Posts: 119
Quote:


So has anyone had success using TiledMap for runtime generated maps? Was there any particularly tough problems that needed to be solved?


You only need to use the render function of TiledMap - if you create your map at runtime.

You can just copy it for runtime generated maps its only one method.

_________________
Gamedev link-collection (german page)
My Gamedev Blog
Play Cyber Dungeon Quest!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 18, 2010 2:47 pm 
Offline

Joined: Thu Sep 24, 2009 8:14 pm
Posts: 50
Not exactly. The render method depends on correctly constructed Layer instances, which is populated from TiLED data. You still have the problem of having to generate your data in a format compatible to TiLED maps.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 05, 2011 4:46 pm 
Offline

Joined: Wed Jan 05, 2011 4:21 pm
Posts: 10
Anyone know the answer to this? It's also something I've been wanting to know. Getting to generate Tiled maps would be much easier than having to recreating all the code for tiled maps.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 06, 2011 1:55 pm 
Offline
Regular

Joined: Sat Aug 16, 2008 7:04 pm
Posts: 119
Well you do not need to use layers for your generated maps.

Here is my code (in lisp/clojure) for rendering a self-generated map.

It is just a prototype so i have coordinates [3 5] for wall and [7 7] for ground-tile on this grid.

Code:

(defn- render-grid [x y sx sy width height]
  (let [map-tile-sheet #^SpriteSheet (:map-tiles sheets)]
    (.startUse map-tile-sheet)
    (dorun
      (for [tx (range width)
            ty (range height)
            :let [tilex (+ sx tx)
                  tiley (+ sy ty)
                  cell (get-cell tilex tiley)]
            :when (inside-map? cell)]
        (let [is-wall (wall? cell)
              sheet-x (if is-wall 3 7)
              sheet-y (if is-wall 5 7)
              image (.getSprite map-tile-sheet sheet-x sheet-y)
              render-x (+ x (* tile-size tx))
              render-y (+ y (* tile-size ty))]
          (set-cached-brightness image tilex tiley)
          (.drawEmbedded image render-x render-y tile-size tile-size))))
    (.endUse map-tile-sheet)))


_________________
Gamedev link-collection (german page)
My Gamedev Blog
Play Cyber Dungeon Quest!


Top
 Profile  
 
PostPosted: Tue Jan 10, 2012 10:00 pm 
Offline

Joined: Tue Jan 10, 2012 9:42 pm
Posts: 3
Any java samples on this? I too am interested. Im very green with java - I just converted over from using a ruby based game engine so Im getting my footing in this language, ide and library. Looks like TiledMapPlushttp://slick.javaunlimited.net/viewtopic.php?p=22708 will be awesome for some parts of this (runtime tile swaps).


Top
 Profile  
 
PostPosted: Fri Jan 20, 2012 11:57 pm 
Offline

Joined: Tue Jan 10, 2012 9:42 pm
Posts: 3
Here is what I ended up doing:


This generates the map data in a few layers (basic topography and then terrain features) using a DiamondSquare fractal implementation I found somewhere on the web. I converted a tiny bit but its not mine so I wont post it here. You can find one - there are many. The game 'logic' switch case thing is useful for my map tiles but you'll want to customize it to fit your needs.

Code:
package game;

import game.DiamondSquare;
import java.util.Random;

class MapFactory {
   int topography[][];
   int terrain[][];
   //int specialFeatures[][];   
   String location = "";
   
   public MapFactory(){
      
      int SIZE = 64;
      this.topography = genTopography(SIZE, 1000, 3, 3.0);
      this.terrain = genTerrain(this.topography, SIZE);
      this.location = new MapXMLFile(this.terrain, SIZE, SIZE).location;
   }
   
   //Generates Topography layers
   public int[][] genTopography(int size, int height_seed, int mod, double height) {
      int[][] topMap = new DiamondSquare(size, height_seed, mod, height).data;
      return topMap;
   }

   
   //Generates the Terrain based on layer and probability
   public int[][] genTerrain(int[][] topography, int size) {
      int[][] terMap = new int[size][size];
      int[][] scatterMap = new DiamondSquare(size, 1000, 4, 128.0).data;
      
      //give me a randomizer
      Random diceRoller = new Random();
      int roll = diceRoller.nextInt(10) + 1;
      
      //loop through the map - generate goodies based on 'catagory' and a scatter map over lay.  Overlay application is based on the roll.
      for(int x = 0; x < size; x++){
         for(int y = 0; y < size; y++){
            switch(topography[x][y]) {
               case 0: terMap[x][y] = 0;
                  break;
               case 1:
                  terMap[x][y] = 1;
                  switch(scatterMap[x][y]) {
                     case 0: terMap[x][y] = 1;
                        break;
                     case 1: if (roll > 6) terMap[x][y] = 2;
                        break;
                     case 2:   if (roll > 8) terMap[x][y] = 3;
                        break;
                     case 3: if (roll > 1) terMap[x][y] = 1; else terMap[x][y] = 4;
                        break;
                  }
                  
                  break;
               case 2: terMap[x][y] = 2;
                  terMap[x][y] = 4;
                  switch(scatterMap[x][y]) {                     
                     case 0: terMap[x][y] = 4;
                        break;
                     case 1: if (roll > 6) terMap[x][y] = 5;
                        break;
                     case 2:   if (roll > 8) terMap[x][y] = 6;
                        break;
                     case 3: if (roll > 3) terMap[x][y] = 7; else terMap[x][y] = 4;
                        break;
                  }
                  
                  break;
            }
         }
      }      
      return terMap;
   }
   
   //TODO: generate special locations
   public int[][] genSpecials(){
      
      int[][] specMap = null;
      
      return specMap;
   }
   
   
}



Here is the file writer that converts it into compressed base 64 encoded file. I didnt do 98% of this. I found this on this forum so Im posting it. If someone out there wants credit hit me up. I found this some time ago and am too lazy to find it again to give credit.

Code:
package game;

import java.io.*;
import java.util.zip.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.util.Date;
import org.apache.commons.codec.binary.Base64;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;


public class MapXMLFile {
   String location = "";
   int[][] data;
   
   
   public MapXMLFile(int[][] data, int width, int height) {
      this.data = data;
      this.location = writeTXM(width, height);
   }
   
   public String writeTXM(int w, int h) {
      try {
         DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
         String width = Integer.toString(w);
         String height = Integer.toString(h);
         
         // root elements
         Document doc = docBuilder.newDocument();
         Element mapElement = doc.createElement("map");
         doc.appendChild(mapElement);
         
         mapElement.setAttribute("version","1.0");
         mapElement.setAttribute("orientation", "orthogonal");
         mapElement.setAttribute("width", width);
         mapElement.setAttribute("height", height);
         mapElement.setAttribute("tilewidth", "48");
         mapElement.setAttribute("tileheight", "48");
         
            Element tileset = doc.createElement("tileset");
            tileset.setAttribute("firstgid", "1");
            tileset.setAttribute("name", "tileset");
            tileset.setAttribute("tilewidth", "48");
            tileset.setAttribute("tileheight", "48");
            
               Element image = doc.createElement("image");
               image.setAttribute("source", "tileset.png");
               image.setAttribute("width", "384");
               image.setAttribute("height", "192");
               
            tileset.appendChild(image);
         
         mapElement.appendChild(tileset);
         
         Element layer = doc.createElement("layer");
         layer.setAttribute("name", "layer");
         layer.setAttribute("width", width);
         layer.setAttribute("height", height);
         
            Element data = doc.createElement("data");
            data.setAttribute("encoding", "base64");
            data.setAttribute("compression", "gzip");
               
               String bytestring = new String();
               for (int x = 0; x < w; x++) {                  
                  for (int y = 0; y < h; y++) {
                     switch(this.data[x][y]){
                        case 1: bytestring += "1000";
                           break;
                        case 2: bytestring += "2000";
                           break;
                        case 3: bytestring += "3000";
                           break;
                        case 4: bytestring += "4000";
                           break;
                        case 5: bytestring += "5000";
                           break;
                        case 6: bytestring += "6000";
                           break;
                        case 7: bytestring += "7000";
                           break;
                     }
                  }
               }
               
               Text value = doc.createTextNode(compress(bytestring));
               
               data.appendChild(value);
            
            layer.appendChild(data);
            
         mapElement.appendChild(layer);
         
   
         // write the content into xml file
         TransformerFactory transformerFactory = TransformerFactory.newInstance();
         Transformer transformer = transformerFactory.newTransformer();
         DOMSource source = new DOMSource(doc);
         Date d = new Date();
         String location = "data/map" + d.hashCode() + ".tmx";
         StreamResult result = new StreamResult(new File(location));
   
         // Output to console for testing
         // StreamResult result = new StreamResult(System.out);
   
         transformer.transform(source, result);
   
         System.out.println("Map saved!");
         System.out.println(location);
   
        } catch (ParserConfigurationException pce) {
         pce.printStackTrace();
        } catch (TransformerException tfe) {
         tfe.printStackTrace();
        }
      
      return location;
   }
   private static String compress(String str){
      
      byte byteAry[] = null;
      
      try{
         byteAry = str.getBytes("UTF-8");   
      }catch( UnsupportedEncodingException e){
         System.out.println("Unsupported character set");
      }
      
      for(int i = 0; i < byteAry.length; i++) {
         System.out.println(byteAry[i]);
         if(byteAry[i] == 48)
            byteAry[i] = 0;
         if(byteAry[i] == 49)
            byteAry[i] = 1;
         if(byteAry[i] == 50)
            byteAry[i] = 2;
         if(byteAry[i] == 51)
            byteAry[i] = 3;
         if(byteAry[i] == 52)
            byteAry[i] = 4;
         if(byteAry[i] == 53)
            byteAry[i] = 5;
         if(byteAry[i] == 54)
            byteAry[i] = 6;
         if(byteAry[i] == 55)
            byteAry[i] = 7;
         if(byteAry[i] == 56)
            byteAry[i] = 8;
         if(byteAry[i] == 57)
            byteAry[i] = 9;
         
      }
      ByteArrayOutputStream buffer = new ByteArrayOutputStream();
      
      try {
         OutputStream deflater = new GZIPOutputStream(buffer);
         deflater.write(byteAry);
         deflater.close();
      }catch (IOException e) {
         throw new IllegalStateException(e);
      }
      String results = Base64.encodeBase64String(buffer.toByteArray());
      return results;
   }   
}




Hope this is useful.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group