Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

1075922 Posts in 44152 Topics- by 36120 Members - Latest Member: Royalhandstudios

December 29, 2014, 03:48:40 PM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Help with this level generator
Pages: [1]
Print
Author Topic: Help with this level generator  (Read 631 times)
caladan21ph
Level 0
*


View Profile Email
« on: January 02, 2012, 08:58:51 PM »

Hi! I'm having trouble with this level generator I'm making. Here it is:

package com 
{
   import flash.sampler.NewObjectSample;
   import org.flixel.*;
   /**
    * ...
    * @author
    */
   public class Level extends FlxGroup
   {
      private var _numTilesX:uint;
      private var _numTilesY:uint;
      public var levelMap:FlxTilemap;
      
      private var _levelArray1:Array;
      private var _levelArray2:Array;
      
      private const _tileEmpty:uint = 0;
      private const _tileWall:uint = 1;
      
      private var _diggers:Array;
      private var _activeDiggers:Boolean;
      
      //for debugging
      private var numIterate:uint = 0;
      
      [Embed(source = "../res/tileMap.png")] private const levelPNG:Class;
      
      
      public function Level():void
      {
         
         _numTilesX = 40;
         _numTilesY =30;
         
         initLevelArrays();
         digLevel();
         generateMap();
         
         
         
      }
      
      public function initLevelArrays():void
      {
         _levelArray1 = new Array();
         _levelArray2 = new Array();
         
         for (var yi:uint = 0; yi < _numTilesY; yi++)
         {
            _levelArray1.push(new Array);
            for (var xi:uint=0; xi < _numTilesX; xi++)
            {
               _levelArray1[yi].push(_tileWall);
            }
            
         }
         
      }
      
      
      public function generateMap():void
      {
         for (var yi:uint = 0; yi < _numTilesY; yi++)
         {
            for (var xi:uint = 0; xi < _numTilesX; xi++)
            {
               _levelArray2.push(_levelArray1[yi][xi]);
            }
         }
         
         levelMap = new FlxTilemap();
         levelMap.loadMap(FlxTilemap.arrayToCSV(_levelArray2, _numTilesX), levelPNG, 16, 16);
         
      }
      
      
      public function digLevel():void
      {
         _diggers = new Array();
         //create first digger
         _diggers.push(new Digger(_numTilesX / 2, _numTilesY / 2, _levelArray1));
         
         
         _activeDiggers = checkActiveDiggers();
      
         
         trace(_activeDiggers);
         while (_activeDiggers && _diggers.length!=400)
         {
            for (var i:uint = 0; i < _diggers.length;i++)
            {
               var digger:Digger = _diggers;
               if (digger.activeDigger)
               {
                  digger.moveAndDig();
                  //trace(digger.x);
                  //trace(digger.y);
                  numIterate ++;
                  
               }
               
            }
            
            if (numIterate >= 30) digger.activeDigger = false;
            _activeDiggers = checkActiveDiggers();
         }
         
         
         
         
      }
      
      
      
      
      
      
      
      public function checkActiveDiggers():Boolean
      {
         
         
         //check if there are active diggers if none then finish digging level
         for (var i:uint = 0; i < _diggers.length; i++)
         {
            
            if (_diggers.activeDigger) return true;
         }
         
         return false;
         
      }
      
   }

}



and here's for the digger class:

