Roguelike Dungeon - Spider Approach
Reference : http://pcgbook.com/wp-content/uploads/2013/09/chapter3.pdf
make spiders ->
rotate check -> dig check -> go forward.
each action consumes energy, and depleted spider stops.
simple algorithm.
/**
* Copyright greentec ( http://wonderfl.net/user/greentec )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/pYYh
*/
package
{
import com.bit101.components.CheckBox;
import com.bit101.components.PushButton;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
/**
* ...
* @author ypc
*/
[SWF(width=465, height=465, backgroundColor=0x292929, frameRate=12)]
public class Main extends Sprite
{
public var dungeonMapArray:Array = new Array(); // 0 - wall, 1 - floor
public var dungeonMapWidth:int = 40;
public var dungeonMapHeight:int = 40;
public var dungeonMapCellWidth:int = 10;
public var dungeonMapCellHeight:int = 10;
public var dungeonMapBitmapData:BitmapData;
public var dungeonMapBitmap:Bitmap;
public var dungeonMapSprite:Sprite;
public var backgroundColor:uint = 0x292929;
public var wallColor:uint = 0x1C0F00;
public var floorColor:uint = 0xB9A87D;
public var spiderSprite:Sprite;
public var spiderNum:int = 40;
public var roomWidth:int = 3;
public var roomHeight:int = 3;
public var spiderDigInitProb:int = 5;
public var spiderDigPlusProb:int = 15;
public var spiderRotateInitProb:int = 5;
public var spiderRotatePlusProb:int = 15;
public var spiderDigList:Array = new Array();
public var spiderArray:Array = new Array();
public var spiderInitEnergy:int = 150;
/*
* spider heading
* 3-N
* 2-W s 0-E
* 1-S
* */
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
stage.scaleMode = "noScale";
var i:int, j:int;
var _resetButton:PushButton = new PushButton(this, 10, dungeonMapHeight * dungeonMapCellHeight + 10, "Reset", onReset);
var _showSpider:CheckBox = new CheckBox(this, _resetButton.x, _resetButton.y + _resetButton.height + 10, "Hide Spider", onShowSpider);
dungeonMapBitmapData = new BitmapData(400, 400, false, backgroundColor);
dungeonMapBitmap = new Bitmap(dungeonMapBitmapData);
dungeonMapSprite = new Sprite();
dungeonMapSprite.addChild(dungeonMapBitmap);
addChild(dungeonMapSprite);
//initDungeonMap();
for (i = 0; i < dungeonMapWidth; i += 1)
{
dungeonMapArray[i] = new Array();
for (j = 0; j < dungeonMapHeight; j += 1)
{
dungeonMapArray[i].push(0); //push wall
}
}
drawMap(); // use dungeonMapArray, everytime redraw
for (i = 0; i < 8; i += 1)
{
spiderDigList[i] = [];
}
spiderDigList[0] = [ 1, 0];
spiderDigList[1] = [ 1, 1];
spiderDigList[2] = [ 0, 1];
spiderDigList[3] = [ -1, 1];
spiderDigList[4] = [ -1, 0];
spiderDigList[5] = [ -1, -1];
spiderDigList[6] = [ 0, -1];
spiderDigList[7] = [ 1, -1];
spiderSprite = new Sprite();
addChild(spiderSprite);
addSpider();
}
private function onShowSpider(e:Event):void
{
if (e.target.selected)
{
e.target.label = "Show Spider";
spiderSprite.alpha = 0;
}
else
{
e.target.label = "Hide Spider";
spiderSprite.alpha = 1;
}
}
private function onReset(e:Event):void
{
var i:int;
//stop onSpiderMove()
removeEventListener(Event.ENTER_FRAME, onSpiderMove);
//reset DungeonMap
initDungeonMap();
//reset Spider
resetSpider();
addEventListener(Event.ENTER_FRAME, onSpiderMove);
}
private function resetSpider():void
{
var i:int;
var spider:Spider;
for (i = 0; i < spiderNum; i += 1)
{
spider = spiderArray[i];
spider.energy = spiderInitEnergy;
spider._x = Math.random() * dungeonMapWidth;
spider._y = Math.random() * dungeonMapHeight;
spider.digProb = spiderDigInitProb;
spider.rotateProb = spiderRotateInitProb;
spider.heading = Math.random() * 4;
spider.rotation = spider.heading * 90;
spider.x = spider._x * dungeonMapCellWidth + dungeonMapCellWidth / 2;
spider.y = spider._y * dungeonMapCellHeight + dungeonMapCellHeight / 2;
dungeonMapArray[spider._x][spider._y] = 1;
}
}
private function addSpider():void
{
var i:int, j:int;
var spider:Spider;
var _x:int, _y:int;
for (i = 0; i < spiderNum; i += 1)
{
_x = Math.random() * dungeonMapWidth;
_y = Math.random() * dungeonMapHeight;
spider = new Spider(_x, _y, spiderInitEnergy); //trace(_x, _y);
spider.digProb = spiderDigInitProb;
spider.rotateProb = spiderRotateInitProb;
spider.heading = Math.random() * 4;
spider.rotation = spider.heading * 90;
spider.x = _x * dungeonMapCellWidth + dungeonMapCellWidth / 2;
spider.y = _y * dungeonMapCellHeight + dungeonMapCellHeight / 2;
spiderArray.push(spider);
spiderSprite.addChild(spider);
dungeonMapArray[_x][_y] = 1; //set floor
}
addEventListener(Event.ENTER_FRAME, onSpiderMove);
}
private function onSpiderMove(e:Event):void
{
var i:int, j:int;
var spider:Spider;
var digX:int, digY:int;
for (i = 0; i < spiderArray.length; i += 1)
{
spider = spiderArray[i];
if (spider.energy > 0)
{
if (Math.random() * 100 < spider.rotateProb) // rotate
{
if (Math.random() < 0.5)
{
spider.heading -= 1;
if (spider.heading == -1)
{
spider.heading = 3;
}
}
else
{
spider.heading += 1;
if (spider.heading == 4)
{
spider.heading = 0;
}
}
spider.rotation = spider.heading * 90;
spider.energy -= spider.rotateEnergy;
}
else
{
spider.rotateProb += spiderRotatePlusProb;
}
}
if (spider.energy > 0)
{
if (Math.random() * 100 < spider.digProb) // dig
{
for (j = 0; j < spiderDigList.length; j += 1)
{
digX = spider._x + spiderDigList[0];
digY = spider._y + spiderDigList[1];
if (digX >= 0 && digY >= 0 && digX < dungeonMapWidth && digY < dungeonMapHeight)
{
if (dungeonMapArray[digX][digY] == 0)
{
dungeonMapArray[digX][digY] = 1; //set floor - dig!
spider.energy -= spider.digOneCellEnergy;
}
}
}
//spider.energy -= spider.digEnergy;
}
else
{
spider.digProb += spiderDigPlusProb;
}
}
if (spider.energy > 0) // dig one Cell, walk
{
digX = spiderDigList[spider.heading * 2][0] + spider._x;
digY = spiderDigList[spider.heading * 2][1] + spider._y;
if (digX >= 0 && digY >= 0 && digX < dungeonMapWidth && digY < dungeonMapHeight)
{
if (dungeonMapArray[digX][digY] == 0)
{
dungeonMapArray[digX][digY] = 1;
spider.energy -= spider.digOneCellEnergy;
}
spider._x = digX;
spider._y = digY;
spider.x = digX * dungeonMapCellWidth + dungeonMapCellWidth / 2;
spider.y = digY * dungeonMapCellHeight + dungeonMapCellHeight / 2;
}
}
}
drawMap();
}
private function initDungeonMap():void
{
var i:int, j:int;
for (i = 0; i < dungeonMapWidth; i += 1)
{
for (j = 0; j < dungeonMapHeight; j += 1)
{
dungeonMapArray[i][j] = 0; //push wall
}
}
}
private function drawMap():void
{
var i:int, j:int;
dungeonMapBitmapData.fillRect(dungeonMapBitmapData.rect, backgroundColor);
for (i = 0; i < dungeonMapArray.length; i += 1)
{
for (j = 0; j < dungeonMapArray[i].length; j += 1)
{
var cellColor:uint = 0xffffff;
switch(dungeonMapArray[i][j])
{
case 0: // wall
cellColor = wallColor;
break;
case 1: // floor
cellColor = floorColor;
break;
default:
cellColor = backgroundColor;
break;
}
dungeonMapBitmapData.fillRect(new Rectangle(i * dungeonMapCellWidth + 2, j * dungeonMapCellHeight + 2, dungeonMapCellWidth - 2, dungeonMapCellHeight - 2), cellColor);
}
}
}
}
}
Class
{
import flash.display.Graphics;
import flash.display.Sprite;
/**
* ...
* @author ypc
*/
class Spider extends Sprite
{
public var id:int;
public var digProb:int;
public var rotateProb:int;
public var energy:int;
//public var digEnergy:int = 16;
public var rotateEnergy:int = 2;
public var digOneCellEnergy:int = 4;
//public var walkEnergy:int = 1;
public var _x:int;
public var _y:int;
public var heading:int;
public function Spider(_x:int, _y:int, energy:int)
{
this._x = _x;
this._y = _y;
this.energy = energy;
draw();
}
private function draw():void
{
var g:Graphics = this.graphics;
g.beginFill(0xff80ff);
g.lineStyle(0, 0xffffff);
g.moveTo(5, 0);
g.lineTo( -5, -4);
g.lineTo( -5, 4);
g.lineTo(5, 0);
g.endFill();
}
}
}