Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Структура написания приложения (http://www.flasher.ru/forum/showthread.php?t=197609)

zzSpirit 10.04.2013 04:57

Структура написания приложения
 
Здравствуйте, уважаемые программисты!
После процедурного программирования все не могу понять, как всетаки начать писать игру...
До паттернов еще не дошел, хочу что-нибудь простенькое для себя пока написать, что бы убрать непонятки.

К примеру, у меня в игре есть меню и сама игра. Пробовал сделать 2 класса Menu и Game и вызывать их из главного класса, но тут возникает проблема - приходится передавать ссылки на класс Main и на прочие...

Решил сделать такую структуру:
Код AS3:

package sources
{
        import flash.display.*;
        import flash.events.*;
 
        public class Main extends Sprite
        {
                public function Main():void
                {
                        if(stage) init(); else addEventListener(Event.ADDED_TO_STAGE,init);
                }
 
                private function init(e:Event = null):void
                {
                        removeEventListener(Event.ADDED_TO_STAGE,init);
                        // тут инициализация
                        menu();
                }
 
                private function menu():void
                {
// тут главное меню
                }
 
                private function game():void
                {
// тут код игры
                        function somethingFunction(e:Event):void
                        {
                        }
                        function enterFrameHandler(e:Event):void
                        {
                        }
                }
 
        }
}

Но тут мне не нравится что все в одном классе, получится слишком длинный код в итоге, где сложно что-то найти поменять и т.д. + неудобно что у меня функции somethingFunction() и enterFrameHandler() располагаются в методе game(). А если я вынесу их за пределы метода game() - то теряется структура и читаемость кода, хотя так читаемость кода тоже не очень хорошая.

Кто как делает?

Добавлено через 1 минуту
Читал другие топики, но там тоже советуют посмотреть как другие приложения написаны, я смотрел, но в основном они также и написаны))) В главном файле

Wolsh 10.04.2013 05:55

Цитата:

приходится передавать ссылки на класс Main и на прочие...
Приходится? Кому и зачем они вдруг понадобились?

Babylon 10.04.2013 06:14

ООП предполагает наличие объекта, над которым производятся какие то процедуры. Например, в JS большая сложная функция jQuery работает над DOM. В AS это Object поэтому от "процедурного" программирования Вы никуда не уйдете. Только процедуры называются функциями и работают они по большей частью со ссылками на разные объекты:) Нарисовали бы логику для начала по-детальнее - что куда? Так и замысел ваш станет более понятен вам самому, а за ним и умысел увидим.

zzSpirit 10.04.2013 06:54

Цитата:

Сообщение от Wolsh (Сообщение 1129066)
Приходится? Кому и зачем они вдруг понадобились?

Недавно я писал *****код, в котором передал ссылку на Main в класс Game, чтобы там создать экземпляр класса APIConnection (vkontakte api). Все получилось и даже выполнял запросы, хотя код очень корявый.

Зачем я так сделал? Перед этим я создавал экземпляр APIConnection в Main классе и передавал ссылку на экземпляр в экземпляр класса Game, но это выдало несколько ошибок, причем не в моих классах, а в классах VK... Понял что это неправильно и так больше делать не стал.

Теперь понял что все это бред и все это надо писать в классе Main. Только код то длинный получается, я в нем начинаю путаться, а если ошибки возникать начинают, в которых компилятор не указывает номер строки - то я полчаса мучаюсь с этим кодом и в итоге создаю новый проект и пишу все снова.

А если так писать всю игру - то несколько тысяч строк кода в классе Main будет в итоге - так и должно быть?

Добавлено через 11 минут
Цитата:

Сообщение от Babylon (Сообщение 1129068)
ООП предполагает наличие объекта, над которым производятся какие то процедуры. Например, в JS большая сложная функция jQuery работает над DOM. В AS это Object поэтому от "процедурного" программирования Вы никуда не уйдете. Только процедуры называются функциями и работают они по большей частью со ссылками на разные объекты:) Нарисовали бы логику для начала по-детальнее - что куда? Так и замысел ваш станет более понятен вам самому, а за ним и умысел увидим.

Вроде бы все понятно, но ведь в главном файле код получится на несколько тысяч строк кода - меня это пугает, т.к. сложно найти ошибку и очень запутанно все будет. Еще методы VK.api работают так, что они не возращают значение в переменную, а вызывают 1 функцию при удаче и другую при неудаче. И у меня получается куча функций, куча api-запросов, причем в этих функциях по одной строчке кода. То есть идет запрос, потом функция возврата значения, потом функция ошибки, потом опять запрос и т.д.

В общем куча таких непоняток, которые мне кайф от программирования прям ломают.
Никакого прогресса, стою на месте, сдвинуться не могу, т.к. не понимаю куда двигаться. Но спать не иду :)

Babylon 10.04.2013 09:28

В вашем словесном потоке очень трудно разобраться, а значит и помочь вам. Код в студию и комменты к нему. А вообще есть видеокурсы по программированию на апи вк. Согласен, апи неидеально, но вполне се работоспособно :)

iflamberg 10.04.2013 13:44

Я уже много раз говорил. Не придумывайте велосипеды. Сначала посмотрите как работают чужие. Изучите движки, как там построено, почитайте туторы по играм. Зачем мучаться? Один уже помучался - скопируйте его наработки.

MikroAcse 10.04.2013 13:49

А я использую кастрированный MVC без модели. Т.е. главный класс создает Controller, который загружает и парсит данные, а потом создает вьюшку, которая использует состояния для отображения (MenuState, GameState extends acse.display.State).
Получается очень простая структура.

in4core 10.04.2013 16:20

Цитата:

А я использую кастрированный MVC без модели
Это не MVC .
Это другой паттерн :) Это паттерн пылесос : vacuum cleaner :faceplam

Gaen 10.04.2013 23:45

Цитата:

Сообщение от zzSpirit (Сообщение 1129071)
несколько тысяч строк кода в классе Main будет в итоге - так и должно быть?

Так быть не должно, Б-же упаси от такого.

Код должен быть разбит по мелким и понятным классам. Объекты создаются по мере надобности. Тот, кто создал объект, дергает его методы и слушает его события. Созданный объект ничего не знает о своем создателе и шлет наверх события в надежде, что их кто-то услышит.

Цитата:

Перед этим я создавал экземпляр APIConnection в Main классе и передавал ссылку на экземпляр в экземпляр класса Game, но это выдало несколько ошибок, причем не в моих классах, а в классах VK... Понял что это неправильно и так больше делать не стал.
Создавать APIConnection в Main и передавать его в Game - это как раз очень правильно, вы зря отказались от этого направления. То, что RTE вылетело из библиотеки вконтакта, еще не означает, что ошибка там. Скорее всего, вы кормите туда кривые данные. Продолжайте копать (:

zzSpirit 12.04.2013 04:02

Наверное лучший совет:
Цитата:

Сообщение от iflamberg (Сообщение 1129116)
Я уже много раз говорил. Не придумывайте велосипеды. Сначала посмотрите как работают чужие. Изучите движки, как там построено, почитайте туторы по играм. Зачем мучаться? Один уже помучался - скопируйте его наработки.

Действительно, когда смотрю чужие коды, туторы и т.д. - много вопросов сами с собой решаются и это большое удовольствие мне приносит. Иногда бывает даже создаю новую тему с вопросом, пока сформулирую вопрос и пока попробую написать код чтобы показать в чем проблема - вопрос решается.

Код AS3:

В вашем словесном потоке очень трудно разобраться, а значит и помочь вам. Код в студию и комменты к нему. А вообще есть видеокурсы по программированию на апи вк. Согласен, апи неидеально, но вполне се работоспособно

Да хрен с ним, с кодом, уже это все не так важно :)

В общем, забью на лень и буду все подряд по теме изучать. iflameberg похоже наставил меня на путь истинный :)
Всем спасибо.

Добавлено через 22 минуты
А хотя, убежусь кое в чем, пользуясь случаем:
Цитата:

Сообщение от Gaen (Сообщение 1129205)
Так быть не должно, Б-же упаси от такого.
Код должен быть разбит по мелким и понятным классам. Объекты создаются по мере надобности. Тот, кто создал объект, дергает его методы и слушает его события. Созданный объект ничего не знает о своем создателе и шлет наверх события в надежде, что их кто-то услышит.

Это я и так знал, но спасибо за то что напомнил об этом и я лучше все обдумал сейчас о структуре.
Цитата:

Создавать APIConnection в Main и передавать его в Game - это как раз очень правильно, вы зря отказались от этого направления. То, что RTE вылетело из библиотеки вконтакта, еще не означает, что ошибка там. Скорее всего, вы кормите туда кривые данные. Продолжайте копать (:
Вроде бы данные были правильные, т.к. в Main запросы работали, в Game - нет, хотя если передать Main ссылкой в Game или написать parent.stage и т.д. - все работало. Ладно, фиг с ним, ща это не так важно, сам разберусь думаю.

Меня очень волнует - правилен ли сам подход такой? прям не терпится узнать... Описываю:
если бы я делал кадрами - то я бы сделал на первом кадре экран загрузки, на втором меню, на третьем игру, на четвертом магазин...
Правильно ли сделать также классами(вместо каждого кадра по классу), что бы не писать все это в главном классе?
То есть у меня будет главный класс Main, который будет создавать экземпляры след. классов и запускать их:
  • Main - главный класс, который запускает все остальные
  • LoadGame - экран загрузки игры
  • Menu - меню игры
  • Game - сама игра
  • Shop - магазин игры

То есть Main первым делом запускает загрузку и слушает ее, как игра загрузилась, делаем LoadGame = null, чтоб не засорять память и создаем класс Menu... Блин, вот опять лажа получилась. Как я из класса Menu вызову класс Game, не используя parent?
Также, при выходе из класса Game как я скажу классу Main чтоб он обнулил класс Game и запустил класс Menu? Хм... По идее Main слушает все классы, но я не пойму как сделать прослушивание не покадрово, не с какой-то переодичностью типа таймера, а чтоб память не засорялась. Т.е. чтоб прослушка не была ежесекундной к примеру, а чтоб Game сказал классу Main что игра окончилась и все, а не было постоянной проверки окончилась ли игра, в игре ведь и так расчетов много очень, нефиг проц грузить.

Кароче нифига я не знаю, фигню понаписал, буду исходники изучать... Но если ответите как это теоритически все работает - очень рад буду. А то пока не пойму как это работает - к паттернам как-то очень хочется переходить, т.к. напишу код, я в нем путаюсь, мне он не нравится, он становится большим - удаляю, замучился уже.

Ну ладно, iflamberg дал мне совет, воспользуюсь им...

Psycho Tiger 13.04.2013 10:19

Ну, я бы сделал вот так (код писал прямо на форуме, не ручаюсь что работает):
Код AS3:

class AbstractStep extends Sprite {
public static const GAME_SCREEN:String = 'gameScreen';
public static const LOAD_SCREEN:String = 'loadScreen';
protected function gotoScreen(screenName):void{
//вызываем на рассылку собственное событие, внутри передаем screenName
dispatchEvent(new MyEvent(MyEvent.CHANGE_SCREEN, screenName));
}
}

Классы наследуются от AbstractStep.
Код AS3:

class Game extends AbstractStep

Когда нужно перейти на другой экран, то дёргается метод AbstractStep'а.
Т.е. внутри Game, например:
Код AS3:

gotoScreen(LOAD_SCREEN);

А в Main:
Код AS3:

private var _currentScreen:AbstractScreen;
private var _hash:Object ={}
public function Main(){
//присваиваем классы
_hash[AbstractScreen.GAME] = Game;
_hash[AbstractScreen.LOAD_SCREEN] = LoadScreen;
_currentScreen = new Game();
addChild(_currentScreen);
_currentScreen.addEventListener(MyEvent.CHANGE_SCREEN, onScreenChanged);
}
 
private function onScreenChanged(event:MyEvent):void{
_currentScreen.removeEventListener(MyEvent.CHANGE_SCREEN, onScreenChanged);
removeChild(_currentScreen);
_currentScreen = _hash[event.screenName]();
addChild(_currentScreen);
_currentScreen.addEventListener(MyEvent.CHANGE_SCREEN, onScreenChanged);
}


Wolsh 13.04.2013 10:44

Цитата:

Также, при выходе из класса Game как я скажу классу Main чтоб он обнулил класс Game и запустил класс Menu? Хм... По идее Main слушает все классы, но я не пойму как сделать прослушивание не покадрово, не с какой-то переодичностью типа таймера, а чтоб память не засорялась. Т.е. чтоб прослушка не была ежесекундной к примеру, а чтоб Game сказал классу Main что игра окончилась и все, а не было постоянной проверки окончилась ли игра, в игре ведь и так расчетов много очень, нефиг проц грузить.
События. Main слушает событие GameEvent.GAME_OVER от Game. Тот посылает это событие, когда игра закончилась. Мейн ловит его, обнуляет игру и показывает меню.
И так со всем.

Babylon 13.04.2013 15:19

Psycho Tiger,
var xml=<screens>
<screen id="1" name="gameScreen"/>
<screen id="2" name="loadScreen"/>
</screens>
var screen:XMLList=xml.screen.(@id=='1').

in4core 13.04.2013 15:27

Babylon - действительно зачем придумывать архитектуры разные, паттерны проектирования и т.п. - когда есть xml - который можно пихнуть отовсюду... ужос

Babylon 13.04.2013 15:31

В чем противоречия между ПП и Xml? Если XML относится к модели, чем плохо?

in4core 13.04.2013 15:34

Ну причем тут вообще хмл как таковой? Хмл - если вы вкурсе - язык разметки. Тоесть отдельный язык так сказать. As3 - язык. Никто не против совмещать 2 языка, и это приходится делать в ряде стандартов, но не стоит в любую кашу сувать другой язык. Я могу поддержать вас только в том, что это ваша фича ( или баг хД) - что никто так не делает собственно.
хмл он для чего нужен по сути? для удобства работы с данными, которые переданы из вне. Будь это конфиг или локализатор.

caseyryan 13.04.2013 15:45

Цитата:

хмл он для чего нужен по сути? для удобства работы с данными, которые переданы из вне. Будь это конфиг или локализатор.
Совсем нет. Я частенько использую XML вшитый в программу. Просто потому что это удобный формат хранения данных, с простой и понятной структурой

Babylon 13.04.2013 16:00

XML - язык разметки только для веб дизайнеров, а для кодеров это не что другое. Для некоторых конечно нет ничего хорошего в разметке модели, рендеринге видов и внешнем коммандере :)

