Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Tile Based Movement in AS3

New Here ,
Jan 24, 2014 Jan 24, 2014

Hello i am still trying to create tile based movement. What i mean by that is the character can move smoothly but will always end up in the middle of a tile (just like the pokemon games). I have managed to make it work if the player uses only one key, however in combination with other keys it does not work. I was hoping someone could give me advise how to fix the code or perhaps some better/easier way to do it.

Here is my code so far (this is only for left and right key) my character movieclip has the instance name char

import flash.ui.Keyboard;

import flash.events.KeyboardEvent;

import flash.events.Event;

import fl.transitions.easing.*;

import com.greensock.*;

var pixelsMoved:Number = 0;

var pixelsLeft:Number = 0;

var tweening:Boolean = false;

var rightKeyDown:Boolean = false;

var leftKeyDown:Boolean = false;

addEventListener(Event.ENTER_FRAME,Loop);

stage.addEventListener(KeyboardEvent.KEY_DOWN,KeyPress);

stage.addEventListener(KeyboardEvent.KEY_UP,KeyRelease);

function Loop(event:Event):void

{

    if (tweening == false)

    {

        if (rightKeyDown == true)

        {

            char.x += 1;

            pixelsMoved += 1;

        }

       

        else if (leftKeyDown == true)

        {

            char.x -= 1;

            pixelsMoved += 1;

        }

       

        if (pixelsMoved >= 25)

        {

            pixelsMoved = 0;

            pixelsLeft = 25;

        }

    }

}

function KeyPress(event:KeyboardEvent):void

{

    if (event.keyCode == Keyboard.RIGHT)

    {

        rightKeyDown = true;

    }

   

    if (event.keyCode == Keyboard.LEFT)

    {

        leftKeyDown = true;

    }

}

function KeyRelease(event:KeyboardEvent):void

{

    pixelsLeft = 25 - pixelsMoved;

   

    if (event.keyCode == Keyboard.RIGHT)

    {

        if (tweening == false)

        {

            var moveRight:TweenLite = new TweenLite(char,pixelsLeft,{x:char.x + pixelsLeft,ease:None.easeNone,useFrames: true,onComplete: resetVars});

        }

        rightKeyDown = false;

        tweening = true;

    }

   

    if (event.keyCode == Keyboard.LEFT)

    {

        if (tweening == false)

        {

            var moveLeft:TweenLite = new TweenLite(char,pixelsLeft,{x:char.x - pixelsLeft,ease:None.easeNone,useFrames: true,onComplete: resetVars});

        }

        leftKeyDown = false;

        tweening = true;

    }

}

function resetVars():void

{

    tweening = false;

    pixelsLeft = 0;

    pixelsMoved = 0;

}

Any help is much apreciated!

TOPICS
ActionScript
1.6K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Jan 24, 2014 Jan 24, 2014

you can use else-if statements for right/left and for up/down but not right/left/up/down in your Loop function.

you also will find it easier to just use four booleans to determine what action to take in Loop.

Translate
Community Expert ,
Jan 24, 2014 Jan 24, 2014

you can use else-if statements for right/left and for up/down but not right/left/up/down in your Loop function.

you also will find it easier to just use four booleans to determine what action to take in Loop.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 24, 2014 Jan 24, 2014

Thanks but it still does not work, when both right and left key is pressed it doesn't work. Can i upload a swf file here? If you want to see what's wrong

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 24, 2014 Jan 24, 2014

if you want both right and left keys to be active, don't use if-else for them either and remove your tweening boolean.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 25, 2014 Jan 25, 2014

I am not sure I understand all the requirements. Also I guess you refer to pacman game - not pokemon.

In any case, here is something that works pretty smooth at 60fps. Note there are no ENTER_FRAME handlers - all animations are handled by TweenLite.

Just dump the code on a timeline in a new FLA - it is not meant to be injected into your existing code. So, this is just an independent fully functional concept. All objects are created dynamically by the script - you don't have to do anything to view/test this example.

Read comments.

import com.greensock.easing.Ease;

import com.greensock.easing.Linear;

import com.greensock.easing.Sine;

import com.greensock.TweenLite;

import flash.display.Graphics;

import flash.display.Shape;

import flash.display.Sprite;

import flash.events.KeyboardEvent;

import flash.geom.Point;

import flash.ui.Keyboard;

var board:Sprite;

var tileSide:Number = 40;

var numRows:int = 10;

var numCols:int = 14;

var char:Shape;

var _currentKey:uint = 0;

var tween:TweenLite;

init();

function init():void

{

          drawBoard();

          configStage();

}

function configStage():void

