/* Section 4: EaterExtendedSolution Roy McElmurry 8/4/2010 */ package { import flash.display.Sprite; import flash.utils.Timer; import flash.events.*; import flash.ui.Keyboard; import flash.geom.Point; import flash.text.*; import flash.net.*; [SWF(backgroundColor="#ffffff", frameRate="24", width="750", height="400")] public class EaterExtendedSolution extends Sprite { private const MAX_TIME:Number = 3; //max time between new squares private const GAME_SPEED:Number = 100; //smaller = faster private const SIZE:Number = 70; private const CURVE:Number = 35; private const SHRINK:Number = 2; private const GUY_SIZE:Number = 15; private const SPEED:int = GUY_SIZE * 2 + 1; private const COLLECTED_SIZE:Number = GUY_SIZE * 2; private const RIGHT_BOUNDARY:Number = stage.stageWidth - 195; private const LEADER_PADDING:Number = 20; private const FONT_SIZE:Number = 24; private var squares:Array; private var newSquareTimer:Timer; private var guy:Sprite; private var collected:Array; private var directions:Array; private var dir:Point; private var scoreText:TextField; private var score:int; public function EaterExtendedSolution():void { var box:Sprite = new Sprite(); box.graphics.beginFill(0xffffff); box.graphics.lineStyle(5, 0x000000); box.graphics.drawRect(0, 0, RIGHT_BOUNDARY, stage.stageHeight); addChild(box); squares = new Array(); collected = new Array(); directions = new Array(); dir = new Point(1, 0); var timer:Timer = new Timer(GAME_SPEED); timer.addEventListener(TimerEvent.TIMER, timerListener); timer.start(); newSquareTimer = new Timer(Math.random() * 1000 * MAX_TIME, 1); newSquareTimer.addEventListener(TimerEvent.TIMER_COMPLETE, addSquare); newSquareTimer.start(); stage.addEventListener(KeyboardEvent.KEY_DOWN, keyListener); guy = new Sprite(); guy.graphics.beginFill(0xff0000); guy.graphics.drawCircle(0, 0, GUY_SIZE); addChild(guy); scoreText = new TextField(); scoreText.autoSize = TextFieldAutoSize.LEFT; scoreText.x = 10; scoreText.y = 10; addChild(scoreText); resetGame(); createLeaderBoard(); } //Load XML Data public function createLeaderBoard():void { var xmlLoader:URLLoader = new URLLoader(); var xmlData:XML = new XML(); function listener(e:Event):void { xmlData = new XML(e.target.data); displayXML(xmlData); } xmlLoader.addEventListener(Event.COMPLETE, listener); xmlLoader.load(new URLRequest("scores.xml")); } //Parse XMl Data public function displayXML(xml:XML):void { var title:TextField = new TextField(); title.text = "Highest Scores:"; title.x = RIGHT_BOUNDARY + 20; title.y = 20; title.setTextFormat(new TextFormat("Arial", FONT_SIZE, null, true, null, true)); addChild(title); for each (var entry:XML in xml.entry) { var name:String = entry.name.text(); var score:String = entry.score.text(); var rank:String = entry.score.@rank; drawRank(rank + ") " + name + ": " + score, (int)(rank)); } } //Draws a single ranking given the name/score string and rank public function drawRank(s:String, rank:int):void { var person:TextField = new TextField(); person.text = s; person.x = RIGHT_BOUNDARY + LEADER_PADDING; person.width = stage.stageWidth - RIGHT_BOUNDARY - LEADER_PADDING; person.y = 50 * (int)(rank); person.setTextFormat(new TextFormat("Arial", FONT_SIZE - (int)(rank) * 2, null)); addChild(person); } //Set the score TextField to have the given score public function setScore(score:*):void { scoreText.text = "Score: " + score; scoreText.setTextFormat(new TextFormat("Arial", FONT_SIZE, null, true)); } //Clean the board and reset for new game public function resetGame():void { for (var i:int = 0; i < squares.length; i++) { removeChild(squares[i]); } for (i = 0; i < collected.length; i++) { removeChild(collected[i]); } guy.x = guy.width / 2; guy.y = stage.stageHeight / 2; score = 0; setScore(score); squares = new Array(); collected = new Array(); directions = new Array(); dir = new Point(1, 0); } //Run the game engine public function timerListener(e:TimerEvent):void { var lastDir:Point = moveGuy(); moveSquares(); moveCollected(); directions.unshift(dir); } //Move the guy and check bounds //Returns a new point representing the directions that the guy was moved public function moveGuy():Point { guy.x += SPEED * dir.x; guy.y += SPEED * dir.y; if (guy.x < 0 || guy.x > RIGHT_BOUNDARY || guy.y < 0 || guy.y > stage.stageHeight) { resetGame(); } return dir.clone(); } //Shrink the squares //Remove squares that have gotten too small //Collect squares that collide with the guy public function moveSquares():void { for (var i:int = 0; i < squares.length; i++) { squares[i].width -= SHRINK; squares[i].height -= SHRINK; if (squares[i].width < 2) { removeChild(squares[i]); squares.splice(i, 1); i--; } else if (squares[i].hitTestObject(guy)) { var square:Sprite = squares.splice(i, 1)[0]; collected.unshift(square); square.width = COLLECTED_SIZE; square.height = COLLECTED_SIZE; //Place the collected square in the front of //the line and hold the line back a move square.x = guy.x - (GUY_SIZE + COLLECTED_SIZE / 2 + 1) * dir.x; square.y = guy.y - (GUY_SIZE + COLLECTED_SIZE / 2 + 1) * dir.y; directions.unshift(new Point(0, 0)); i--; //Set score score++; setScore(score); } } } //Move the collected squares and detect collisions with the guy public function moveCollected():void { for (var i:int = 0; i < collected.length; i++) { if (guy.hitTestObject(collected[i])) { resetGame(); } collected[i].x += SPEED * directions[i].x; collected[i].y += SPEED * directions[i].y; } directions.pop(); } //Add a new square to the stage and restart the newSquareTimer public function addSquare(e:TimerEvent):void { squares.push(makeSquare(Math.random() * RIGHT_BOUNDARY, Math.random() * stage.stageHeight)); newSquareTimer = new Timer(Math.random() * 1000 * MAX_TIME, 1); newSquareTimer.addEventListener(TimerEvent.TIMER_COMPLETE, addSquare); newSquareTimer.start(); } //Handle keyboard events public function keyListener(e:KeyboardEvent):void { if (e.keyCode == Keyboard.UP) { dir = new Point(0, -1); } else if (e.keyCode == Keyboard.DOWN) { dir = new Point(0, 1); } else if (e.keyCode == Keyboard.LEFT) { dir = new Point(-1, 0); } else if (e.keyCode == Keyboard.RIGHT) { dir = new Point(1, 0); } } //Place a square on the stage at the given position //Returns the created square public function makeSquare(x:Number, y:Number):Sprite { var square:Sprite = new Sprite(); square.graphics.beginFill(0x000000); square.graphics.drawRoundRect(- SIZE / 2, - SIZE / 2, SIZE, SIZE, CURVE, CURVE); square.x = x; square.y = y; addChild(square); return square; } } }