package com 
{
   import org.flixel.*;
   /**
    * ...
    * @author
    */
   public class Digger extends FlxObject
   {
      private const _tileEmpty:uint = 0;
      private const _tileWall:uint = 1;
      private var _levelArray:Array;
      public var activeDigger:Boolean;
      
      public function Digger(xInTiles:uint,yInTiles:uint,levelArray:Array):void
      {
         super(xInTiles, yInTiles);
         trace(x);
         trace(y);
         _levelArray = levelArray;
         activeDigger = true;
         _levelArray[y]
  • = _tileEmpty;
         
         
      }
      
      public function moveAndDig():void
      {
          var targetLoc:FlxPoint = getTargetLoc();
          //trace(targetLoc);
          x = targetLoc.x;
          y = targetLoc.y;
         _levelArray[y]
  • = _tileEmpty;
         
      }
      
      public function getTargetLoc():FlxPoint
      {
         var availableSpaces:Array = new Array();
         
         for (var i:int = -1; i < 1; i++)
         {
            for (var j:int = -1; j < 1; j++)
            {
               //trace(y);
               //trace(i);
               //trace("y+i=" + (y + i));
               //trace("x+j=" + (x + j));
               //if (Math.abs(y + i) == 1 || Math.abs(x + j) == 1) continue;
               //if (i < 0 || j < 0 || i > _levelArray.length  || j > _levelArray.length) continue;
               if (_levelArray[y + i][x + j] == _tileWall) availableSpaces.push(new FlxPoint(x + j, y + i));
            
            }
         }
         
         var choice:uint = Math.floor(Math.random() * availableSpaces.length);
         trace(choice);
         if (!choice) choice = 0;
         return availableSpaces[choice];
      }
      
      
      
      
   }
      
      
}


anyway, the problem seems to be that choice is undefined. I can't find the problem to why that is. By the way this is what I'm trying to make: http://www.noelberry.ca/category/tutorialsarticles/ .

Thanks!
Logged
st33d
Guest
« Reply #1 on: January 03, 2012, 08:56:19 AM »

Okay. Just some guidelines on posting code first: Less is more, try to post as little code as possible. Also, use the code tags, otherwise some of the code just ends up unreadable.

Looking at the variable "choice", there is no reason for it to be undefined.

In fact, the uint datatype cannot be undefined. Observe:
Code:
var c:uint = undefined;
trace(c); // outputs: 0

On top of this, there is no valid reason to be using the uint datatype unless you are defining a colour or doing binary operations. It is a slower datatype than int. Google it.

Also getTargetLoc looks only at positions to the left and above. Not only that, but it will be able to move diagonally as well. Is that right? I'm assuming you actually just want it to move Up, Down, Left and Right.

You could do that by defining some points:
Code:
var dirs:Array = [new Point(-1, 0), new Point(1, 0), new Point(0,-1), new Point(0,1)];
And just looping through those points to check for free spaces to move into.
Logged
caladan21ph
Level 0
*


View Profile Email
« Reply #2 on: January 03, 2012, 04:55:51 PM »

Code:
Also getTargetLoc looks only at positions to the left and above. Not only that, but it will be able to move diagonally as well. Is that right? I'm assuming you actually just want it to move Up, Down, Left and Right.

Hmm, I'm not sure about this because the author said 'surround' so I assumed all the tiles neighbors including the diagonal ones. How does one usually implement the part where it loops and runs through all the miners and make them dig? I get errors like 'a property is undefined' when ever I use a while loop to make the miners start digging. Whats the easiest way to do this because I'm just starting to learn about procedural level generation.

hmm..the error seems to happen with more iterations. and then Flash develop tells me that " a term is undefined" here:
Code:
if (_levelArray[y + i][x + j] == _tileWall) availableSpaces.push(new FlxPoint(x + j, y + i));
« Last Edit: January 03, 2012, 10:47:03 PM by caladan21ph » Logged
st33d
Guest
« Reply #3 on: January 04, 2012, 02:47:38 AM »

You're not checking that the position to dig is actually inside the diggable area.

By just looking for any tile you will go beyond the boundaries of the map and the program will crash.

Also:

Code:
for(i = -1; i < 1; i++)

will yield: -1, 0

The for loop runs whilst i is less than 1. Thus you are not checking all the neighbours.
Logged
caladan21ph
Level 0
*


View Profile Email
« Reply #4 on: January 05, 2012, 12:23:31 AM »

Thanks it works a bit a bit now, but I'm getting a single large cavern instead of the one with the tunnels.
Logged
Geeze
Level 5
*****


Totally.


View Profile
« Reply #5 on: January 05, 2012, 12:52:37 AM »

I once played around with drunken walk algorithms.
A very simple approach to make diggers make more tunnel-like shapes is simply raising the probability of going in same direction.

In my version there was 1/5 chance to go in some specific cardinal direction and 1/5 chance to go in the same direction as on the last turn.
Logged

Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic