玩過《紅警》或者《帝國時代》的朋友應該都知道,這類游戲有一個框選功能。鼠標在屏幕上拉一個框,處在方框之內的都被選中。如圖:

[1b]我們這個例子的原型是這樣的:[/1b]
1、坦克的選擇有框選和點擊選擇兩種方式。
2、坦克被選中后會顯示自己被選中。
3、鼠標在屏幕上點擊時,如果有坦克被選中,坦克將移動到鼠標點擊位置附近(是附近不是鼠標點擊位置),同時選擇狀態自動取消。
4、如果有新的選擇,則之前選擇的坦克的選擇狀態將取消。
先看一下完成后的效果:
?
[1b]講解:[/1b]
[1b]1、坦克的被選擇和非選擇狀態的實現
[/1b]
在我們的坦克類里面設置一個屬性select,通過set方法來實現。當select=true時,讓坦克的幀跳轉到第2幀。當select=false時,讓坦克的幀跳轉到第1幀。在坦克類Tank中設定一個私有變量_select,然后設置getter/setter:?
[1b]
??????
public?function?get?select():Boolean
??????{
???????????return?_select;
??????}
??????public?function?set?select(s:Boolean)
??????{
???????????_select=s;
???????????this.gotoAndStop(_select==true??2:1)
??????}????
2、坦克點擊選擇的實現
[/1b]? ?? ?我們沒有必要給每一輛坦克都注冊鼠標事件,只要給放置坦克的容器注冊一個鼠標事件就能知道用戶點擊的是哪一輛坦克。
? ?? ?MouseEvent有target和currentTarget兩個屬性。這兩個屬性有區別,target返回的是最先接收到點擊的交互物體,而currentTarget返回的是你addEventListener注冊的這個對象。見下圖:

[1b]
3、坦克框選的實現
[/1b]
基本上我們會需要做這幾個步驟:
A、通過鼠標的MOUSE_MOVE事件實現拉框效果。
B、通過畫的這個框和物體的邊界框比較判斷那些物體被選擇了。
C、讓這些物體變為選擇的狀態。
D、當鼠標再一次被點擊時,如果有坦克在選擇狀態下并且點擊的位置是空地,則所有坦克向目標點附近移動,同時取消所有選擇狀態。
實現思路是——準備兩個數組一個記錄所有坦克的引用tankList,一個記錄任何時候被選擇的坦克的引用selectList。這里我們會用到平時使用不多的兩個數組里的方法forEach()和filter(),這兩個方法將在這里發揮重要的作用。數組對象共有5個你可能沒怎么關注的新的方法。如下圖:

來看一下我們在這個例子里面是怎么用的:
??????
[/color]
selectList=tankList.filter(selectTank);?//找出被框選的坦克
??????selectList.forEach(moveTank);?//讓所有被選中的坦克移動
??????function?selectTank(element:*,?index:int,?arr:Array)
??????{
???????????//如果坦克邊界與選框相交,則讓坦克顯示為選擇狀態
???????????if(element.getBounds(this).intersects(rec)==true)
???????????{
????????????????element.select=true;
????????????????return?true;
??????????}
???????????return?false;
??????}
??????function?moveTank(element:*,?index:int,?arr:Array)
??????{
?????????element.select=false;?//移動時取消坦克的選擇狀態
??????????var?randomX=targetPoint.x+Math.random()*150-75;
??????????var?randomY=targetPoint.y+Math.random()*150-75;
??????????element.moveTo(randomX,randomY);?//讓坦克移動
???????}[1b]
完整代碼如下:
==================================================================================
主程序:[/1b]
[1b]
[color="#ff0000"]
[1b]
import?Tank;
var?map:Sprite=new?Sprite();?//定義一個地圖容器
var?tankList:Array=new?Array();?//定義一個記錄所有坦克的列表
var?selectList:Array=new?Array();?//定義一個記錄當前選擇的坦克的列表
var?targetPoint:Point;?//目標點
var?rec:Rectangle;?//選擇框的矩形對象
var?shape:Shape=new?Shape();?//用于顯示選擇框的Shape對象
var?isMove:Boolean;?//選擇坦克還是移動坦克
addChild(map);?//把地圖放入顯示列表
addChild(shape);?//選擇框
//產生20輛坦克
for?(var?i=0;i0&&rec.height>0)//重新框選
???{
????????selectList.forEach(unSelect);
???????clearArray(selectList);
????????selectList=tankList.filter(selectTank);
???????rec.width=rec.height=0;
???}
????else?if(selectList.length>0&&isMove==true)
????{
????????selectList.forEach(moveTank)
????????clearArray(selectList);
????}
}
//用來篩選哪些坦克被選中的過濾方法
function?selectTank(element:*,?index:int,?arr:Array)
{
????if(element.getBounds(this).intersects(rec)==true)
???{
????????element.select=true;
???????return?true;
????}
????return?false;
}
//取消坦克的選擇狀態的方法
function?unSelect(element:*,?index:int,?arr:Array)
{
??????element.select=false;
}
//移動坦克的方法
function?moveTank(element:*,?index:int,?arr:Array)
{
????element.select=false;
????var?randomX=targetPoint.x+Math.random()*150-75;
????var?randomY=targetPoint.y+Math.random()*150-75;
????element.moveTo(randomX,randomY);
}
function?clearArray(arr:Array)
{
????while(arr.length>0)
???{
???????arr.shift();
????}
}==================================================================================
坦克類:[/1b]
package
{
/**
*?一個簡單的坦克類的模型
*?作者:閃刀浪子
*?blog:http://hi.baidu.com/mr_ziqiang
*/
import?flash.display.MovieClip
import?flash.geom.Point
import?flash.events.Event;
public?class?Tank?extends?MovieClip
{
???private?var?speed:int;?//坦克的速度
???private?var?targetPoint:Point;?//目標點
???private?var?_select:Boolean;?//此坦克是否被選中,選中則顯示被選中狀態
???/**
???*?Tank類構造函數
???*?初始化的時候隨機產生一個坐標
???*/
???public?function?Tank()
???{
????this.mouseChildren=false;?//這里記得禁用子對象的鼠標點擊
????this.x=300*Math.random()+10;?//設置坦克出現的時候在左上角100*100大小范圍類隨機
????this.y=300*Math.random()+10;
????this.scaleX=this.scaleY=1+Math.random();?//體積大的就是紅警中最牛的猛犸坦克了
????speed=(3-scaleX)*4;?//呵呵,體積越大速度當然要越慢了
???}
???public?function?moveTo(tx:Number,ty:Number)
???{
????this.removeEventListener(Event.ENTER_FRAME,onMove);
????targetPoint=new?Point(tx,ty);
????this.addEventListener(Event.ENTER_FRAME,onMove);
???}
???private?function?onMove(evt:Event)
???{
????var?dx?=?targetPoint.x?-?this.x;
????var?dy?=?targetPoint.y?-?this.y;
????var?radian?=?Math.atan2(dy,?dx);//求新角度??
????body.rotation=radian*180/Math.PI;?//我的坦克類里有一個body的mc,方便轉向的時候綠框不隨著轉
????if?(dx?*?dx?+?dy?*?dy?[/1b]
本文轉自:http://www.5uflash.com/flashjiaocheng/Flashyingyongkaifa/4611.html
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
