Току-що завърших основната структура на малка игра и запазих простия предварително зареждащ файл за последно. Колко съм глупав.
След множество уроци открих този, който работи за мен - Pre Loader във Flash Builder
Предварителното зареждане работи и играта е на сцената, но замръзва моментално. Всяко позоваване на етапа в моя код LevelOne извежда грешки. грешка #1009: няма достъп до свойство или метод на препратка към нулев обект.
Преди прилагането на Preloader, моят клас на приложение (RookiesGame) беше използван като превключвател на нива. Всяко ниво се съдържа в спрайт. RookiesGame започва с добавяне на LevelOne към етапа, след което, след като играчът го завърши, RookiesGame премахва LevelOne и добавя LevelTwo към етапа и т.н.
Класовете на ниво препращат към етапа с променливата _stage.
Откакто изучавам тази структура, това, че предварителното зареждане се превръща в клас на приложението, а RookiesGame става просто друг клас, наистина ме обърка. Не трябва ли _stage var все още да работи? Добре ли е да запазите RookiesGame като превключвател на нива?
Както и да е, основният проблем е реферирането на етапа от класовете на ниво.
Текущ код:
Клас за предварително зареждане
Работи добре, играта започва.
package
{
import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.utils.getDefinitionByName;
[SWF(width="650", height="450", backgroundColor="#FFFFFF", frameRate="60")]
public class Preloader extends Sprite
{
// Private
private var _preloaderBackground:Shape
private var _preloaderPercent:Shape;
private var _checkForCacheFlag:Boolean = true;
// Constants
private static const MAIN_CLASS_NAME:String = "RookiesGame";
public function Preloader()
{
trace("Preloader: Initialized.")
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
public function dispose():void
{
trace("Preloader: Disposing.")
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
if (_preloaderBackground)
{
removeChild(_preloaderBackground);
_preloaderBackground = null;
}
if (_preloaderPercent)
{
removeChild(_preloaderPercent);
_preloaderPercent = null;
}
}
// Private functions
private function onAddedToStage(e:Event):void
{
trace("Preloader: Added to stage.");
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
stage.scaleMode = StageScaleMode.SHOW_ALL;
stage.align = StageAlign.TOP_LEFT;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void
{
if (_checkForCacheFlag == true)
{
_checkForCacheFlag = false;
if (root.loaderInfo.bytesLoaded >= root.loaderInfo.bytesTotal)
{
trace("Preloader: No need to load, all " + root.loaderInfo.bytesTotal + " bytes are cached.");
finishedLoading();
}
else
beginLoading();
}
else
{
if (root.loaderInfo.bytesLoaded >= root.loaderInfo.bytesTotal)
{
trace("Preloader: Finished loading all " + root.loaderInfo.bytesTotal + " bytes.");
finishedLoading();
}
else
{
var percent:Number = root.loaderInfo.bytesLoaded / root.loaderInfo.bytesTotal;
updateGraphic(percent);
trace("Preloader: " + (percent * 100) + " %");
}
}
}
private function beginLoading():void
{
// Might not be called if cached.
// ------------------------------
trace("Preloader: Beginning loading.")
_preloaderBackground = new Shape()
_preloaderBackground.graphics.beginFill(0x333333)
_preloaderBackground.graphics.lineStyle(2,0x000000)
_preloaderBackground.graphics.drawRect(0,0,200,20)
_preloaderBackground.graphics.endFill()
_preloaderPercent = new Shape()
_preloaderPercent.graphics.beginFill(0xFFFFFFF)
_preloaderPercent.graphics.drawRect(0,0,200,20)
_preloaderPercent.graphics.endFill()
addChild(_preloaderBackground)
addChild(_preloaderPercent)
_preloaderBackground.x = _preloaderBackground.y = 10
_preloaderPercent.x = _preloaderPercent.y = 10
_preloaderPercent.scaleX = 0
}
private function updateGraphic(percent:Number):void
{
// Might not be called if cached.
// ------------------------------
_preloaderPercent.scaleX = percent
}
private function finishedLoading():void
{
var RookiesGame:Class = getDefinitionByName(MAIN_CLASS_NAME) as Class;
if (RookiesGame == null)
throw new Error("Preloader: There is no class \"" + MAIN_CLASS_NAME + "\".");
var main:DisplayObject = new RookiesGame() as DisplayObject;
if (main == null)
throw new Error("Preloader: The class \"" + MAIN_CLASS_NAME + "\" is not a Sprite or MovieClip.");
addChild(main);
dispose();
}
}
}
Клас RookiesGame (преди клас на приложение)
Всички препратки към етапа извеждаха грешка #1009, която спря, когато промених stage.addChild на this.addChild
Все още не съм стигнал до манипулатора на превключвателя на ниво с предварителното зареждане, така че също не знам как ще работи stage.focus!
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
public class RookiesGame extends Sprite
{
private var _levelOne:LevelOne;
private var _levelTwo:LevelTwo;
public function RookiesGame()
{
_levelOne = new LevelOne(stage);
_levelTwo = new LevelTwo(stage);
this.addChild(_levelOne);
this.addEventListener("levelOneComplete",levelTwoSwitchHandler);
}
private function levelTwoSwitchHandler(event:Event):void
{
this.removeChild(_levelOne);
_levelOne = null;
this.addChild(_levelTwo);
stage.focus = stage;
}
}
}
Клас първо ниво
Много грешки #1009. Всичко, което се отнася до сцената.
Класът е огромен, така че ще подчертая проблемните части.
Грешка #1009 при рефериране на етап, добавяне на слушателите на клавиатурата.
_stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
_stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
Също така #1009, когато препращате към етап, за да проверите границите на етапа. Вече не мога просто да променям сцената. на това..
private function checkStageBoundaries(gameObject:MovieClip):void
{
if (gameObject.x < 50)
{
gameObject.x = 50;
}
if (gameObject.y < 50)
{
gameObject.y = 50;
}
if (gameObject.x + gameObject.width > _stage.stageWidth - 50)
{
gameObject.x = _stage.stageWidth - gameObject.width - 50;
}
if (gameObject.y + gameObject.height > _stage.stageHeight - 50)
{
gameObject.y = _stage.stageHeight - gameObject.height - 50;
}
}
Позовавам се на _stage по-късно в програмата, за да премахна слушателите на събития. Това е.
_stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
_stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
Как мога да реферирам сцената, без тези грешки и да запазя RookiesGame като превключвател на нива.
Структура на класа LevelOne
За да покажа как използвам(d) _stage.
package
{
//import classes
public class LevelOne extends Sprite
{
//Declare the variables to hold the game objects
//A variable to store the reference to the stage from the application class
private var _stage:Object;
public function LevelOne(stage:Object)
{
_stage = stage;
this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(event:Event):void
{
startGame();
this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function startGame():void
{
//Includes _stage references that mess everything up.
}
private function levelCleared():void
{
//When Level finished, dispatch event to tell RookiesGame to switch levels.
dispatchEvent(new Event("levelOneComplete", true));
}
}
}
Съжалявам, ако това е объркващо, но ако можете да ми помогнете да препратя етапа чрез класове LevelOne и RookiesGame, ще бъда много благодарен.