initial commit
This commit is contained in:
commit
710ea0e879
17
AIR_readme.txt
Normal file
17
AIR_readme.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
Instructions for DISTRIBUTING* your application:
|
||||
|
||||
1. Creating a self-signed certificate:
|
||||
- edit CreateCertificate.bat to change the path to Flex SDK,
|
||||
- edit CreateCertificate.bat to set your certificate password (and name if you like),
|
||||
- run CreateCertificate.bat to generate your self-signed certificate,
|
||||
- wait a minute before packaging.
|
||||
|
||||
2. Packaging the application:
|
||||
- edit PackageApplication.bat and change the path to Flex SDK,
|
||||
- if you have a signed certificate, edit PackageApplication.bat to change the path to the certificate,
|
||||
- run PackageApplication.bat, you will be prompted for the certificate password,
|
||||
(note that you may not see '***' when typing your password - it works anyway)
|
||||
- the packaged application should appear in your project in a new 'air' directory.
|
||||
|
||||
* to test your application from FlashDevelop, just press F5 as usual.
|
86
KlikPunk.as3proj
Normal file
86
KlikPunk.as3proj
Normal file
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project>
|
||||
<!-- Output SWF options -->
|
||||
<output>
|
||||
<movie disabled="False" />
|
||||
<movie input="" />
|
||||
<movie path="bin\KlikPunk.swf" />
|
||||
<movie fps="30" />
|
||||
<movie width="800" />
|
||||
<movie height="600" />
|
||||
<movie version="10" />
|
||||
<movie background="#FFFFFF" />
|
||||
</output>
|
||||
<!-- Other classes to be compiled into your SWF -->
|
||||
<classpaths>
|
||||
<class path="src" />
|
||||
</classpaths>
|
||||
<!-- Build options -->
|
||||
<build>
|
||||
<option accessible="False" />
|
||||
<option allowSourcePathOverlap="False" />
|
||||
<option benchmark="False" />
|
||||
<option es="False" />
|
||||
<option locale="" />
|
||||
<option loadConfig="" />
|
||||
<option optimize="True" />
|
||||
<option showActionScriptWarnings="True" />
|
||||
<option showBindingWarnings="True" />
|
||||
<option showInvalidCSS="True" />
|
||||
<option showDeprecationWarnings="True" />
|
||||
<option showUnusedTypeSelectorWarnings="True" />
|
||||
<option strict="True" />
|
||||
<option useNetwork="True" />
|
||||
<option useResourceBundleMetadata="True" />
|
||||
<option warnings="True" />
|
||||
<option verboseStackTraces="False" />
|
||||
<option linkReport="" />
|
||||
<option loadExterns="" />
|
||||
<option staticLinkRSL="True" />
|
||||
<option additional="+configname=air" />
|
||||
<option compilerConstants="" />
|
||||
<option customSDK="" />
|
||||
</build>
|
||||
<!-- SWC Include Libraries -->
|
||||
<includeLibraries>
|
||||
<!-- example: <element path="..." /> -->
|
||||
</includeLibraries>
|
||||
<!-- SWC Libraries -->
|
||||
<libraryPaths>
|
||||
<!-- example: <element path="..." /> -->
|
||||
</libraryPaths>
|
||||
<!-- External Libraries -->
|
||||
<externalLibraryPaths>
|
||||
<!-- example: <element path="..." /> -->
|
||||
</externalLibraryPaths>
|
||||
<!-- Runtime Shared Libraries -->
|
||||
<rslPaths>
|
||||
<!-- example: <element path="..." /> -->
|
||||
</rslPaths>
|
||||
<!-- Intrinsic Libraries -->
|
||||
<intrinsics>
|
||||
<!-- example: <element path="..." /> -->
|
||||
</intrinsics>
|
||||
<!-- Assets to embed into the output SWF -->
|
||||
<library>
|
||||
<!-- example: <asset path="..." id="..." update="..." glyphs="..." mode="..." place="..." sharepoint="..." /> -->
|
||||
</library>
|
||||
<!-- Class files to compile (other referenced classes will automatically be included) -->
|
||||
<compileTargets>
|
||||
<compile path="src\Main.as" />
|
||||
</compileTargets>
|
||||
<!-- Paths to exclude from the Project Explorer tree -->
|
||||
<hiddenPaths>
|
||||
<!-- example: <hidden path="..." /> -->
|
||||
</hiddenPaths>
|
||||
<!-- Executed before build -->
|
||||
<preBuildCommand>taskkill /f /fi "IMAGENAME eq adl.exe"</preBuildCommand>
|
||||
<!-- Executed after build -->
|
||||
<postBuildCommand alwaysRun="False" />
|
||||
<!-- Other project options -->
|
||||
<options>
|
||||
<option showHiddenPaths="False" />
|
||||
<option testMovie="Custom" />
|
||||
<option testMovieCommand="$(FlexSDK)\bin\adl.exe;application.xml bin" />
|
||||
</options>
|
||||
</project>
|
48
PackageApplication.bat
Normal file
48
PackageApplication.bat
Normal file
|
@ -0,0 +1,48 @@
|
|||
@echo off
|
||||
|
||||
:: AIR application packaging
|
||||
:: More information:
|
||||
:: http://livedocs.adobe.com/flex/3/html/help.html?content=CommandLineTools_5.html#1035959
|
||||
|
||||
:: Path to Flex SDK binaries
|
||||
set PATH=%PATH%;C:\Dev\flash\flex\bin
|
||||
|
||||
:: Signature (see 'CreateCertificate.bat')
|
||||
set CERTIFICATE="KlikPunk.pfx"
|
||||
set SIGNING_OPTIONS=-storetype pkcs12 -keystore %CERTIFICATE% -tsa none
|
||||
if not exist %CERTIFICATE% goto certificate
|
||||
|
||||
:: Output
|
||||
if not exist air md air
|
||||
set AIR_FILE=air/KlikPunk.air
|
||||
|
||||
:: Input
|
||||
set APP_XML=application.xml
|
||||
set FILE_OR_DIR=-C bin .
|
||||
|
||||
echo Signing AIR setup using certificate %CERTIFICATE%.
|
||||
call adt -package %SIGNING_OPTIONS% %AIR_FILE% %APP_XML% %FILE_OR_DIR%
|
||||
if errorlevel 1 goto failed
|
||||
|
||||
echo.
|
||||
echo AIR setup created: %AIR_FILE%
|
||||
echo.
|
||||
goto end
|
||||
|
||||
:certificate
|
||||
echo Certificate not found: %CERTIFICATE%
|
||||
echo.
|
||||
echo Troubleshotting:
|
||||
echo A certificate is required, generate one using 'CreateCertificate.bat'
|
||||
echo.
|
||||
goto end
|
||||
|
||||
:failed
|
||||
echo AIR setup creation FAILED.
|
||||
echo.
|
||||
echo Troubleshotting:
|
||||
echo did you configure the Flex SDK path in this Batch file?
|
||||
echo.
|
||||
|
||||
:end
|
||||
pause
|
27
application.xml
Normal file
27
application.xml
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<application xmlns="http://ns.adobe.com/air/application/1.5">
|
||||
|
||||
<id>KlikPunk</id>
|
||||
<version>1.0</version>
|
||||
<filename>KlikPunk</filename>
|
||||
|
||||
<name>KlikPunk</name>
|
||||
<description></description>
|
||||
<copyright></copyright>
|
||||
|
||||
<initialWindow>
|
||||
<title>KlikPunk</title>
|
||||
<content>KlikPunk.swf</content>
|
||||
<systemChrome>standard</systemChrome>
|
||||
<transparent>false</transparent>
|
||||
<visible>true</visible>
|
||||
<minimizable>true</minimizable>
|
||||
<maximizable>false</maximizable>
|
||||
<resizable>false</resizable>
|
||||
</initialWindow>
|
||||
|
||||
<!--
|
||||
More options:
|
||||
http://livedocs.adobe.com/flex/3/html/File_formats_1.html#1043413
|
||||
-->
|
||||
</application>
|
BIN
assets/folder.png
Normal file
BIN
assets/folder.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 537 B |
BIN
assets/punk.png
Normal file
BIN
assets/punk.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
2
assets/readme.txt
Normal file
2
assets/readme.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
Icons by Mark James, licensed under a Creative Commons Attribution 2.5 license:
|
||||
http://www.famfamfam.com/lab/icons/silk/
|
BIN
assets/save.png
Normal file
BIN
assets/save.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 620 B |
21
src/Button.as
Normal file
21
src/Button.as
Normal file
|
@ -0,0 +1,21 @@
|
|||
package
|
||||
{
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class Button extends EntitySidebarImg
|
||||
{
|
||||
private var dgOnClick:Function;
|
||||
public function Button(sidebar:Sidebar, bmp:*, dgOnClick: Function)
|
||||
{
|
||||
super(sidebar, bmp);
|
||||
this.dgOnClick = dgOnClick;
|
||||
}
|
||||
override public function OnClick():void
|
||||
{
|
||||
this.dgOnClick();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
44
src/Drag.as
Normal file
44
src/Drag.as
Normal file
|
@ -0,0 +1,44 @@
|
|||
package
|
||||
{
|
||||
import flash.geom.Point;
|
||||
import net.flashpunk.utils.Input;
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class Drag
|
||||
{
|
||||
private var mouseXLast: int;
|
||||
private var mouseYLast: int;
|
||||
private static var drag: Drag = null;
|
||||
|
||||
public function Drag()
|
||||
{
|
||||
Update();
|
||||
}
|
||||
|
||||
public static function Claim() : Drag
|
||||
{
|
||||
if (drag === null)
|
||||
{
|
||||
drag = new Drag();
|
||||
return drag;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public function Delta(zoom:Number = 1): Point
|
||||
{
|
||||
return new Point((Input.mouseX - mouseXLast) / zoom, (Input.mouseY - mouseYLast) / zoom);
|
||||
}
|
||||
public function Update(): void
|
||||
{
|
||||
mouseXLast = Input.mouseX;
|
||||
mouseYLast = Input.mouseY;
|
||||
}
|
||||
public function Done(): void
|
||||
{
|
||||
drag = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
32
src/EntitySidebar.as
Normal file
32
src/EntitySidebar.as
Normal file
|
@ -0,0 +1,32 @@
|
|||
package
|
||||
{
|
||||
import net.flashpunk.Entity;
|
||||
import net.flashpunk.Graphic;
|
||||
import net.flashpunk.utils.Input;
|
||||
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class EntitySidebar extends Entity
|
||||
{
|
||||
protected var sidebar: Sidebar;
|
||||
public function EntitySidebar(sidebar: Sidebar, h:int, graphic:Graphic)
|
||||
{
|
||||
super(sidebar.x, 0 /*set by sidebar.add*/, graphic);
|
||||
setHitbox(sidebar.width, h, 0, 0);
|
||||
this.sidebar = sidebar;
|
||||
sidebar.Add(this);
|
||||
}
|
||||
|
||||
override public function update():void
|
||||
{
|
||||
super.update();
|
||||
if (Input.mousePressed && collidePoint(x, y, Input.mouseX, Input.mouseY))
|
||||
OnClick();
|
||||
}
|
||||
public function OnClick(): void { }
|
||||
public function Fade(pct:Number):void { }
|
||||
}
|
||||
|
||||
}
|
29
src/EntitySidebarImg.as
Normal file
29
src/EntitySidebarImg.as
Normal file
|
@ -0,0 +1,29 @@
|
|||
package
|
||||
{
|
||||
import net.flashpunk.Entity;
|
||||
import net.flashpunk.Graphic;
|
||||
import net.flashpunk.graphics.Image;
|
||||
import net.flashpunk.utils.Input;
|
||||
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class EntitySidebarImg extends EntitySidebar
|
||||
{
|
||||
protected var img: Image;
|
||||
public function EntitySidebarImg(sidebar: Sidebar, bmp:*)
|
||||
{
|
||||
img = new Image(bmp);
|
||||
img.scale = sidebar.width / img.width;
|
||||
|
||||
super(sidebar, img.scaledHeight, img);
|
||||
}
|
||||
override public function Fade(pct:Number):void
|
||||
{
|
||||
super.Fade(pct);
|
||||
img.alpha = pct;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
22
src/EvNewImg.as
Normal file
22
src/EvNewImg.as
Normal file
|
@ -0,0 +1,22 @@
|
|||
package
|
||||
{
|
||||
import flash.display.BitmapData;
|
||||
import flash.events.Event;
|
||||
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class EvNewImg extends Event
|
||||
{
|
||||
public var rel: String;
|
||||
public var bmp: BitmapData;
|
||||
public function EvNewImg(type: String, rel: String, bmp: BitmapData)
|
||||
{
|
||||
this.rel = rel;
|
||||
this.bmp = bmp;
|
||||
super(type);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
35
src/Factory.as
Normal file
35
src/Factory.as
Normal file
|
@ -0,0 +1,35 @@
|
|||
package
|
||||
{
|
||||
import flash.display.BitmapData;
|
||||
import flash.geom.Point;
|
||||
import net.flashpunk.Entity;
|
||||
import net.flashpunk.Graphic;
|
||||
import net.flashpunk.graphics.Image;
|
||||
import net.flashpunk.Mask;
|
||||
import net.flashpunk.utils.Input;
|
||||
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class Factory extends EntitySidebarImg
|
||||
{
|
||||
private var bmp: BitmapData;
|
||||
private var relf: String;
|
||||
public function Factory(sidebar: Sidebar, relf: String, bmp:BitmapData)
|
||||
{
|
||||
super(sidebar, bmp);
|
||||
this.bmp = bmp;
|
||||
this.relf = relf;
|
||||
}
|
||||
override public function OnClick():void
|
||||
{
|
||||
var worldStage: WorldStage = WorldStage(world);
|
||||
var posMouseReal: Point = worldStage.PointRealFromScreen(new Point(Input.mouseX, Input.mouseY));
|
||||
var relfBmp: String = worldStage.RelFull(relf);
|
||||
var tok: Token = new Token(bmp, relfBmp, posMouseReal.x - this.bmp.width / 2, posMouseReal.y - this.bmp.height / 2);
|
||||
world.add(tok);
|
||||
worldStage.tokSelected = tok;
|
||||
}
|
||||
}
|
||||
}
|
43
src/Folder.as
Normal file
43
src/Folder.as
Normal file
|
@ -0,0 +1,43 @@
|
|||
package
|
||||
{
|
||||
import net.flashpunk.Entity;
|
||||
import net.flashpunk.Graphic;
|
||||
import net.flashpunk.graphics.Graphiclist;
|
||||
import net.flashpunk.graphics.Image;
|
||||
import net.flashpunk.graphics.Text;
|
||||
import net.flashpunk.Mask;
|
||||
import net.flashpunk.utils.Input;
|
||||
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class Folder extends EntitySidebarImg
|
||||
{
|
||||
[Embed(source = '../assets/folder.png')]
|
||||
private const bmpFolder:Class;
|
||||
|
||||
private var reld: String;
|
||||
private var text: Text;
|
||||
|
||||
public function Folder(sidebar: Sidebar, reld: String)
|
||||
{
|
||||
super(sidebar, bmpFolder);
|
||||
text = new Text(reld, 2, (img.scaledHeight / 2) - 6);
|
||||
text.color = 0x4444FF;
|
||||
addGraphic(text);
|
||||
|
||||
this.reld = reld;
|
||||
}
|
||||
override public function OnClick():void
|
||||
{
|
||||
WorldStage(world).Chdir(this.reld);
|
||||
}
|
||||
override public function Fade(pct:Number):void
|
||||
{
|
||||
super.Fade(pct);
|
||||
text.alpha = pct;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
75
src/Imgdir.as
Normal file
75
src/Imgdir.as
Normal file
|
@ -0,0 +1,75 @@
|
|||
package
|
||||
{
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.Bitmap;
|
||||
import flash.display.Loader;
|
||||
import flash.display.LoaderInfo;
|
||||
import flash.events.Event;
|
||||
import flash.events.EventDispatcher;
|
||||
import flash.events.FileListEvent;
|
||||
import flash.events.IOErrorEvent;
|
||||
import flash.filesystem.File;
|
||||
import flash.net.URLRequest;
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class Imgdir extends EventDispatcher
|
||||
{
|
||||
public static const LOADED: String = "ImgLoaded";
|
||||
private var dir: File;
|
||||
private var mprelf_bmp: Object;
|
||||
private var rgreld: Object;
|
||||
public function Imgdir(url: String)
|
||||
{
|
||||
trace("imgdir: " + url);
|
||||
this.dir = new File(url);
|
||||
this.dir.addEventListener(FileListEvent.DIRECTORY_LISTING, OnDirUpdate);
|
||||
this.mprelf_bmp = { };
|
||||
this.rgreld = { };
|
||||
}
|
||||
|
||||
public function Update() : void
|
||||
{
|
||||
this.dir.getDirectoryListingAsync();
|
||||
}
|
||||
|
||||
private function OnDirUpdate(ev:FileListEvent) : void
|
||||
{
|
||||
for each (var file: File in ev.files)
|
||||
{
|
||||
var rel: String = file.name;
|
||||
if (file.isDirectory && !rgreld[rel])
|
||||
{
|
||||
rgreld[rel] = true;
|
||||
dispatchEvent(new EvNewImg(LOADED, rel, null));
|
||||
}
|
||||
else if (!file.isDirectory && /\.(png|gif|jpg|jpeg)$/i.test(rel) && !mprelf_bmp[rel])
|
||||
LoadBmp(file, OnBmpLoaded);
|
||||
}
|
||||
}
|
||||
public static function LoadBmp(file: File, dgOnLoad: Function, dgOnFail: Function = null):void
|
||||
{
|
||||
var loader : Loader = new Loader();
|
||||
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,
|
||||
function (evBmp: Event) : void {
|
||||
try
|
||||
{
|
||||
var bmp : BitmapData = Bitmap(LoaderInfo(evBmp.target).content).bitmapData;
|
||||
dgOnLoad(bmp, file);
|
||||
}
|
||||
catch(e:*) {}
|
||||
} );
|
||||
if (dgOnFail === null)
|
||||
dgOnFail = function(): void { }; // ignore errors
|
||||
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, dgOnFail);
|
||||
loader.load(new URLRequest(file.url));
|
||||
}
|
||||
private function OnBmpLoaded(bmp: BitmapData, file: File) : void
|
||||
{
|
||||
mprelf_bmp[file.name] = bmp;
|
||||
this.dispatchEvent(new EvNewImg(LOADED, file.name, bmp));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
27
src/Main.as
Normal file
27
src/Main.as
Normal file
|
@ -0,0 +1,27 @@
|
|||
package
|
||||
{
|
||||
import net.flashpunk.Engine;
|
||||
import net.flashpunk.FP;
|
||||
import splash.Splash;
|
||||
import flash.events.FileListEvent
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class Main extends Engine
|
||||
{
|
||||
public function Main():void
|
||||
{
|
||||
super(800, 600, 60, false);
|
||||
}
|
||||
|
||||
override public function init():void
|
||||
{
|
||||
FP.world = new WorldMenu();
|
||||
//var worldSplash: Splash = new Splash;
|
||||
//var worldStage: WorldStage = new WorldStage;
|
||||
//FP.world.add(worldSplash);
|
||||
//worldSplash.start(worldStage);
|
||||
}
|
||||
}
|
||||
}
|
115
src/Sidebar.as
Normal file
115
src/Sidebar.as
Normal file
|
@ -0,0 +1,115 @@
|
|||
package
|
||||
{
|
||||
import net.flashpunk.Entity;
|
||||
import net.flashpunk.Graphic;
|
||||
import net.flashpunk.Mask;
|
||||
import net.flashpunk.Tween;
|
||||
import net.flashpunk.tweens.misc.Alarm;
|
||||
import net.flashpunk.tweens.misc.NumTween;
|
||||
import net.flashpunk.tweens.misc.VarTween;
|
||||
import net.flashpunk.utils.Draw;
|
||||
import net.flashpunk.utils.Ease;
|
||||
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class Sidebar extends Entity
|
||||
{
|
||||
private var yNew:int;
|
||||
private var tweenX:VarTween;
|
||||
private var tweenY:VarTween;
|
||||
private var tweenFade:NumTween;
|
||||
private var yLast:Number;
|
||||
private var alarm:Alarm;
|
||||
private var xShow:int;
|
||||
private var xHide:int;
|
||||
private var yShow:int;
|
||||
private var yHide:int;
|
||||
public var fScrollable:Boolean;
|
||||
public function Sidebar(xShow:int, xHide: int, yShow:int, yHide:int, w:int, h:int, layer:int, fStartShown: Boolean, fScrollable: Boolean)
|
||||
{
|
||||
super(fStartShown ? xShow : xHide, fStartShown ? yShow : yHide);
|
||||
this.xShow = xShow;
|
||||
this.xHide = xHide;
|
||||
this.yShow = yShow;
|
||||
this.yHide = yHide;
|
||||
this.yLast = y;
|
||||
this.fScrollable = fScrollable;
|
||||
setHitbox(w, h, 0, 0);
|
||||
this.layer = layer + 1;
|
||||
this.yNew = y;
|
||||
tweenX = VarTween(addTween(new VarTween(MoveSidebar)));
|
||||
tweenY = VarTween(addTween(new VarTween(MoveSidebar)));
|
||||
tweenFade = NumTween(addTween(new NumTween(MoveSidebar)));
|
||||
alarm = null;
|
||||
if (fStartShown)
|
||||
tweenFade.value = 1.0;
|
||||
else
|
||||
tweenFade.value = 0.0;
|
||||
}
|
||||
public function LayerEntities():int { return this.layer - 1; }
|
||||
public function Add(entity: EntitySidebar):void
|
||||
{
|
||||
entity.y = yNew;
|
||||
yNew = yNew + entity.height;
|
||||
entity.layer = LayerEntities();
|
||||
world.add(entity); // eehhhhhh
|
||||
}
|
||||
public function Die(): void
|
||||
{
|
||||
var rgentity: Vector.<EntitySidebar> = new Vector.<EntitySidebar>();
|
||||
world.getLayer(LayerEntities(), rgentity);
|
||||
world.removeList(rgentity);
|
||||
world.remove(this);
|
||||
}
|
||||
override public function render():void
|
||||
{
|
||||
Draw.rect(x, y, width, height, 0x7777FF, 0.1);
|
||||
}
|
||||
override public function update():void
|
||||
{
|
||||
super.update();
|
||||
if (tweenX.active)
|
||||
MoveSidebar();
|
||||
}
|
||||
public function Toggle(dgOnComplete: Function = null): void
|
||||
{
|
||||
if (alarm !== null && alarm.active)
|
||||
removeTween(alarm);
|
||||
if (x !== xShow || y !== yShow)
|
||||
{
|
||||
tweenX.tween(this, "x", xShow, 0.3, Ease.cubeOut);
|
||||
tweenY.tween(this, "y", yShow, 0.3, Ease.cubeOut);
|
||||
tweenFade.tween(tweenFade.value, 1.0, 0.3, Ease.cubeOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
tweenX.tween(this, "x", xHide, 0.3, Ease.cubeIn);
|
||||
tweenY.tween(this, "y", yHide, 0.3, Ease.cubeIn);
|
||||
tweenFade.tween(tweenFade.value, 0, 0.3, Ease.cubeIn);
|
||||
}
|
||||
if (dgOnComplete !== null)
|
||||
alarm = Alarm(addTween(new Alarm(0.3, dgOnComplete, Tween.ONESHOT), true));
|
||||
}
|
||||
public function MoveSidebar(dy:int = 0): void
|
||||
{
|
||||
if (world !== null)
|
||||
{
|
||||
dy = dy + (y - yLast);
|
||||
var rgentity: Array = [];
|
||||
world.getLayer(LayerEntities(), rgentity);
|
||||
for each (var entity: EntitySidebar in rgentity)
|
||||
{
|
||||
entity.x = x;
|
||||
entity.y += dy;
|
||||
entity.Fade(tweenFade.value);
|
||||
}
|
||||
yNew += dy;
|
||||
yLast = y;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
25
src/TextSidebar.as
Normal file
25
src/TextSidebar.as
Normal file
|
@ -0,0 +1,25 @@
|
|||
package
|
||||
{
|
||||
import net.flashpunk.Graphic;
|
||||
import net.flashpunk.graphics.Text;
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class TextSidebar extends EntitySidebar
|
||||
{
|
||||
public function TextSidebar(sidebar:Sidebar, st:String, zoom:int = 1)
|
||||
{
|
||||
var text:Text = new Text(st);
|
||||
text.scale = zoom;
|
||||
text.x = (sidebar.width / 2) - (text.scaledWidth / 2);
|
||||
super(sidebar, text.scaledHeight, text);
|
||||
}
|
||||
override public function Fade(pct:Number):void
|
||||
{
|
||||
super.Fade(pct);
|
||||
Text(graphic).alpha = pct;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
137
src/Token.as
Normal file
137
src/Token.as
Normal file
|
@ -0,0 +1,137 @@
|
|||
package
|
||||
{
|
||||
import flash.display.BitmapData;
|
||||
import flash.geom.Point;
|
||||
import flash.geom.Rectangle;
|
||||
import net.flashpunk.Entity;
|
||||
import net.flashpunk.graphics.Image;
|
||||
import net.flashpunk.utils.Draw;
|
||||
import net.flashpunk.utils.Input;
|
||||
import net.flashpunk.utils.Key;
|
||||
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class Token extends Entity
|
||||
{
|
||||
private var drag: Drag;
|
||||
public var posReal: Point;
|
||||
private var relf: String;
|
||||
private var xml: XML;
|
||||
public function Token(source:BitmapData, relf: String, x: int, y: int, xml:XML = null)
|
||||
{
|
||||
this.posReal = new Point(x, y);
|
||||
super(x, y, new Image(source));
|
||||
this.type = "Token";
|
||||
this.layer = WorldStage.LAYER_TOKENS;
|
||||
this.drag = null;
|
||||
this.relf = relf;
|
||||
if (xml === null)
|
||||
this.xml = XML("<token/>");
|
||||
else
|
||||
this.xml = xml;
|
||||
}
|
||||
public function FSelected(): Boolean
|
||||
{
|
||||
return WorldStage(this.world).tokSelected === this;
|
||||
}
|
||||
override public function removed():void
|
||||
{
|
||||
super.removed();
|
||||
if (drag !== null)
|
||||
{
|
||||
drag.Done();
|
||||
drag = null;
|
||||
}
|
||||
}
|
||||
override public function added():void
|
||||
{
|
||||
super.added();
|
||||
FixupZoom();
|
||||
}
|
||||
private function FixupZoom(): Number
|
||||
{
|
||||
var worldStage: WorldStage = WorldStage(world);
|
||||
var zoom: Number = worldStage.zoom;
|
||||
var img: Image = Image(this.graphic);
|
||||
Image(this.graphic).scale = zoom;
|
||||
var posScreen : Point = worldStage.PointScreenFromReal(posReal);
|
||||
x = int(posScreen.x);
|
||||
y = int(posScreen.y);
|
||||
this.setHitbox(img.scaledWidth, img.scaledHeight, -img.x, -img.y);
|
||||
|
||||
return zoom;
|
||||
}
|
||||
override public function update():void
|
||||
{
|
||||
super.update();
|
||||
|
||||
var zoom: Number = FixupZoom();
|
||||
|
||||
if (Input.mouseUp && drag !== null)
|
||||
{
|
||||
trace("drag done");
|
||||
drag.Done();
|
||||
drag = null;
|
||||
}
|
||||
|
||||
if (FSelected())
|
||||
{
|
||||
var deltaMove: Point = null;
|
||||
if (Input.pressed(Key.UP))
|
||||
deltaMove = new Point(0, -1);
|
||||
else if (Input.pressed(Key.DOWN))
|
||||
deltaMove = new Point(0, 1);
|
||||
else if (Input.pressed(Key.LEFT))
|
||||
deltaMove = new Point(-1, 0);
|
||||
else if (Input.pressed(Key.RIGHT))
|
||||
deltaMove = new Point(1, 0);
|
||||
|
||||
if (Input.pressed(Key.PAGE_UP))
|
||||
world.bringForward(this);
|
||||
else if (Input.pressed(Key.PAGE_DOWN))
|
||||
world.sendBackward(this);
|
||||
|
||||
if (Input.mouseDown)
|
||||
{
|
||||
if (drag === null && collidePoint(x, y, Input.mouseX, Input.mouseY))
|
||||
{
|
||||
drag = Drag.Claim();
|
||||
if (drag !== null)
|
||||
trace("drag claimed for " + relf);
|
||||
else
|
||||
trace("drag failed for " + relf);
|
||||
}
|
||||
|
||||
if (drag !== null)
|
||||
{
|
||||
deltaMove = drag.Delta(zoom);
|
||||
drag.Update();
|
||||
}
|
||||
}
|
||||
if (deltaMove !== null)
|
||||
posReal = posReal.add(deltaMove);
|
||||
|
||||
if (Input.pressed(Key.DELETE))
|
||||
WorldStage(world).KillToken(this);
|
||||
}
|
||||
}
|
||||
override public function render():void
|
||||
{
|
||||
super.render();
|
||||
if (FSelected())
|
||||
Draw.hitbox(this);
|
||||
}
|
||||
|
||||
public function GenXML(): XML
|
||||
{
|
||||
var xml: XML = this.xml.copy();
|
||||
xml.@x = int(posReal.x);
|
||||
xml.@y = int(posReal.y);
|
||||
xml.@path = relf;
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
98
src/WorldMenu.as
Normal file
98
src/WorldMenu.as
Normal file
|
@ -0,0 +1,98 @@
|
|||
package
|
||||
{
|
||||
import flash.events.Event;
|
||||
import flash.filesystem.File;
|
||||
import flash.net.FileFilter;
|
||||
import flash.net.FileReference;
|
||||
import flash.net.FileReferenceList;
|
||||
import flash.net.URLRequest;
|
||||
import flash.utils.Dictionary;
|
||||
import net.flashpunk.Entity;
|
||||
import net.flashpunk.FP;
|
||||
import net.flashpunk.graphics.Image;
|
||||
import net.flashpunk.graphics.Text;
|
||||
import net.flashpunk.utils.Input;
|
||||
import net.flashpunk.World;
|
||||
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class WorldMenu extends World
|
||||
{
|
||||
[Embed(source = '../assets/punk.png')]
|
||||
private const bmpPunk:Class;
|
||||
|
||||
private var mpentity_dgclick: Dictionary;
|
||||
|
||||
public function WorldMenu()
|
||||
{
|
||||
super();
|
||||
AddText("KlikPunk", FP.height / 8, 5);
|
||||
AddText("icons by Mark James http://www.famfamfam.com/lab/icons/silk/", FP.height - 32);
|
||||
var imgPunk: Image = new Image(bmpPunk);
|
||||
imgPunk.scale = 8;
|
||||
var entityPunk: Entity = new Entity((FP.width / 2) - (imgPunk.scaledWidth / 2), 10, imgPunk);
|
||||
entityPunk.layer = 10;
|
||||
add(entityPunk);
|
||||
SetMenu(["New Stage", NewStage], ["Open Stage", OpenStage]);
|
||||
}
|
||||
private function SetMenu(...rgmenu):void
|
||||
{
|
||||
var yMenu:int = (FP.height / 2);
|
||||
var hMenus:int = FP.height - yMenu - (FP.height / 8);
|
||||
var dyMenu:int = hMenus / rgmenu.length;
|
||||
mpentity_dgclick = new Dictionary();
|
||||
for each(var menu:Array in rgmenu)
|
||||
{
|
||||
var entityMenu: Entity = AddText(menu[0], yMenu, 2);
|
||||
entityMenu.type = "menuitem";
|
||||
mpentity_dgclick[entityMenu] = menu[1];
|
||||
yMenu = yMenu + dyMenu;
|
||||
}
|
||||
}
|
||||
private function AddText(stText:String, y:int, scale:Number = 1): Entity
|
||||
{
|
||||
var text: Text = new Text(stText);
|
||||
text.scale = scale;
|
||||
var entity: Entity = addGraphic(text, 0, (FP.width / 2) - (text.scaledWidth / 2), y - (text.scaledHeight / 2));
|
||||
entity.setHitbox(text.scaledWidth, text.scaledHeight, 0, 0);
|
||||
return entity;
|
||||
}
|
||||
public function NewStage(): void
|
||||
{
|
||||
FileForBrowse().browseForSave("Choose your destiny");
|
||||
}
|
||||
public function OpenStage(): void
|
||||
{
|
||||
FileForBrowse().browseForOpen("Find your thing", [new FileFilter("Stages", "*.xml")]);
|
||||
}
|
||||
private function FileForBrowse(): File
|
||||
{
|
||||
var file: File = new File(File.userDirectory.nativePath + File.separator + "NewStage.xml");
|
||||
file.addEventListener(Event.SELECT, function():void {
|
||||
FP.world = new WorldStage(file.url);
|
||||
});
|
||||
|
||||
return file;
|
||||
}
|
||||
override public function update():void
|
||||
{
|
||||
var rgentityMenu: Array = [];
|
||||
getType("menuitem", rgentityMenu);
|
||||
for each(var entityMenu: Entity in rgentityMenu)
|
||||
{
|
||||
if (entityMenu.collidePoint(entityMenu.x, entityMenu.y, Input.mouseX, Input.mouseY))
|
||||
{
|
||||
if (Input.mousePressed)
|
||||
mpentity_dgclick[entityMenu]();
|
||||
Text(entityMenu.graphic).color = 0xFFFFFF;
|
||||
}
|
||||
else
|
||||
Text(entityMenu.graphic).color = 0x888888;
|
||||
}
|
||||
super.update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
308
src/WorldStage.as
Normal file
308
src/WorldStage.as
Normal file
|
@ -0,0 +1,308 @@
|
|||
package
|
||||
{
|
||||
import flash.display.BitmapData;
|
||||
import flash.events.Event;
|
||||
import flash.filesystem.File;
|
||||
import flash.filesystem.FileMode;
|
||||
import flash.filesystem.FileStream;
|
||||
import flash.geom.Point;
|
||||
import net.flashpunk.debug.Console;
|
||||
import net.flashpunk.Entity;
|
||||
import net.flashpunk.FP;
|
||||
import net.flashpunk.graphics.Image;
|
||||
import net.flashpunk.Tween;
|
||||
import net.flashpunk.tweens.misc.Alarm;
|
||||
import net.flashpunk.tweens.misc.VarTween;
|
||||
import net.flashpunk.utils.Ease;
|
||||
import net.flashpunk.utils.Key;
|
||||
import net.flashpunk.World;
|
||||
import net.flashpunk.utils.Input;
|
||||
/**
|
||||
* ...
|
||||
* @author jjp
|
||||
*/
|
||||
public class WorldStage extends World
|
||||
{
|
||||
[Embed(source = '../assets/save.png')]
|
||||
private const bmpSave:Class;
|
||||
|
||||
public static const LAYER_TOKENS: int = 100;
|
||||
public static const LAYER_SIDEBAR: int = 50;
|
||||
public static const LAYER_SAVE: int = 60;
|
||||
public static const LAYER_MSG: int = 70;
|
||||
|
||||
private var imgdir: Imgdir;
|
||||
private var drag: Drag;
|
||||
private var absd: String;
|
||||
private var relf: String;
|
||||
private var rgreld: Array;
|
||||
private var alarmImgdir: Tween;
|
||||
private var rgsidebar: Vector.<Sidebar>;
|
||||
|
||||
private var sidebarMsg: Sidebar;
|
||||
private var rgmsg: Vector.<String>;
|
||||
private var alarmMsg: Alarm;
|
||||
|
||||
public var tokSelected: Token;
|
||||
public var zoom: Number;
|
||||
public var pointView: Point;
|
||||
|
||||
public function WorldStage(absf: String)
|
||||
{
|
||||
super();
|
||||
var match:* = /(.*\/)([^\/]*)$/.exec(absf);
|
||||
this.absd = match[1];
|
||||
this.relf = match[2];
|
||||
this.rgreld = [];
|
||||
this.rgsidebar = new Vector.<Sidebar>();
|
||||
|
||||
var sidebarSave: Sidebar = AddSidebar(new Sidebar(FP.width - 32, FP.width, 0, 0, 32, 32, LAYER_SAVE, false, false));
|
||||
new Button(sidebarSave, bmpSave, Save);
|
||||
|
||||
sidebarMsg = null;
|
||||
alarmMsg = null;
|
||||
rgmsg = new Vector.<String>()
|
||||
|
||||
zoom = 1;
|
||||
pointView = new Point(0, 0);
|
||||
drag = null;
|
||||
Chdir(null);
|
||||
ToggleUI();
|
||||
Load();
|
||||
}
|
||||
|
||||
public function KillToken(tok: Token): void
|
||||
{
|
||||
remove(tok);
|
||||
tok.active = false;
|
||||
if (tokSelected === tok)
|
||||
tokSelected = null;
|
||||
}
|
||||
public function PointRealFromScreen(pointScreen: Point): Point
|
||||
{
|
||||
return new Point((pointScreen.x / zoom) + pointView.x, (pointScreen.y / zoom) + pointView.y);
|
||||
}
|
||||
public function PointScreenFromReal(pointReal: Point) : Point
|
||||
{
|
||||
return new Point((pointReal.x - pointView.x) * zoom, (pointReal.y - pointView.y) * zoom);
|
||||
}
|
||||
private function OnNewImg(ev: EvNewImg) : void
|
||||
{
|
||||
var entity: Entity;
|
||||
if (ev.bmp === null)
|
||||
entity = new Folder(SidebarFind(LAYER_SIDEBAR), ev.rel);
|
||||
else
|
||||
entity = new Factory(SidebarFind(LAYER_SIDEBAR), ev.rel, ev.bmp);
|
||||
}
|
||||
public function RelFull(relf:String = null): String
|
||||
{
|
||||
var rel:String = rgreld.join(File.separator);
|
||||
if (relf !== null)
|
||||
rel = rel + File.separator + relf;
|
||||
return rel;
|
||||
}
|
||||
public function Chdir(reld: String): void
|
||||
{
|
||||
if (alarmImgdir !== null)
|
||||
{
|
||||
removeTween(alarmImgdir);
|
||||
|
||||
var rgui: Array = [];
|
||||
getLayer(LAYER_SIDEBAR, rgui);
|
||||
for each (var entity: Entity in rgui)
|
||||
{
|
||||
remove(entity);
|
||||
entity.active = false;
|
||||
}
|
||||
}
|
||||
if (reld === "..")
|
||||
rgreld = rgreld.slice(0, rgreld.length - 1);
|
||||
else if (reld !== null)
|
||||
rgreld.push(reld);
|
||||
|
||||
imgdir = new Imgdir(absd + RelFull());
|
||||
imgdir.addEventListener(Imgdir.LOADED, OnNewImg);
|
||||
imgdir.Update();
|
||||
alarmImgdir = this.addTween(new Alarm(3, imgdir.Update, Tween.LOOPING), true);
|
||||
|
||||
AddSidebar(new Sidebar(0, -32, 0, 0, 32, FP.height, LAYER_SIDEBAR, reld !== null /*fStartShown*/, true));
|
||||
|
||||
if (rgreld.length > 0)
|
||||
OnNewImg(new EvNewImg(Imgdir.LOADED, "..", null));
|
||||
}
|
||||
private function SidebarFind(layer: int):Sidebar
|
||||
{
|
||||
for each (var sidebar:Sidebar in rgsidebar)
|
||||
if (sidebar.LayerEntities() === layer)
|
||||
return sidebar;
|
||||
return null;
|
||||
}
|
||||
private function RemoveSidebar(layer:int):void
|
||||
{
|
||||
rgsidebar = rgsidebar.filter(
|
||||
function(sidebarOld:Sidebar, isidebarOld:int, rg:Vector.<Sidebar>):Boolean {
|
||||
if (sidebarOld.LayerEntities() === layer)
|
||||
{
|
||||
sidebarOld.Die();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, this);
|
||||
}
|
||||
private function AddSidebar(sidebar: Sidebar):Sidebar
|
||||
{
|
||||
RemoveSidebar(sidebar.LayerEntities());
|
||||
add(sidebar);
|
||||
rgsidebar.push(sidebar);
|
||||
return sidebar;
|
||||
}
|
||||
private function ToggleUI(): void
|
||||
{
|
||||
for each (var sidebar: Sidebar in rgsidebar)
|
||||
sidebar.Toggle();
|
||||
}
|
||||
override public function update():void
|
||||
{
|
||||
var dyFactory:int = 0;
|
||||
if (Input.mousePressed)
|
||||
{
|
||||
var rgtok: Array = [];
|
||||
getLayer(LAYER_TOKENS, rgtok);
|
||||
tokSelected = null;
|
||||
// getLayer returns tokens in draw order, which means furthest back first
|
||||
for (var itok:int = rgtok.length - 1; itok >= 0; itok --)
|
||||
{
|
||||
var tok: Token = rgtok[itok];
|
||||
if (tok.collidePoint(tok.x, tok.y, Input.mouseX, Input.mouseY))
|
||||
{
|
||||
tokSelected = tok;
|
||||
break;
|
||||
}
|
||||
}
|
||||
trace("clicked on " + tokSelected);
|
||||
}
|
||||
if (Input.pressed(Key.TAB))
|
||||
ToggleUI();
|
||||
if (Input.mouseWheel)
|
||||
{
|
||||
var fSidebarScrolled:Boolean = false;
|
||||
for each (var sidebar: Sidebar in rgsidebar)
|
||||
{
|
||||
if (sidebar.fScrollable && sidebar.collidePoint(sidebar.x, sidebar.y, Input.mouseX, Input.mouseY))
|
||||
{
|
||||
sidebar.MoveSidebar(Input.mouseWheelDelta * 5);
|
||||
fSidebarScrolled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!fSidebarScrolled)
|
||||
{
|
||||
var zoomNew: Number = zoom + (Input.mouseWheelDelta / 100);
|
||||
if (zoomNew <= 0)
|
||||
zoomNew = 0.01;
|
||||
// keep the point under the mouse cursor in the same place
|
||||
var dx: Number = (Input.mouseX / zoom) - (Input.mouseX / zoomNew);
|
||||
var dy: Number = (Input.mouseY / zoom) - (Input.mouseY / zoomNew);
|
||||
pointView.x = pointView.x + dx;
|
||||
pointView.y = pointView.y + dy;
|
||||
zoom = zoomNew;
|
||||
}
|
||||
}
|
||||
super.update();
|
||||
}
|
||||
|
||||
public function ShowMsg(stMsg: String):void
|
||||
{
|
||||
rgmsg.push(stMsg);
|
||||
if (alarmMsg === null)
|
||||
ShowNextMsg();
|
||||
}
|
||||
private function ShowNextMsg(): void
|
||||
{
|
||||
if (sidebarMsg !== null)
|
||||
{
|
||||
sidebarMsg.Die();
|
||||
sidebarMsg = null;
|
||||
}
|
||||
if (alarmMsg !== null && alarmMsg.active)
|
||||
removeTween(alarmMsg);
|
||||
alarmMsg = null;
|
||||
|
||||
if (rgmsg.length > 0)
|
||||
{
|
||||
var stMsg:String = rgmsg.shift();
|
||||
var x:int = FP.width / 8;
|
||||
sidebarMsg = Sidebar(add(new Sidebar(x, x, FP.height - 45, FP.height, x * 6, 45, LAYER_MSG, false, false)));
|
||||
new TextSidebar(sidebarMsg, stMsg, 2);
|
||||
sidebarMsg.Toggle();
|
||||
alarmMsg = Alarm(addTween(new Alarm(2, function():void { sidebarMsg.Toggle(ShowNextMsg); }, Tween.ONESHOT), true));
|
||||
}
|
||||
}
|
||||
|
||||
public function Save(): void
|
||||
{
|
||||
var stream: FileStream = new FileStream();
|
||||
stream.open(new File(absd + File.separator + relf), FileMode.WRITE);
|
||||
stream.writeUTFBytes(GenXML().toXMLString());
|
||||
stream.close();
|
||||
ShowMsg("Saved.");
|
||||
}
|
||||
public function Load(): void
|
||||
{
|
||||
var file: File = new File(absd + File.separator + relf);
|
||||
if (file.exists)
|
||||
{
|
||||
var stream: FileStream = new FileStream();
|
||||
stream.open(file, FileMode.READ);
|
||||
var xml: XML = XML(stream.readUTFBytes(file.size));
|
||||
var itoken:int = 0;
|
||||
var rgtoken:Object = { ctokenLoaded: 0, ctoken: xml.children().length(), rgtoken: [] };
|
||||
for each (var xmlToken: XML in xml.children())
|
||||
{
|
||||
LoadToken(xmlToken, itoken, rgtoken);
|
||||
itoken = itoken + 1;
|
||||
}
|
||||
ShowMsg("Loaded.");
|
||||
}
|
||||
}
|
||||
private function LoadToken(xml: XML, itoken: int, rgtoken:Object): void
|
||||
{
|
||||
trace("loading " + xml.@path);
|
||||
Imgdir.LoadBmp(new File(absd + File.separator + xml.@path),
|
||||
function(bmp: BitmapData, file: File):void {
|
||||
trace("loadtoken: " + xml.@path);
|
||||
var token: Token = new Token(bmp, xml.@path.toString(), int(xml.@x), int(xml.@y), xml);
|
||||
FixupTokens(rgtoken, token, itoken);
|
||||
},
|
||||
function():void
|
||||
{
|
||||
FixupTokens(rgtoken, null, itoken);
|
||||
});
|
||||
}
|
||||
private function FixupTokens(rgtoken:Object, tokenLoaded: Token, itokenLoaded:int):void
|
||||
{
|
||||
rgtoken.ctokenLoaded ++;
|
||||
rgtoken.rgtoken[itokenLoaded] = tokenLoaded;
|
||||
if (rgtoken.ctokenLoaded === rgtoken.ctoken)
|
||||
{
|
||||
for (var itoken:int = 0; itoken < rgtoken.ctoken; itoken ++)
|
||||
{
|
||||
var token:Token = rgtoken.rgtoken[itoken];
|
||||
if (token !== null)
|
||||
add(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
public function GenXML():XML
|
||||
{
|
||||
var xml: XML = XML("<stage/>");
|
||||
var rgtoken:Array = [];
|
||||
this.getLayer(LAYER_TOKENS, rgtoken);
|
||||
for each(var token: Token in rgtoken)
|
||||
xml.appendChild(token.GenXML());
|
||||
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
291
src/net/flashpunk/Engine.as
Normal file
291
src/net/flashpunk/Engine.as
Normal file
|
@ -0,0 +1,291 @@
|
|||
package net.flashpunk
|
||||
{
|
||||
import flash.display.Bitmap;
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.MovieClip;
|
||||
import flash.display.StageAlign;
|
||||
import flash.display.StageDisplayState;
|
||||
import flash.display.StageQuality;
|
||||
import flash.display.StageScaleMode;
|
||||
import flash.events.Event;
|
||||
import flash.events.TimerEvent;
|
||||
import flash.geom.Rectangle;
|
||||
import flash.utils.getTimer;
|
||||
import flash.utils.Timer;
|
||||
import net.flashpunk.utils.Draw;
|
||||
import net.flashpunk.utils.Input;
|
||||
|
||||
/**
|
||||
* Main game Sprite class, added to the Flash Stage. Manages the game loop.
|
||||
*/
|
||||
public class Engine extends MovieClip
|
||||
{
|
||||
/**
|
||||
* If the game should stop updating/rendering.
|
||||
*/
|
||||
public var paused:Boolean = false;
|
||||
|
||||
/**
|
||||
* Cap on the elapsed time (default at 30 FPS). Raise this to allow for lower framerates (eg. 1 / 10).
|
||||
*/
|
||||
public var maxElapsed:Number = 0.0333;
|
||||
|
||||
/**
|
||||
* The max amount of frames that can be skipped in fixed framerate mode.
|
||||
*/
|
||||
public var maxFrameSkip:uint = 5;
|
||||
|
||||
/**
|
||||
* The amount of milliseconds between ticks in fixed framerate mode.
|
||||
*/
|
||||
public var tickRate:uint = 4;
|
||||
|
||||
/**
|
||||
* Constructor. Defines startup information about your game.
|
||||
* @param width The width of your game.
|
||||
* @param height The height of your game.
|
||||
* @param frameRate The game framerate, in frames per second.
|
||||
* @param fixed If a fixed-framerate should be used.
|
||||
*/
|
||||
public function Engine(width:uint, height:uint, frameRate:Number = 60, fixed:Boolean = false)
|
||||
{
|
||||
// global game properties
|
||||
FP.width = width;
|
||||
FP.height = height;
|
||||
FP.assignedFrameRate = frameRate;
|
||||
FP.fixed = fixed;
|
||||
|
||||
// global game objects
|
||||
FP.engine = this;
|
||||
FP.screen = new Screen;
|
||||
FP.bounds = new Rectangle(0, 0, width, height);
|
||||
FP._world = new World;
|
||||
|
||||
// miscellanious startup stuff
|
||||
if (FP.randomSeed == 0) FP.randomizeSeed();
|
||||
FP.entity = new Entity;
|
||||
FP._time = getTimer();
|
||||
|
||||
// on-stage event listener
|
||||
addEventListener(Event.ADDED_TO_STAGE, onStage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this, called after Engine has been added to the stage.
|
||||
*/
|
||||
public function init():void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the game, updating the World and Entities.
|
||||
*/
|
||||
public function update():void
|
||||
{
|
||||
if (FP._world.active)
|
||||
{
|
||||
if (FP._world._tween) FP._world.updateTweens();
|
||||
FP._world.update();
|
||||
}
|
||||
FP._world.updateLists();
|
||||
if (FP._goto) checkWorld();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the game, rendering the World and Entities.
|
||||
*/
|
||||
public function render():void
|
||||
{
|
||||
// timing stuff
|
||||
var t:Number = getTimer();
|
||||
if (!_frameLast) _frameLast = t;
|
||||
|
||||
// render loop
|
||||
FP.screen.swap();
|
||||
Draw.resetTarget();
|
||||
FP.screen.refresh();
|
||||
if (FP._world.visible) FP._world.render();
|
||||
FP.screen.redraw();
|
||||
|
||||
// more timing stuff
|
||||
t = getTimer();
|
||||
_frameListSum += (_frameList[_frameList.length] = t - _frameLast);
|
||||
if (_frameList.length > 10) _frameListSum -= _frameList.shift();
|
||||
FP.frameRate = 1000 / (_frameListSum / _frameList.length);
|
||||
_frameLast = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the game's stage properties. Override this to set them differently.
|
||||
*/
|
||||
public function setStageProperties():void
|
||||
{
|
||||
stage.frameRate = FP.assignedFrameRate;
|
||||
stage.align = StageAlign.TOP_LEFT;
|
||||
stage.quality = StageQuality.HIGH;
|
||||
stage.scaleMode = StageScaleMode.NO_SCALE;
|
||||
stage.displayState = StageDisplayState.NORMAL;
|
||||
}
|
||||
|
||||
/** @private Event handler for stage entry. */
|
||||
private function onStage(e:Event = null):void
|
||||
{
|
||||
// remove event listener
|
||||
removeEventListener(Event.ADDED_TO_STAGE, onStage);
|
||||
|
||||
// set stage properties
|
||||
FP.stage = stage;
|
||||
setStageProperties();
|
||||
|
||||
// enable input
|
||||
Input.enable();
|
||||
|
||||
// switch worlds
|
||||
if (FP._goto) checkWorld();
|
||||
|
||||
// game start
|
||||
init();
|
||||
|
||||
// start game loop
|
||||
_rate = 1000 / FP.assignedFrameRate;
|
||||
if (FP.fixed)
|
||||
{
|
||||
// fixed framerate
|
||||
_skip = _rate * maxFrameSkip;
|
||||
_last = _prev = getTimer();
|
||||
_timer = new Timer(tickRate);
|
||||
_timer.addEventListener(TimerEvent.TIMER, onTimer);
|
||||
_timer.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
// nonfixed framerate
|
||||
_last = getTimer();
|
||||
addEventListener(Event.ENTER_FRAME, onEnterFrame);
|
||||
}
|
||||
}
|
||||
|
||||
/** @private Framerate independent game loop. */
|
||||
private function onEnterFrame(e:Event):void
|
||||
{
|
||||
// update timer
|
||||
_time = _gameTime = getTimer();
|
||||
FP._flashTime = _time - _flashTime;
|
||||
_updateTime = _time;
|
||||
FP.elapsed = (_time - _last) / 1000;
|
||||
if (FP.elapsed > maxElapsed) FP.elapsed = maxElapsed;
|
||||
FP.elapsed *= FP.rate;
|
||||
_last = _time;
|
||||
|
||||
// update console
|
||||
if (FP._console) FP._console.update();
|
||||
|
||||
// update loop
|
||||
if (!paused) update();
|
||||
|
||||
// update input
|
||||
Input.update();
|
||||
|
||||
// update timer
|
||||
_time = _renderTime = getTimer();
|
||||
FP._updateTime = _time - _updateTime;
|
||||
|
||||
// render loop
|
||||
if (!paused) render();
|
||||
|
||||
// update timer
|
||||
_time = _flashTime = getTimer();
|
||||
FP._renderTime = _time - _renderTime;
|
||||
FP._gameTime = _time - _gameTime;
|
||||
}
|
||||
|
||||
/** @private Fixed framerate game loop. */
|
||||
private function onTimer(e:TimerEvent):void
|
||||
{
|
||||
// update timer
|
||||
_time = getTimer();
|
||||
_delta += (_time - _last);
|
||||
_last = _time;
|
||||
|
||||
// quit if a frame hasn't passed
|
||||
if (_delta < _rate) return;
|
||||
|
||||
// update timer
|
||||
_gameTime = _time;
|
||||
FP._flashTime = _time - _flashTime;
|
||||
|
||||
// update console
|
||||
if (FP._console) FP._console.update();
|
||||
|
||||
// update loop
|
||||
if (_delta > _skip) _delta = _skip;
|
||||
while (_delta > _rate)
|
||||
{
|
||||
// update timer
|
||||
_updateTime = _time;
|
||||