Форум 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=209259)

Wormhole 23.10.2014 20:12

Анимация ходьбы
 
Я хочу сделать анимацию ходьбы героя в игре. Это отдельный символ, в нем четыре кадра: 1 - стоит, смотрит вправо, 2 - идет вправо (анимация ходьбы в отдельном символе, 3 - стоит, смотрит влево, 4 - идет влево. Мне надо, чтобы, пока зажата левая стрелка, проигрывалась анимация ходьбы влево, а пока зажата правая стрелка - ходьбы вправо. Вместо этого при запуске ролика и нажатии клавиши влево/вправо (до нажатия герой стоит, все нормально) герой начинает стоять при удерживании кнопки, а при отпускании начинает бежать. Вообщем, все получается ровно наоборот. Хотелось бы знать, как решить данную проблему.
Код первого кадра:
Код AS3:

stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN, movementIn);
function movementIn (e:KeyboardEvent){
        if (e.keyCode == 39){
                gotoAndPlay('goright');
        } else if (e.keyCode == 37){
                gotoAndPlay('stopleft');
        //} else if (e.keyCode == 38){
 
        }
}

Код второго кадра:
Код AS3:

import flash.events.KeyboardEvent;
 
stop()
stage.addEventListener(Event.ENTER_FRAME, updateRight);
function updateRight(e: Event) {
        stage.addEventListener(KeyboardEvent.KEY_UP, stopRight);
        function stopRight(e: KeyboardEvent) {
                if (e.keyCode == 39) {
                        gotoAndPlay('stopright');
                }
        }
}

Код третьего кадра:
Код AS3:

stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN, movementIn2);
function movementIn2 (e:KeyboardEvent){
        if (e.keyCode == 39){
                gotoAndPlay('stopright');
        } else if (e.keyCode == 37){
                gotoAndPlay('goleft');
        //} else if (e.keyCode == 38){
 
        }
}

Код четвертого кадра:
Код AS3:

import flash.events.Event;
import flash.events.KeyboardEvent;
 
stop();
stage.addEventListener(Event.ENTER_FRAME, updateLeft);
function updateLeft(e: Event) {
        stage.addEventListener(KeyboardEvent.KEY_UP, stopLeft);
        function stopLeft(e: KeyboardEvent) {
                if (e.keyCode == 37) {
                        gotoAndPlay('stopleft');
                }
        }
}

На кадрах расставлены метки, думаю, понятно, что к чему относится. Заранее спасибо

Gerbert 23.10.2014 21:57

Вам было бы проще помочь, если бы Вы писали в классах.
А так как Вы пишете в кадрах, то могу посоветовать лишь почитать про design patterns State.

Добавлено через 49 секунд
Или же я могу маленький пример накидать в классе, если сможете разобраться, то скажите, мне не трудно.

Wormhole 23.10.2014 22:36

Цитата:

Сообщение от Gerbert (Сообщение 1174002)
Вам было бы проще помочь, если бы Вы писали в классах.
А так как Вы пишете в кадрах, то могу посоветовать лишь почитать про design patterns State.

Добавлено через 49 секунд
Или же я могу маленький пример накидать в классе, если сможете разобраться, то скажите, мне не трудно.

Накидайте, пожалуйста. Попробую разобраться

Gerbert 23.10.2014 23:15

Код AS3:

package
{
        public class KeyBoardController
        {
                private var _keyboardFlags: Object = {};
                public function get keyboardFlags( ): Object
                {
                        return this._keyboardFlags;
                }
 
                private var _hero: Hero;
                public function setHero( hero: Hero ): void
                {
                        this._hero = hero;
                }
 
                public function KeyBoardController( ){
 
                }
 
                public function update( ):void
                {
                        this.keyboardValidate( );
 
                        if( _keyboardFlags.LEFT == true ){
                                _hero.leftState( );
                        }else if( _keyboardFlags.RIGHT == true ){
                                _hero.rightState( );
                        }else if( _keyboardFlags.STOP == true ){
                                _hero.stopState( );
                        }
                }
 
                private function keyboardValidate( ): void
                {
                        if( _keyboardFlags.LEFT == true && _keyboardFlags.RIGHT == true ){
                                _keyboardFlags.STOP = true;
                        }
                }
 
                public function reset( ): void
                {
                        for( var flag in this._keyboardFlags ){
                                if( this._keyboardFlags[flag] == true ){
                                        this._keyboardFlags[flag] = false;
                                }
                        }
                }
        }
}

Код AS3:

package
{
        public class Hero
        {
                private var _view:DisplayObject;
 
                public function Hero( view:DisplayObject ){
                        this._view = view;
                }
 
                public function leftState( ): void
                {
                        //
                }
 
                public function rightState( ): void
                {
                        //
                }
 
                public function stopState( ): void
                {
                        //
                }
        }
}

Код AS3:

// и где-то в коде
var _hero: Hero = new Hero( mc );
var _keyBoardController: KeyBoardController = new KeyBoardController( _hero );
var _keyboardFlags = _keyBoardController.keyboardFlags;
 
stage.addEventListener( KeyboardEvent.DOWN, stage_keyboardEventDown );
stage.addEventListener( Event.ENTER_FRAME, stage_enterFrame );
 
private function stage_keyboardEventDown( event: KeyboardEvent ): void
{
        if( event.keyCode == Keyboard.LEFT ){
                _keyboardFlags.LEFT = true;
        }
 
        if( event.keyCode == Keyboard.RIGHT ){
                _keyboardFlags.RIGHT = true;
        }
}
 
private function stage_enterFrame( event: Event ): void
{
        _keyBoardController.update( );
        _keyBoardController.reset( );
}

Добавлено через 1 минуту
Если что-то не понимаете, то спрашивайте, а то неохото все расписывать.

Добавлено через 27 минут
Или вот так -
Код AS3:

package
{
        public class KeyBoardController
        {
                private var _keyboardFlags: Object = {};
                public function get keyboardFlags( ): Object
                {
                        return this._keyboardFlags;
                }
 
                private var _hero: Hero;
                public function setHero( hero: Hero ): void
                {
                        this._hero = hero;
                }
 
                public function KeyBoardController( ){
 
                }
 
                public function update( ):void
                {
                        this.keyboardValidate( );
 
                        if( _keyboardFlags.LEFT == true ){
                                _hero.setState = Hero.LEFT;
                        }else if( _keyboardFlags.RIGHT == true ){
                                _hero.setState = Hero.RIGHT;
                        }else if( _keyboardFlags.STOP == true ){
                                _hero.setState = Hero.STOP;
                        }
 
                        return this;
                }
 
                private function keyboardValidate( ): void
                {
                        if( _keyboardFlags.LEFT == true && _keyboardFlags.RIGHT == true ){
                                _keyboardFlags.STOP = true;
                        }
                }
 
                public function reset( ): void
                {
                        for( var flag in this._keyboardFlags ){
                                if( this._keyboardFlags[flag] == true ){
                                        this._keyboardFlags[flag] = false;
                                }
                        }
 
                        return this;
                }
        }
}
 
package
{
        public class Hero
        {
                public static const LEFT: String = 'left';
                public static const RIGHT: String = 'right';
                public static const STOP: String = 'stop';
 
                private var _currentState: String;
                public function set currentState( value ): void
                {
                        if( this._currentState == value ){
                                return;
                        }
 
                        this._currentState = value;
                }
 
                private var _view:DisplayObject;
 
                public function Hero( view:DisplayObject ){
                        this._view = view;
                }
 
                private function leftState( ): void
                {
                        //
                }
 
                private function rightState( ): void
                {
                        //
                }
 
                private function stopState( ): void
                {
                        //
                }
 
                public function execute( ): void
                {
                        if( _currentState == Hero.LEFT ){
                                this.leftState( );
                        }else if( _currentState == Hero.RIGHT ){
                                this.rightState( );
                        }else if( _currentState == Hero.STOP ){
                                this.stopState( );
                        }
                }
        }
}
 