{

          stage.scaleMode = StageScaleMode.NO_SCALE;

          stage.align = StageAlign.TOP_LEFT;

          stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPress);

          stage.addEventListener(KeyboardEvent.KEY_UP, onKeyRelease);

}

function onKeyRelease(e:KeyboardEvent):void

{

          // if the latest processed key was not release - we block the latest pressed key

          if (e.keyCode == _currentKey)

                    _currentKey = 0;

}

function onKeyPress(e:KeyboardEvent):void

{

          currentKey = e.keyCode;

}

function get tile():Shape

{

          var shape:Shape = new Shape();

          shape.cacheAsBitmap = true;

          var color:uint = 0x808080;

          var g:Graphics = shape.graphics;

          g.lineStyle(1, color);

          g.beginFill(0xEBEBEB);

          g.drawRect(-tileSide / 2, -tileSide / 2, tileSide, tileSide);

          return shape;

}

function moveChar(targetX:int = 0, targetY:int = 0):void

{

          tween = TweenLite.to(char, 0.45, {x: targetX, y: targetY, ease: Linear.easeNone, onComplete: onTweenComplete});

}

function onTweenComplete():void

{

          /**

           * need to do that

           * a. if key is kept pressed

           * c. to override situations when another key is pressed simulataneously

           */

          currentKey = _currentKey;

}

function set currentKey(value:uint):void

{

          var targetPosition:Number = 0;

          /**

           * key value is proccessed if

           * a. key is allowed - via switch

           * b. there is no key pressed before or ptreviously pressed key _currentKey is the same as new value

           * c. tween in not active

           */

          if ((!_currentKey || _currentKey == value) && !tween._active)

          {

                    switch (value)

                    {

                              case Keyboard.RIGHT:

                                        targetPosition = char.x + tileSide;

                                        if (targetPosition < tileSide * numCols)

                                        {

                                                  moveChar(targetPosition, char.y);

                                                  charRotation = 0;

                                        }

                                        _currentKey = value;

                                        break;

                              case Keyboard.LEFT:

                                        targetPosition = char.x - tileSide;

                                        if (targetPosition >= 0)

                                        {

                                                  moveChar(targetPosition, char.y);

                                                  charRotation = 180;

                                        }

                                        _currentKey = value;

                                        break;

                              case Keyboard.UP:

                                        targetPosition = char.y - tileSide;

                                        if (targetPosition >= 0)

                                        {

                                                  moveChar(char.x, targetPosition);

                                                  charRotation = -90;

                                        }

                                        _currentKey = value;

                                        break;

                              case Keyboard.DOWN:

                                        targetPosition = char.y + tileSide;

                                        if (targetPosition < tileSide * numRows)

                                        {

                                                  moveChar(char.x, targetPosition);

                                                  charRotation = 90;

                                        }

                                        _currentKey = value;

                                        break;

                    }

          }

}

function set charRotation(value:Number):void

{

          if (char.rotation == -180)

                    char.rotation = 180;

          if (char.rotation == 180 && value == -90)

                    char.rotation = -180;

          else if (char.rotation == -90 && value == 180)

                    value = -180;

          TweenLite.to(char, 0.2 * (Math.abs((char.rotation - value) / 90) || 1), {rotation: value});

}

function drawBoard():void

{

          board = new Sprite();

          var numTiles:int = numRows * numCols;

          for (var i:int = 0; i < numTiles; i++)

          {

                    var t:Shape = tile;

                    t.x = tileSide * (i % numCols);

                    t.y = tileSide * int(i / numCols);

                    board.addChild(t);

          }

          board.addChild(addChar);

          addChild(board);

          board.x = board.y = 20 + tileSide / 2;

}

function get addChar():Shape

{

          var radius:Number = tileSide / 2 - 4;

          char = new Shape();

          var g:Graphics = char.graphics;

          g.lineStyle(1);

          g.beginFill(0xff0000);

          g.drawCircle(0, 0, radius);

          g.endFill();

          g.lineStyle(2);

          g.moveTo(0, 0);

          g.lineTo(radius, 0);

          g.beginFill(0x000000);

          g.moveTo(radius, 0);

          g.lineTo(radius - 10, 4);

          g.lineTo(radius - 10, -4);

          g.endFill();

          tween = new TweenLite(char, 1, null);

          char.cacheAsBitmap = true;

          return char;

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 27, 2014 Jan 27, 2014
LATEST

Hey thank you for all your troubles! That is some very good code however it does take a small amount of time for flash to load the next tween which makes the character stop for a moment everytime it lands on a new tile. I have already found this tutorial which i am probably going to use. http://tbg.tonypa.pri.ee/tut05.html

Thanks for the help though

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines