Copy link to clipboard
Copied
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!
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
if you want both right and left keys to be active, don't use if-else for them either and remove your tweening boolean.
Copy link to clipboard
Copied
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;
}
Copy link to clipboard
Copied
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
Find more inspiration, events, and resources on the new Adobe Community
Explore Now