// и где-то в коде
var _hero: Hero = new Hero( mc );
var _keyBoardController: KeyBoardController = new KeyBoardController( ).setHero( _hero )
var _keyboardFlags = _keyBoardController.keyboardFlags;
 
stage.addEventListener( KeyboardEvent.DOWN, stage_keyboardEventDown );
stage.addEventListener( Event.ENTER_FRAME, stage_enterFrame );
 
private function stage_keyboardEventDown( event: KeyboardEvent ): void
{
        if( event.keyCode == Keyboard.LEFT ){
                _keyboardFlags.LEFT = true;
        }
 
        if( event.keyCode == Keyboard.RIGHT ){
                _keyboardFlags.RIGHT = true;
        }
}
 
private function stage_enterFrame( event: Event ): void
{
        _keyBoardController.update( ).reset( );
        _hero.execute( );
}


Wormhole 24.10.2014 16:21

Хорошо. Что хранит переменная _keyboardFlags?

Gerbert 24.10.2014 17:26

Код AS3:

private function stage_keyboardEventDown( event: KeyboardEvent ): void
{
        if( event.keyCode == Keyboard.LEFT ){
                _keyboardFlags.LEFT = true;
        }
 
        if( event.keyCode == Keyboard.RIGHT ){
                _keyboardFlags.RIGHT = true;
        }
}

Видите, если по условию keyCode == кнопки "стрелка влево", то присваеваем
значение для свойства LEFT true. Понимаете? Если нажали влево, то сделали об этом запись,
если нажали вправо, то тоже сделали запись.
Да и само название свойства говорит, что в нем хранятся "флаги клавиатуры".

Можно вопрос - Вы книги по as3 читали или учитесь по урокам и видео и если по урокам и видео,
то as3 это первый Ваш язык?

Wormhole 24.10.2014 18:15

Цитата:

Сообщение от Gerbert (Сообщение 1174042)
Код AS3:

private function stage_keyboardEventDown( event: KeyboardEvent ): void
{
        if( event.keyCode == Keyboard.LEFT ){
                _keyboardFlags.LEFT = true;
        }
 
        if( event.keyCode == Keyboard.RIGHT ){
                _keyboardFlags.RIGHT = true;
        }
}

Видите, если по условию keyCode == кнопки "стрелка влево", то присваеваем
значение для свойства LEFT true. Понимаете? Если нажали влево, то сделали об этом запись,
если нажали вправо, то тоже сделали запись.
Да и само название свойства говорит, что в нем хранятся "флаги клавиатуры".

Можно вопрос - Вы книги по as3 читали или учитесь по урокам и видео и если по урокам и видео,
то as3 это первый Ваш язык?

Учился по официальному курсу Adobe - там про классы мало, сейчас начал читать колина мука. До as писал на js и D

Добавлено через 3 минуты
Хорошо, но в чем принципиальная разница между "записать нажатие и регулярно его проверять, если верно - выполнить действие" и "при нажатии выполнить действие"

Gerbert 24.10.2014 18:19

Тогда не садитесь за flash, пока книгу не прочтете, а то учится программировать в кадрах,
это пустая трата времени.

elder_Nosferatu 24.10.2014 18:31

@Wormhole
Извиняюсь за оффтоп

@Gerbert
Код AS3:

                private var _keyboardFlags: Object = {};
                public function get keyboardFlags( ): Object
                {
                        return this._keyboardFlags;
                }

И зачем это? Защита свойства _keyboardFlags через геттер keyboardFlags даст Вам уверенность лишь в том, что _keyboardFlags не будет содержать null или экземпляр нединамического класса. Но я всегда могу сделать чтото вроде этого
Код AS3:

private function handleEnterFrame(event:Event):void {
  var instance:KeyBoardController = giveMeYourKBCInstance();
    for (var key:String in instance.keyboardFlags) {
      delete instance.keyboardFlags[ key ];
  }
}

и насмерть убить зашитую в приложение логику взаимодействия с клавиатурой, заставив такой хендлер слушать ЭнтерФрейм. Так почему бы не сделать просто
Код AS3:

public var keyboardFlags:Object = {};

Не будет лишнего вызова гет-функции при доступе, останется просто работа со свойством экземпляра. Более того, если свойству keyboardFlags нечаяно присвоить null или экземпляр нединамического класса, то это вылезет боком при попытке доступа к {любому}/{несуществующему} свойству, что даст пищу для размышлений (гдет-то я загнал в свойство значение извне, а его нужно только читать). А в таком виде, как у Вас, все будет работать без сбоев, но (если "ДУРАК" поработает) не ТАК, КАК ЗАДУМАНО! Терпеть не могу бездумное использование аксессоров, особенно если оправдание этому звучит так: "такой подход дисциплинирует..." Думайте головой, а не следуйте шаблонам. Помните, что шаг вперед лучше шага назад тогда, когда перед Вами не пропасть!!!
Оправданием использования {гет}/{сет}/{гет+сет} - аксессоров только для доступа к скрытому свойству может быть только одно - предполагаемому классу нужно прописать свойство, посредством интерфейса (интерфейсы описывают только методы, а getParam() / setParam(value:*) - это уже синтаксическая соль по сравнению с аксессорами).

@Все, кто дочитал до моего поста включительно || прочитал только мой пост
Извините, наболело... Да и седьмой литр темного пива для меня не просто детектор лжи, он провоцирует на откровенность :drinks:

Gerbert 24.10.2014 20:29

elder_Nosferatu, в одном маленьком-маленьком городе,
живет один человечек, который носит трусы поверх брюк. И вот этот человечек встречает Вас
и спрашивает - "а почему ты не носишь трусы по верх брюк? Ответы, что это не правильно, не по дрескоду,
и прочие, я слушать НЕ ХОЧУ!".

Вот что Вы этому нехочухе ответите?

Wormhole 24.10.2014 20:39

Цитата:

Сообщение от Gerbert (Сообщение 1174052)
elder_Nosferatu, в одном маленьком-маленьком городе,
живет один человечек, который носит трусы поверх брюк. И вот этот человечек встречает Вас
и спрашивает - "а почему ты не носишь трусы по верх брюк? Ответы, что это не правильно, не по дрескоду,
и прочие, я слушать НЕ ХОЧУ!".

Вот что Вы этому нехочухе ответите?

При чем тут это? То, что предложил элдер, не мешает коду, наоборот, делает его быстрее и лаконичнее.

Почему писать код в кадрах - это неправильно. Просто почему. Мне интересно знать, так как писать в кадрах я привык и это для меня кажется удобным. На крайняк могу сделать парочку простых классов.

Gerbert 24.10.2014 21:16

Цитата:

При чем тут это?
При том, что есть правило ооп, которое гласит, что обращаться к свойству можно только через аксессор.
Можно и без, но это не ооп. Но я запомню Ваше пожелания и буду показывать так, как неправильно,
но быстрее.
Цитата:

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

nubideus 25.10.2014 02:10

Цитата:

Почему писать код в кадрах - это неправильно. Просто почему. Мне интересно знать, так как писать в кадрах я привык и это для меня кажется удобным.
я тебе честно скажу, все что ты сейчас делаешь, пока учишься программировать, пойдет в мусорку. и не потому что "код - испражнения, все переписать", а потому что вещи элементарные. то есть разницы особой нет, тебе главное мозг качать.
выучить ооп - в крайнем случае полгода, учиться программировать в целом - несколько лет.

Цитата:

есть правило ооп, которое гласит, что обращаться к свойству можно только через аксессор.
вспомним java

elder_Nosferatu 25.10.2014 10:54

Цитата:

Сообщение от Gerbert (Сообщение 1174054)
При том, что есть правило ооп, которое гласит, что обращаться к свойству можно только через аксессор.

Ну раз так, то как Вы оправдаете это:
Код AS3:

private var _keyboardFlags: Object = {};
...
... _keyboardFlags.LEFT ...
... _keyboardFlags.RIGHT ...
... _keyboardFlags.STOP ...
...

Мало того, что свойства LEFT, RIGHT и STOP экземпляра класса Object ничем не прикрыты, так Вы еще и ссылку на этот экзепляр передаете наружу ПРАВОСЛАВНЫМ ГЕТ-АКСЕССОРОМ...
Если уж так приспичило ООПрограммировать, то делайте все правильно.
Пример 1: Геттер возвращает копию _keyboardFlags, тем самым не даем возможности изменить извне значения флагов. [Encapsulation completed ;)]
Код AS3:

public class KeyBoardController {
        private var _keyboardFlags:Object = {};
        public function get keyboardFlags( ):Object {
                var hash:Object = {};
                for (var key:String in _keyboardFlags) {
                        hash[ key ] = _keyboardFlags[ key ];
                }
                return hash;
        }
}

Пример 2: Возвращаем значение флага по его имени (без прямого доступа к незащищенному хранилищу флагов - _keyboardFlags). [Encapsulation completed ;)]
Код AS3:

public class KeyBoardController {
        private var _keyboardFlags:Object = {};
        public function getKeyboardFlagByName( name:String ):Object {
                return _keyboardFlags[ name ];
        }
}

Пример 3: То же, что и Пример 2, но доступ по имени заменяем на геттеры отдельных флагов. [Encapsulation completed ;)]
Код AS3:

public class KeyBoardController {
        private var _keyboardFlags:Object = {};
        public function get flagLEFT( ):Object {
                return _keyboardFlags[ "LEFT" ];
        }
        public function get flagRIGHT( ):Object {
                return _keyboardFlags[ "RIGHT" ];
        }
        public function get flagSTOP( ):Object {
                return _keyboardFlags[ "STOP" ];
        }
}

Пример 4: То же, что и пример 3, но хранилище флагов заменяем на соответствующие нужным флагам свойства. [Encapsulation completed ;)]
Код AS3:

public class KeyBoardController {
        private var _flagLEFT:Object;
        private var _flagRIGHT:Object;
        private var _flagSTOP:Object;
        public function get flagLEFT( ):Object {
                return _flagLEFT;
        }
        public function get flagRIGHT( ):Object {
                return _flagRIGHT;
        }
        public function get flagSTOP( ):Object {
                return _flagSTOP;
        }
}

ЗЫ: Если Вы охарактеризовали мой прежний пост, как ношение нижнего белья поверх брюк, то либо ничерта не поняли, либо огрызаетесь праведным идеологическим гневом вместо тог, чтобы аргументировано отстоять свою позицию. Я не предлагаю вам делать ничего противоестественного. Более того, я предлагаю не делать ничего неуместного. Приведу свою аналогию. Вы выставляете на показ яйцо Фаберже. Вы знаете, что посмотреть на него прийдут всякие сомнительные личности и пытаетесь защитить свое богатство охранной системой. Но вместо того, чтобы накрыть яйцо стеклянной витриной с сигнализацией, Вы подсоединяете напряжение к подставке для яйца. Я Вам говорю, что такой подход не страхует Вас от кражы яйца, а Вы мне заявляете, что нельзя же без охранной системы.:confused:

Gerbert 25.10.2014 13:47

Сорри, я не понял с первого раза о чем Вы.
Да Вы правы! Getter на _keyboardFlags в данной ситуации действительно не нужен.

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

Добавлено через 30 минут
Но вот небольшой вопрос - SimpleButton от adobe имеет
Код AS3:

public function get upState():DisplayObject
public function set upState(value:DisplayObject):void

и для себя я объяснил это так - передаю Shape и SimpleButton не может изменить нарисованное,
так DO это не позволит. Но! Ведь я могу взять у кнопки этот стайт и поменять его координаты, ширину или даже
перерисовать прикастовав его к Shape, это ведь тоже не защищает объект. И если следовать этому пути,
то на DO вообще нельзя делать set-get... Что Вы по этому поводу можете сказать?

elder_Nosferatu 25.10.2014 15:04

Во первых, кнопке (экземпляру SimpleButton) плевать чем Вы ее напичкаете, главное, чтобы это были экранные объекты. А будут они прямоугольные, красные, большие или даже пустые внутри - дело Ваше.
Во вторых, как кнопка сможет сходу поменять разместить в себе Ваш апСтейт-объект, если бы у нее было просто публичное свойство upState без аксессоров? Можно, конечно прикрутить ей некий публичный метод refresh() и дергать его самостоятельно, после изменения значения одного из состояний, но зачем тогда аксессоры? Короче, предположу, что:
Код AS3:

private var _upState:DisplayObject;
public function get upState():DisplayObject {
        return _upState;
}
public function set upState(value:DisplayObject):void {
        if (_upState) {
                // remove old state
        }
        _upState = value;
        if (_upState) {
                // place new state
        }
}


Gerbert 25.10.2014 15:14

То есть, Вы считаете adobe таким примитивным, что у них состояния в сеттере меняются?)

Повторю вопрос в догонку - по Вашему мнению на DO вообще не нужно делать аксессоры,
если конечно, что-то да не меняется, как в примере выше?

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

elder_Nosferatu 25.10.2014 17:48

Цитата:

Сообщение от Gerbert (Сообщение 1174091)
То есть, Вы считаете adobe таким примитивным, что у них состояния в сеттере меняются?)

Если установка нового значения должна сопровождаться изменением состояния, то сеттер как раз и берет на себя эту функцию. И не важно будет это сделано непосредственно в сеттере или он просто вызовет специальный метод, который отвечает за применение нового состояния или даже новое состояние сохранится в промежуточном свойстве, а из сеттера отправится запрос инвалидатции.
Например кнопка находится в состоянии "UP" и Вы заганяете новое значение для upState. Вы считаете adobe таким примитивным, что на enterFrame-обработчике висит проверка "а не изменилось ли какое нибудь состояние"? По моему им хватило ума из сеттера инициировать замену. А как она производится мне уже не так интересно. В своем же примере я показал только общую идею, а не конкретную реализацию.

Цитата:

Сообщение от Gerbert (Сообщение 1174091)
Повторю вопрос в догонку - по Вашему мнению на DO вообще не нужно делать аксессоры,
если конечно, что-то да не меняется, как в примере выше?

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

private var _param:int;
public function get param():int { return _param; }
public function set param(value:int):void { _param = value; }

то это уже бред... Спросим у Википедии на счет инкапсуляции:
Цитата:

Сообщение от Википедия
Инкапсуляция — это свойство системы, позволяющее объединить данные и методы, работающие с ними в классе, и скрыть детали реализации от пользователя.

Пример выше ничего от пользователя не скрывает, но в то же время усложняет класс. Работа с таким "защищенным" свойством не отличается от обычного публичного свойства, зато чтение и запись сопровождаэтся вызовом ненужных функций.

Цитата:

Сообщение от Gerbert (Сообщение 1174091)
И не подумайте, что я пытаюсь придраться, я уточняю, так как Вы обосновали свое мнение и я вижу в нем долю истины.

Ну что Вы, придирайтесь на здоровье! Но только если по существу. Ато плодотворная дискуссия (в которлй между прочим может родится истина :) ) превратится в банальный срач.

Gerbert 25.10.2014 18:18

Думал, что можно ответить, но пришел к обычному - Спасибо!


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

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