//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Wilderness Copyright (c) 2009 Dave Griffiths // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import flash.display.MovieClip; import flash.events.MouseEvent; import flash.events.KeyboardEvent; import flash.events.Event; import flash.display.Stage; import flash.display.BitmapData; import flash.ui.Keyboard; class BlueCubeTex extends BitmapData { public function new() { super(0,0); } } class GrassCube01Tex extends BitmapData { public function new() { super(0,0); } } class GrassCube02Tex extends BitmapData { public function new() { super(0,0); } } class GrassCube03Tex extends BitmapData { public function new() { super(0,0); } } class SeaCube01Tex extends BitmapData { public function new() { super(0,0); } } class SeaCube02Tex extends BitmapData { public function new() { super(0,0); } } class SeaCube03Tex extends BitmapData { public function new() { super(0,0); } } class RBotNorthTex extends BitmapData { public function new() { super(0,0); } } class RBotSouthTex extends BitmapData { public function new() { super(0,0); } } class RBotEastTex extends BitmapData { public function new() { super(0,0); } } class RBotWestTex extends BitmapData { public function new() { super(0,0); } } class FlowersTex extends BitmapData { public function new() { super(0,0); } } class LollyPopTex extends BitmapData { public function new() { super(0,0); } } class ClimberTex extends BitmapData { public function new() { super(0,0); } } class CanopyTex extends BitmapData { public function new() { super(0,0); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Cube extends Entity { public function new(pos:Vec3) { super(pos, new BlueCubeTex()); //UpdateTex(); } public function UpdateTex(rnd:RndGen) { if (Pos.z<0) { if (rnd.RndFlt()<0.5) { ChangeBitmap(new SeaCube01Tex()); } else { if (rnd.RndFlt()<0.5) { ChangeBitmap(new SeaCube02Tex()); } else { ChangeBitmap(new SeaCube03Tex()); } } } else { if (rnd.RndFlt()<0.5) { ChangeBitmap(new GrassCube01Tex()); } else { if (rnd.RndFlt()<0.5) { ChangeBitmap(new GrassCube02Tex()); } else { ChangeBitmap(new GrassCube03Tex()); } } } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Plant extends Entity { public var Owner:String; var PlantScale:Float; public function new(owner:String,pos,bitmap) { super(pos,bitmap); Owner=owner; PlantScale=230; Scale(0.1); } public override function Update(frame:Int, world:World) { super.Update(frame,world); if (PlantScale>0) { Scale(1.01); PlantScale--; } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class PlayerEntity extends Entity { public function new(pos:Vec3) { super(pos, new RBotNorthTex()); } public function Handle(e:KeyboardEvent, world:World) { var pos=new Vec3(Pos.x,Pos.y,Pos.z); if (e.keyCode==Keyboard.LEFT) { pos.x-=1; ChangeBitmap(new RBotNorthTex()); } if (e.keyCode==Keyboard.RIGHT) { pos.x+=1; ChangeBitmap(new RBotSouthTex()); } if (e.keyCode==Keyboard.UP) { pos.y-=1; ChangeBitmap(new RBotEastTex()); } if (e.keyCode==Keyboard.DOWN) { pos.y+=1; ChangeBitmap(new RBotWestTex()); } if (e.keyCode==32) { world.AddServerPlant(new Vec3(pos.x,pos.y,1)); } var oldworldpos=new Vec3(world.WorldPos.x,world.WorldPos.y,world.WorldPos.z); if (pos.x<0) { pos.x=world.Width-1; world.UpdateWorld(world.WorldPos.Add(new Vec3(-1,0,0))); } if (pos.x>=world.Width) { pos.x=0; world.UpdateWorld(world.WorldPos.Add(new Vec3(1,0,0))); } if (pos.y<0) { pos.y=world.Height-1; world.UpdateWorld(world.WorldPos.Add(new Vec3(0,-1,0))); } if (pos.y>=world.Height) { pos.y=0; world.UpdateWorld(world.WorldPos.Add(new Vec3(0,1,0))); } if (world.GetCube(pos).Pos.z>-1) { Pos=pos; Pos.z=world.GetCube(Pos).Pos.z+1; UpdatePos(); } else { world.UpdateWorld(oldworldpos); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class WildernessWorld extends World { public var Width:Int; public var Height:Int; var Objs:Array; var Player:PlayerEntity; public var WorldPos:Vec3; var MyRndGen:RndGen; public var WorldClient:Client; public var MyTextEntry:TextEntry; var Plants:Array; var MyName:String; public function new(w:Int, h:Int) { super(); Width=w; Height=h; Objs = []; Plants = []; WorldPos = new Vec3(0,0,0); MyRndGen = new RndGen(); WorldClient=new Client(OnConnectedCallback,OnServerPlantsCallback); for (y in 0...h) { for (x in 0...w) { var ob:Cube = new Cube(new Vec3(0,0,0)); Objs.push(ob); addChild(ob); } } UpdateWorld(new Vec3(0,0,0)); Player = new PlayerEntity(new Vec3(5,5,1)); addChild(Player); MyTextEntry=new TextEntry(190,170,310,30,NameCallback); addChild(MyTextEntry); } public function NameCallback(name) { removeChild(MyTextEntry); WorldClient.Identify(name); MyName=name; WorldClient.GetPlants(cast(WorldPos.x,Int),cast(WorldPos.y,Int)); } public function UpdateWorld(pos:Vec3) { WorldPos=pos; var circles = []; for (i in Plants) { removeChild(i); } Plants=[]; for (x in -1...2) { for (y in -1...2) { MyRndGen.Seed(cast((WorldPos.x+x)+(WorldPos.y+y)*139,Int)); for (i in 0...5) { MyRndGen.RndFlt(); MyRndGen.RndFlt(); MyRndGen.RndFlt(); MyRndGen.RndFlt(); var pos = new Vec3(MyRndGen.RndFlt()*10+x*10, MyRndGen.RndFlt()*10+y*10, 0); circles.push(new Circle(pos, MyRndGen.RndFlt()*5)); } } } for (i in 0...Objs.length) { var pos=new Vec3(i%Width,Math.floor(i/Width),-1); MyRndGen.Seed(cast(WorldPos.x+pos.x+WorldPos.y+pos.y*139,Int)); MyRndGen.RndFlt(); MyRndGen.RndFlt(); MyRndGen.RndFlt(); MyRndGen.RndFlt(); var inside:Bool=false; for (c in circles) { if (c.Inside(pos)) pos.z=0; } Objs[i].Pos=pos; Objs[i].UpdatePos(); Objs[i].UpdateTex(MyRndGen); } WorldClient.GetPlants(cast(WorldPos.x,Int),cast(WorldPos.y,Int)); } public function GetCube(pos:Vec3) : Cube { return Objs[cast(pos.x+pos.y*Width,Int)]; } public function OnConnectedCallback(_) { } public function PlantTex(i) { var l = [new FlowersTex(),new CanopyTex(),new ClimberTex(),new LollyPopTex()]; return l[i]; } public function OnServerPlantsCallback(ServerPlants:Array) { for (splant in ServerPlants) { var plant = new Entity(new Vec3(splant.x,splant.y,1),PlantTex(splant.type)); addChild(plant); Plants.push(plant); } } public function AddServerPlant(pos:Vec3) { // call by reference! :S var type = Math.floor(Math.random()*4); var plant = new Plant(MyName,new Vec3(pos.x,pos.y,1),PlantTex(type)); addChild(plant); Plants.push(plant); WorldClient.AddPlant(cast(WorldPos.x,Int), cast(WorldPos.y,Int), new ServerPlant(MyName,cast(pos.x,Int),cast(pos.y,Int),type)); } public function Update(frame:Int) { Player.Update(frame,this); for (plant in Plants) { plant.Update(frame,this); } } public function Handle(e:KeyboardEvent) { Player.Handle(e,this); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Wilderness extends MovieClip { var Frame:Int; var World:WildernessWorld; public function new() { super(); World = new WildernessWorld(10,10); addChild(World); flash.Lib.current.stage.addEventListener("enterFrame",Update); flash.Lib.current.stage.addEventListener(flash.events.KeyboardEvent.KEY_DOWN,OnKeyDown,false); } function OnKeyDown(e:KeyboardEvent) { World.Handle(e); } function Update(e:Event) { World.Update(Frame); Frame++; } static function main() { var m:Wilderness = new Wilderness(); flash.Lib.current.addChild(m); } }