zoukankan      html  css  js  c++  java
  • Flash/Flex学习笔记(17):按键捕获

    先来看简单的单个按键捕获:

    package {
    	import flash.display.Sprite;
    	import fl.controls.Label;
    	import flash.events.KeyboardEvent;
    	import flash.ui.Keyboard;
    
    	public class KeyDown extends Sprite {
    
    		private var lbl:Label;
    		private var ball:Sprite;		
    
    		public function KeyDown():void {
    			init();
    		}
    
    		private function init():void {
    			stage.focus=this;//N多资料上说要先设置焦点,但是在实际测试中,发现不加这一行,好象也能处理键盘事件?
    			
    			lbl = new Label();
    			lbl.text="请按键,这里将显示您的按键值,按方向键可以移动小球";
    			lbl.autoSize="center";
    			addChild(lbl);
    			lbl.width=stage.stageWidth;
    			lbl.height=20;
    			lbl.move(0,10);
    
    			ball = new Sprite();
    			addChild(ball);
    			
    			//画小球 
    			ball.graphics.beginFill(0xff0000);
    			ball.graphics.drawCircle(0,0,30);
    			ball.graphics.endFill();
    			
    			//定位到舞台中心
    			ball.x=stage.stageWidth/2;
    			ball.y=stage.stageHeight/2;
    
    			stage.addEventListener(KeyboardEvent.KEY_DOWN,KeyDownHandler);			
    		}
    
    		public function KeyDownHandler(e:KeyboardEvent):void {
    			lbl.text="您的按键值是:"+e.keyCode.toString()+";按键是:"+String.fromCharCode(e.keyCode);
    			switch (e.keyCode) {
    				case Keyboard.UP :
    					ball.y-=10;
    					break;
    				case Keyboard.DOWN :
    					ball.y+=10;
    					break;
    				case Keyboard.LEFT :
    					ball.x-=10;
    					break;
    				case Keyboard.RIGHT :
    					ball.x+=10;
    				default :
    					break;
    			}
    
    			if (e.ctrlKey) {
    				lbl.text="您按下了Ctrl键!";
    			}
    			if (e.shiftKey) {
    				lbl.text="您按下了Shift键!";
    			}
    			//注:实际上,在很多浏览器,包括flash播放器里,Alt都是默认用做菜单激活键的,所以Alt键会被他们拦截,从而导致Flash无法捕获
    			if (e.altKey) {
    				lbl.text="您按下了Alt键!";
    			}
    		}
    	}
    }
    

    再来看下类似: A + B + C 的这种组合键捕获:

    先分析一下过程,比如用户按下Ctrl + A 时,实际上是先按下Ctrl键,同时触发KeyDown事件,然后在Ctrl不放的同时,再按下A键,再次触发KeyDown事件,然后松开(触发KeyUp事件),这是一个顺序的过程。

    思路:在用户按下键且尚未松开任何键时,可以考虑用一个数据,把本次按下的所有的键值都存储起来,然后等待用户松开,一旦松开,就可以认为本次组合键 输入完成,这时再清空数据,准备下次使用,这样数组中保存的就是用户按下的组合键。

    按这个思路把上面的代码改进一下:

    package {
    	import flash.display.Sprite;
    	import fl.controls.Label;
    	import flash.events.KeyboardEvent;
    	import flash.ui.Keyboard;
    	import flash.ui.*;
    
    	public class KeyDown extends Sprite {
    
    		private var lbl:Label;
    		private var ball:Sprite;
    		private var keyValueArr:Array;//捕获组合键时,用来存放本次(在未触KeyUp事件前)所有按下的所有键值
    		private var keyNameArr:Array;//按键值对应的字符
    
    		public function KeyDown():void {
    			init();
    		}
    
    		private function init():void {
    			stage.focus=this;//N多资料上说要先设置焦点,但是在实际测试中,发现不加这一行,好象也能处理键盘事件?
    
    			lbl = new Label();
    			lbl.text="请按键(支持Ctrl,Shift组合键),这里将显示您的按键值,按方向键可以移动小球";
    			lbl.autoSize="center";
    			addChild(lbl);
    			lbl.width=stage.stageWidth;
    			lbl.height=20;
    			lbl.move(0,10);
    
    			ball = new Sprite();
    			addChild(ball);
    
    			//画小球 
    			ball.graphics.beginFill(0xff0000);
    			ball.graphics.drawCircle(0,0,30);
    			ball.graphics.endFill();
    
    			//定位到舞台中心
    			ball.x=stage.stageWidth/2;
    			ball.y=stage.stageHeight/2;
    
    			stage.addEventListener(KeyboardEvent.KEY_DOWN,KeyDownHandler);
    			stage.addEventListener(KeyboardEvent.KEY_UP,KeyUpHandler);
    
    			keyValueArr = new Array();
    			keyNameArr = new Array();
    		}
    
    		public function KeyDownHandler(e:KeyboardEvent):void {
    			//注:既然Alt总是被浏览器或播放器菜单栏 拦截,干脆就不检测了
    			if (!(e.keyCode==Keyboard.SHIFT||e.keyCode==Keyboard.CONTROL)) {
    				keyValueArr.push(e.keyCode);
    				keyNameArr.push(String.fromCharCode(e.keyCode));
    			}
    
    			lbl.text="您的按键值是:" + e.keyCode.toString()+";按键是:" + String.fromCharCode(e.keyCode);
    			switch (e.keyCode) {
    				case Keyboard.UP :
    					ball.y-=10;
    					break;
    				case Keyboard.DOWN :
    					ball.y+=10;
    					break;
    				case Keyboard.LEFT :
    					ball.x-=10;
    					break;
    				case Keyboard.RIGHT :
    					ball.x+=10;
    				default :
    					break;
    			}
    
    			if (e.ctrlKey) {
    				if (keyValueArr.length>0) {
    					lbl.text="您按下了Ctrl + "+keyNameArr.join(',');
    				}
    			}
    			if (e.shiftKey) {
    				if (keyValueArr.length>0) {
    					lbl.text="您按下了Shift + "+keyNameArr.join(',');
    				}
    			}		
    
    		}
    
    		public function KeyUpHandler(e:KeyboardEvent):void {
    			keyValueArr.length=0;
    			keyNameArr.length=0;
    		}
    	}
    }
    

    最后再来看看所谓的"八方向"移动:很多小游戏都可以用方向键控制人物的移动方向,上面的示例中,只能沿水平垂直四个方向移动,如果要做到8方向移动,就要用到组合键,仍然在上面的代码基本上做些修改:

    package {
    	import flash.display.Sprite;
    	import fl.controls.Label;
    	import flash.events.KeyboardEvent;
    	import flash.ui.Keyboard;
    	import flash.ui.*;
    
    	public class KeyDown extends Sprite {
    
    		private var lbl:Label;
    		private var ball:Sprite;
    		private var keyValueArr:Array;//捕获组合键时,用来存放本次(在未触KeyUp事件前)所有按下的所有键值
    		private var keyNameArr:Array;//按键值对应的字符
    
    		public function KeyDown():void {
    			init();
    		}
    
    		private function init():void {
    			stage.focus=this;//N多资料上说要先设置焦点,但是在实际测试中,发现不加这一行,好象也能处理键盘事件?
    
    			lbl = new Label();
    			lbl.text="请按键(支持Ctrl,Shift组合键),这里将显示您的按键值,按方向键可以移动小球(支持8方向)";
    			lbl.autoSize="center";
    			addChild(lbl);
    			lbl.width=stage.stageWidth;
    			lbl.height=20;
    			lbl.move(0,10);
    
    			ball = new Sprite();
    			addChild(ball);
    
    			//画小球 
    			ball.graphics.beginFill(0xff0000);
    			ball.graphics.drawCircle(0,0,30);
    			ball.graphics.endFill();
    
    			//定位到舞台中心
    			ball.x=stage.stageWidth/2;
    			ball.y=stage.stageHeight/2;
    
    			stage.addEventListener(KeyboardEvent.KEY_DOWN,KeyDownHandler);
    			stage.addEventListener(KeyboardEvent.KEY_UP,KeyUpHandler);
    
    			keyValueArr = new Array();
    			keyNameArr = new Array();
    		}
    
    		public function KeyDownHandler(e:KeyboardEvent):void {
    			//注:既然Alt总是被浏览器或播放器菜单栏 拦截,干脆就不检测了
    			if (!(e.keyCode==Keyboard.SHIFT||e.keyCode==Keyboard.CONTROL)) {
    				if (keyValueArr.indexOf(e.keyCode)==-1) {
    					keyValueArr.push(e.keyCode);
    					keyNameArr.push(String.fromCharCode(e.keyCode));
    				}
    			}
    
    			lbl.text="您的按键值是:"+ keyValueArr.join(',') +";按键是:" + keyNameArr.join(',');
    
    			//单方向移动
    			if (keyValueArr.length==1) {
    				switch (e.keyCode) {
    					case Keyboard.UP :
    						ball.y-=10;
    						break;
    					case Keyboard.DOWN :
    						ball.y+=10;
    						break;
    					case Keyboard.LEFT :
    						ball.x-=10;
    						break;
    					case Keyboard.RIGHT :
    						ball.x+=10;
    					default :
    						break;
    				}
    			} else if (keyValueArr.length>1) {
    				//trace(keyValueArr.join(','));				
    				if (keyValueArr.indexOf(Keyboard.UP)!=-1 && keyValueArr.indexOf(Keyboard.LEFT)!=-1) {		
    					//左上
    					ball.x -= 10;
    					ball.y -= 10;
    				} else if (keyValueArr.indexOf(Keyboard.UP)!=-1 && keyValueArr.indexOf(Keyboard.RIGHT)!=-1) {
    					//右上
    					ball.x += 10;
    					ball.y -= 10;
    				}
    				else if (keyValueArr.indexOf(Keyboard.DOWN)!=-1 && keyValueArr.indexOf(Keyboard.RIGHT)!=-1) {
    					//右下
    					ball.x += 10;
    					ball.y += 10;
    				}
    				else if (keyValueArr.indexOf(Keyboard.DOWN)!=-1 && keyValueArr.indexOf(Keyboard.LEFT)!=-1) {
    					//左下
    					ball.x -= 10;
    					ball.y += 10;
    				}
    			}
    
    			if (e.ctrlKey) {
    				if (keyValueArr.length>0) {
    					lbl.text="您按下了Ctrl + "+keyNameArr.join(',');
    				}
    			}
    			if (e.shiftKey) {
    				if (keyValueArr.length>0) {
    					lbl.text="您按下了Shift + "+keyNameArr.join(',');
    				}
    			}
    
    		}
    
    		public function KeyUpHandler(e:KeyboardEvent):void {
    			keyValueArr.length=0;
    			keyNameArr.length=0;
    		}
    	}
    }
    

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    拖动图片浏览的程序(VB6)
    Nod32升级服务器(转)
    看了部电影"蝴蝶效应"
    BackgroundWorker的替代者! (转)
    为什么我爱黑莓8700
    什么是反射(.NET)[转]
    使用VS2008编写了第一个WM5短信发送程序!
    不睡觉果然还是不行。
    关于net2.0里面新出现的类backgroundworker的应用 (转)
    是男人就打5000分!(C#)
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1701317.html
Copyright © 2011-2022 走看看