PDA

Просмотр полной версии : Запустить главный класс со второго кадра


TurboDizel
12.01.2013, 19:45
Есть в общем почти готовая игра, которая начинается с класса main. Решил сделать прелоадер, который надо было сделать ещё перед игрой, и чего-то даже не знаю, каким образом после того как прелоадер на первом кадре отработал, запустить на втором кадре класс main? Возможно это вообще делается по другому, и было бы не плохо узнать как именно).

NikolyA
12.01.2013, 20:04
не лучший мануал: http://www.8bitrocket.com/2008/04/22/tutorial-preloading-actionscript-3-as3-games-in-flash-cs3/

caseyryan
12.01.2013, 20:06
Что мешает сделать отдельный прелодер?

TurboDizel
12.01.2013, 20:26
Что мешает сделать отдельный прелодер?

В смысле отдельный? Я наверное что-то элементарное сейчас пропускаю, но реально что-то не могу понять.
Сам класс main должен быть на втором кадре ведь, если он будет на первом, то он начнет сразу загружать все мувики использующиеся там, и прелоадер даже если будет в начале появится только после того, как весь main загрузится. На первом кадре проверяется общее количество загруженных байт и общее их количество, и если совпадает то переход на второй кадр, а на втором кадре код, чтобы запустить класс main и начать игру. Просто Вы наверное какой-то другой способ спрашиваете, который я не понял).

не лучший мануал: http://www.8bitrocket.com/2008/04/22/tutorial-preloading-actionscript-3-as3-games-in-flash-cs3/

Я так понял, что там всё так же по кадрам без отдельных as файлов. Просто англ тяжко идет.

СлаваRa
12.01.2013, 20:54
Main

package {
import flash.display.Sprite;

[SWF(width = "800", height = "600", frameRate = "30")]

/**
* @author SlavaRa
*/
[Frame(factoryClass="Preloader")]
public final class Main extends Sprite {

public function Main():void {
super();
}
}
}


Preloader

package {
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.utils.getDefinitionByName;

/**
* @author SlavaRa
*/
public class Preloader extends MovieClip {

public function Preloader() {
super();
this.configureStage();
this.addListeners();
//TODO: this.showAsset();
}

private function configureStage():void {
super.stage.scaleMode = StageScaleMode.NO_SCALE;
super.stage.align = StageAlign.TOP_LEFT;
}

private function addListeners():void {
super.addEventListener(Event.ENTER_FRAME, this.onSuperEnterFrame);
super.loaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.onIoError);
super.loaderInfo.addEventListener(ProgressEvent.PROGRESS, this.onProgress);
}

private function onSuperEnterFrame(event:Event):void {
if (super.currentFrame == super.totalFrames) {
super.currentFrame;
super.stop();
this.removeListeners();
//TODO: this.hideAsset();
this.startup();
}
}

private function onIoError(event:IOErrorEvent):void {
trace("error:", event.text);
}

private function onProgress(event:ProgressEvent):void {
//TODO: this.updateAsset();
}

private function removeListeners():void {
super.removeEventListener(Event.ENTER_FRAME, this.onSuperEnterFrame);
super.loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, this.onIoError);
super.loaderInfo.removeEventListener(ProgressEvent.PROGRESS, this.onProgress);
}

private function startup():void {
const c:Class = getDefinitionByName("Main") as Class;
super.addChild(DisplayObject(new c()));
}
}
}

TurboDizel
12.01.2013, 21:49
СлаваRa, попробовал, покопался в инете, вроде и код почти такой же как у Вас везде, всё должно работать, но почему-то класс main сам себе так дальше и загружается, будто я ничего и не менял.
main:

[Frame(factoryClass="preloader")]
//переменные
public class main extends MovieClip {
public function main() {
//функции и т.д.
}
}
//и тут функции


preloader:

package
{
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.utils.getDefinitionByName;
/**
* ...
* @author Turbo-Dizel
*/
public class preloader extends MovieClip
{

private var BTN:MovieClip = new btn();

public function preloader()
{
addChild(BTN);
BTN.x = 300;
BTN.y = 300;
BTN.addEventListener(MouseEvent.CLICK, clickb);
}

function clickb():void {
var mainClass:Class = Class(getDefinitionByName("main"));
var mainClassObj:Object = new mainClass();
addChild(mainClassObj as DisplayObject);
}

}

}

