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

nzk_3000 18.03.2015 17:08

Проблемы с анимацией
 
Вложений: 1
Недавно начал изучать actionscript 3. Сейчас пытаюсь разобраться с анимацией передвижения и возникла следующая проблема. Есть персонаж, анимации находятся в его символе(movieclip), c 1-24 кадра находится перемещение, с 25 по 44 - прыжок. Нужно сделать так, чтобы когда единоразово нажималась кнопка прыжка воспроизводилась соответствующая анимация. Все что смог придумать: либо привязывать анимацию к переменной нажатия кнопки прыжка, но тогда если отпустить эту кнопку воспроизведение анимации прекратиться, либо привязывать анимацию к моменту нахождения персонажа в воздухе, но и так воспроизведение не работает правильно(персонаж просто зависает в воздухе на первом кадре анимации, а когда приземляется воспроизводиться вся анимация персонажа начиная с текущего кадра до тех пока как-то не сдвинуть персонажа, на гифке запечатлен этот процесс). Думаю возможно каким-то образом проконтролировать воспроизведение анимации до конца и только затем воспроизводить следующую, но я не знаю как это сделать. Может кто-то уже сталкивался с подобными проблемами? не могли бы вы мне помочь?
Код ниже

Код AS3:

import flash.events.KeyboardEvent
import flash.events.Event;
stage.frameRate=30;
 
var mleft:Boolean;
var mright:Boolean;
var mjump:Boolean;
var speed:Number=0;
var accel:Number=0.7;
var fric:Number=0.6;
var gravity:Number=0;
 
character.stop();
 
stage.addEventListener(Event.ENTER_FRAME,main);
stage.addEventListener(KeyboardEvent.KEY_DOWN,walk);
stage.addEventListener(KeyboardEvent.KEY_UP,no_walk);
 
function main(e:Event){
        if (mright)
{       
        character.scaleX= scaleX;
        speed+=accel;
        character.play();
        if(character.currentFrame==24)
        character.gotoAndPlay(1);
        character.x+=speed;
}
 
        if(mleft)
{
        character.scaleX= -scaleX;
        speed-=accel;
        character.play();
        if(character.currentFrame==24)
        character.gotoAndPlay(1);
        character.x+=speed;
 
}
        if ((mright==false) && (mleft==false))
{
        speed*=fric;
        character.x+=speed;
}
 
        if (speed>10) speed=10;
        if (speed<-10) speed=-10;
 
        if(mjump&&character.hitTestObject(ground))
        {
                gravity=-15;
        }
 
        character.y+=gravity;
        if (!character.hitTestObject(ground))
        {
                character.gotoAndPlay(25);
                if (character.currentFrame<44)
                character.gotoAndPlay(25);
                gravity++;
                gravity++;
        }
        else
        gravity=0;
 
        if (character.x-character.width/2<0)
        character.x=character.width/2;
 
        if (character.x+character.width/2>1280)
        character.x=1280-character.width/2;
}
 
function walk(e:KeyboardEvent)
{
        if (e.keyCode==39)
                mright=true;
 
        if (e.keyCode==37)
                mleft=true;
 
        if (e.keyCode==38)
                mjump=true;
}
 
 
function no_walk(e:KeyboardEvent)
{
        if (e.keyCode==39)
                mright=false;
 
        if (e.keyCode==37)
                mleft=false;
 
        if (e.keyCode==38)
                mjump=false;
 
        character.gotoAndStop(1);
 
}


neonoviiwolf 18.03.2015 23:24

честно говоря по мне функция организована чрез одно место.
Почему бы просто не написать условия анимации хождения
пример на вскидку как способ реализации
Код AS3:

