- 浏览: 575935 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
wzh051527:
我是大四实习生一个,自我感觉技术能力在第三年。。唯一不明白,为 ...
十年技术,不要再迷茫 -
room_bb:
.hrl文件怎么加入到编译规则里面?比如:pp.hrl文件-d ...
Erlang中用的makefile的一点解释 -
吉米家:
感觉帆软报表的flash打印就很不错哇,特别好用
JSP 实现报表打印 -
雪碧爱芬达:
苦逼程序员的辛酸反省与总结 -
mlyjxx:
...
十年技术,不要再迷茫
上一次发了一篇Rectangle对象在游戏开发中的应用的文章,下面还是围绕Rectangle对象介绍一下在即时战略游戏中的实际应用。同时还将会用到数组对象中平时用的不多的几个方法。 玩过《红警》或者《帝国时代》的朋友应该都知道,这类游戏有一个框选功能。鼠标在屏幕上拉一个框,处在方框之内的都被选中。如图: 我们这个例子的原型是这样的: 1、坦克的选择有框选和点击选择两种方式。 先看一下做好的效果,点击这里 讲解: 1、坦克的被选择和非选择状态的实现 在坦克类Tank中设定一个私有变量_select,然后设置getter/setter public function get select():Boolean 2、坦克点击选择的实现 3、坦克框选的实现 实现思路是——准备两个数组一个记录所有坦克的引用tankList,一个记录任何时候被选择的坦克的引用selectList。 这里我们会用到平时使用不多的两个数组里的方法forEach()和filter(),这两个方法将在这里发挥重要的作用。数组对象共有5个你可能没怎么关注的新的方法。如下图:\ 来看一下我们在这个例子里面是怎么用的: selectList=tankList.filter(selectTank); //找出被框选的坦克 function selectTank(element:*, index:int, arr:Array) function moveTank(element:*, index:int, arr:Array) 完整代码如下: var map:Sprite=new Sprite(); //定义一个地图容器 //产生20辆坦克 addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler) function mouseDownHandler(evt:MouseEvent) ================================================================================== package
2、坦克被选中后会显示自己被选中
3、鼠标在屏幕上点击时,如果有坦克被选中,坦克将移动到鼠标点击位置附近(是附近不是鼠标点击位置),同时选择状态自动取消。
4、如果有新的选择,则之前选择的坦克的选择状态将取消。
在我们的坦克类里面设置一个属性select,通过set方法来实现。当select=true时,让坦克的帧跳转到第2帧。当select=false时,让坦克的帧跳转到第1帧。
{
return _select;
}
public function set select(s:Boolean)
{
_select=s;
this.gotoAndStop(_select==true? 2:1)
}
我们没有必要给每一辆坦克都注册鼠标事件,只要给放置坦克的容器注册一个鼠标事件就能知道用户点击的是哪一辆坦克。
MouseEvent有target和currentTarget两个属性。这两个属性有区别,target返回的是最先接收到点击的交互物体,而currentTarget返回的是你addEventListener注册的这个对象。见下图:
基本上我们会需要做这几个步骤:
A、通过鼠标的MOUSE_MOVE事件实现拉框效果。
B、通过画的这个框和物体的边界框比较判断那些物体被选择了
C、让这些物体变为选择的状态
D、当鼠标再一次被点击时,如果有坦克在选择状态下并且点击的位置是空地,则所有坦克向目标点附近移动,同时取消所有选择状态。
selectList.forEach(moveTank); //让所有被选中的坦克移动
{
//如果坦克边界与选框相交,则让坦克显示为选择状态
if(element.getBounds(this).intersects(rec)==true)
{
element.select=true;
return true;
}
return false;
}
{
element.select=false; //移动时取消坦克的选择状态
var randomX=targetPoint.x+Math.random()*150-75;
var randomY=targetPoint.y+Math.random()*150-75;
element.moveTo(randomX,randomY); //让坦克移动
}
==================================================================================
主程序:
import Tank;
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); //选择框
for (var i=0;i<20;i++)
{
var tank=new Tank();
map.addChild(tank);
tankList.push(tank); //把坦克的引用记录下来
}
addEventListener(MouseEvent.MOUSE_UP,mouseUpHandler)
{
targetPoint=new Point(evt.currentTarget.mouseX,evt.currentTarget.mouseY);
//如果点击在坦克上,则此坦克被选中。否则注册一个鼠标移动事件
if((evt.target is Tank)==true)
{
selectList.forEach(unSelect); //将已选择链表中所有坦克变为非选择状态
clearArray(selectList); //清空selectList数组
evt.target.select=true
selectList.push(evt.target)
isMove=false;
}
else
{
addEventListener(MouseEvent.MOUSE_MOVE,mouseMoveHandler)
isMove=true;
}
}
function mouseMoveHandler(evt:MouseEvent)
{
var recWidth=evt.currentTarget.mouseX-targetPoint.x;
var recHeight=evt.currentTarget.mouseY-targetPoint.y;
shape.graphics.clear();
shape.graphics.beginFill(0x99ccff,0.2);
shape.graphics.lineStyle(2, 0x000000,0.8);
shape.graphics.drawRect(targetPoint.x,targetPoint.y, recWidth, recHeight)
shape.graphics.endFill();
}
function mouseUpHandler(evt:MouseEvent)
{
removeEventListener(MouseEvent.MOUSE_MOVE,mouseMoveHandler)
rec=shape.getBounds(this);
shape.graphics.clear();
if(rec.width>0&&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();
}
}
坦克类
{
/**
* 一个简单的坦克类的模型
* 作者:闪刀浪子
* 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 <= speed * speed)
{
this.x=targetPoint.x;
this.y=targetPoint.y;
this.removeEventListener(Event.ENTER_FRAME,onMove);
}
else
{
var vx = Math.cos(radian) * speed;//求增量
var vy = Math.sin(radian) * speed;
this.x += vx;
this.y += vy;
}
}
public function get select():Boolean
{
return _select;
}
public function set select(isSelect:Boolean)
{
_select=isSelect;
if(_select==true)
{
this.gotoAndStop(2);
}
else
{
this.gotoAndStop(1);
}
}
}
}
发表评论
-
as3 Loader 加载资源后内存泄露无法释放的问题。
2014-06-21 10:30 631as3 Loader 加载资源后内存泄露无法释放的问题。 ... -
as3判断flash player版本的函数
2014-06-10 20:35 789//判断当前版本是否高于9.0.115.0为例子. pr ... -
CSS 中文字体的英文名称 (simhei, simsun) 宋体 微软雅黑
2014-04-03 15:25 957华文细黑:STHeiti Light [STXihei]华文 ... -
as3.0的垃圾回收机制
2013-09-07 14:02 1459还是同样的博客,还是同样的作者(Daniel Sidhio ... -
AIR程序多开
2013-09-07 13:55 963AIR应用通常不能像QQ那样能进行多开操作。为了让一个用AI ... -
starling性能优化总结
2013-07-22 14:06 1436在项目开发的过程中总结了一下starling的性能优化方案: ... -
AS3 Socket从零开始
2013-07-22 12:54 1063大家如果想学AS3 Socket直接在百度里搜一下,会找到很 ... -
绕开AS3安全沙箱 跨域加载SWF
2013-07-11 12:53 858AS3的安全沙箱的确是 ... -
解决AS3在ie中初始化时stageWidth和stageHeight为0
2013-06-14 09:23 964先看下面的一段脚本,这是比较经典的初始化脚本: pac ... -
动态获取swc中的类
2013-05-25 10:32 906想通过代码生成,来获取swc中的类,并且可以作为普通类正常使 ... -
AS3 中字符串的format功能实现
2013-05-25 10:19 800使用C#的朋友都知道,string.Format();还是挺 ... -
总结调用Flash的几种方法
2013-05-02 16:18 1618一、Adobe 提供的方法 <object wi ... -
Flash3D错误集锦
2013-05-02 14:03 886VerifyError: Error #1014: 无法找到 ... -
使用scale拉伸之后的坐标问题
2013-04-12 09:38 1234最近发现论坛多了很多 ... -
30个实用的网页设计工具
2013-03-20 09:58 773作为一位网页设计师或开发者,你一直需要搜寻获取强大的网页设计 ... -
如何成为强大的程序员?
2013-03-11 11:27 692Aaron Stannard是新创公 ... -
漫谈重构
2013-03-11 11:09 814因为工作内容的原因, ... -
AS3使用谷歌API生成二维码
2012-12-10 16:24 1304二维码在新闻杂志,网站,网络广告,电视广告等地方随处可见 ... -
OOP的聚合原则
2012-12-10 16:21 894什么是聚合? 聚合可以很好地表达对象是什么和做 ... -
压缩速率追踪
2012-11-02 14:16 1421Flash Player 11.3添加了一个压缩和解压B ...
相关推荐
即时战略游戏开发:Rectangle应用实战+Array中被你忽略的方法 类似弹弓的小游戏 由浅入深学习Flash制作高射炮游戏 由浅入深学习Flash制作物体弹跳游戏 游戏的任务事件处理解决方案 游戏基本操作:上下左右的移动(AS...
)一个软件团队开发绘图系统,设计了圆对象(Circle)、矩形对象(Rectangle)、线对象(Line)都支持Draw()函数,即可以通过Draw()函数绘制图形。为了加快项目进度,将角度对象(Angle)绘制功能交给了合作团队...
C++ 对象 例题 rectangle clock
public class Rectangle { //声明矩形类 int xTopLeft; //左上角横坐标 int yTopLeft; //左上角纵坐标 int xBottomRight; //右下角横坐标 int yBottomRight; //右下角纵坐标 int id; //唯一编号 static int ...
按以下描述和要求建立两个类:基类 Rectangle(矩形类) 和派生类 Cube(正方体) 1. Rectangle 私有成员: double x1, y1; //左下角的坐标 double x2, y2; //右上角的坐标 公有成员: 带缺省值的构造...
编写一个接口Shape类,Rectangle、Triangle、Square等三个类实现(implements)接口Shape,并通过实现Shape中的接口来实现具体功能。 编写两个接口Phone、GameMachine,MobilePhone类实现接口Phone和GameMachine中...
可以掌握Rectangle类的用法,以及相关的使用,其实多看几次就会懂了。
实现利用Rectangle输出一个矩形的周长和面积
创建一个retangle类矩形框的设计方法
3. 生成一个Rectangle类(长方形),这个类的length和width属性默认取值为1,其成员函数计算长方形的perimeter(周长)和area(面积)。为该类的length和width设置set函数和get函数。set函数应验证length和width均为...
几何形状示例:对显示对象应用矩阵转换 第章:使用绘图API 绘制API的基础 Graphics类 绘制线条和曲线 使用内置方法绘制形状 创建渐变线条和填充 将Math类与绘制方法配合使用 使用绘图API进行动画处理 绘制API示例:...
初学java之接口的一个小程序 Circle Rectangle
Rectangle程序分析
//创建常量对象 const CRectangle crt3(lt,rd); cout当前创建的矩形个数为:"; cout(); //返回矩形的左上和右下点 CPoint lt1=crt.GetLefttop(); CPoint lt2=crt.GetRightdown(); //显示矩形的坐标 cout...
c#响应控件的拖拽功能,将文件拖拽到控件区域 将文件拖拽到控件区域.
本代码主要利用MATLAB工具实现MATLAB——使用rectangle命令创建二维矩形或椭圆区域,简单明了,易于理解
Qt Qml 可拖动设置Rectangle大小Demo
LeetCode题目Largest Rectangle in Histogram 解答
构造main函数,生成Rectangle和Circle对象,并用Shape类型的变量调用Rectangle和Circle对象的getArea()和getPerim()方法。 2、以电话为父类,移动电话和固定电话为两个子类,并使移动电话实现接口:可移动。固定...
mac最好用的分屏软件.