понедельник, 17 января 2011 г.

Урок 11.1. Движение персонажа

Здесь движение будет отличаться от урока 8. Там, если нажать кнопку влево, то квадрат поедет влево, а тут – только повернётся влево и если нажать клавишу вверх, то вертолёт полетит в указанном направлении. Похоже, но не то. В этом уроке я попытаюсь, как можно более точно объяснить, как начать работу (создать новый документ, подключить класс и т.д.) чтобы не возвращаться к этому в следующих уроках.
Создание нового документа:
Запускаем Flash CS4, появляется табличка, если не появляется, то нажимаем Ctrl+N


Выбираем Flash File(ActionScript 3.0)

В окне Publish в строке Class пишем game

Нам говорят, что у нас нет такого класса, но скоро будет ;) , нажимаем ок.

Рисуем вертолёт конвертим в символ (выделить и нажать F8) называем helicopter, Экспортируем в ActionScript, короче вот скрин.

Заходим в вертолёт (кликаем 2 раза по нему) рисуем пропеллер. Конвертим в символ, называем как-нибудь, размещаем его, где нам надо, заходим в него (2 раза кликнуть) и пишем код:
this.addEventListener(Event.ENTER_FRAME, rotat);
function rotat(e:Event){
 this.rotation+=20;
}
Для того чтобы пропеллер вращался.
С этим закончили.
Теперь создаём класс game – это будет главный класс, то же самое, что и писать во фреймах, т.е. можно использовать stage, root и т.д. как обычно. Этот класс будет вызываться, когда программа запущена. Создали класс, я надеюсь, с этим проблем не возникнет. Называем этот класс game, пишем в нём код:
package {
 import flash.display.Sprite;
 public class game extends Sprite {
  public var Player;
  public var general_container;//контейнер, куда мы будем сваливать всякие объекты (боты, люди, карта)
  public var stgWidth:Number=600;
  public var stgHeight:Number=500;
  public function game() {
   general_container=new Sprite();
   stage.addChildAt(general_container,0);
   
   Player=new player(this);
  }
 }
}
Создаём класс player. Код:
package {
 import flash.display.MovieClip;
 import flash.events.*;
 import flash.ui.Keyboard;
 public class player extends MovieClip {

  public var game;
  
  private var radians:Number=Math.PI/180;
  
  private var up,down,left,right:Boolean;
  public var speed,rotationSpeed:Number;
  private var moveSpeed,friction,maxSpeed,rotatSpeed:Number;

  public function player(Game){
   game=Game;// т.к. в классе game лежат нужные нам данные, то делаем ссылку на этот класс
   this.x=game.stgWidth/2;//по центру экрана
   this.y=game.stgHeight/2;//по центру экрана
   game.stage.addChildAt(this,2);
   speed=0;//ставим в 0 то, что мы просто объявили, иначе оно будет равно не нулю, а NaN
   rotationSpeed=0;
   maxSpeed=20;
   friction=0.94;//замедление
   moveSpeed=1;
   rotatSpeed=1;
   this.rotation=-90;//чтобы вертолёт смотрел вверх
   
   game.stage.addEventListener(KeyboardEvent.KEY_DOWN,key_down);
   game.stage.addEventListener(KeyboardEvent.KEY_UP,key_up);
   this.addEventListener(Event.ENTER_FRAME,move_player);
  }  
  private function key_down(e:KeyboardEvent) {
   if (e.keyCode==Keyboard.UP||e.keyCode==87) {
    up=true;
   }
   if (e.keyCode==Keyboard.LEFT||e.keyCode==65) {
    left=true;
   }
   if (e.keyCode==Keyboard.RIGHT||e.keyCode==68) {
    right=true;
   }
   if (e.keyCode==Keyboard.DOWN||e.keyCode==83) {
    down=true;
   }
  }
  private function key_up(e:KeyboardEvent) {
   if (e.keyCode==Keyboard.UP||e.keyCode==87) {
    up=false;
   }
   if (e.keyCode==Keyboard.LEFT||e.keyCode==65) {
    left=false;
   }
   if (e.keyCode==Keyboard.RIGHT||e.keyCode==68) {
    right=false;
   }
   if (e.keyCode==Keyboard.DOWN||e.keyCode==83) {
    down=false;
   }
  }
  private function move_player(e:Event) {
   if (maxSpeed>=Math.abs(speed)) {
    if (right==true) {
     rotationSpeed+=rotatSpeed;
    }
    if (up==true) {
     speed+=moveSpeed;
    }
    if (left==true) {
     rotationSpeed-=rotatSpeed;
    }
    if (down==true) {
     speed-=moveSpeed;
    }
   }
   else{
    speed=maxSpeed*(speed/Math.abs(speed));
   }
   update_coordinats();
  }
  private function update_coordinats() {
   this.rotation+=rotationSpeed;//увеличиваем поворот
   this.x+=Math.cos(this.rotation*radians)*speed;//те кому надо - поймут)
   this.y+=Math.sin(this.rotation*radians)*speed;
   rotationSpeed-=rotationSpeed*0.1;//уменьшаем скорость поворота, чтобы была инерция при повороте
   speed*=friction;//уменьшаем скорость, чтобы была инерция
  }
 }
}
Надеюсь, что всё понятно!)
Вот, что должно получится:

Скачать исходник.

3 комментария:

  1. привет, благодарю за уроки, и собственно

    > this.x+=Math.cos(this.rotation*radians)*speed;//те кому надо - поймут)
    > this.y+=Math.sin(this.rotation*radians)*speed;


    надо, но не понял ;) объясни пожалуйста суть этих преобрахований? что-то вроди линейного приращения скорости с учётом энерции? блин. забыл теор мех и физику, вот теперь думаю надо вспоминать, когда увлёкся as3 и геймдевом в частности.

    ОтветитьУдалить
  2. this.rotation - это поворот игрока в градусах, умножаем на radians (Math.PI/180), чтобы перевести градусы в радианы, т.к. флеш извлекает синус и косинус из радиан.
    > Math.cos - Находим косинус угла.
    Умножаем на коэффициент Speed, в результате узнаём на сколько нужно сдвинуть игрока по x.
    Тоже самое с Y.
    А инерция возникает из-за уменьшения коэффициента
    > speed*=friction; (friction=0.94)
    P.S. Смотрю я сейчас на этот код и думаю, а не переписать ли все уроки заново :D

    ОтветитьУдалить
  3. перепеши..много кода(хоть и ооп), мало объяснений. на ас2 для этого гораздо меньше..
    и зачем делать главный контейнер(general_container)?

    а вообще пример хороший
    зы я в ас3 недавно, много чего не понимаю

    ОтветитьУдалить