From Dust
Hehe, bought From Dust game few days ago, inspired me to return and work a little more on my old work I called Islands http://wonderwhy-er.deviantart.com/gallery/#/d2oe52m
It originally was my attempt to participate in LudumDare 17 http://www.ludumdare.com/compo/ludum-dare-17/?action=previewwhich theme was Islands. My idea kind of was similar to From Dust, save villagers from flood. But failed to do it in 48 hours :D
And now with From Dust inspiration and ludumdare 21 starting tomorrow I decided to play with it more as inspiration and publish it here ;) Have fun :)
/**
* Copyright wonderwhyer ( http://wonderfl.net/user/wonderwhyer )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/6rvK
*/
package
{
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.display.Loader;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.BlendMode;
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
import com.bit101.components.*;
import flash.display.GradientType;
public class Main extends MovieClip
{
public var heightMap : BitmapData
public var mapWidth : int = 100;
public var mapHeight : int = 100;
public var grid : Vector.<GridCell>;
public var waterBitmap : BitmapData;
public var positions : Vector.<Pos>;
public var scale : Number = 4;
public var md : Boolean = false;
public var ToolStrength : Knob;
public var ToolRadious : Knob;
public var SelectWater : RadioButton;
public var SelectEarth : RadioButton;
public var CreateIslandBtn : PushButton;
public var CreateRandomBtn : PushButton;
public var ClearBtn : PushButton;
public var palpha:Number = 5;
public var nalpha:Number = 1 / palpha;
public var loader:Loader;
public function Main():void {
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,init);
var url:String = "http://assets.wonderfl.net/images/related_images/0/02/0216/0216beeb7c40aff17d46a6ef5ef6b54c82d86c2c";
loader.load(new URLRequest(url),new LoaderContext(true));
}
public function init(e:Event):void
{
grid = new Vector.<GridCell>(mapWidth*mapHeight,true);
positions = new Vector.<Pos>(mapWidth * mapHeight, true);
heightMap = new BitmapData(mapWidth, mapHeight, false, 0);
waterBitmap = new BitmapData(mapWidth, mapHeight, true, 0);
var DisObj:DisplayObject;
ToolStrength = new Knob(this, 410, 300,"Strength");
ToolRadious = new Knob(this, 410, 220,"Radious");
ToolRadious.value = 5;
ToolRadious.minimum = -50;
ToolRadious.maximum = 50;
SelectWater = new RadioButton(this, 410, 10, "Water", true,ToolChanged);
SelectEarth = new RadioButton(this, 410, 30, "Earth", false,ToolChanged);
SelectEarth.groupName = SelectWater.groupName = "tool";
CreateIslandBtn = new PushButton(this, 405, 50, "Island", CreateIsland);
CreateRandomBtn = new PushButton(this, 405, 75, "Random", Random);
ClearBtn = new PushButton(this, 405, 100, "Clear", ClearLand);
CreateIslandBtn.width = CreateRandomBtn.width = ClearBtn.width = 45;
DisObj = addChildAt(new Bitmap(waterBitmap),0);
DisObj.scaleX = DisObj.scaleY = scale;
DisObj = addChildAt(new Bitmap(heightMap),0);
DisObj.scaleX = DisObj.scaleY = scale;
ToolChanged();
for (var i:uint = 0; i < positions.length; i++) {
var pos:Pos = indexToPosition(i);
var cell:GridCell = grid[i] = new GridCell(pos.x,pos.y,0,0,0);
}
for (i = 0; i < grid.length; i++) {
var neighbours:Vector.<GridCell> = new Vector.<GridCell>();
cell = grid[i];
if (cell.x > 0)
neighbours.push(grid[positionToIndex( cell.x-1, cell.y )]);
if (cell.x < mapWidth-1)
neighbours.push(grid[positionToIndex( cell.x+1, cell.y )]);
if (cell.y > 0)
neighbours.push(grid[positionToIndex( cell.x, cell.y - 1 )]);
if (cell.y < mapHeight-1)
neighbours.push(grid[positionToIndex( cell.x, cell.y + 1 )]);
if (cell.y < mapHeight-1&&cell.x < mapWidth-1)
neighbours.push(grid[positionToIndex( cell.x+1, cell.y + 1 )]);
if (cell.y < mapHeight-1&&cell.x >0)
neighbours.push(grid[positionToIndex( cell.x-1, cell.y + 1 )]);
if (cell.y > 0&&cell.x < mapWidth-1)
neighbours.push(grid[positionToIndex( cell.x+1, cell.y - 1 )]);
if (cell.y > 0&&cell.x >0)
neighbours.push(grid[positionToIndex( cell.x-1, cell.y - 1 )]);
cell.neighbours = neighbours;
}
addEventListener(Event.ENTER_FRAME, frame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
CreateIsland();
}
public function Random(e:Event=null):void
{
heightMap.perlinNoise(15 + Math.random() * 15, 15 + Math.random() * 15, Math.random() * 3, Math.random() * int.MAX_VALUE, true, Math.random() < 0.5, 7, true);
InitMap();
}
public function CreateIsland(e:Event=null):void
{
heightMap.perlinNoise(20, 20, 2, Math.random()*int.MAX_VALUE, true,false, 7, true);
var map:Sprite = new Sprite();
var m:Matrix = new Matrix();
m.createGradientBox(80, 80, 0, 10, 10);
map.graphics.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0], [1, 1], [50, 255], m);
map.graphics.drawRect(0, 0, 100, 100);
map.graphics.endFill();
m.createGradientBox(20, 20, 0, 40, 40);
map.graphics.beginGradientFill(GradientType.RADIAL, [0x303030, 0xFFFFFF], [1, 1], [0, 255], m);
map.graphics.drawCircle(50, 50, 10);
heightMap.draw(map, null, null, BlendMode.HARDLIGHT);
InitMap()
}
public function ClearLand(e:Event=null):void
{
for (var i:uint = 0; i < positions.length; i++) {
var pos:Pos = indexToPosition(i);
var cell:GridCell = grid[i];
cell.groundLevel = 0;
cell.waterLevel = 0;
}
DrawMap();
}
public function InitMap(e:Event=null):void
{
for (var i:uint = 0; i < positions.length; i++) {
var pos:Pos = indexToPosition(i);
var cell:GridCell = grid[i];
cell.groundLevel = heightMap.getPixel(pos.x, pos.y) % 256;
}
DrawMap();
}
public function ToolChanged(e:Event=null):void
{
if (SelectEarth.selected)
{
ToolStrength.maximum = 100;
ToolStrength.minimum = -100;
ToolStrength.value = 1;
}
else
{
ToolStrength.maximum = 100;
ToolStrength.minimum = -100;
ToolStrength.value = 10;
}
}
public function DrawMap():void
{
var colors:BitmapData = (loader.content as Bitmap).bitmapData;
for(var x:int=0;x<heightMap.width;x++){
for (var y:int = 0; y < heightMap.width; y++) {
var cell:GridCell = grid[positionToIndex(x, y)];
heightMap.setPixel(x,y,colors.getPixel(Math.random()*(colors.width-1),255-cell.groundLevel));
}
}
}
public function indexToPosition(index:uint):Pos {
return new Pos(index % mapWidth, index / mapWidth);
}
public function positionToIndex(x:uint,y:uint):uint {
return y * mapWidth + x;
}
public function mouseDown(e:Event):void {
md = true;
}
public function mouseUp(e:Event):void {
md = false;
}
public function roundTo(n:Number,p:Number):Number{
return Math.round(p*n)/p;
}
public function frame(e:Event):void{
//waterBitmap.fillRect(waterBitmap.rect, 0);
if (md && mouseX < 400) {
var cX:int = mouseX / scale;
var cY:int = mouseY / scale;
for (var xx:int = - ToolRadious.value; xx < ToolRadious.value;xx++)
{
for (var yy:int = - ToolRadious.value; yy < ToolRadious.value;yy++)
{
var multi:Number = 1 - Math.sqrt(Math.sqrt(xx * xx + yy * yy) / ToolRadious.value);
if (multi > 0)
{
var index:uint = positionToIndex(xx+cX, yy+cY);
if (index < grid.length) {
if (SelectWater.selected)
{
grid[index].waterLevel = Math.max(0, grid[index].waterLevel + ToolStrength.value*multi );
}
else
{
grid[index].groundLevel = Math.min(255, Math.max(0, grid[index].groundLevel + ToolStrength.value*multi ));
}
}
}
}
}
if (SelectEarth.selected)
DrawMap();
}
var level:Number;
var pos:Pos;
var weights:Vector.<Number> = new Vector.<Number>(8,true);
var i:int;
for (i = 0; i < grid.length; i++) {
var cell:GridCell = grid[i];
var neighbours:Vector.<GridCell> = cell.neighbours;
var levelSum:Number = 0;
var levelElems:int = 0;
var cellLevel:Number = cell.groundLevel + cell.waterLevel+cell.waterLevelChange;
for (var j:uint = 0; j < neighbours.length; j++) {
var neighbour:GridCell = neighbours[j];
var param:Number = cell.dmp*(neighbour.waterLevel+neighbour.groundLevel-cellLevel);
if (param < 0) {
levelElems++;
levelSum += param;
weights[j] = param;
}else {
weights[j] = 0;
}
}
if (levelSum < -cell.waterLevel) {
for (j = 0; j < neighbours.length; j++) {
if(weights[j]<0){
neighbour = neighbours[j];
neighbour.waterLevelChange += cell.waterLevel*(weights[j] / levelSum);
}
}
cell.waterLevelChange-= cell.waterLevel;
}else {
cell.waterLevelChange += levelSum;
for (j = 0; j < neighbours.length; j++) {
neighbour = neighbours[j];
neighbour.waterLevelChange -= weights[j];
}
}
}
for (i = 0; i < grid.length; i++) {
cell = grid[i];
cell.waterLevel = cell.waterLevel + cell.waterLevelChange;
var aa:Number = cell.waterLevelChange-cell.dc;
var bb:Number = cell.dc - cell.ddc;
cell.dmp = 0.5 / (1+Math.abs(aa-bb));
cell.ddc = cell.dc;
cell.dc = cell.waterLevelChange;
cell.waterLevelChange = 0;
//waterLevel[i]= Math.max(0,waterLevel[i]+waterLevelChange[i]);
level = cell.waterLevel;
//var change:Number = waterLevelChange[i];
//pos = positions[i];
if(level>0){
var a:uint = Math.round(128 * Math.min(palpha, level) * nalpha);
waterBitmap.setPixel32(cell.x,cell.y,0xff + (a<<24));
}else{
waterBitmap.setPixel32(cell.x,cell.y,0);
}
}
}
}
}
class Pos
{
public var x:int;
public var y:int;
public function Pos(x:int,y:int)
{
this.x = x;
this.y = y;
}
public function toString():String {
return "("+x.toString()+":"+y.toString()+")";
}
}
class GridCell
{
public var neighbours : Vector.<GridCell>;
public var groundLevel : Number;
public var waterLevel : Number;
public var waterLevelChange : Number;
public var x : Number;
public var y : Number;
public var dc : Number;
public var ddc : Number;
public var dmp : Number;
public function GridCell(x:Number, y:Number, groundLevel : Number, waterLevel : Number, waterLevelChange: Number) {
this.groundLevel = groundLevel;
this.waterLevel = waterLevel;
this.waterLevelChange = waterLevelChange;
this.x = x;
this.y = y;
}
}