following character
push cursor key
/**
* Copyright cpu_t ( http://wonderfl.net/user/cpu_t )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/askX
*/
package
{
import flash.display.Loader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.ui.Keyboard;
public class Main extends Sprite
{
private static const STAGE_WIDTH:Number = 465;
private static const STAGE_HEIGHT:Number = 465;
private static const CHARACTER_SIZE:Number = 10;
private static const BLOCK_NUM:int = 40;
private static const MOVE_LEFT:String = "left";
private static const MOVE_RIGHT:String = "right";
private static const MOVE_UP:String = "up";
private static const MOVE_DOWN:String = "down";
private static const CHECK_LENGTH:Number = 80;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private var _player:Shape;
private var _buddyA:Shape;
private var _buddyB:Shape;
private var _map:Sprite;
private var _blocks:Vector.<Rectangle>;
private var _playerState:String;
private var _buddyAState:String;
private var _buddyBState:String;
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
_player = new Shape();
_player.graphics.beginFill(0xFF0000);
_player.graphics.lineStyle(0, 0x000000);
_player.graphics.drawRect(
-CHARACTER_SIZE / 2,
-CHARACTER_SIZE / 2,
CHARACTER_SIZE,
CHARACTER_SIZE
);
addChild(_player);
_buddyA = new Shape();
_buddyA.graphics.beginFill(0x00FF00);
_buddyA.graphics.lineStyle(0, 0x0000FF);
_buddyA.graphics.drawRect(
-CHARACTER_SIZE / 2,
-CHARACTER_SIZE / 2,
CHARACTER_SIZE,
CHARACTER_SIZE
);
addChildAt(_buddyA, 0);
_buddyB = new Shape();
_buddyB.graphics.beginFill(0x00FF00);
_buddyB.graphics.lineStyle(0, 0x0000FF);
_buddyB.graphics.drawRect(
-CHARACTER_SIZE / 2,
-CHARACTER_SIZE / 2,
CHARACTER_SIZE,
CHARACTER_SIZE
);
addChildAt(_buddyB, 0);
reset();
stage.addEventListener(MouseEvent.CLICK, onClick);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
addEventListener(Event.ENTER_FRAME, update);
}
private function reset():void
{
_player.x = STAGE_WIDTH / 2;
_player.y = STAGE_HEIGHT / 2;
_buddyA.x = STAGE_WIDTH / 2;
_buddyA.y = STAGE_HEIGHT / 2;
_buddyB.x = STAGE_WIDTH / 2;
_buddyB.y = STAGE_HEIGHT / 2;
if (_map)
{
removeChild(_map);
}
_map = new Sprite();
addChildAt(_map, 0);
_blocks = new Vector.<Rectangle>();
for (var blockCount:int = 0; blockCount < BLOCK_NUM; blockCount++)
{
var blockWidth:Number = int(1 + Math.random() * 2) * 20;
var blockHeight:Number = int(1 + Math.random() * 2) * 20;
var leftPoint:Number = int(Math.random() * (STAGE_WIDTH - blockWidth) / 20) * 20;
var topPoint:Number = int(Math.random() * (STAGE_HEIGHT - blockHeight) / 20) * 20;
var block:Rectangle = new Rectangle(
leftPoint,
topPoint,
blockWidth,
blockHeight
);
if (block.left < _player.x + 50 &&
block.right > _player.x - 50 &&
block.top < _player.y + 50 &&
block.bottom > _player.y - 50)
{
continue;
}
_blocks.push(block);
var wall:Shape = new Shape();
wall.graphics.beginFill(0x000000);
wall.graphics.drawRect(block.left, block.top, block.width, block.height);
_map.addChild(wall);
}
}
private function onClick(e:MouseEvent):void
{
reset();
}
private function onKeyDown(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.LEFT)
{
_playerState = MOVE_LEFT;
}
else if (e.keyCode == Keyboard.RIGHT)
{
_playerState = MOVE_RIGHT;
}
else if (e.keyCode == Keyboard.UP)
{
_playerState = MOVE_UP;
}
else if (e.keyCode == Keyboard.DOWN)
{
_playerState = MOVE_DOWN;
}
}
private function onKeyUp(e:KeyboardEvent):void
{
_playerState = null;
}
private function update(e:Event):void
{
if (_playerState == MOVE_LEFT)
{
moveCharacter(_player, -5, 0);
}
else if (_playerState == MOVE_RIGHT)
{
moveCharacter(_player, +5, 0);
}
else if (_playerState == MOVE_UP)
{
moveCharacter(_player, 0, -5);
}
else if (_playerState == MOVE_DOWN)
{
moveCharacter(_player, 0, +5);
}
_buddyAState = checkBuddy(_buddyA, _player, _buddyAState);
if (_buddyAState == MOVE_LEFT) moveCharacter(_buddyA, -5, 0);
else if (_buddyAState == MOVE_RIGHT) moveCharacter(_buddyA, +5, 0);
else if (_buddyAState == MOVE_UP) moveCharacter(_buddyA, 0, -5);
else if (_buddyAState == MOVE_DOWN) moveCharacter(_buddyA, 0, +5);
_buddyBState = checkBuddy(_buddyB, _buddyA, _buddyBState);
if (_buddyBState == MOVE_LEFT) moveCharacter(_buddyB, -5, 0);
else if (_buddyBState == MOVE_RIGHT) moveCharacter(_buddyB, +5, 0);
else if (_buddyBState == MOVE_UP) moveCharacter(_buddyB, 0, -5);
else if (_buddyBState == MOVE_DOWN) moveCharacter(_buddyB, 0, +5);
}
private function moveCharacter(target:Shape, moveX:Number, moveY:Number):Boolean
{
var wayArea:Rectangle = new Rectangle();
var wallPoint:Number;
var block:Rectangle;
var hitWall:Boolean = false;
if (moveX != 0)
{
if (moveX > 0) wayArea.x = target.x - CHARACTER_SIZE / 2;
else wayArea.x = target.x - CHARACTER_SIZE / 2 + moveX;
wayArea.width = moveX + CHARACTER_SIZE;
wayArea.y = target.y - CHARACTER_SIZE / 2;
wayArea.height = CHARACTER_SIZE;
wallPoint = NaN;
for each(block in _blocks)
{
if (block.left < wayArea.right &&
block.right > wayArea.left &&
block.top < wayArea.bottom &&
block.bottom > wayArea.top)
{
if (isNaN(wallPoint)) wallPoint = moveX > 0 ? block.left : block.right;
if ((moveX < 0 && block.left < wallPoint) ||
(moveX > 0 && block.right > wallPoint))
{
wallPoint = moveX > 0 ? block.left : block.right;
}
}
}
if (isNaN(wallPoint))
{
target.x += moveX;
}
else
{
target.x = wallPoint + (moveX > 0 ? -CHARACTER_SIZE / 2 - 0.1 : CHARACTER_SIZE / 2 + 0.1);
hitWall = true;
}
}
if (moveY != 0)
{
wayArea.x = target.x - CHARACTER_SIZE / 2;
wayArea.width = CHARACTER_SIZE;
if (moveY > 0) wayArea.y = target.y - CHARACTER_SIZE / 2;
else wayArea.y = target.y - CHARACTER_SIZE / 2 + moveY;
wayArea.height = moveY + CHARACTER_SIZE;
wallPoint = NaN;
for each(block in _blocks)
{
if (block.left < wayArea.right &&
block.right > wayArea.left &&
block.top < wayArea.bottom &&
block.bottom > wayArea.top)
{
if (isNaN(wallPoint)) wallPoint = moveY > 0 ? block.top : block.bottom;
if ((moveY < 0 && block.top < wallPoint) ||
(moveY > 0 && block.bottom > wallPoint))
{
wallPoint = moveY > 0 ? block.top : block.bottom;
}
}
}
if (isNaN(wallPoint))
{
target.y += moveY;
}
else
{
target.y = wallPoint + (moveY > 0 ? -CHARACTER_SIZE / 2 - 0.1 : CHARACTER_SIZE / 2 + 0.1);
hitWall = true;
}
}
return hitWall;
}
private function checkBuddy(target:Shape, parent:Shape, state:String):String
{
var hitWall:Boolean;
var passedCrossPoint:Boolean;
var length:Number;
if (state == MOVE_LEFT) hitWall = moveCharacter(target, -1, 0);
else if (state == MOVE_RIGHT) hitWall = moveCharacter(target, +1, 0);
else if (state == MOVE_UP) hitWall = moveCharacter(target, 0, -1);
else if (state == MOVE_DOWN) hitWall = moveCharacter(target, 0, +1);
length = Math.abs(parent.x - target.x) + Math.abs(parent.y - target.y);
if ((state == MOVE_LEFT && target.x < parent.x) ||
(state == MOVE_RIGHT && target.x > parent.x) ||
(state == MOVE_UP && target.y < parent.y) ||
(state == MOVE_DOWN && target.y > parent.y))
{
passedCrossPoint = true;
}
if (state)
{
if (length < CHECK_LENGTH)
{
return null;
}
else if (hitWall || passedCrossPoint)
{
if (state == MOVE_LEFT || state == MOVE_RIGHT)
{
return (parent.y < target.y) ? MOVE_UP : MOVE_DOWN;
}
else
{
return (parent.x < target.x) ? MOVE_LEFT : MOVE_RIGHT;
}
}
}
else
{
if (length > CHECK_LENGTH)
{
if (Math.abs(parent.x - target.x) > Math.abs(parent.y - target.y))
{
return (parent.x < target.x) ? MOVE_LEFT : MOVE_RIGHT;
}
else
{
return (parent.y < target.y) ? MOVE_UP : MOVE_DOWN;
}
}
}
return state;
}
}
}