Move&Move游戏键盘控制方法浅析

  在Flash中关于侦听键盘事件的移动,最普通的方法莫过于此:
package {
    import flash.display.Sprite;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;
    import flash.events.MouseEvent;
    public class main extends Sprite {
        private function keyEvt(event:KeyboardEvent):void {
            trace(event.keyCode);
            switch (event.keyCode) {
                case Keyboard.UP :
                    event.target.y-=10;
                    break;
                case Keyboard.DOWN :
                    event.target.y+=10;
                    break;
                case Keyboard.LEFT :
                    event.target.x-=10;
                    break;
                case Keyboard.RIGHT :
                    event.target.x+=10;
                    break;
                default :
                    break;
            }
        }
        
        public function main():void {
            var sp:Sprite=new Sprite();
            sp.graphics.beginFill(0x0000ff);
            sp.graphics.drawRect(200,200,100,100);
            sp.graphics.endFill();
            addChild(sp);
            sp.buttonMode=true;
            sp.addEventListener(KeyboardEvent.KEY_DOWN,keyEvt);
            
        }
    }
}
这段代码的确可以让我们的主角沿着四个方向移动,但是很快我们就发现这个代码不能让我们满意,为什么呢?因为利用KeyDown的事件是由键盘触发的,当我们按下键盘的一个键不松开的时候,受到键盘重复速率的影响,主角的移动并不平滑。那怎么办呢?
最好的办法是改变一个思路,当我们按下一个键,在松开之前,主角的移动不受到键盘重复事件的影响。
最容易想到的思路,就是利用时间触发器,当按下一个键,主人公按照触发器指定的时间间隔进行移动。松开按键,计时停止。主人公也当然的停止下来。
在这个例子里,我建立了一个名叫player的MC,在第一帧中加入如下代码:
var _player:MovieClip=new player();
_player.x=stage.stageWidth/2;
_player.y=stage.stageHeight/2;
var timer:Timer=new Timer(30);
var movespeed=2;//移动速度;
addChild(_player);
var _transferobject
[img]/uploads/allimg/090629/1005050.gif[/img]
isplayObject=_player;//为了方便改动,设立了一个中间变量
var _direction:uint=0;//准备一个存储方向的变量
stage.addEventListener(KeyboardEvent.KEY_DOWN,handler_Keydown,false,0,true);
stage.addEventListener(KeyboardEvent.KEY_UP,handler_Keyup,false,0,true);
timer.addEventListener(TimerEvent.TIMER,handler_time,false,0,true);
function handler_Keydown(event:KeyboardEvent):void{
trace(event.keyCode);
switch (event.keyCode) {
                case Keyboard.UP :
                    _direction=1;
                    break;
                case Keyboard.DOWN :
                    _direction=3;
                    break;
                case Keyboard.LEFT :
                    _direction=2;
                    break;
                case Keyboard.RIGHT :
                    _direction=4;
                    break;
                default :
                    break;
            }
   timer.start();
}
function handler_Keyup(event:KeyboardEvent):void{
timer.stop();
_direction=0;
}
function handler_time(event:TimerEvent):void{
_move(_transferobject);
}
function _move(obj
[img]/uploads/allimg/090629/1005050.gif[/img]
isplayObject){
  switch (_direction) {
   case 0:
   timer.stop();
   break;
   case 1:
   obj.y-=movespeed;
   break;
   case 2:
   obj.x-=movespeed;
   break;
   case 3:
   obj.y+=movespeed;
   break;
   case 4:
   obj.x+=movespeed;
   break;
   default :
   break;
  }
}
测试一下,OK,平滑了许多,但是能不能在精简一些资源呢,不用时间触发呢?答案是肯定的,那就是利用ENTER_FRAME事件(这两者的资源消耗我也把握不准,我认为是不用时间触发器更节约资源)
另外,在基本的八方向游戏中由于有组合键的问题,而且人物移动的方向将影响到人物表现,所以我们采用了这样的方案
下面是改良后的8方向移动的代码,涉及倒组合键的判断,抛砖引玉,请高手优化指教。
package{
/**
by深闪
键盘控制
8    1    2
  \   |   /
7-    X    - 3
  /   |   \
6    5    4
**/
import flash.display.*
import flash.display.InteractiveObject;
import flash.events.KeyboardEvent;
import flash.events.Event;
public class KeyListener extends MovieClip{
private static var current_stage:InteractiveObject;
private static var key:Array;
private static var dir:uint;
private static var eventHandler:Function;
public static function init(io:InteractiveObject,keyfun:Function){
  current_stage=io;
  eventHandler=keyfun;
  key=new Array(false,false,false,false);
  current_stage.addEventListener(KeyboardEvent.KEY_DOWN,keydownHandler);
  current_stage.addEventListener(KeyboardEvent.KEY_UP,keyupHandler);
}
private static function keydownHandler(e:KeyboardEvent):void {
  
        switch (e.keyCode) {
                case 38 :
     key[0]=true;                        
                    break;
                case 39 :
     key[1]=true;                        
     break;
    case 40 :
     key[2]=true;                                                         
                    break;
                case 37 :
     key[3]=true;                        
                    break;
                default :
                    break;
            }
        current_stage.addEventListener(Event.ENTER_FRAME,eventHandler);
}
  
   private static function keyupHandler(e:KeyboardEvent):void {
  
        switch (e.keyCode) {
                case 38 :
     key[0]=false;                        
                    break;
                case 39 :
     key[1]=false;                        
     break;
    case 40 :
     key[2]=false;                                                      
                    break;
                case 37 :
     key[3]=false;                       
                    break;
                default :
                    break;
            }
  !key[0]&&!key[1]&&!key[2]&&!key[3]&&(current_stage.removeEventListener(Event.ENTER_FRAME,eventHandler));
}
//返回方向
public static function getDirection():uint{
  key[0]&&(dir=1);
  key[1]&&(dir=3);
  key[2]&&(dir=5);
  key[3]&&(dir=7);
  key[0]&&key[1]&&(dir=2);
  key[1]&&key[2]&&(dir=4);
  key[2]&&key[3]&&(dir=6);
  key[3]&&key[0]&&(dir=8);
  return dir;
}
}
}
使用方法:
KeyListener.init(stage,eventHandler);
function eventHandler(e:Event):void{
//使用的时候这里加个判断就可以根据不同方向进行不同操作了
trace(KeyListener.getDirection());
}
本文转自:http://www.5uflash.com/flashjiaocheng/Flashyingyongkaifa/5057.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值