2D random dungeon with FOV
1. make random dungeon (with iteration and attenuation)
2. add fog of war and Field of view
3. add character move code (wasd or arrow keys)
I will add more things!
- monster, stat, minimap, stair, death, animation...
/**
* Copyright greentec ( http://wonderfl.net/user/greentec )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7saV
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.filters.BitmapFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import com.bit101.components.PushButton;
/**
* ...
* @author ypc
*/
[SWF(width="465", height="465", backgroundColor="#292929")]
public class Main extends Sprite
{
public var tileBitmapData:BitmapData;
//public var tileBitmap:Bitmap;
public var mapBitmapData:BitmapData;
public var mapBitmap:Bitmap;
public var mapArray:Array = [];
public var mapWidth:int = 32;
public var mapHeight:int = 32;
//[Embed(source = "normal.png")]
//public var tileImage:Class;
//[Embed(source = "char1.png")]
//public var tileImage:Class;
//
//public var colorMap:Object = { };
//public var colorArray:Array = [];
//public var colorBitmapIntegers:Array = [];
public var tileColorArray:Array = [0x301800, 0x200000, 0xe07000, 0x804000, 0x603000, 0x402000, 0xa05000, 0xc06000, 0x101010, 0x505050, 0x606060, 0x404040, 0x303030, 0x202020];
public var tileBitmapString:String = "011010100234445400101000023636440276226717643435056226731343633517636634133663340673434306343435023363400736343403336343033433450763343316633445176634441764443002667364063435450743453403334454127666330733445413346445173455450737344403434555066343540534545416334334010100101634434501101001043635450776767407643440056767670246434416336334063634011366333402734345036634341763454516366345076334541433334413365454076336450633444515463434076345441633444502445455143443451334454506363440035545550763343405445455036344000011001003445434010001110633440414767665136543550576767407343445023363440633434416636334174443400263645303343435073363440334340513363344066334441363444317344454023443430433434506343343036343450264343415343454067634451534450516634334055454540633434015554054076366440010100007664450001010000364334516737345063334011566773516334450063634341364454413636444023445050763444407634345163634431743545113633435166334441763463502334545063643340764345506363455025434540363334403434545036343450345455003636445063445450764340001101010023444540010100002363644114622671764343505622674134363351472763413366334037343430634343503236340073634340633634303343345037334331663344517663444176544300276736406343345154343340343545412666633076344441104644414345545073734440743343404514633011111111633433406464344167153440157677604363545034344450767111505734343024643441334345506363651176634340273434505434345176345331436634507643454101010111336444501155455043345111546343407635454147711110005510014344345153445450633763306700011076334341111110003334500076766001733643501577766063344041733437613663345057436340734344512663444163343441764643417444340073336330334343507336344033434051636363416634454166344451734445402636333053343450334335107634345026334341554345406764501163404051633436301010100063450661345405407636334067676630345664405440500026436451763734500563454000000051733444007363435137445441367776407344335076345440763434516363443174343411363345516633444176346350233344506364334076434550636345507543454036333450343454503634345034545400363644506344545076434000110101002344454001010010236364400462267176434350562245013436335147266341336633406734665111154550423634007363434033363640675111100433433166334451766343617376651005443640634354507434534063344331275543307335454133464431734554507373554054545550673435405345454163343351100001017344345011010010436354500100763076434400567676302464344100373340636340113663334027343450066343417634545163663450763345414333344133654540763364506364444154634340063454416334445024454441434434510044545013634400355454505633434000004550513450000110110554444340100011106555334147651551115435505767674073734450237400505665344166363341744434002636701033434350733634403343405133633605663344413634443173444540234434654334345063433430363434502643437153434540676344515344505167743343554545407334340155540540763774400101000076644500010100000643635107373450633340110007735100343400636343413644063100364440670540507634444046450351036344317470001136334351500064417634635023377450636433400663455063634550254345403633344034345450363434503454550036364450634454507643400011010100234445400101000023636440374446717643435056226731343633517646634133663340673434301043435033363400736343403336343005533450464343316633445176634441110553003467364053435450743453501111054147666331555545413346451111555050737344411114555066343511511115016334334010100101534434501101001043635450546551511513441115577450446434414336351073534011577633402734345054334351763154516446345076734541433434115765151063344450673444515453435007345401434444502445450143543451534400016463450035545150463443500511011043335000011011005445534011001110443400514767015146543550505577507345055023367010633435410577335174501500263675004343435005363400351510513363375056434541503445511011554023443630053434505743340105151410264343615043454157634551111451116734336015554551633454011551011076366440010100017665450001011100364334511557345063434011114773516334450057734341554454411636544043445050563444407354345143634531111115117733435167750341763463507265115073643340764650006363455025466410363334403433675036343450745455003636445063444400764340088888888888888888888888888888888889aa9bac8c9ab9bddc9baa9bd899aac8abcdddbd8bdcdbcd8adcdddd8addcd889cbdbbdd89dccbd89cd9bccd8ad9bdd8adbccdcd8b8dbdd89bbb9bcd8cbccbd89ccddcd8d8dd8889c9dcdbb88ddd9dc8acdd888d899cdd8bdcbdbbd8d8dcbbc8bdd88d89bccdd8d8ddc9cd8d8d8ddcd89888d88cdbdcdd88d8ddcd88d8d8ddd8b8bbd888dbcdbcd88bbc88dbcd8dd8d88b9cdb9c89c9ddc8bccdd8bc9cdd8888dcdc89cdc8bcbdd8dddcd8bddbcdcd88c9bc8bddc8bcbcd8dcccd8cdc9dbbdd8add8dddcbd8ddd8dccdd8d88dcbcdbd8acbd8cdd9cd8ccd88d8888d8db9bbcd89cd8ddbbcdd8cdd8d88b9d888dcccdc8add8d8dcbc88dd88889cdcd888dddcd88d8888dcdd8bc88cd8bdbddd8888dcd8d8dbbd8dd8bccddddc8cbcdc8cdd88d8abcd9dd888bcdcbbdd8dcdcd8dcbd888a9d9bd89bd8d8bdcdd88dcd89db9d8889bdccd9dc98d8cddd8bd8888bc9bbd88888888bcdb99d88889ccd8888dbbdd88a8cc8bcdbddc9b889dcbd89cd8dd8888b9bd8bcd99ccc888bdbdd89ddc88ddd89ddb88dccbcd8bdd8ddd89d9bbdddcd8ac888d8dcdb89cbd8d88bccbddddbdc88899d888dc889dccd8888ddcdb9dbdb8ccbdbc8d8889cbcdd8b998dddbccddc8a9ddbc888dbdbbddc89cbb88dddbbcc8abdccdd8d8bcdccdd89dcdd8dddddcc8bdccccdd88ddcddcd8cdddd88888ddd88888888888888888888888888888888888ba9bac8c9ab9bddc9baa9b9b9d8d888baccdbd8bdcdbcdcadcddbcbdc9dd889ac9cbdd89dccbd8dda9bccbdcd9b9d8a9bbcdcd8b8dbdd88ddb9bcbcdbccbd89cbcdbd8d8dd888dd8ddacbcbddd9dc8ab9cb88d899bc9cbdc88dbdddcdcbbc8bcbcdd89bccddd9dcb888d8dcd8ddcd89bcdcd8cdbdcbcbcbcdd88888888ddd8bcbccd88dbcdbdbcccbcc8dbcd8dd8d888dddb9c89b9cbdcbccdd8bc9cdd8888d88889cdc89cbddbcdddc8bddbcdcd88c9b88bddc8bcbccddcccd8cdc9dbbdd8add8dddcbd8ddd8dccdd8d88dcbcdbd8acbd8cdd9cd8ccd88d8888d8db9bbcd89cd8ddbbcdd88888d88b9d8d8dcccdc8add8d8dcb888dd88889cdcd888dddcd88d8888dc888bbc8dd8bdbddd8d88dcd8d8dbbd888bbccccddc8cbcdc8cdd88d8abcd9dd899ccdcdcdd8dcdcd8dcbd888a9d9bd89cdddcddcdd88dcd89db9d8889bdccd9cccdcddcdd8bd8888bc9bbd88888888bcdcdcdcd889ccd8888dbbdd88a8cc8bcdbddcdd889dcbd89cd8dd8888b9bd8bcd99ccc888bdbdd89ddc88d8d89ddb88dccbcd8bdd8ddd89d9bbd888d8ac888d8dcdb89cbd8d88bccbdd889dc88899d888dc889dccd8888ddcd8c9bdb8ccbdbc8d8889cbcdd8b998ddd89bcdc8a9ddbc888dbdbbddc89cbb888d9bbcc8abdccdd8d8bcdccdd89dcdd8d9bcccc8bdccccdd88ddcddcd8cdddd88bc8ddd88888888888888888888888888888888889aa98cd8b9ab9bddc9baa9bd899aac8abccdd8c9cdcdbcd8adcdddd89bbcd889ccdbbd89cdccbd89cd9bccd8ab9bdd8adbccdcd8b8dbdd89bbb9bcd8abccbd8dbcddcd8d8dd8889c9dcdbb8abcb9dc88dbb888d9bbcdd8bdcbdbbdcaccbbbc8dc888d89cbcdd8d8ddc9cd8abdccbcd888d8d88bdcdcdd88d8ddcd8accdccbd8dcbbd888dbcdbcd88bbc88acbbbdcbd8bb9bbb9b8889ddc8bcbdd8accccddd889cdcb9ccbbb88dd8bddcd8bcbbcccb88a9bdcbcbcdcc8cd8dcccd8cdc9dcddd89ddddcbddddcd88dccdd8d88d9ccdcd8bccddcccddddc8888d8888d8dcbdccd8bcddddcdccddcd88d8bb9d888dcccdc8adddcddccdddcd8888ccccd888ddddd8bdddcdcdcdcdd88cd8bbcbdd8888dcd8c9ccdbcddccdcd8ddbbddcdbdcdd88d88bdcddbcdcdddc8bdcddcdcddbcbd888889dccbcbcdcd8bcdddccccddbd9d888c98cddcccdcd88bccdbdcdbccdddbd889b98ddccdd88888cbdbdbdccdbbddd889ccc8ddd88d99b8bcccddccbcdddd888bccd8bc889cddd8bddccdcbccdcdddd89ddb88889bcccb8dcdcbbdccddcddcd8ac888d8d9dcddc8dcbccdddcdcddbdc88899d88cccdccd88dcddccbdcccdbdb8ccbdbc8ddcc9cbc8dcb99dcddcdcddc8a9ddbc88ddcdbbdd8cccbcccdddbbcc8abdccdd8d8bcdccd88cdccdccddddcc8bdccccdd88ddcddcd8cdddd88888ddd88888888888888888888888888888888889aa88abbc9ab9b88c9baa9bd899aac8abcd8bbddddcdbc88adcdddd8addcd889cbd8bddcccdcdc89cd9bccd8ad9bdd8adbc8dcddcdddcd89bbb9bc88cbccbd89ccd8cd8dcdcccd9c9dcdb888ddd9dc8acddd88dcdcddc8bdcbd8888d8dcbbc8bdd8dd88dccdcdd888d98d8d8d8ddcd89ddd888d8ddccd8ddd8d8d88d8d8ddd8bd8d8d88dbccd8d8cddd88dbcd8dd8d888d88b9c89dd8ddc9c88d8bc9cdd8888dc8d89c8c8b888c9cdd88ddddbcdcd88c9bc8b8dcdc8cc9cdbcd88ddc9dbbdd8adddd888dc8cdcdcdbcc88d8888cdbd8acbd888888c8dd8ddcbbcc8ddd8bbcd89cd8ddcbc8dd88d8dccbcd88d8cccdc8add8dcdcb8c8dc888ddcbdd8d8dddcd88d888ccc88bd99cddcdcdd8dd888dcd8d8dc8d8cb9bbcbdd8dcdd88c8cdd88d8acccc888bc9cccdc8d8888d8ddcbd888a9bcb888bcbccdddd8dbcdcdddb9d8889cdcc898dbbcdcc88dbdcd8d889bbd888cddd88cddcdcddd8ccddd8888bbdd88acdb8b888d8d8dd8dd88dd9cd88d8888b9bd8bc888d8d888888d889ddc88ddd89ddb88dc88888bd88d8d89d9bbdddcd8ac888d8d8db89cbd8d8dbccbddddbdc88899d888dc889dccd8888ddcdb9dbdb8ccbdbc8d8889cbcdd8b998dddbccddc8a9ddbc888dbdbbddc89cbb88dddbbcc8abdccdd8d8bcdccdd89dcdd8dddddcc8bdccccdd88ddcddcd8cdddd88888ddd";
public var charColorArray:Array = [0x0, 0xff774e39, 0xff291f14, 0xff282038, 0xffd48c52, 0xff000000, 0xff452e30, 0xffa397db, 0xffebb385, 0xffc9ccf8, 0xffa17854, 0xfffcd9af, 0xff806cb3, 0xffc1ab84, 0xff838670, 0xff506ba5];
public var charBitmapString:String = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000000000200022000000031445500000000000006202622220003718163500000000200212661622000379a863b850000000622612616228220699a134b850000002126116116662222777ca31445000000616a16a16166611622c63551550000006a1d1a16116228841ccccc3ccc3650021daaa111162e99b8437797cc773ee6561aa1666662155ffb8179997c793bde161a161aa162155ffbb4c9999c793bdea611611ada162888bbb41ad11311ddee166111aa66222288bbb81199c3ce6ee65266166622bbb888bbb81aad13ed6550026662222bbbb888bbb81199c3ce6ee65661a26222bbb888bbb41ad11311ddee161aa61aa622155ffbb4c9999c793bdea61da161da16255ffb8179997c793bde121a1a166111629b98417797cc773ee652616d1662661628841ccccc3ccc3650002161a1662226611622c63551550000002626111666622222777ca314450000000202611166228220699a134b850000000000216266222000379a863b850000000000262026222200037181f3500000000000020002200000003144550000000000000000002000000000110000000000000000000000000000000000000000000000000000000000000000000000000";
public var roomMinWidth:int = 6;
public var roomMaxWidth:int = 10;
public var directionSelectMax:int = 4;
public var directionSelectProb:int = 90;
public var attenuationMin:int = 70; //make room smaller
public var attenuationMax:int = 90;
public var attenuationNumMax:int = 4;
public var corridorMin:int = 1;
public var corridorMax:int = 4;
public var startPointX:int;
public var startPointY:int;
public var cameraPointX:int;
public var cameraPointY:int;
public var char:Character;
public var fogBitmapData:BitmapData;
public var fogBitmap:Bitmap;
public var fogArray:Array = [];
public var lightSourceDistance:int = 7;
public var noiseBitmapData:BitmapData;
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";
tileBitmapData = new BitmapData(32 * 8, 32, true, 0x0);
//initialize tile graphics with color compressed string
var i:int, j:int;
var index:int;
for (i = 0; i < 256; i += 1)
{
for (j = 0; j < 32; j += 1)
{
index = parseInt("0x" + tileBitmapString.substr(i * 32 + j, 1));
tileBitmapData.setPixel32(i, j, 0xff << 24 | tileColorArray[index]);
}
}
//initialize map array
for (i = 0; i < mapWidth; i += 1)
{
for (j = 0; j < mapHeight; j += 1)
{
mapArray.push(-1);
}
}
//make random dungeon
var roomW:int = int(Math.random() * (roomMaxWidth - roomMinWidth)) + roomMinWidth;
var roomH:int = int(Math.random() * (roomMaxWidth - roomMinWidth)) + roomMinWidth;
var roomX:int = int(mapWidth / 2 - roomW / 2);
var roomY:int = int(mapHeight / 2 - roomH / 2);
makeRoom(roomX, roomY, roomW, roomH, 1);
//make edge wall for natural map - south, east
for (i = 0; i < mapWidth; i += 1)
{
mapArray[i * mapHeight + mapWidth - 1] = 1; //south
}
for (i = 0; i < mapHeight; i += 1)
{
mapArray[(mapWidth - 1) * mapHeight + i] = 1; //east
}
//draw tile to map
mapBitmapData = new BitmapData(32 * mapWidth, 32 * mapHeight, false, 0x0);
for (i = 0; i < mapWidth; i += 1)
{
for (j = 0; j < mapHeight; j += 1)
{
index = Math.random() * 4;
if (mapArray[i * mapHeight + j] == 0) //floor
{
index += 4;
}
//draw tile
mapBitmapData.copyPixels(tileBitmapData, new Rectangle(32 * index, 0, 32, 32), new Point(i * 32, j * 32));
}
}
//set camera and starting point
mapBitmap = new Bitmap(mapBitmapData);
startPointX = int(Math.random() * roomW) + roomX;
startPointY = int(Math.random() * roomH) + roomY;
cameraPointX = startPointX - 7;
cameraPointY = startPointY - 7;
mapBitmap.x = -1 * 32 * cameraPointX;
mapBitmap.y = -1 * 32 * cameraPointY;
addChild(mapBitmap);
//initialize character
var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x0);
for (i = 0; i < 32; i += 1)
{
for (j = 0; j < 32; j += 1)
{
index = parseInt("0x" + charBitmapString.substr(i * 32 + j, 1));
if (index != 0)
{
bitmapData.setPixel32(i, j, charColorArray[index]);
}
}
}
char = new Character(startPointX, startPointY, new Bitmap(bitmapData));
char.x = 32 * 7;
char.y = 32 * 7;
addChild(char);
//character move listener
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
//initialize fog
fogBitmapData = new BitmapData(32 * mapWidth, 32 * mapHeight, true, 0xff000000);
fogBitmap = new Bitmap(fogBitmapData);
fogBitmap.x = mapBitmap.x;
fogBitmap.y = mapBitmap.y;
addChild(fogBitmap);
for (i = 0; i < mapWidth; i += 1)
{
for (j = 0; j < mapHeight; j += 1)
{
fogArray.push( -1);
}
}
//initialize fog noise
noiseBitmapData = new BitmapData(32, 32, true, 0);
noiseBitmapData.noise(int.MAX_VALUE * Math.random(), 0, 50, 7, true);
noiseBitmapData.colorTransform(noiseBitmapData.rect, new ColorTransform(1, 1, 1, 0.1, 0, 0, 0, 0));
//noiseBitmapData.noise(int.MAX_VALUE * Math.random(), 0, 255, 7);
drawFog();
var button:PushButton = new PushButton(this, 465 - 110, 465 - 30, "Reset", onReset);
//tileBitmapData.fillRect(new Rectangle(0, 0, 32, 32), 0xffff0000);
//graphic compress code!!
/*
var bmp:Bitmap = new tileImage();
var bitmapData:BitmapData = bmp.bitmapData;
var _width:int = bitmapData.width;
var _height:int = bitmapData.height;
var color:uint;
for (i = 0; i < _width; i += 1)
{
for (j = 0; j < _height; j += 1)
{
color = bitmapData.getPixel32(i, j);
if (colorMap.hasOwnProperty(color) == false)
{
colorMap[color] = 1;
colorArray.push(color);
}
colorBitmapIntegers.push(colorArray.indexOf(color).toString(16));
}
}
trace(colorArray.length);
var str:String = "";
for (i = 0; i < colorArray.length; i += 1)
{
str += "0x" + colorArray[i].toString(16) + ",";
}
trace(str);
trace("");
trace(colorBitmapIntegers.join(""));
*/
}
private function onReset(e:Event):void
{
var i:int, j:int;
var index:int;
//reset map array
for (i = 0; i < mapWidth; i += 1)
{
for (j = 0; j < mapHeight; j += 1)
{
mapArray[i * mapHeight + j] = -1;
}
}
//make random dungeon
var roomW:int = int(Math.random() * (roomMaxWidth - roomMinWidth)) + roomMinWidth;
var roomH:int = int(Math.random() * (roomMaxWidth - roomMinWidth)) + roomMinWidth;
var roomX:int = int(mapWidth / 2 - roomW / 2);
var roomY:int = int(mapHeight / 2 - roomH / 2);
makeRoom(roomX, roomY, roomW, roomH, 1);
//make edge wall for natural map - south, east
for (i = 0; i < mapWidth; i += 1)
{
mapArray[i * mapHeight + mapWidth - 1] = 1; //south
}
for (i = 0; i < mapHeight; i += 1)
{
mapArray[(mapWidth - 1) * mapHeight + i] = 1; //east
}
//draw tile to map
mapBitmapData.fillRect(mapBitmapData.rect, 0x0);
for (i = 0; i < mapWidth; i += 1)
{
for (j = 0; j < mapHeight; j += 1)
{
index = Math.random() * 4;
if (mapArray[i * mapHeight + j] == 0) //floor
{
index += 4;
}
//draw tile
mapBitmapData.copyPixels(tileBitmapData, new Rectangle(32 * index, 0, 32, 32), new Point(i * 32, j * 32));
}
}
//set camera and starting point
startPointX = int(Math.random() * roomW) + roomX;
startPointY = int(Math.random() * roomH) + roomY;
cameraPointX = startPointX - 7;
cameraPointY = startPointY - 7;
mapBitmap.x = -1 * 32 * cameraPointX;
mapBitmap.y = -1 * 32 * cameraPointY;
//reset character
char.posX = startPointX;
char.posY = startPointY;
char.x = 32 * 7;
char.y = 32 * 7;
//reset fog
fogBitmapData.fillRect(fogBitmapData.rect, 0xff000000);
fogBitmap.x = mapBitmap.x;
fogBitmap.y = mapBitmap.y;
for (i = 0; i < mapWidth; i += 1)
{
for (j = 0; j < mapHeight; j += 1)
{
fogArray[i * mapHeight + j] = -1;
}
}
drawFog();
}
private function drawFog():void
{
var i:int, j:int;
var maxScreenX:int = Math.min(cameraPointX + 15, mapWidth);
var maxScreenY:int = Math.min(cameraPointY + 15, mapHeight);
var dist:int;
//judge line of sight
var lineSightArray:Array = [];
for (i = cameraPointX; i < maxScreenX; i += 1)
{
for (j = cameraPointY; j < maxScreenY; j += 1)
{
lineSightArray.push( -1);
}
}
lineSightArray[(char.posX - cameraPointX) * 15 + (char.posY - cameraPointY)] = 0;
var dx:Number;
var dy:Number;
var nowX:Number;
var nowY:Number;
for (i = -180; i <= 180; i += 1)
{
dx = Math.cos(Number(i) * 0.01744);
dy = Math.sin(Number(i) * 0.01744);
nowX = char.posX + dx + 0.5;
nowY = char.posY + dy + 0.5;
for (j = 0; j < 7; j += 1)
{
lineSightArray[int(nowX - cameraPointX) * 15 + int(nowY - cameraPointY)] = 0;
if (mapArray[int(nowX) * mapHeight + int(nowY)] != 0)
{
break;
}
nowX += dx;
nowY += dy;
}
}
//initialize fogAlpha : visited -> 0
for (i = cameraPointX; i < maxScreenX; i += 1)
{
for (j = cameraPointY; j < maxScreenY; j += 1)
{
if (fogArray[i * mapHeight + j] > 0)
{
fogArray[i * mapHeight + j] = 0;
}
}
}
//calculate distance from char (light source)
for (i = cameraPointX; i < maxScreenX; i += 1)
{
for (j = cameraPointY; j < maxScreenY; j += 1)
{
dist = Math.abs(char.posX - i) + Math.abs(char.posY - j);
if (dist <= lightSourceDistance)
{
if (lineSightArray[(i - cameraPointX) * 15 + (j - cameraPointY)] == 0) //can see
{
fogArray[i * mapHeight + j] = lightSourceDistance - dist;
}
else
{
//fogArray[i * mapHeight + j] = 0;
}
}
}
}
//trace((char.posX - cameraPointX), (char.posY - cameraPointY));
//draw fog
fogBitmapData.fillRect(new Rectangle(cameraPointX * 32, cameraPointY * 32, (maxScreenX - cameraPointX) * 32, (maxScreenY - cameraPointY) * 32), 0x00ffffff);
var fogRect:Rectangle;
var fogAlpha:int;
var color:uint;
for (i = cameraPointX; i < maxScreenX; i += 1)
{
for (j = cameraPointY; j < maxScreenY; j += 1)
{
fogRect = new Rectangle(i * 32, j * 32, 32, 32);
fogAlpha = fogArray[i * mapHeight + j];
//trace((i - cameraPointX), (j - cameraPointY));
//trace(lineSightArray[(i - cameraPointX) * mapHeight + (j - cameraPointY)]);
if (fogAlpha == -1) //unvisited
{
fogBitmapData.fillRect(fogRect, 0xff000000);
}
else if (lineSightArray[(i - cameraPointX) * 15 + (j - cameraPointY)] == -1) //can't see, but visited
{
color = ((lightSourceDistance - 0) / (lightSourceDistance + 1) * 255) << 24; //+1 for visited place
fogBitmapData.fillRect(fogRect, color);
//add noise
fogBitmapData.draw(noiseBitmapData, new Matrix(1, 0, 0, 1, i * 32, j * 32), null, "lighten");
}
else
{
if (lineSightArray[(i - cameraPointX) * 15 + (j - cameraPointY)] == 0) //can see, visited
{
color = ((lightSourceDistance - fogAlpha) / (lightSourceDistance + 1) * 255) << 24; //+1 for visited place
fogBitmapData.fillRect(fogRect, color);
//add noise
//fogBitmapData.applyFilter(noiseBitmapData, noiseBitmapData.rect, new Point(i * 32, j * 32), new BitmapFilter());
fogBitmapData.draw(noiseBitmapData, new Matrix(1, 0, 0, 1, i * 32, j * 32), null, "lighten");
//fogBitmapData.draw(noiseBitmapData, new Matrix(1, 0, 0, 1, i * 32, j * 32), null, "multiply");
}
}
}
}
/*
for (i = 0; i < 15; i += 1)
{
var str:String = "";
for (j = 0; j < 15; j += 1)
{
str = str.concat(String(lineSightArray[i * 15 + j]) + "\t");
}
trace(str);
}
*/
}
private function onKeyDown(e:KeyboardEvent):void
{
switch(e.keyCode)
{
case 87: //w
case 38: //Up
//wall check
if (char.posY - 1 >= 0 &&
mapArray[char.posX * mapHeight + (char.posY - 1)] == 0)
{
charMove(0, -1);
drawFog();
}
break;
case 83: //s
case 40: //Down
//wall check
if (char.posY + 1 < mapHeight &&
mapArray[char.posX * mapHeight + (char.posY + 1)] == 0)
{
charMove(0, 1);
drawFog();
}
break;
case 65: //a
case 37: //Left
//wall check
if (char.posX - 1 >= 0 &&
mapArray[(char.posX - 1) * mapHeight + char.posY] == 0)
{
charMove( -1, 0);
drawFog();
}
break;
case 68: //d
case 39: //Right
//wall check
if (char.posX + 1 < mapWidth &&
mapArray[(char.posX + 1) * mapHeight + char.posY] == 0)
{
charMove(1, 0);
drawFog();
}
break;
}
}
private function charMove(moveX:int, moveY:int):void
{
//trace(char.posX, char.posY, cameraPointX, cameraPointY);
char.posX += moveX;
char.posY += moveY;
/*
//edge move - don't scroll map
if (cameraPointX == 0)
{
char.x += moveX * 32;
char.y += moveY * 32;
//mapBitmap.y -= moveY * 32;
return;
}
if (cameraPointY == 0)
{
char.x += moveX * 32;
char.y += moveY * 32;
//mapBitmap.x -= moveX * 32;
return;
}
*/
//map scroll
if (char.posX - cameraPointX == 3 && cameraPointX != 0)
{
mapBitmap.x += 32;
cameraPointX -= 1;
fogBitmap.x = mapBitmap.x;
return;
}
if (cameraPointX + 14 - char.posX == 3 && cameraPointX != mapWidth - 15)
{
mapBitmap.x -= 32;
cameraPointX += 1;
fogBitmap.x = mapBitmap.x;
return;
}
if (char.posY - cameraPointY == 3 && cameraPointY != 0)
{
mapBitmap.y += 32;
cameraPointY -= 1;
fogBitmap.y = mapBitmap.y;
return;
}
if (cameraPointY + 14 - char.posY == 3 && cameraPointY != mapHeight - 15)
{
mapBitmap.y -= 32;
cameraPointY += 1;
fogBitmap.y = mapBitmap.y;
return;
}
char.x += moveX * 32;
char.y += moveY * 32;
}
private function makeRoom(roomX:int, roomY:int, roomWidth:int, roomHeight:int, scaleFactor:int):void
{
//trace("roomX: ", roomX, "\nroomY:", roomY, "\nroomWidth:", roomWidth, "\nroomHeight:", roomHeight);
var i:int, j:int;
//check possible
if (roomX < 0 || roomX >= mapWidth || roomY < 0 || roomY >= mapHeight)
{
//trace("fail to batch");
return;
}
if (roomX + roomWidth >= mapWidth || roomY + roomHeight >= mapHeight)
{
//trace("fail to batch room");
return;
}
/*
for (i = roomX; i < roomX + roomWidth; i += 1)
{
for (j = roomY; j < roomY + roomHeight; j += 1)
{
if (mapArray[i * mapHeight + j] != -1)
{
//trace("not empty space");
return;
}
}
}
*/
//make empty place
for (i = roomX; i < roomX + roomWidth; i += 1)
{
for (j = roomY; j < roomY + roomHeight; j += 1)
{
mapArray[i * mapHeight + j] = 0;
}
}
if (scaleFactor == attenuationNumMax)
{
return;
}
//direction select
var directionArray:Array = [0, 1, 2, 3];
var directionIndex:int;
var direction:int;
var childRoomW:int;
var childRoomH:int;
var childRoomX:int;
var childRoomY:int;
var corridorIndex:int;
var corridorLength:int;
var corridorCellX:int;
var corridorCellY:int;
for (i = 0; i < directionSelectMax; i += 1)
{
if (Math.random() * 100 > directionSelectProb)
{
continue;
}
childRoomW = roomWidth * (Math.random() * (attenuationMax - attenuationMin) + attenuationMin) / 100;
childRoomH = roomHeight * (Math.random() * (attenuationMax - attenuationMin) + attenuationMin) / 100;
directionIndex = int(Math.random() * directionArray.length);
direction = directionArray.splice(directionIndex, 1);
switch(direction)
{
case 0: //N
//roomW = int(Math.random() * (roomMaxWidth - roomMinWidth)) + roomMinWidth;
childRoomX = int(Math.random() * (roomWidth - childRoomW)) + roomX;
corridorLength = int(Math.random() * (corridorMax - corridorMin) + corridorMin);
childRoomY = roomY - childRoomH - corridorLength;
//make corridor
corridorIndex = int(Math.random() * childRoomW) + childRoomX;
for (j = 0; j < corridorLength; j += 1)
{
corridorCellX = corridorIndex;
corridorCellY = roomY - 1 - j;
if (corridorCellX < 0 || corridorCellX >= mapWidth || corridorCellY < 0 || corridorCellY >= mapHeight)
{
break;
}
mapArray[corridorCellX * mapHeight + corridorCellY] = 0;
//trace("corridor:", corridorCellX, corridorCellY);
}
break;
case 1: //W
corridorLength = int(Math.random() * (corridorMax - corridorMin) + corridorMin);
childRoomX = roomX - childRoomW - corridorLength;
childRoomY = int(Math.random() * (roomHeight - childRoomH)) + roomY;
//make corridor
corridorIndex = int(Math.random() * childRoomH) + childRoomY;
for (j = 0; j < corridorLength; j += 1)
{
corridorCellX = roomX - 1 - j;
corridorCellY = corridorIndex;
if (corridorCellX < 0 || corridorCellX >= mapWidth || corridorCellY < 0 || corridorCellY >= mapHeight)
{
break;
}
mapArray[corridorCellX * mapHeight + corridorCellY] = 0;
//trace("corridor:", corridorCellX, corridorCellY);
}
break;
case 2: //S
childRoomX = int(Math.random() * (roomWidth - childRoomW)) + roomX;
corridorLength = int(Math.random() * (corridorMax - corridorMin) + corridorMin);
childRoomY = roomY + roomHeight + corridorLength;
//make corridor
corridorIndex = int(Math.random() * childRoomW) + childRoomX;
for (j = 0; j < corridorLength; j += 1)
{
corridorCellX = corridorIndex;
corridorCellY = roomY + roomHeight + j;
if (corridorCellX < 0 || corridorCellX >= mapWidth || corridorCellY < 0 || corridorCellY >= mapHeight)
{
break;
}
mapArray[corridorCellX * mapHeight + corridorCellY] = 0;
//trace("corridor:", corridorCellX, corridorCellY);
}
break;
case 3: //E
corridorLength = int(Math.random() * (corridorMax - corridorMin) + corridorMin);
childRoomX = roomX + roomWidth + corridorLength;
childRoomY = int(Math.random() * (roomHeight - childRoomH)) + roomY;
//make corridor
corridorIndex = int(Math.random() * childRoomH) + childRoomY;
for (j = 0; j < corridorLength; j += 1)
{
corridorCellX = roomX + roomWidth + j;
corridorCellY = corridorIndex;
if (corridorCellX < 0 || corridorCellX >= mapWidth || corridorCellY < 0 || corridorCellY >= mapHeight)
{
break;
}
mapArray[corridorCellX * mapHeight + corridorCellY] = 0;
//trace("corridor:", corridorCellX, corridorCellY);
}
break;
}
//trace("make to:", roomX, roomY, childRoomX, childRoomY);
makeRoom(childRoomX, childRoomY, childRoomW, childRoomH, scaleFactor + 1);
}
}
}
}
Class
{
import flash.display.Bitmap;
import flash.display.Sprite;
/**
* ...
* @author ypc
*/
class Character extends Sprite
{
public var posX:int;
public var posY:int;
public var bitmap:Bitmap;
public function Character(_x:int, _y:int, bmp:Bitmap)
{
posX = _x;
posY = _y;
bitmap = bmp;
addChild(bitmap);
}
}
}