Turkey haXe game Source Code
April 3rd, 2009
full source for Turkey haXe
requested by Raf
crude source code, never thought anyone else would see it after i finished, including myself.
248 lines in the main class. i also created a few supporting classes for this game that i’ve been reusing ever since, and included in my common library.
comments
the haxe compile file
compile.hxml
-swf main.swf
-swf-version 9
-swf-header 550:500:300:FFFFFF
-main TurkeyHaXe
comments
the main class
TurkeyHaXe.hx
import com.remixtechnology.GraphicsLoader;
import flash.Lib;
import flash.display.Stage;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.ui.Mouse;
import flash.text.TextField;
import flash.text.TextFormat;
class TurkeyHaXe
{
public var stage:Stage;
public var bg_layer:Sprite;
public var game_layer:Sprite;
public var over_layer:Sprite;
private var start_but:Button;
//private var high_scores_but:Button;
private var play_again_but:Button;
private var game_bg:Sprite;
private var intro_bg:Sprite;
private var instructions:Sprite;
private var score:Int;
private var scoreBoard:ShadowedTextField;
private var finalScoreBoard:ShadowedTextField;
private var control:Sprite;
private var stuffing:Array<Sprite>;
private var stuffing_graphics:Array<GraphicsLoader>;
private var fail_graphics:Array<Sprite>;
private var fail_message:Sprite;
private var drop_interval:Int; //seconds //current
private var drop_timer:Timer;
private var drops:Int;
private var first_time:Bool;
private var drop_speed:Float;
public static function main() {
new TurkeyHaXe();
}
private function new(){
stage = Lib.current.stage;
init();
}
private function init(){
//make layers
bg_layer = new Sprite();
stage.addChild(bg_layer);
game_layer = new Sprite();
stage.addChild(game_layer);
over_layer = new Sprite();
stage.addChild(over_layer);
stuffing = new Array<Sprite>();
stuffing_graphics = new Array<GraphicsLoader>();
fail_graphics = new Array<Sprite>();
score = 0;
//show start screen
intro_bg = new GraphicsLoader(Settings.graphics_path + "intro_bg.png").sprite;
bg_layer.addChild(intro_bg);
start_but = new Button("intro_start_but.png", "intro_start_but_over_bg.png");
over_layer.addChild(start_but);
start_but.addEventListener(MouseEvent.CLICK, click_start_but);
//start_but.x = 300;
//start_but.y = 210;
start_but.x = 200;
start_but.y = 130;
/*
high_scores_but = new Button("intro_high_scores_but.png", "intro_high_scores_but_over_bg.png");
over_layer.addChild(high_scores_but);
high_scores_but.x = 260;
high_scores_but.y = 260;
start_but.addEventListener(MouseEvent.CLICK, click_high_scores_but); */
//gimme stuffing
stuffing_graphics.push(new GraphicsLoader(Settings.graphics_path + "stuffing_0.png"));
stuffing_graphics.push(new GraphicsLoader(Settings.graphics_path + "stuffing_1.png"));
stuffing_graphics.push(new GraphicsLoader(Settings.graphics_path + "stuffing_2.png"));
//gimme fail
fail_graphics.push(new GraphicsLoader(Settings.graphics_path + "fail_0.png").sprite);
fail_graphics.push(new GraphicsLoader(Settings.graphics_path + "fail_1.png").sprite);
fail_graphics.push(new GraphicsLoader(Settings.graphics_path + "fail_2.png").sprite);
fail_graphics.push(new GraphicsLoader(Settings.graphics_path + "fail_3.png").sprite);
fail_graphics.push(new GraphicsLoader(Settings.graphics_path + "fail_4.png").sprite);
fail_graphics.push(new GraphicsLoader(Settings.graphics_path + "fail_5.png").sprite);
fail_graphics.push(new GraphicsLoader(Settings.graphics_path + "fail_6.png").sprite);
first_time = true;
}
private function click_start_but(_):Void{
loadGame();
}
private function click_high_scores_but(_):Void{
//showHighScores();
}
private function loadGame():Void{
drop_interval = Settings.init_drop_interval;
drop_timer = new Timer(drop_interval);
drop_timer.addEventListener(TimerEvent.TIMER, tick_drop);
drop_timer.start();
drop_speed = Settings.init_drop_speed;
control = new GraphicsLoader(Settings.graphics_path + "control.png").sprite;
game_layer.addChild(control);
control.y = 360;
stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouse_move);
stage.addEventListener(Event.ENTER_FRAME, loop);
if(first_time){
clear_intro();
game_bg = new GraphicsLoader(Settings.graphics_path + "game_bg.png").sprite;
bg_layer.addChild(game_bg);
showInstructions();
scoreBoard = new ShadowedTextField();
over_layer.addChild(scoreBoard);
scoreBoard.x = 15;
scoreBoard.y = 15;
}
score = 0;
scoreBoard.setText(Std.string(score));
if(Settings.hide_cursor) {Mouse.hide();}
}
private function setDropTimer():Void{
drop_timer.stop();
drop_timer.removeEventListener(TimerEvent.TIMER, tick_drop);
drop_timer = null;
drop_timer = new Timer(drop_interval);
drop_timer.addEventListener(TimerEvent.TIMER, tick_drop);
drop_timer.start();
}
private function tick_drop(_):Void{
var randX:Int = Math.round(Math.random()*(stage.stageWidth-80))+30;
var randS:Int = Math.floor(Math.random()*stuffing_graphics.length);
var s:Sprite = new Sprite();
game_layer.addChild(s);
stuffing_graphics[randS].getCopySprite(s);
stuffing.push(s);
s.x = randX;
s.y = -10;
s.rotation = Math.round(Math.random()*360);
drops++;
if((drops % Settings.increment_drop_speed_every) == 0){
drop_speed += Settings.increment_drop_speed;
}
if( ((drops % Settings.increment_drop_every) == 0) && drop_interval > Settings.min_drop_interval){
drop_interval -= Settings.increment_drop_interval;
setDropTimer();
}
}
private function showInstructions():Void{
var t:Timer = new Timer(3000,1);
t.addEventListener(TimerEvent.TIMER_COMPLETE, complete_instructions);
t.start();
instructions = new GraphicsLoader(Settings.graphics_path + "catch_all_the_stuffing.png").sprite;
over_layer.addChild(instructions);
instructions.x = 65;
instructions.y = 100;
first_time = false;
}
private function complete_instructions(_):Void{
over_layer.removeChild(instructions);
instructions = null;
}
private function stage_mouse_move(_):Void{
control.x = stage.mouseX - 40;
}
private function loop(_):Void{
var s:Sprite;
for(s in stuffing){
s.y += drop_speed;
if(s.y >= stage.stageHeight){
gameOver();
}else if(s.hitTestPoint(stage.mouseX, 410)){
stuffing.remove(s);
game_layer.removeChild(s);
s = null;
awardPoints();
}
}
}
private function clear_intro():Void{
start_but.parent.removeChild(start_but);
//high_scores_but.parent.removeChild(high_scores_but);
intro_bg.parent.removeChild(intro_bg);
start_but = null;
//high_scores_but = null;
intro_bg = null;
}
private function awardPoints():Void{
score += drops + Math.round(drop_speed) + (Settings.init_drop_interval - drop_interval);
scoreBoard.setText(Std.string(score));
}
private function gameOver():Void{
drop_timer.removeEventListener(TimerEvent.TIMER, tick_drop);
drop_timer.stop();
game_layer.removeChild(control);
control = null;
var s:Sprite;
for(s in stuffing){
game_layer.removeChild(s);
}
stuffing = new Array<Sprite>();
stage.removeEventListener(MouseEvent.MOUSE_MOVE, stage_mouse_move);
stage.removeEventListener(Event.ENTER_FRAME, loop);
if(Settings.hide_cursor) {Mouse.show();}
// show fail message
var randF:Int = Math.floor(Math.random()*fail_graphics.length);
fail_message = new Sprite();
game_layer.addChild(fail_message);
fail_message.addChild(fail_graphics[randF]);
fail_message.x = 40;
fail_message.y = 80;
// show try again
play_again_but = new Button("try_again_but.png", "try_again_but_over_bg.png");
over_layer.addChild(play_again_but);
play_again_but.x = 150;
play_again_but.y = 420;
play_again_but.addEventListener(MouseEvent.CLICK, try_again_click);
}
private function try_again_click(_):Void{
game_layer.removeChild(fail_message);
fail_message = null;
play_again_but.removeEventListener(MouseEvent.CLICK, try_again_click);
over_layer.removeChild(play_again_but);
play_again_but = null;
loadGame();
}
}
comments
a very simple class that loads an external image. i found this class to be very very handy, but is by no means perfect. part of the com.remixtechnology package.
GraphicsLoader.hx
/* loads a graphic (at runtime), returns a Sprite with that graphic in it using getSprite() */
package com.remixtechnology;
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLRequest;
class GraphicsLoader{
private var fileName:String;
private var bm:Bitmap;
private var ldr:Loader;
private var copies:Array<Sprite>;
public var sprite:Sprite;
public var loaded:Bool;
public function new(_fileName:String){
fileName = _fileName;
init();
}
private function init():Void{
loaded = false;
sprite = new Sprite();
copies = new Array();
ldr = new Loader();
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_complete);
ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loader_ioError);
ldr.load(new URLRequest(fileName));
}
private function loader_ioError(event:IOErrorEvent):Void{
trace("ioErrorHandler: " + event.text);
trace("Could not load: " + fileName);
}
private function loader_complete(event:Event):Void{
loaded = true;
bm = event.target.content;
sprite.addChild(bm);
if(copies.length > 0){
var i:Sprite;
for(i in copies){
copySprite(i);
}
}
}
public function getCopySprite(emptySprite:Sprite):Void{ // gets a copy of the sprite,
// but leaves the original alone
// take an emptySprite, and promise to attach a bitmap when it's done loading
// track promises using the array 'copies'
// unless it's already loaded, then just get a copy
if(loaded){
copySprite(emptySprite);
}else{
copies.push(emptySprite);
}
}
private function copySprite(s:Sprite):Void{
var data:BitmapData = new BitmapData(Std.int(bm.width), Std.int(bm.height), true, 0);
data.draw(bm);
var bitmap:Bitmap = new Bitmap(data);
s.addChild(bitmap); // promise fulfilled
}
}
comments
a simple button class that extends Sprite, all it really does is load a couple of graphics to create a rollover state. lines 12 and 13 are little hacks because of the way i exported my graphics. in the newest version of this class, the rollover is a nice fading tween, and of course lines 12 and 13 are not there. and this class has been added to the com.remixtechnology package.
Button.hx
import com.remixtechnology.GraphicsLoader;
import flash.display.Sprite;
import flash.events.MouseEvent;
class Button extends Sprite{
private var normal_state:Sprite;
private var over_state:Sprite;
public function new(normal_state_path:String, over_state_path:String){
normal_state = new GraphicsLoader(Settings.graphics_path + normal_state_path).sprite;
over_state = new GraphicsLoader(Settings.graphics_path + over_state_path).sprite;
addChild(over_state);
addChild(normal_state);
normal_state.x = 15;
normal_state.y = 6;
over_state.visible = false;
addListeners();
super();
}
private function addListeners():Void{
addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
}
private function mouseOver(_):Void{
over_state.visible = true;
}
private function mouseOut(_):Void{
over_state.visible = false;
}
}
comments a simple text field class that i use a lot, this version is not very customizable, but i’ve added it to the com.remixtechnology package and made it a lot more customizable with some decent default settings. here i use it to display the score, but i use it a lot for tracing because if you add graphics to the stage, like in this game, it covers haXe’s trace messages.
ShadowedTextField.hx
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
class ShadowedTextField extends Sprite
{
private var fgColor:UInt;
private var bgColor:UInt;
private var xoff:Float;
private var yoff:Float;
private var tfFore:TextField;
private var tfBack:TextField;
private var fmtFore:TextFormat;
private var fmtBack:TextFormat;
private var size:Int;
private var font:String;
public function new()
{
bgColor = 0x000000;
fgColor = Settings.font_color;
xoff = 1;
yoff = 1;
size = 24;
font = 'Verdana';
mouseChildren = false;
mouseEnabled = false;
tfBack = new TextField();
tfBack.autoSize = TextFieldAutoSize.LEFT;
tfBack.selectable = false;
tfBack.x = xoff;
tfBack.y = yoff;
addChild(tfBack);
tfFore = new TextField();
tfFore.autoSize = TextFieldAutoSize.LEFT;
tfFore.selectable = false;
addChild(tfFore);
fmtFore = new TextFormat();
fmtFore.color = fgColor;
fmtFore.size = size;
fmtFore.font = font;
fmtFore.bold = true;
fmtBack = new TextFormat();
fmtBack.color = bgColor;
fmtBack.size = size;
fmtBack.font = font;
fmtBack.bold = true;
super();
}
public function setText(n:String):Void
{
tfFore.text = n;
tfFore.setTextFormat(fmtFore);
tfBack.text = n;
tfBack.setTextFormat(fmtBack);
}
}
comments
some settings for the game, not sure why i left it out of the main class, i guess i just wanted a quick way to access some static settings from any class. i think it’s unnecessary, and i don’t do this anymore.
Settings.hx
class Settings{
public static var hide_cursor:Bool = false;
//local
public static var graphics_path:String = "graphics/";
//on remixtechnology
//public static var graphics_path:String = "/haXe/turkey_haXe/graphics/";
public static var init_drop_interval:Int = 1500;
public static var increment_drop_interval:Int = 50;
public static var increment_drop_every:Int = 3;
public static var min_drop_interval:Int = 300;
public static var init_drop_speed:Float = 4;
public static var increment_drop_speed:Float = .25;
public static var increment_drop_speed_every:Float = 5;
public static var font_color:UInt = 0xffa312;
}
and finally, here is the zip file complete with all assets, everything that i used to create this simple game.
Download the entire source + assets (3.8 Mb)





thanks for sharing this ;)
thanks for sharing it too! I've been trying to find some nice open source haxe games that target Flash 9, but haven't found many at all!
thanks for sharing it too! I've been trying to find some nice open source haxe games that target Flash 9, but haven't found many at all!
Hey Justin, Thanks a lot for sharing! I always appreciate it when people share their game source code so that I can study it (even if it is simple to you)! Thanks again, I followed the link from the haxe mailing list this past Sunday, 11/29/09. I had posted the "A couple of Newb questions" thread.
hey Rick, i saw your posts on the haXe list, i'm not Justin Lawerance Mills though :) i'm theRemix i'm happy we can help
Hey theRemix, :) Sorry about that! Again, I appreciate you sharing the source. I have a couple of quick questions. I don't see the pumpkin or the pie in the graphics or the walls; I'm trying to determine what part or parts of the code determines the collision of the items against the "wall" graphic and keeps them in the "diamond." Could you go into detail about that just a little bit? If you want, I could throw the question on the haxe list. Thanks! -Rick
@Rick Stranberg actually the source code above is for Turkey haXe (2008) not for full source for Thanksgiving Kitchen Hero (2009)