Александр Мостовой 13.04.2013 17:59

С xml работать впринципе можно как с быстрым промежуточным вариантом, но только если следовать правилу: изменять его только через методы и сеттеры соотвтетствующего объекта-хранителей этого XML.
Тогда не сложно будет в случае необходимости перейти на более формализованную структуру.

СлаваRa 13.04.2013 18:02

Xml избыточен

Babylon 13.04.2013 18:47

Цитата:

Сообщение от Александр Мостовой (Сообщение 1129686)
С xml работать впринципе можно как с быстрым промежуточным вариантом, но только если следовать правилу: изменять его только через методы и сеттеры соотвтетствующего объекта-хранителей этого XML.
Тогда не сложно будет в случае необходимости перейти на более формализованную структуру.

Насчет сеттеров и геттеров. XML вообще должен "торчать" только из модели. Во всех остальных случаях должна быть инкапсуляция. XML может и избыточен в описании, но он с лихвой перекрывает избыточность кодирования другими способами.

Psycho Tiger 14.04.2013 12:54

Цитата:

Сообщение от Babylon (Сообщение 1129637)
Psycho Tiger,
var xml=<screens>
<screen id="1" name="gameScreen"/>
<screen id="2" name="loadScreen"/>
</screens>
var screen:XMLList=xml.screen.(@id=='1').

Ну в принципе да, но это бесполезно если не подразумевается загрузка отдельных экранов через разные swf, например.
Ну, то есть, если этот XML вшивать в флешку – получим ряд проблем. Например, никто не гарантирует уникальность ID'шника (он может не существовать, а может существовать аж 2), проблемы из за рефлекшена (в моём примере мы жестко ссылаемся на класс – мистайп контроллируется компилятором, в XML – строки).

