package { import flash.display.Sprite; public class GameplayView extends Sprite { protected var model:GameStateModel; protected var views:Vector.; protected var firstDraw:Boolean = true; protected var scrollView:Sprite; protected var floorLayer:Sprite; protected var followEntity:EntityModel; protected var hudView:HUDView; public function GameplayView(model:GameStateModel, followEntity:EntityModel) { this.model = model; this.followEntity = followEntity; scrollView = new Sprite(); scrollView.scaleX = scrollView.scaleY = 2; floorLayer = new Sprite(); scrollView.addChild(floorLayer); views = new Vector.(); for each (var object:GameObjectModel in model.objects) { addViewForObject(object); } addChild(scrollView); hudView = new HUDView(model); addChild(hudView); model.addEventListener(GameObjectEvent.ADDED, onGameObjectAdded); } private function tileViewClassForType(type:int):Class { switch (type) { case TileModel.TILE_CoffeeHotE1: case TileModel.TILE_CoffeeHotE2: case TileModel.TILE_CoffeeHotS1: case TileModel.TILE_CoffeeHotS2: return HotCoffeeView; case TileModel.TILE_CoffeemakerE: case TileModel.TILE_CoffeemakerS: return CoffeePotView; case TileModel.TILE_DoorFrameE: case TileModel.TILE_DoorFrameN: case TileModel.TILE_DoorFrameS: case TileModel.TILE_DoorFrameW: return OfficeDoorFrameView; case TileModel.TILE_FridgeE: case TileModel.TILE_FridgeS: return FridgeView; default: return TileView; } } private function addTile(type:int, indexX:int, indexZ:int, layerIndex:int):void { var tileModel:TileModel; var tileView:TileView; var screenPosition:Vector2; if (type == -1) { return; } switch (layerIndex) { case 0: tileModel = new TileModel(type, indexX, indexZ); break; case 1: tileModel = model.tiles[indexZ * model.level.sizeX + indexX]; break; case 2: tileModel = model.doodads[indexZ * model.level.sizeX + indexX]; break; } tileView = new (tileViewClassForType(type))(tileModel, layerIndex); screenPosition = IsoMath.localToScreen(tileModel.position); tileView.x = screenPosition.x; tileView.y = screenPosition.y; if (layerIndex == 0) { floorLayer.addChild(tileView); tileView.draw(0); } else { views.push(tileView); scrollView.addChild(tileView); for each (var attachedView:TileView in tileView.attachedViews) { views.push(attachedView); scrollView.addChild(attachedView); } } } public function draw(delta:Number):void { var screenPos:Vector2; if (firstDraw) { for (var tileIndexZ:int = 0; tileIndexZ < model.level.sizeZ; tileIndexZ++) { for (var tileIndexX:int = 0; tileIndexX < model.level.sizeX; tileIndexX++) { if (tileIndexX > 0 && tileIndexZ > 0) { addTile((tileIndexX + tileIndexZ) % 2 ? TileModel.TILE_FloorA : TileModel.TILE_FloorB, tileIndexX, tileIndexZ, 0); } addTile(model.tileTypeAtPosition(tileIndexX, tileIndexZ), tileIndexX, tileIndexZ, 1); addTile(model.doodadTypeAtPosition(tileIndexX, tileIndexZ), tileIndexX, tileIndexZ, 2); } } floorLayer.cacheAsBitmap = true; firstDraw = false; } for each (var view:GameObjectView in views) { view.draw(delta); } views.sort(function(lhs:GameObjectView, rhs:GameObjectView):Number { if (lhs is TileView && TileModel(lhs.model).isFloor && (!(rhs is TileView) || !TileModel(rhs.model).isFloor)) { return -1; } if (rhs is TileView && TileModel(rhs.model).isFloor && (!(lhs is TileView) || !TileModel(lhs.model).isFloor)) { return 1; } var lhsDepth:Number = lhs.position.x + lhs.position.z; var rhsDepth:Number = rhs.position.x + rhs.position.z; if (lhsDepth < rhsDepth) { return -1; } if (lhsDepth > rhsDepth) { return 1; } if (lhs.position.z < rhs.position.z) { return 1; } if (lhs.position.z > rhs.position.z) { return -1; } if (lhs is TileView && rhs is TileView) { if (TileView(lhs).layerIndex < TileView(rhs).layerIndex) { return -1; } if (TileView(lhs).layerIndex > TileView(rhs).layerIndex) { return 1; } } return 0; }); for (var viewIndex:int = 0; viewIndex < views.length; viewIndex++) { scrollView.setChildIndex(views[viewIndex], viewIndex + 1); } screenPos = IsoMath.localToScreen(followEntity.position); screenPos.y += 48; scrollView.x = Math.round(stage.stageWidth / 2) + Math.round(-screenPos.x) * scrollView.scaleX; scrollView.y = Math.round(stage.stageHeight / 2) + Math.round(-screenPos.y) * scrollView.scaleY; hudView.draw(); } private function addViewForObject(object:GameObjectModel):void { var view:GameObjectView = null; if (object is PlayerModel) { view = new PlayerView(object as PlayerModel); } else if (object is WorkerModel) { view = new WorkerView(object as WorkerModel); } if (view != null) { views.push(view); scrollView.addChild(view); } } private function onGameObjectAdded(event:GameObjectEvent):void { addViewForObject(event.object); } } }