Skip to content

Instantly share code, notes, and snippets.

@jgranick
Created February 23, 2012 20:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jgranick/1894940 to your computer and use it in GitHub Desktop.
Save jgranick/1894940 to your computer and use it in GitHub Desktop.
Pirate Pig for NME
<?xml version="1.0" encoding="utf-8"?>
<project>
<meta title="Pirate Pig" package="com.eclecticdesignstudio.piratepig" version="1.0.0" company="Eclectic Design Studio" />
<app path="Export" file="PiratePig" main="com.eclecticdesignstudio.piratepig.PiratePig" />
<window width="800" height="600" if="desktop" />
<window fps="30" />
<source path="Source" />
<haxelib name="nme" />
<haxelib name="actuate" />
<assets path="Assets/fonts" rename="fonts" include="*.ttf" />
<assets path="Assets/images" rename="images" include="*" />
<assets path="Assets/sounds" rename="sounds" if="web">
<sound path="3.mp3" id="sound3" />
<sound path="4.mp3" id="sound4" />
<sound path="5.mp3" id="sound5" />
<music path="theme.mp3" id="soundTheme" />
</assets>
<assets path="Assets/sounds" rename="sounds" unless="web">
<sound path="3.wav" id="sound3" />
<sound path="4.wav" id="sound4" />
<sound path="5.wav" id="sound5" />
<music path="theme.mp3" id="soundTheme" />
</assets>
<icon path="Assets/icon-32.png" size="32" />
<icon path="Assets/icon-48.png" size="48" />
<icon path="Assets/icon-56.png" size="56" />
<icon path="Assets/icon-64.png" size="64" />
<ndll name="std" />
<ndll name="regexp" />
<ndll name="zlib" />
<ndll name="nme" haxelib="nme" />
<section if="release-sign">
<certificate path="C:\Users\Joshua\eclecticdesignstudio.keystore" if="android" />
</section>
</project>
package com.eclecticdesignstudio.piratepig;
import nme.Assets;
import nme.display.Bitmap;
import nme.display.BitmapData;
import nme.display.Sprite;
import nme.display.StageAlign;
import nme.display.StageScaleMode;
import nme.events.Event;
import nme.events.KeyboardEvent;
import nme.Lib;
/**
* @author Joshua Granick
*/
class PiratePig extends Sprite {
private var Background:Sprite;
private var BackgroundFill:BitmapData;
private var Footer:Bitmap;
private var Game:PiratePigGame;
public function new () {
super ();
initialize ();
construct ();
resize (Lib.current.stage.stageWidth, Lib.current.stage.stageHeight);
Lib.current.stage.addEventListener (Event.RESIZE, stage_onResize);
#if android
Lib.current.stage.addEventListener (KeyboardEvent.KEY_UP, stage_onKeyUp);
#end
}
private function construct ():Void {
Footer.smoothing = true;
addChild (Background);
addChild (Footer);
addChild (Game);
}
private function initialize ():Void {
Lib.current.stage.align = StageAlign.TOP_LEFT;
Lib.current.stage.scaleMode = StageScaleMode.NO_SCALE;
Background = new Sprite ();
BackgroundFill = Assets.getBitmapData ("images/background_tile.png");
Footer = new Bitmap (Assets.getBitmapData ("images/center_bottom.png"));
Game = new PiratePigGame ();
}
private function resize (newWidth:Int, newHeight:Int):Void {
Background.graphics.clear ();
Background.graphics.beginBitmapFill (BackgroundFill);
if (newHeight < BackgroundFill.height) {
Background.graphics.drawRect (0, 0, newWidth, newHeight);
Background.scaleY = 1;
} else {
Background.graphics.drawRect (0, 0, newWidth, BackgroundFill.height);
Background.scaleY = newHeight / BackgroundFill.height;
}
Game.resize (newWidth, newHeight);
Footer.scaleX = Game.currentScale;
Footer.scaleY = Game.currentScale;
Footer.x = newWidth / 2 - Footer.width / 2;
Footer.y = newHeight - Footer.height;
}
private function stage_onKeyUp (event:KeyboardEvent):Void {
#if android
if (event.keyCode == 27) {
event.stopImmediatePropagation ();
Lib.exit ();
}
#end
}
private function stage_onResize (event:Event):Void {
resize (stage.stageWidth, stage.stageHeight);
}
// Entry point
public static function main () {
Lib.current.addChild (new PiratePig ());
}
}
package com.eclecticdesignstudio.piratepig;
import com.eclecticdesignstudio.motion.Actuate;
import com.eclecticdesignstudio.motion.easing.Quad;
import nme.display.Bitmap;
import nme.display.Sprite;
import nme.events.Event;
import nme.events.MouseEvent;
import nme.filters.BlurFilter;
import nme.filters.DropShadowFilter;
import nme.geom.Point;
import nme.media.Sound;
import nme.text.TextField;
import nme.text.TextFormat;
import nme.text.TextFormatAlign;
import nme.Assets;
import nme.Lib;
/**
* ...
* @author Joshua Granick
*/
class PiratePigGame extends Sprite {
private static var NUM_COLUMNS:Int = 8;
private static var NUM_ROWS:Int = 8;
private var Background:Sprite;
private var IntroSound:Sound;
private var Logo:Bitmap;
private var Score:TextField;
private var Sound3:Sound;
private var Sound4:Sound;
private var Sound5:Sound;
private var TileContainer:Sprite;
public var currentScale:Float;
public var currentScore:Int;
private var cacheMouse:Point;
private var needToCheckMatches:Bool;
private var selectedTile:Tile;
private var tiles:Array <Array <Tile>>;
public function new () {
super ();
initialize ();
construct ();
newGame ();
}
private function addTile (row:Int, column:Int, animate:Bool = true):Void {
var tile = new Tile ();
tile.row = row;
tile.column = column;
tiles[row][column] = tile;
var position = getPosition (row, column);
if (animate) {
var firstPosition = getPosition (-1, column);
tile.alpha = 0;
tile.x = firstPosition.x;
tile.y = firstPosition.y;
tile.moveTo (0.1 + 0.05 * (row + 1), position.x, position.y);
Actuate.tween (tile, 0.15, { alpha: 1 } ).ease (Quad.easeOut);
} else {
tile.x = position.x;
tile.y = position.y;
}
TileContainer.addChild (tile);
needToCheckMatches = true;
}
private function construct ():Void {
Logo.smoothing = true;
addChild (Logo);
var font = Assets.getFont ("fonts/FreebooterUpdated.ttf");
var defaultFormat = new TextFormat (font.fontName, 60, 0x000000);
defaultFormat.align = TextFormatAlign.RIGHT;
var contentWidth = 75 * NUM_COLUMNS;
Score.x = contentWidth - 200;
Score.width = 200;
Score.y = 12;
Score.selectable = false;
Score.defaultTextFormat = defaultFormat;
Score.filters = [ new BlurFilter (1.5, 1.5), new DropShadowFilter (1, 45, 0, 0.2, 5, 5) ];
Score.embedFonts = true;
addChild (Score);
Background.y = 85;
Background.graphics.beginFill (0xFFFFFF, 0.4);
Background.graphics.drawRect (0, 0, contentWidth, 75 * NUM_ROWS);
Background.filters = [ new BlurFilter (10, 10) ];
addChild (Background);
TileContainer.x = 14;
TileContainer.y = Background.y + 14;
TileContainer.addEventListener (MouseEvent.MOUSE_DOWN, TileContainer_onMouseDown);
Lib.current.stage.addEventListener (MouseEvent.MOUSE_UP, stage_onMouseUp);
addChild (TileContainer);
IntroSound = Assets.getSound ("soundTheme");
Sound3 = Assets.getSound ("sound3");
Sound4 = Assets.getSound ("sound4");
Sound5 = Assets.getSound ("sound5");
}
private function dropTiles ():Void {
for (column in 0...NUM_COLUMNS) {
var spaces = 0;
for (row in 0...NUM_ROWS) {
var index = (NUM_ROWS - 1) - row;
var tile = tiles[index][column];
if (tile == null) {
spaces++;
} else {
if (spaces > 0) {
var position = getPosition (index + spaces, column);
tile.moveTo (0.15 * spaces, position.x,position.y);
tile.row = index + spaces;
tiles[index + spaces][column] = tile;
tiles[index][column] = null;
needToCheckMatches = true;
}
}
}
for (i in 0...spaces) {
var row = (spaces - 1) - i;
addTile (row, column);
}
}
}
private function findMatches (byRow:Bool, accumulateScore:Bool = true):Array <Tile> {
var matchedTiles = new Array <Tile> ();
var max:Int;
var secondMax:Int;
if (byRow) {
max = NUM_ROWS;
secondMax = NUM_COLUMNS;
} else {
max = NUM_COLUMNS;
secondMax = NUM_ROWS;
}
for (index in 0...max) {
var matches = 0;
var foundTiles = new Array <Tile> ();
var previousType = -1;
for (secondIndex in 0...secondMax) {
var tile:Tile;
if (byRow) {
tile = tiles[index][secondIndex];
} else {
tile = tiles[secondIndex][index];
}
if (tile != null && !tile.moving) {
if (previousType == -1) {
previousType = tile.type;
foundTiles.push (tile);
continue;
} else if (tile.type == previousType) {
foundTiles.push (tile);
matches++;
}
}
if (tile == null || tile.moving || tile.type != previousType || secondIndex == secondMax - 1) {
if (matches >= 2 && previousType != -1) {
if (accumulateScore) {
if (matches > 3) {
Sound5.play ();
} else if (matches > 2) {
Sound4.play ();
} else {
Sound3.play ();
}
currentScore += Std.int (Math.pow (matches, 2) * 50);
}
matchedTiles = matchedTiles.concat (foundTiles);
}
matches = 0;
foundTiles = new Array <Tile> ();
if (tile == null || tile.moving) {
needToCheckMatches = true;
previousType = -1;
} else {
previousType = tile.type;
foundTiles.push (tile);
}
}
}
}
return matchedTiles;
}
private function getPosition (row:Int, column:Int):Point {
return new Point (column * (57 + 16), row * (57 + 16));
}
private function initialize ():Void {
currentScale = 1;
currentScore = 0;
tiles = new Array <Array <Tile>> ();
for (row in 0...NUM_ROWS) {
tiles[row] = new Array <Tile> ();
for (column in 0...NUM_COLUMNS) {
tiles[row][column] = null;
}
}
Background = new Sprite ();
Logo = new Bitmap (Assets.getBitmapData ("images/logo.png"));
Score = new TextField ();
TileContainer = new Sprite ();
}
public function newGame ():Void {
currentScore = 0;
Score.text = "0";
for (row in 0...NUM_ROWS) {
for (column in 0...NUM_COLUMNS) {
removeTile (row, column, false);
}
}
for (row in 0...NUM_ROWS) {
for (column in 0...NUM_COLUMNS) {
addTile (row, column, false);
}
}
IntroSound.play ();
removeEventListener (Event.ENTER_FRAME, this_onEnterFrame);
addEventListener (Event.ENTER_FRAME, this_onEnterFrame);
}
public function removeTile (row:Int, column:Int, animate:Bool = true):Void {
var tile = tiles[row][column];
if (tile != null) {
tile.remove (animate);
}
tiles[row][column] = null;
}
public function resize (newWidth:Int, newHeight:Int):Void {
var maxWidth = newWidth * 0.90;
var maxHeight = newHeight * 0.86;
currentScale = 1;
scaleX = 1;
scaleY = 1;
if (width > maxWidth || height > maxHeight) {
var maxScaleX = maxWidth / width;
var maxScaleY = maxHeight / height;
if (maxScaleX < maxScaleY) {
currentScale = maxScaleX;
} else {
currentScale = maxScaleY;
}
scaleX = currentScale;
scaleY = currentScale;
}
x = newWidth / 2 - width / 2;
}
private function swapTile (tile:Tile, targetRow:Int, targetColumn:Int):Void {
if (targetColumn >= 0 && targetColumn < NUM_COLUMNS && targetRow >= 0 && targetRow < NUM_ROWS) {
var targetTile = tiles[targetRow][targetColumn];
if (targetTile != null && !targetTile.moving) {
tiles[targetRow][targetColumn] = tile;
tiles[tile.row][tile.column] = targetTile;
if (findMatches (true, false).length > 0 || findMatches (false, false).length > 0) {
targetTile.row = tile.row;
targetTile.column = tile.column;
tile.row = targetRow;
tile.column = targetColumn;
var targetTilePosition = getPosition (targetTile.row, targetTile.column);
var tilePosition = getPosition (tile.row, tile.column);
targetTile.moveTo (0.3, targetTilePosition.x, targetTilePosition.y);
tile.moveTo (0.3, tilePosition.x, tilePosition.y);
needToCheckMatches = true;
} else {
tiles[targetRow][targetColumn] = targetTile;
tiles[tile.row][tile.column] = tile;
}
}
}
}
// Event Handlers
private function stage_onMouseUp (event:MouseEvent):Void {
if (cacheMouse != null && selectedTile != null && !selectedTile.moving) {
var differenceX = event.stageX - cacheMouse.x;
var differenceY = event.stageY - cacheMouse.y;
if (Math.abs (differenceX) > 10 || Math.abs (differenceY) > 10) {
var swapToRow = selectedTile.row;
var swapToColumn = selectedTile.column;
if (Math.abs (differenceX) > Math.abs (differenceY)) {
if (differenceX < 0) {
swapToColumn --;
} else {
swapToColumn ++;
}
} else {
if (differenceY < 0) {
swapToRow --;
} else {
swapToRow ++;
}
}
swapTile (selectedTile, swapToRow, swapToColumn);
}
}
selectedTile = null;
cacheMouse = null;
}
private function this_onEnterFrame (event:Event):Void {
if (needToCheckMatches) {
var matchedTiles = new Array <Tile> ();
matchedTiles = matchedTiles.concat (findMatches (true));
matchedTiles = matchedTiles.concat (findMatches (false));
for (tile in matchedTiles) {
removeTile (tile.row, tile.column);
}
if (matchedTiles.length > 0) {
Score.text = Std.string (currentScore);
dropTiles ();
}
}
}
private function TileContainer_onMouseDown (event:MouseEvent):Void {
if (Std.is (event.target, Tile)) {
selectedTile = cast event.target;
cacheMouse = new Point (event.stageX, event.stageY);
} else {
cacheMouse = null;
selectedTile = null;
}
}
}
package com.eclecticdesignstudio.piratepig;
import com.eclecticdesignstudio.motion.Actuate;
import com.eclecticdesignstudio.motion.actuators.GenericActuator;
import com.eclecticdesignstudio.motion.easing.Quad;
import nme.Assets;
import nme.display.Bitmap;
import nme.display.Sprite;
import nme.filters.BlurFilter;
/**
* ...
* @author Joshua Granick
*/
class Tile extends Sprite {
public var column:Int;
public var moving:Bool;
public var removed:Bool;
public var row:Int;
public var type:Int;
private static var images:Array <String> = [ "images/game_bear.png", "images/game_bunny_02.png", "images/game_carrot.png", "images/game_lemon.png", "images/game_panda.png", "images/game_piratePig.png" ];
public function new () {
super ();
moving = false;
type = Math.round (Math.random () * (images.length - 1));
var image = new Bitmap (Assets.getBitmapData (images[type]));
image.smoothing = true;
addChild (image);
filters = [ new BlurFilter (0, 0) ];
mouseChildren = false;
buttonMode = true;
graphics.beginFill (0x000000, 0);
graphics.drawRect (-5, -5, 66, 66);
}
public function moveTo (duration:Float, targetX:Float, targetY:Float):Void {
moving = true;
var blurX = 0;
var blurY = 0;
if (targetX != x) {
blurX = Std.int (Math.abs (x - targetX) / 3);
}
if (targetY != y) {
blurY = Std.int (Math.abs (y - targetY) / 3);
}
Actuate.effects (this, 0.001).filter (BlurFilter, { blurX: blurX, blurY: blurY } );
Actuate.effects (this, duration * (2 / 3), false).filter (BlurFilter, { blurX: 0, blurY: 0 } ).delay (duration / 3);
Actuate.tween (this, duration, { x: targetX, y: targetY } ).onComplete (this_onAnimationComplete).ease (Quad.easeOut);
}
public function remove (animate:Bool = true):Void {
if (!removed) {
if (animate) {
parent.addChildAt (this, 0);
Actuate.tween (this, 0.3, { scaleX: 0, scaleY: 0, x: x + width / 2, y: y + height / 2 } ).ease (Quad.easeOut).onComplete (parent.removeChild, [ this ]);
} else {
parent.removeChild (this);
}
}
removed = true;
}
// Event Handlers
private function this_onAnimationComplete ():Void {
moving = false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment