Flash Actionscript教程:游戏中的碰撞检测

教程

简单碰撞

下面是代码:
//把你舞台上的MC实例名放入数组,测试
var ballA:Array = [ball1, ball2, ball3, ball4, ball5];
//随机初始化每个MC的运动速度和方向
for (var i = 0; i<ballA.length; i++) {
ballA.dx = 11*rand1_1();
ballA.dy = 7*rand1_1();
}
//随机产生1或-1
function rand1_1():Number {
return random(2) ? -1 : 1;
}
Stage.scaleMode = "noScale";
Stage.align = "TL";
var sw:Number = Stage.width;
var sh:Number = Stage.height;
var stageListener:Object = new Object();
//舞台大小改变时,重置sw、sh
stageListener.onResize = function() {
sw = Stage.width;
sh = Stage.height;
};
Stage.addListener(stageListener);
onEnterFrame = function () {
for (var i = 0; i<ballA.length; i++) {
  //检测所有MC之间是否有碰撞,有就根据情况改变“增量”方向
  for (var j = i+1; j<ballA.length; j++) {
   if (ballA.hitTest(ballA[j])) {
    mc12(ballA, ballA[j]);
    ballA._x += ballA.dx;
    ballA[j]._x += ballA[j].dx;
    ballA._y += ballA.dy;
    ballA[j]._y += ballA[j].dy;
   }
  }
  //如果到了边界,就反射
  if ((ballA._x<ballA._width/2 && ballA.dx<0) or (ballA._x>sw-ballA._width/2 && ballA.dx>0)) {
   ballA.dx *= -1;
  }
  if ((ballA._y<ballA._height/2 && ballA.dy<0) or (ballA._y>sh-ballA._height/2 && ballA.dy>0)) {
   ballA.dy *= -1;
  }
  //移动一个“增量”          
  ballA._x += ballA.dx;
  ballA._y += ballA.dy;
}
};
//碰撞函数,根据两球碰撞方向和自身运动方向合成新的增量值
function mc12(mc1:MovieClip, mc2:MovieClip) {
var ang:Number = Math.atan2(mc2._y-mc1._y, mc2._x-mc1._x);
var ang1:Number = Math.atan2(mc1.dy, mc1.dx);
var ang2:Number = Math.atan2(mc2.dy, mc2.dx);
var r1:Number = (mc1.dy/Math.sin(ang1))*Math.cos(ang-ang1);
var r2:Number = (mc2.dy/Math.sin(ang2))*Math.cos(ang-ang2);
var dx1:Number = r1*Math.cos(ang)+r2*Math.cos(ang);
var dy1:Number = r1*Math.sin(ang)+r2*Math.sin(ang);
mc1.dx = -mc1.dx+dx1;
mc1.dy = -mc1.dy+dy1;
mc2.dx = -mc2.dx+dx1;
mc2.dy = -mc2.dy+dy1;
}

  加入反弹效果

  代码:

//把你舞台上的MC实例名放入数组,测试
var ballA:Array = [ball1, ball2, ball3, ball4, ball5];
//随机初始化每个MC的运动速度和方向
for (var i = 0; i<ballA.length; i++) {
ballA[i].dx = 5*rand1_1();
ballA[i].dy = 5*rand1_1();
ballA[i].N=i;
}
//随机产生1或-1
function rand1_1():Number {
return random(2) ? -1 : 1;
}
Stage.scaleMode = "noScale";
Stage.align = "TL";
var sw:Number = Stage.width;
var sh:Number = Stage.height;
var stageListener:Object = new Object();
//舞台大小改变时,重置sw、sh
stageListener.onResize = function() {
sw = Stage.width;
sh = Stage.height;
};
Stage.addListener(stageListener);
onEnterFrame = function () {
for (var i = 0; i<ballA.length; i++) {
  //如果到了边界,就反射
  if ((ballA[i]._x<ballA[i]._width/2 && ballA[i].dx<0) or (ballA[i]._x>sw-ballA[i]._width/2 && ballA[i].dx>0)) {
   ballA[i].dx *= -1;
  }
  if ((ballA[i]._y<ballA[i]._height/2 && ballA[i].dy<0) or (ballA[i]._y>sh-ballA[i]._height/2 && ballA[i].dy>0)) {
   ballA[i].dy *= -1;
  }
  //检测所有MC之间是否有碰撞,有就根据情况改变“增量”方向
  for (var j = i+1; j<ballA.length; j++) {
   if (myHitTest(ballA[i],ballA[j])) {
   //if (ballA[i].hitTest(ballA[j])) {
    mc12(ballA[i], ballA[j]);
    ballA[i]._x += ballA[i].dx;
    ballA[j]._x += ballA[j].dx;
    ballA[i]._y += ballA[i].dy;
    ballA[j]._y += ballA[j].dy;
   }
  }
  //移动一个“增量”          
  ballA[i]._x += ballA[i].dx;
  ballA[i]._y += ballA[i].dy;
}
updateAfterEvent();
};
//碰撞函数,根据两球碰撞方向和自身运动方向合成新的增量值
function mc12(mc1:MovieClip, mc2:MovieClip) {
//碰撞角
var ang:Number = Math.atan2(mc2._y-mc1._y, mc2._x-mc1._x);
//运动角
var ang1:Number = Math.atan2(mc1.dy, mc1.dx);
var ang2:Number = Math.atan2(mc2.dy, mc2.dx);
//反射角
var _ang1:Number = 2*ang-ang1-Math.PI;
var _ang2:Number = 2*ang-ang2-Math.PI;
//运动矢量
var r1:Number=Math.sqrt(mc1.dx*mc1.dx+mc1.dy*mc1.dy);
var r2:Number=Math.sqrt(mc2.dx*mc2.dx+mc2.dy*mc2.dy);
//碰撞矢量
var a1:Number = (mc1.dy/Math.sin(ang1))*Math.cos(ang-ang1);
var a2:Number = (mc2.dy/Math.sin(ang2))*Math.cos(ang-ang2);
//碰撞矢量合成
var dx1:Number = a1*Math.cos(ang)+a2*Math.cos(ang);
var dy1:Number = a1*Math.sin(ang)+a2*Math.sin(ang);
//碰撞后的增量
mc1.dx = r1*Math.cos(_ang1)+dx1;
mc1.dy = r1*Math.sin(_ang1)+dy1;
mc2.dx = r2*Math.cos(_ang2)+dx1;
mc2.dy = r2*Math.sin(_ang2)+dy1;
}
//碰撞侦测
function myHitTest(mc1:MovieClip,mc2:MovieClip):Boolean{
var a:Number=Math.sqrt((mc1._x-mc2._x)*(mc1._x-mc2._x)+(mc1._y-mc2._y)*(mc1._y-mc2._y));
if(a-5<=(mc1._width+mc2._width)/2){
  return true;
}else{
  return false;
}
}

  带旋转效果:

  代码:

//把你舞台上的MC实例名放入数组,测试
var ballA:Array = [ball1, ball2, ball3, ball4, ball5];
//随机初始化每个MC的运动速度、方向、旋转
for (var i = 0; i<ballA.length; i++) {
ballA[i].dx = 5*rand1_1();
ballA[i].dy = 5*rand1_1();
ballA[i].dr = 0;//增加旋转属性
ballA[i].N=i;//球编号
}
//随机产生1或-1
function rand1_1():Number {
return random(2) ? -1 : 1;
}
//舞台属性
Stage.scaleMode = "noScale";
Stage.align = "TL";
var sw:Number = Stage.width;
var sh:Number = Stage.height;
var stageListener:Object = new Object();
//舞台大小改变时,重置sw、sh
stageListener.onResize = function() {
sw = Stage.width;
sh = Stage.height;
};
Stage.addListener(stageListener);
//------
onEnterFrame = function () {
for (var i = 0; i<ballA.length; i++) {
  //如果到了边界,就反射
  if (ballA[i]._x<ballA[i]._width/2 && ballA[i].dx<0) {
   ballA[i].dx *= -1;
   ballA[i].dr += ballA[i].dy;
  }
  if (ballA[i]._x>sw-ballA[i]._width/2 && ballA[i].dx>0) {
   ballA[i].dx *= -1;
   ballA[i].dr += -ballA[i].dy;
  }
  if (ballA[i]._y<ballA[i]._height/2 && ballA[i].dy<0) {
   ballA[i].dy *= -1;
   ballA[i].dr += -ballA[i].dx;
  }
  if (ballA[i]._y>sh-ballA[i]._height/2 && ballA[i].dy>0) {
   ballA[i].dy *= -1;
   ballA[i].dr += ballA[i].dx;
  }
  //检测所有MC之间是否有碰撞,有就根据情况改变“增量”方向
  for (var j = i+1; j<ballA.length; j++) {
   if (myHitTest(ballA[i],ballA[j])) {
   //if (ballA[i].hitTest(ballA[j])) {
    mc12(ballA[i], ballA[j]);
    ballA[i]._x += ballA[i].dx;
    ballA[j]._x += ballA[j].dx;
    ballA[i]._y += ballA[i].dy;
    ballA[j]._y += ballA[j].dy;
   }
  }
  //移动一个“增量”          
  ballA[i]._x += ballA[i].dx;
  ballA[i]._y += ballA[i].dy;
  ballA[i]._rotation += ballA[i].dr;
  ballA[i].dr -= ballA[i].dr*0.01;

};
//碰撞函数,根据两球碰撞方向和自身运动方向合成新的增量值
function mc12(mc1:MovieClip, mc2:MovieClip) {
//碰撞角
var ang:Number = Math.atan2(mc2._y-mc1._y, mc2._x-mc1._x);
//运动角
var ang1:Number = Math.atan2(mc1.dy, mc1.dx);
var ang2:Number = Math.atan2(mc2.dy, mc2.dx);
//反射角
var _ang1:Number = 2*ang-ang1-Math.PI;
var _ang2:Number = 2*ang-ang2-Math.PI;
//运动矢量
var r1:Number=Math.sqrt(mc1.dx*mc1.dx+mc1.dy*mc1.dy);
var r2:Number=Math.sqrt(mc2.dx*mc2.dx+mc2.dy*mc2.dy);
//碰撞矢量
var a1:Number = (mc1.dy/Math.sin(ang1))*Math.cos(ang-ang1);
var a2:Number = (mc2.dy/Math.sin(ang2))*Math.cos(ang-ang2);
//碰撞矢量合成
var dx1:Number = a1*Math.cos(ang)+a2*Math.cos(ang);
var dy1:Number = a1*Math.sin(ang)+a2*Math.sin(ang);
//旋转矢量,这里还有点问题,旋转方向有时不对。
mc1.dr += r1*Math.sin(ang-ang1);
mc2.dr += r2*Math.sin(ang-ang2);
//碰撞后的增量
mc1.dx = r1*Math.cos(_ang1)+dx1;
mc1.dy = r1*Math.sin(_ang1)+dy1;
mc2.dx = r2*Math.cos(_ang2)+dx1;
mc2.dy = r2*Math.sin(_ang2)+dy1;
}
//碰撞侦测
function myHitTest(mc1:MovieClip,mc2:MovieClip):Boolean{
var a:Number=Math.sqrt((mc1._x-mc2._x)*(mc1._x-mc2._x)+(mc1._y-mc2._y)*(mc1._y-mc2._y));
if(a-2<=(mc1._width+mc2._width)/2){
  return true;
}else{
  return false;
}
}

时间: 2024-09-20 01:14:47

Flash Actionscript教程:游戏中的碰撞检测的相关文章

3D游戏中的碰撞检测以及爬楼梯的算法

问题描述 3D游戏中的碰撞检测以及爬楼梯的算法 比如说在地面上的时候,人是直着往前走的,当遇到楼梯以后,就不能往前走了,而是会直接沿着楼梯向上走,请问这个怎么实现呢??比如这个例子中的上楼梯的算法是怎么实现的呢?http://www.babylonjs.com/Demos/WCafe/ 解决方案 简单碰撞检测的3D游戏3D游戏中的碰撞检测android 3D 游戏实现之简单碰撞检测

积少成多 Flash(ActionScript 3.0 &amp;amp; Flex 3.0) 系列文章索引

Flash 之 ActionScript 3.0 1.积少成多Flash(1) - ActionScript 3.0 基础之数据类型.操作符和流程控制语句 介绍 Flash ActionScript 3.0 中所有的数据类型都是对象,操作符和流程控制语句的语法与C#类似   2.积少成多Flash(2) - ActionScript 3.0 基础之包.类.包外类.命名空间.属性.方法.接口和继承 介绍 Flash ActionScript 3.0 是一种面向对象的语言,包.类.包外类.命名空间.

Flash游戏开发系列一:游戏中的敌人(4)

第三篇:Flash游戏开发系列一:游戏中的敌人. 四(插).半随机移动的敌人 看看这个例子: 我们可以看到,一个敌人按照一定的规律从上面到下面移动.主要的规律是自上而下,但是移动的范围是随机的.这种方法在早期的游戏里面经常使用,包括一些大型的游戏.其实这是一种非常简单的运动方式,但是如果使用得当,也很有威胁. 我们大概瞧一下原理: 敌人每次向一个方向以随机的速度走八步,然后再改变方向,再走八步.在这个例子里面,为了简单说明,敌人走到画面底部以后,我们会让它重新回到原来的位置,重新再走. 我们创建

Flash游戏开发系列一:游戏中的敌人1

对于目前的 Flash 来说,开发一些像模像样的游戏并不是什么奇怪的事情了.我这里所涉及到的内容和开发游戏有关,但是都是一些比较基本的知识.如果您是游戏开发方面的高手,那么完全可以忽略我这里所描述的内容.我的计划是要做一系列的教程,这是其中一个系列. 游戏是一个交互作品,简单说,就是通过用户的行为,会对这个作品的进程产生一定的影响.说到游戏,总要提到难度,游戏的难度在于:当你想要达到某种目的的时候,你会发现它的实现多少有些困难,困难越难克服,难度也就越大.不同类型的游戏有不同的难度,以及不同的实

Flash游戏中使用漂亮的文字

从标题到StageClear字样,从分数到对话框,游戏中很多地方要用到文字.若是简单的使用Flash标准字体?这算游戏吗?我们需要华丽的文字! 偶们即将系统滴讨论游戏中的文字,目标是--把文字美化到牙齿!! 有一些文字是静态的,可以用各种绘图手段极尽美化之能事--但是也是很有讲究的:然而另一些是动态的,只能用动态文本吗?--废柴!未够班阿! 1 用Flash绘图工具处理静态文字 Flash绘图工具很好用.写下一排文字之后,Ctrl+B 两次,可以将文本打散成填充.这个时候我们就可以用各种方法来处

Flash游戏开发系列一:游戏中的敌人(7)

第六篇:Flash游戏开发系列一:游戏中的敌人. 五.跟踪导弹(续完) 上次我们已经知道怎样让导弹的旋转看起来像那么回事,紧接着就是让导弹运动起来了. 导弹的一些属性,我们需要好好定义一下,这是完整的初始化函数: init = function () {enemy._x = 40;enemy._y = 350;enemy._rotation = 0;enemy_obj.MAXAngle = 6;enemy_obj.MAXSpeed = 4;enemy_obj.speedX = enemy_obj

Flash游戏开发系列一:游戏中的敌人(6)

第五篇:Flash游戏开发系列一:游戏中的敌人. 五.跟踪导弹(续) 前面讲过了如何让导弹朝向玩家,但是真正在应用的时候,不可能这么生硬的体现.大家可能也发现了,导弹的方向一直指向玩家,其实很不真实,那么如何才能更加真实一些呢.常用的方法有几种,我们这里介绍其中一种,其它的大家可能要去参考游戏开发图书了. 在这里,我们使用的方法是,导弹有一个最大转向角度,也就是说,如果转向达到这个角度,就不能再转了,这样,看起来就会真实一些,导弹也就不回一下子面对玩家,看看下面这个例子,我把导弹的最大转向角度设

Flash游戏开发系列一:游戏中的敌人(5)

第四篇:Flash游戏开发系列一:游戏中的敌人. 五.跟踪导弹 看看这个例子,在动画屏幕上按下鼠标,导弹就会跟踪玩家,直到击中玩家: 对于新手来说,一下子就实现它可能不太容易,我们来一点一点的做. (1)导弹的方向 我们先来实现导弹朝向玩家的功能,就像下面这个:(按下鼠标观看) 首先,我们注意到,敌人的导弹是要朝向玩家的,这和前面不同.前面的敌人是一个圆头圆脑的家伙,不用分辨它的方向.我们就先来看一下如何让敌人有方向感. 首先给新手讲解一下基本知识:用鼠标来触发动画. 我们先设定一个变量,布尔类

Flash游戏开发系列一:游戏中的敌人(3)

第二篇:Flash游戏开发系列一:游戏中的敌人. 三.指定范围内的跟踪深化 再看看这个例子: 现在的敌人的视线范围比较真实了,它一直在四周查看,只有当你进入它的视觉范围的时候,敌人才会来追赶你. 这就是有指定范围的跟踪敌人,它的原理是和前面一样的: 如果(玩家进入敌人范围){ 如果(玩家x坐标 <> 敌人x坐标){调整敌人x坐标,趋近玩家x坐标}如果(玩家y坐标 <> 敌人y坐标){调整敌人y坐标,趋近玩家y坐标}} 我们可以在 enemy 里面放置一个扇形的范围,给一个实例名叫做