//стоит ещё сделать кадр, когда персонаж стоит
//пока нажата кнопка идти
if ((jump == false) && (run)){
character.gotoAndPlay(1);
 if (character.currentFrame == 24) //конец анимации ходьбы
        character.gotoAndPlay(1);
//если нажата клавиша прыжок
if (jump){ //тип булеан true, но она НЕ примет значение false, пока анимация не достигнет последнего кадра прыжка if (character.currentFrame == 44) {jump = false}, а вот значение true она должна принимать при нажатии клавиши
      character.gotoAndPlay(25);
      startJump = true; // ведь сначала анимация началы прыжка, колени сжал и т.д.
      }
if ((startJump) && ((character.currentFrame == 30)){ //типо с тридцатого кадра он отрвётся отземли и будет как-то там себя вести в вуздухе
***// тут пишем его физику, куда и как он летит

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

Добавлено через 5 минут
стоит так же разделить вашу функцию на отдельные части, одни реагируют на нажатия клавиш, другие воспроизводит соответствующую анимацию

nzk_3000 19.03.2015 02:34

изменил код

Код AS3:

import flash.events.KeyboardEvent
import flash.events.Event;
stage.frameRate=30;
 
var mleft:Boolean;
var mright:Boolean;
var mjump:Boolean;
var speed:Number=0;
var accel:Number=0.7;
var fric:Number=0.6;
var gravity:Number=0;
 
character.stop();
 
stage.addEventListener(Event.ENTER_FRAME,main);
stage.addEventListener(KeyboardEvent.KEY_DOWN,walk);
stage.addEventListener(KeyboardEvent.KEY_UP,no_walk);
 
function main(e:Event){
        if (mright)
{       
        character.scaleX= scaleX;
        speed+=accel;
        character.x+=speed;
}
 
        if(mleft)
{
        character.scaleX= -scaleX;
        speed-=accel;
        character.x+=speed;
 
}
        if ((mright==false) && (mleft==false))
{
        speed*=fric;
        character.x+=speed;
}
 
        if (speed>10) speed=10;
        if (speed<-10) speed=-10;
 
        if(mjump&&character.hitTestObject(ground))
        {
                gravity=-15;
        }
 
        character.y+=gravity;
        if (!character.hitTestObject(ground))
        {
                if (character.currentFrame<44)
                character.gotoAndPlay(25);
                gravity++;
                gravity++;
        }
        else
        gravity=0;
 
        if (character.currentFrame==44)
        mjump = false;
 
        if ((mright&&!mjump)||(mleft&&!mjump))
        {character.play();
        if(character.currentFrame==24)
        character.gotoAndPlay(1);}
 
        if (mjump)
        character.gotoAndPlay(25);
 
        if (character.x-character.width/2<0)
        character.x=character.width/2;
 
        if (character.x+character.width/2>1280)
        character.x=1280-character.width/2;
}
 
function walk(e:KeyboardEvent)
{
        if (e.keyCode==39)
                mright=true;
 
        if (e.keyCode==37)
                mleft=true;
 
        if (e.keyCode==38)
                mjump=true;
}
 
 
function no_walk(e:KeyboardEvent)
{
        if (e.keyCode==39)
                mright=false;
 
        if (e.keyCode==37)
                mleft=false;
 
        if (e.keyCode==38)
                mjump=false;
 
        character.gotoAndStop(1);
 
}

Теперь при нажатии на кнопку прыжка происходит переход на 25 кадр, дальше анимация не проигрывается и персонаж начинает постоянно прыгать.Я понимаю причину проблемы - у меня в каждом кадре происходит переход на 25 кадр анимации персонажа вот он и застыл. А как сделать так, что бы анимация начала проигрываться дальше?

а еще мне кажется не совсем правильно что значение переменной прыжка зависит от анимации, хоть и частично

neonoviiwolf 19.03.2015 03:58

введите к примеру ещё одну булевскую переменную, надеюсь идея будет понятно

Код AS3:

var controlJump: boolean = true; //соответственно это должна быть глобальная переменная
//нажали на кнопку прыжка jump = true
if ((jump) && (controlJump)){
      character.gotoAndPlay(25);
      controlJump = false;
}
if (character.currentFrame == 44){
      jump = false;      //не забудь в условии, для начала анимации движения(не прыжка) добавить if (jump == false)
      controlJump = true; 
}

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

а еще мне кажется не совсем правильно что значение переменной прыжка зависит от анимации, хоть и частично
не стоит путать, вы пишите программу, и у вас не значение анимации, а своего рода номер элемента массива, в котором находится рисунок, имеющий координаты, размеры, прозрачность, угол и ещё много чего. Значение переменной изменяется, когда на сцену выводится элемент этого массива

delphic 19.03.2015 08:32

вот тебе пример который лично у меня без глюков работает, со своей игры взял
Код AS3:

animationHero.gotoAndStop("action");
                                                          if(animationHero.pers.currentFrame!= 21)
                                      {
                                        animationHero.pers.play();
                                  }
                                  else
                                        {
                                        animationHero.pers.stop();

это лишь кусочек,но я думаю ты уже понял, главное метки поставить в мувике и пока currentFrame не достигнут играть аниме,иначе лесом остальные действия проигрования, у меня на персе таких меток ну наверное 6))) и ничего глючного.Зачем усложнять,что то куда то привязывать,потом будешь вспоминать зачем так много переменных,которые сомневаюсь что помогут в решении)))

dimarik 19.03.2015 22:17

Цитата:

Сообщение от nzk_3000 (Сообщение 1180203)
Думаю возможно каким-то образом проконтролировать воспроизведение анимации до конца и только затем воспроизводить следующую, но я не знаю как это сделать.

Глобально два варианта:
— имея на руках "карту" анимаций в виде таблицы с номером кадра начала очередной анимации и номером кадра окончания этой анимации, самостоятельно отслеживать номер кадра на событии ENTER_FRAME или подобном, и делать вывод об окончании анимации на основании этой таблицы. Этот подход условно называется "pull", мы сами "вытягиваем" из таймлайна то, чем он сейчас занимается.
— в исходный таймлайн в начало анимации вставлять метки (label) с названиями этих видов анимаций, а в конце каждой анимации сделать вызов рассылки события окончания анимации. Этот подход тянет на "push", сама анимация сообщает, что она закончилась. Вызов анимации осуществляется переходом на метку gotoAndPlay('run_animation');

Первый подход довольно прост. Не нужно никаких меток и вообще никакого кода в файле анимации. Сложен в поддержании актуальности, ведь для этого нужна внешняя таблица. Хорошо, если эта таблица будет в самой анимации. На выручку приходят метки (labels).

Второй подход вынудит использовать простейший код в последних кадрах анимации, что-то типа
Код AS3:

dispatchEvent(new Event(Event.COMPLETE));



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

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