СлаваRa
12.01.2013, 22:17
Если бы все было также, то и работало бы как надо, какой-то странный у вас подход к оформлению кода(.

TurboDizel
12.01.2013, 22:40
Если бы все было также, то и работало бы как надо, какой-то странный у вас подход к оформлению кода(.

Ну тот код, который я выложил, должен был загрузить класс preloader. Этот класс добавляет на сцену мувик, и проверяет его на клик мыши. Если кликнули, то "возвращаемся" в main. Просто сам прелоадер ещё не делал, а для проверки "кнопку" поставил.
Он же по идее ждать моего клика должен.
А что не так с оформлением кода?)

caseyryan
12.01.2013, 23:01
В смысле отдельный? Я наверное что-то элементарное сейчас пропускаю, но реально что-то не могу понять.

Отдельным swf файлом вообще. Это нормальная практика, когда делают небольшой swf чисто для загрузки другого. И не нужно будет никаких фактори классов или второго кадра.

Wolsh
13.01.2013, 00:00
BTN.addEventListener(MouseEvent.CLICK, clickb);
//.....
function clickb():void {Этот код что, компилится? Где аргументы функции?

А Вы точно сделали preloader документ-классом?

BBOY Ильич
13.01.2013, 00:13
Документ-классом должен быть, кажись, тот, где [Frame(factoryClass="")] прописан...

TurboDizel
13.01.2013, 01:11
Отдельным swf файлом вообще. Это нормальная практика, когда делают небольшой swf чисто для загрузки другого. И не нужно будет никаких фактори классов или второго кадра.

Это просто загрузить флешку Loader`ом, и по окончанию загрузки (Event.COMPLETE) добавить загруженное через addChild?

Этот код что, компилится? Где аргументы функции?

А Вы точно сделали preloader документ-классом?

Так он мне ошибку не выдавал, так как до класса preloader дело даже не доходило. Получается, что эта строка в моем случае ничего не делает:
[Frame(factoryClass = "preloader")]

Так класс документа вообще в IDE там де прописываю должен быть preloader? Просто я думал что строка [Frame(factoryClass = "preloader")] как бы передает управление классу preloader, а в конце прелоадера возвращается назад.

Добавлено через 41 минуту
Нашел причину: во-первых, конечно же, preloader должен был быть классом документа, но без это были и другие ошибки.
Постоянно вылазила ошибка Variable frameq is not defined, где frameq имя класса. Решение этой проблемы оказалось каким-то странным. Вместо такой записи:

var mainClass:Class = getDefinitionByName("frameq") as Class;
var mainC = new mainClass();
addChild(mainC as DisplayObject);

Надо написать такую

frameq
var mainClass:Class = getDefinitionByName("frameq") as Class;
var mainC = new mainClass();
addChild(mainC as DisplayObject);

Не могу понять вообще, почему так работает. Обычно пытаюсь всегда понимать то, что написал, но тут исключение). Если кто прошаренный, интересно было бы узнать).

Wolsh
13.01.2013, 04:01
Ничего странного. Эта запись, frameq, говорит компилятору что данный библиотечный класс будет использоваться, то есть фактически Вы его импортируете (умный компилятор не импортирует классы, которые не используются в коде, даже если Вы напишите руками импорт; использование через getDefinitionByName компилятором не распознается, так как там используется не класс, а только строка с его именем).
Просто я думал что строка [Frame(factoryClass = "preloader")] как бы передает управление классу preloaderВообще-то эта строка говорит "я — кадр мувиклипа класса Прелоадер". Однако же Прелоадер должен быть точкой входа в программу, нет? А так — Получается, что эта строка в моем случае ничего не делает: [Frame(factoryClass = "preloader")]Точка входа не может быть частью чего-то бОльшего, например кадром мувиклипа. Документ-класс включает в себя всё остальное. Здесь фишка лишь в том, чтобы "всё остальное" не грузилось в первый кадр.
Так он мне ошибку не выдавал, так как до класса preloader дело даже не доходило.Компилятор(!) должен был ошибку выдавать, то есть дело не должно было дойти до свф-файла. Включите строгий режим компиляции. А впрочем, у Вас наверное и сам класс Прелоадер не вкомпиливался, так как классом документа был другой, и Прелоадер в нем уже не упоминался, то есть был "не нужным" и компилятор его даже не смотрел.

caseyryan
13.01.2013, 12:17
Это просто загрузить флешку Loader`ом, и по окончанию загрузки (Event.COMPLETE) добавить загруженное через addChild?


Именно так.

TurboDizel
13.01.2013, 14:50
Ничего странного. Эта запись, frameq, говорит компилятору что данный библиотечный класс будет использоваться, то есть фактически Вы его импортируете (умный компилятор не импортирует классы, которые не используются в коде, даже если Вы напишите руками импорт; использование через getDefinitionByName компилятором не распознается, так как там используется не класс, а только строка с его именем).
Вообще-то эта строка говорит "я — кадр мувиклипа класса Прелоадер". Однако же Прелоадер должен быть точкой входа в программу, нет? А так — Точка входа не может быть частью чего-то бОльшего, например кадром мувиклипа. Документ-класс включает в себя всё остальное. Здесь фишка лишь в том, чтобы "всё остальное" не грузилось в первый кадр.
Компилятор(!) должен был ошибку выдавать, то есть дело не должно было дойти до свф-файла. Включите строгий режим компиляции. А впрочем, у Вас наверное и сам класс Прелоадер не вкомпиливался, так как классом документа был другой, и Прелоадер в нем уже не упоминался, то есть был "не нужным" и компилятор его даже не смотрел.
Вот теперь хоть понятно что делает строчка frameq и тег Frame.
А вот когда дело начало до прелоадера доходить, то компилятор все ошибки показал).

И когда я говорил, что нашел причину и якобы решил проблему, то видимо я рано сделал выводы). У меня есть класс frame, и класс preloader. preloader документ-класс. Он по-идее должен выполнится первым, а в итоге его содержимое появляться только после загрузки frame. Т.е. как Вы я так понял и говорили: 'Здесь фишка лишь в том, чтобы "всё остальное" не грузилось в первый кадр'.
Если ещё кому-то не надоело отвечать на мои вопросы, то надеюсь кто-то скажет, как не дать загрузить frame раньше, чем само содержимое документ-класса).
frame

[Frame(factoryClass = "preloader")]
public class frameq extends MovieClip {
var BG = new bg();
public function frameq() {
addChild(BG);
BG.x = 0;
BG.y = 0;
}

preloader

public class preloader extends MovieClip
{
private var BTN:MovieClip = new btn();
public function preloader() {
addChild(BTN);
BTN.x = 300;
BTN.y = 300;
BTN.addEventListener(MouseEvent.CLICK, clickb);
}

function clickb(e:MouseEvent):void {
frameq
var mainClass:Class = getDefinitionByName("frameq") as Class;
var mainC = new mainClass();
addChild(mainC as DisplayObject);
}

}

Wolsh
13.01.2013, 17:48
А вот когда дело начало до прелоадера доходить, то компилятор все ошибки показал).
Но правда в том, что документ-классом должен быть не прелоадер. Этот эксперимент показал, что Ваш компилятор не понимает тега [Frame].
Он вообще не компилит прелоадер, если тот не объявлен документ-классом.
А должен был прочитать это в теге [Frame].
Вы точно компилируете с помощью flex_sdk?
И вот это Ваше отсутствие пакетов в оформлении классов — это так и есть, или Вы для нас старательно скопировали код без объявлений пакетов?

TurboDizel
13.01.2013, 18:34
Но правда в том, что документ-классом должен быть не прелоадер. Этот эксперимент показал, что Ваш компилятор не понимает тега [Frame].
Он вообще не компилит прелоадер, если тот не объявлен документ-классом.
А должен был прочитать это в теге [Frame].
Вы точно компилируете с помощью flex_sdk?
И вот это Ваше отсутствие пакетов в оформлении классов — это так и есть, или Вы для нас старательно скопировали код без объявлений пакетов?

Просто чтобы сообщение не было на всю страницу, пытаюсь убирать очевидные вещи).
В итоге всё сделал через Loader как предлагал caseyryan.
Всем спасибо за помощь, я бы разобрался с тегом Frame, но пока Loader более чем устраивает).