
ND2D: The Main Classes II
the sprites
GameSprite.as
package frogger.sprites {
import flash.geom.Rectangle;
import frogger.*;
import de.nulldesign.nd2d.display.Node2D;
import de.nulldesign.nd2d.display.Sprite2D;
public class GameSprite {
public var active:Boolean = true;
public var x:Number;
public var y:Number;
public var skin:Sprite2D;
public var body:Rectangle;
protected var _game:Game;
function GameSprite (game:Game, x:int, y:int) {
_game = game;
this.x = x;
this.y = y;
}
//move reference point to center of Image
public function setSkin (skin:Sprite2D):void {
this.skin = skin;
skin.x = x;
skin.y = y;
_game.screen.spriteBatch.addChild(skin);
}
public function get width ():Number {
return this.skin.width;
}
public function get height ():Number {
return this.skin.height;
}
public function get right ():Number {
return x + this.width * 0.5;
}
public function get left ():Number {
return x - this.width * 0.5;;
}
public function get top ():Number {
return y - this.height * 0.5;
}
public function get bottom ():Number {
return y + this.height * 0.5;
}
public function get bounds ():Rectangle {
return new Rectangle(x - skin.width * 0.2, y - skin.height * 0.2, skin.width * 0.8, skin.height * 0.8);
}
public function reset():void {}
public function update (dt:Number):void {}
public function show ():void {
if (skin) skin.visible = true;
}
public function hide ():void {
if (skin) skin.visible = false;
}
}
}
NumberSprite.as
package frogger.sprites
{
import de.nulldesign.nd2d.display.Sprite2D;
import frogger.Game;
public class NumberSprite extends GameSprite
{
public var value:int = 0;
protected var _textures:Array;
protected var _numbers:Vector.;
public function NumberSprite(game:Game, x:int, y:int, nameRoot:String) {
super(game, x, y);
_textures = [];
_numbers = new Vector.;
var img:Sprite2D;
for (i = 0; i < 8; i++) {
img = new Sprite2D();
_game.screen.spriteBatch.addChild(img);
img.setFrameByName(nameRoot+"1.png");
//img.x = x + i * (img.spriteSheet.spriteWidth + 2);
img.x = x + i * (img.width + 2);
img.y = y;
img.visible = false;
_numbers.push(img);
}
var i:int;
for (i = 0; i < 10; i++) {
_textures.push(_numbers[0].spriteSheet.getIndexForFrame(nameRoot+i+".png"));
}
}
public function showValue (value:uint):void {
this.value = value;
var string:String = ""+value;
var len:int = string.length;
if (len > 8) return;
for (var i:int = 0; i < len; i++) {
_numbers[i].visible = true;
_numbers[i].spriteSheet.frame = _textures[int(string.charAt(i))];
}
}
override public function reset ():void {
for (var i:int = 0; i < _numbers.length; i++) {
_numbers[i].spriteSheet.frame = _textures[0];
if (i > 0) {
_numbers[i].visible = false;
}
}
}
override public function show ():void {
hide();
showValue(value);
}
override public function hide ():void {
for (var i:int = 0; i < _numbers.length; i++) {
_numbers[i].visible = false;
}
}
}
}
Player.as
package frogger.elements {
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Timer;
import flash.utils.setTimeout;
import flash.events.Event;
import frogger.*;
import frogger.screens.GameScreen;
import frogger.sprites.*;
import de.nulldesign.nd2d.display.Sprite2D;
import de.nulldesign.nd2d.materials.texture.ASpriteSheetBase;
import de.nulldesign.nd2d.events.SpriteSheetAnimationEvent;
public class Player extends MovingSprite {
public static const MOVE_TOP:int = 0;
public static const MOVE_DOWN:int = 1;
public static const MOVE_LEFT:int = 2;
public static const MOVE_RIGHT:int = 3;
public var tierSpeed:Number = 0;
public var dead:Boolean = false;
public var moving:Boolean = false;
public var moveTimer:Timer;
public var tierIndex:int = 0;
public var hasBonus:Boolean = false;
private var _frogStand:uint;
private var _frogJump:uint;
private var _frogSide:uint;
private var _frogSideJump:uint;
private var _restFrame:uint;
private var _sideStep:int = 22;
private var _startPoint:Point;
private var _moveCnt:Number = 0.0;
private var _moveInterval:int = 6;
function Player (game:Game, x:int, y:int) {
super(game, x, y);
_startPoint = new Point(x,y);
//death animation
//must create animation before adding the skin that will play it, inside the sprite batch
_game.screen.textureAtlas.addAnimation("death_animation", [
"death_1.png",
"death_2.png",
"death_3.png",
"death_4.png",
"death_4.png",
"death_4.png",
"death_4.png",
"death_4.png"], false);
setSkin(new Sprite2D);
//store textures for frog
_frogStand = skin.spriteSheet.getIndexForFrame("frog_stand.png");
_frogJump = skin.spriteSheet.getIndexForFrame("frog_jump.png");
_frogSide = skin.spriteSheet.getIndexForFrame("frog_side.png");
_frogSideJump = skin.spriteSheet.getIndexForFrame("frog_side_jump.png");
skin.spriteSheet.frame = _frogStand;
_restFrame = _frogStand;
moveTimer = new Timer(200, 1);
moveTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onFrogRest);
moveTimer.start();
}
override public function reset ():void {
skin.spriteSheet.frame = _frogStand;
x = skin.x = nextX = _startPoint.x;
y = skin.y = nextY = _startPoint.y;
active = true;
hasBonus = false;
dead = false;
show();
tierIndex = 0;
skin.scaleX = skin.scaleY = 1;
skin.spriteSheet.removeEventListener(SpriteSheetAnimationEvent.ANIMATION_FINISHED, onDeathComplete);
}
public function moveFrogUp ():void {
if (!moving) {
tierIndex++;
if (tierIndex >= Tier.TIER_Y.length) tierIndex = Tier.TIER_Y.length - 1;
nextY = Tier.TIER_Y[tierIndex] + skin.height*0.5;
moveTimer.reset();
moveTimer.start();
showMoveFrame(MovingSprite.UP);
_game.gameData.addScore(GameData.POINTS_JUMP);
_game.sounds.play(Sounds.SOUND_JUMP);
}
}
public function moveFrogDown ():void {
if (!moving) {
moving = true;
tierIndex--;
if (tierIndex < 0) tierIndex = 0;
nextY = Tier.TIER_Y[tierIndex] + skin.height*0.5;
_game.gameData.addScore(GameData.POINTS_JUMP);
_game.sounds.play(Sounds.SOUND_JUMP);
showMoveFrame(MovingSprite.DOWN);
}
}
public function moveFrogLeft ():void {
if (!moving) {
moving = true;
nextX -= _sideStep;
_game.sounds.play(Sounds.SOUND_JUMP);
showMoveFrame(MovingSprite.LEFT);
}
}
public function moveFrogRight ():void {
if (!moving) {
moving = true;
nextX += _sideStep;
_game.sounds.play(Sounds.SOUND_JUMP);
showMoveFrame(MovingSprite.RIGHT);
}
}
override public function update (dt:Number):void {
//play animation if dead
if (dead) {
return;
}
if (moving) {
if (_moveCnt > _moveInterval) {
moving = false;
skin.spriteSheet.frame = _restFrame;
_moveCnt = 0.0;
}
_moveCnt += 20*dt;
}
//add tier speed if player is on top of a moving object
nextX += tierSpeed * dt;
place();
}
override public function place ():void {
//limit movement if player is not on water Tiers so frog does not leave the screen
if (tierIndex < 7) {
if (nextX < width * 0.5)
nextX = width * 0.5;
if (nextX > _game.screenWidth - width * 0.5)
nextX = _game.screenWidth - width * 0.5
} else {
//make player go back to start if frog leaves screen on water Tiers
if (nextX < -width*0.5 || nextX > _game.screenWidth + width*0.5) {
_game.sounds.play(Sounds.SOUND_OUTOFBOUNDS);
reset();
}
}
super.place();
}
public function kill ():void {
active = false;
tierSpeed = 0;
_game.gameData.gameMode = Game.GAME_STATE_ANIMATE;
moving = false;
skin.scaleX = skin.scaleY = 1;
skin.spriteSheet.playAnimation("death_animation", 0, false, true);
skin.spriteSheet.addEventListener(SpriteSheetAnimationEvent.ANIMATION_FINISHED, onDeathComplete, false, 0, true);
dead = true;
}
private function showMoveFrame (dir:int):void {
switch (dir) {
case MovingSprite.LEFT:
skin.scaleX = -1;
skin.spriteSheet.frame = _frogSideJump;
_restFrame = _frogSide;
break;
case MovingSprite.RIGHT:
skin.scaleX = 1;
skin.spriteSheet.frame = _frogSideJump;
_restFrame = _frogSide;
break;
case MovingSprite.UP:
skin.scaleY = 1;
skin.spriteSheet.frame = _frogJump;
_restFrame = _frogStand;
break;
case MovingSprite.DOWN:
skin.scaleY = -1;
skin.spriteSheet.frame = _frogJump;
_restFrame = _frogStand;
break;
}
}
private function onFrogRest (event:TimerEvent):void {
skin.spriteSheet.frame = _restFrame;
}
private function onDeathComplete (event:Event):void {
skin.spriteSheet.stopCurrentAnimation();
skin.spriteSheet.removeEventListener(SpriteSheetAnimationEvent.ANIMATION_FINISHED, onDeathComplete);
skin.visible = false;
if (_game.gameData.lives >= 0) {
setTimeout (
function ():void {
reset();
_game.gameData.gameMode = Game.GAME_STATE_PLAY;
}, 500
);
} else {
GameScreen(_game.screen).gameOver();
}
}
}
}