У меня вообще отношение к XML'у весьма своеобразное. e4x одновременно и тащит, и требует особой внимательности. Достаточно часто и обидно падаю по RTE из за несовпадения XML / XMLList типов. По идее, это должно контроллироваться компилятором – почему он не контроллирует – не понятно...
Вообще, например, в Ruby такими штуками являются YAML файлы. Что то вроде HAML'a для XML'a, например
Код:

key1:
  key2:
    value1: 'hello'
    value2: 'world'

Подобная штука для флеша на каком-нибудь нативном уровне была бы просто чудесна. XML действительно избыточен, в 2 из 3 случаев уместнее использовать что - то такое. Некоторый Object, который удобоварим для чтения-заполенения.

Babylon 15.04.2013 00:54

XMLList это список xml нод, а XML - это xml нода. Компилятор здесь не при делах. Он определяет несоответствие типов, и делает абсолютно корректно.
E4X появился только в AS3. До этого были костыли типа XMLtoOutput , XML2Object и др. Поэтому появление в стандарте XMLList было ожидаемо. XML в первую очередь нужен для агрегации и запросов. На JSON агрегацию также технично не сделаешь, а jQuery для AS тоже нет, в отличии от XPath

caseyryan 15.04.2013 07:24

Цитата:

По идее, это должно контроллироваться компилятором - почему он не контроллирует – не понятно...
Потому что не знает он, что туда попадет в рантайме, будет это XML или XMLList ему по барабану

Babylon 15.04.2013 09:40

Я просто не представляю как еще компилятор должен обработать данную ситуацию, иначе чем выдать ошибку о не соответствии типов.

Psycho Tiger 15.04.2013 11:34

Цитата:

Сообщение от Babylon (Сообщение 1129892)
Я просто не представляю как еще компилятор должен обработать данную ситуацию, иначе чем выдать ошибку о не соответствии типов.

Цитата:

Потому что не знает он, что туда попадет в рантайме, будет это XML или XMLList ему по барабану
XMLList может состоять и из одной ноды ) Поэтому это компилятор и должен контроллировать.
Это никогда не будет XML
Код:

root.node // XMLList
root.(@id == 'attr') //XMLList

А это никогда не будет XMLList'ом
Код:

root.node[0] //XML

Babylon 15.04.2013 11:53

Компилятор же выдает предупреждение о неправильном кол-ве элементов.

Simplifier 15.04.2013 21:32

Так XML и XMLList же динамические классы, поэтому компилятор тут вообще не при делах, по идее

namespaces 16.04.2013 00:27

Вот здесь есть хороший пример для заготовки шаблона, на начальном этапе этого хватит.
Для дальнейшего развития копайте в сторону готовых разработок, я бы посоветовал присмотреться к Gaia Framework. . Давно уже в открытом доступе.

Psycho Tiger 16.04.2013 09:46

Цитата:

Сообщение от Babylon (Сообщение 1129910)
Компилятор же выдает предупреждение о неправильном кол-ве элементов.

Хм. Ну у меня в стрикте не выдаёт :(

Babylon 16.04.2013 12:27

не везет вам

Котяра 16.04.2013 13:22

Если уж нравится xml - тогда используйте
MXML - так хотя бы получите проверку и автокомплиты в редакторе.
что-то вроде
Код AS3:

<?xml version="1.0" encoding="utf-8"?>
<EventDispatcher xmlns="flash.events.*"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        <fx:Declarations>
                <screen:Screen id="gameScreen" name="gameScreen"/>
                <screen:Screen id="loadScreen" name="loadScreen"/>
                <screen:Screen id="currentScreen" />
        </fx:Declarations>
        <fx:Script>
                <![CDATA[
                        currentScreen = gameScreen;
                ]]>
        </fx:Script>
</EventDispatcher>


Babylon 16.04.2013 18:50

К, сожалению, MXML не дорос до агрегатирования и боюсь уже не дорастет :).


Часовой пояс GMT +4, время: 08:12.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.