以文本方式查看主题 - ╋艺 镇╋ (http://zyzsky.com/bbs/index.asp) -- ┣◇FLASH交流 (http://zyzsky.com/bbs/list.asp?boardid=5) ---- 男人就撑100秒教程1 (http://zyzsky.com/bbs/dispbbs.asp?boardid=5&id=1684) |
-- 作者:卡西莫咄 -- 发布时间:2008/6/20 10:31:32 -- 男人就撑100秒教程1 1前言: while(runFlag)
{ For all particles { If(current particle is not lived) { Init this particle. } Else if(current particle is out of the game area) { Current particle set to dead. } Else { Current particle move and show If(current particle is collided with the plane) runFlag=flase; } } } 这里要注意一下if….else if 中的条件判定对应的现实意义,即是否会出现实中无意义但在程序中却出现的情况,如果出现的话,这样的BUG将比较难抓出. if(current particle is out of the game area)
{ Current particle set to dead. } Else if(current particle is not lived) { Init this particle. } 在第一个if判定中,会将这样一种情况被包括进去: if(current particle is out of game area&& current is not lived)
此时,将导致第二个判定永远无法到达. class SPhy.CSPhyMc extends MovieClip
{ public var v :Number=0;//1 demision Velocity or together Velocity of vx ,vy public var vx:Number=0; public var vy:Number=0; …… public function setLife(lifeValue:Number):Void { life=lifeValue; } public function getLife():Number { return life; } public function isLived():Boolean { return life==LIVED; } … … } 而在游戏中,这采用一个数组来实现粒子的群落,理由是使用方便而且快速。(当然,出于一种美学上的要求,你可能会选链表,因为它的插入和删除来的比较漂亮和干净,这就取决于你自己的喜好了) If(Len(O1O2)<=r1+r2)
{ Two circles collide. } Else { Safe condition. } 如果在视觉效果要求比较高的场和,尤其是不允许出现物体重叠的场和,不仿在Len(O1O2) 后加上一个偏移值。这样可以保证视觉上不会看到两个物体重叠的现像,尽管在精确的数值模型上二者并未相碰。而在数值精度要求高的场和,恐怕情况就要反一下了,图形是第二位的,数据的精准才是最重要的。具体如何去平衡图形和数据间的对应关系,还请诸位自己去斟酌了。 y=k0(x-x1)+y1.
P1P3: y=k1(x-x1)+y1 P2P3: y=k2(x-x2)+y2 这样,判定一个点是否在三解形内,就只要判断这个点是否在三条边指向三角形内的一侧.这里,如果要判的点为p(x’,y’),则根据图1的情况,有: If(k0(x’-x1)+y1>=0&&k1(x’-x1)+y1<=0&& y’>=y2)//考虑到P2P3是水平的情况
{ Collide! } Else { Safe Condition. } 显然,这个算法并不算得上好,因为如果三解形旋转的话,原来的某直线的左侧意味着三角形的内侧可能就会意味着外侧。这时,可以考虑再增加一个三元组,用来实时指示当前的三条直线指向三角形内侧的方面,可取的情况有以下几种: |
-- 作者:admin -- 发布时间:2008/6/20 11:12:19 -- 4实现部分的关键代码(AS2) 4.1粒子类: import SMotion.*
import SColDet.* class SPhy.CSPhyMc extends MovieClip { public var m:Number=0;//mass public var g:Number=0;//gravity public var pF:Number=0;//Positive forces,attention here UpCase!!!!!!! //Because the compiler was not so perfect as you think ,add a p here to prepare for the case. public var r:Number =0;//when it become a ball---radius. public var v :Number=0;//1 demision Velocity or together Velocity of vx ,vy public var vx:Number=0; public var vy:Number=0; public var f :Number=0;//fraction forces. public var fx:Number=0; public var fy:Number=0; public var a :Number=0;//acclerate v public var ax:Number=0; public var ay:Number=0; //plane game use; public var bigFire:Number=0; private static var DEAD:Number=0; private static var LIVED:Number=1; private var life:Number; private var mMotionCom:RCSMove; private var mColDetCom:RCSColDet; private static var thisP:Object; public function setLife(lifeValue:Number):Void { life=lifeValue; } public function getLife():Number { return life; } public function isLived():Boolean { return life==LIVED; } public function init():Void { thisP=this; this.vx=0; this.vy=0; this.v=3+random(3); this._width=10; this._height=10; this.r=5; this.initCom(); } public function initPos(targetPlane:CSPhyMc):Void { var randNum:Number=random(100); //set init positoin:down,left,up,right if(randNum<25) { this._x=random(Stage.width); trace("Width"+Stage.width+"Height"+Stage.height); this._y=Stage.height; } else if(randNum<50) { thisP._x=_root.gStageLeft; this._y=random(Stage.height); } else if(randNum<75) { this._x=random(Stage.width); thisP._y=_root.gStageTop; } else { this._x=Stage.width; this._y=random(Stage.height); } this.CalVx_Vy(this,targetPlane); } private function GetDis(mc1:CSPhyMc, mc2:CSPhyMc):Number { return Math.sqrt((mc1._x-mc2._x)*(mc1._x-mc2._x)+(mc1._y-mc2._y)*(mc1._y-mc2._y)); } private function CalVx_Vy(mcChase:CSPhyMc, mcAim:CSPhyMc):Void { var len:Number= GetDis(mcChase, mcAim); mcChase.vx=(mcAim._x-mcChase._x)/len*mcChase.v; mcChase.vy=(mcAim._y-mcChase._y)/len*mcChase.v; } public function initCom():Void { mMotionCom=new RCSMove(); mColDetCom=new RCSColDet(); } public function outDetect():Boolean { var offset:Number=25; return mColDetCom.particleOutDet(this,0-offset,0-offset,Stage.width+2*offset,Stage.height+2*offset); } public function move_show():Void { mMotionCom.Move2D(this,this.vx,this.vy); } public function collideDect(targetPlane:CSPhyMc):Boolean { if(_root.mcLibPlaneName=="ball") return mColDetCom.TwoBall(targetPlane,this); //return this.hitTest(targetPlane.getBounds(_root).xMin,targetPlane.getBounds(_root).yMax,false); } } |
-- 作者:admin -- 发布时间:2008/6/20 11:12:58 -- 4.2游戏主调度类 class ChaseAim
{ static private var thisP:Object; private var staturs:Number;//gaming 1,failure 0 private var speed:Number; private var bulletNum:Number=20; private var start:Number=0; private var end:Number=0; public function init():Void { thisP=this; staturs=1; speed=3; bulletNum=20; for(var i=0;i<11;i++) { _root.createTextField("txt"+i,i,0,(i-1)*25,500,25); } _root.attachMovie("ball","ball1",11); _root.ball1._x=250; _root.ball1._y=200; _root.ball1.r=20; for(var i=0;i<bulletNum;i++) { _root.attachMovie("bullet","bullet"+i,20+i); _root["bullet"+i].vx=0; _root["bullet"+i].vy=0; _root["bullet"+i].v=3+random(3); _root["bullet"+i].r=5; _root["bullet"+i]._width=10; _root["bullet"+i]._height=10; GenBullet(_root["bullet"+i]); } start=getTimer(); setInterval(EffectF,100); } private function EffectF():Void { if(thisP.staturs!=0) { for(var i=0;i<thisP.bulletNum;i++) { if (thisP.CheckOutBounds(_root["bullet"+i])) thisP.GenBullet(_root["bullet"+i]); if(thisP.TwoBallCol(_root.ball1,_root["bullet"+i]))thisP.staturs=0; thisP.Move2D(_root["bullet"+i]); //_root.txt3.text=_root["bullet"+i].vx; //_root.txt4.text=_root["bullet"+i].vy; } if( Key.isDown(Key.LEFT))_root.ball1._x -= thisP.speed; if( Key.isDown(Key.RIGHT))_root.ball1._x += thisP.speed; if( Key.isDown(Key.UP))_root.ball1._y -= thisP.speed; if( Key.isDown(Key.DOWN))_root.ball1._y += thisP.speed; if(thisP.staturs==0) { _root.txt0.text="you failure"; thisP.end=getTimer(); var tmp:Number=thisP.end-thisP.start; _root.txt1.text="你共坚持了"+tmp/1000+"秒"; //delete this.onEnterFrame; } } } private function GenBullet(tmpMc:CSPhyMc):Void { var left:Number; var top:Number; if(random(2)) { left=random(7)*100-100; top=random(2)*400; } else { left=random(2)*600; top=random(6)*100-100; } tmpMc._x=left; tmpMc._y=top; CalVx_Vy(tmpMc, _root.ball1); } private function CheckOutBounds(tmpMc:CSPhyMc):Boolean { if(tmpMc._x<-10||tmpMc._x>510||tmpMc._y<-10||tmpMc._y>410) return true; else return false; } private function TwoBallCol(ball1:CSPhyMc,ball2:CSPhyMc):Boolean { if(Math.sqrt((ball1._x-ball2._x)*(ball1._x-ball2._x)+(ball1._y-ball2._y)*(ball1._y-ball2._y))<=(ball1.r+ball2.r)) return true; else return false; } private function GetDis(mc1:CSPhyMc, mc2:CSPhyMc):Number { return Math.sqrt((mc1._x-mc2._x)*(mc1._x-mc2._x)+(mc1._y-mc2._y)*(mc1._y-mc2._y)); } private function CalVx_Vy(mcChase:CSPhyMc, mcAim:CSPhyMc):Void { var len:Number= GetDis(mcChase, mcAim); mcChase.vx=(mcAim._x-mcChase._x)/len*mcChase.v; mcChase.vy=(mcAim._y-mcChase._y)/len*mcChase.v; } private function Move2D(mc:CSPhyMc):Void { mc._x+=mc.vx; mc._y+=mc.vy; } } |
-- 作者:admin -- 发布时间:2008/6/20 11:15:05 -- 4.3核心运行函数: function mainLoop():Void { UserPlaneControl(); if(_root.gRunFlag) { //trace("yes"); for(var i:Number=0;i<_root.gBulletNum;i++) { //trace("yes"); if(!_root[mcUserBulletName+i].isLived()) { //trace("relife:"+i); _root[mcUserBulletName+i].setLife(LIVED); _root[mcUserBulletName+i].init(); _root[mcUserBulletName+i].initPos(_root[mcUserPlaneName]); } else if(_root[mcUserBulletName+i].outDetect()) { //trace("outDetect:"+i); _root[mcUserBulletName+i].setLife(DEAD); } else { _root[mcUserBulletName+i].move_show(); if(_root[mcUserBulletName+i].collideDect(_root[mcUserPlaneName])) _root.gRunFlag=false; } } } else { var timeCount:Number=0; //clear the main game scence clearInterval(_root.gIntervalID); /*for(var i:Number=0;i<_root.gBulletNum;i++) _root[mcUserBulletName+i].removeMovieClip(); _root[mcUserPlaneName].removeMovieClip(); */ _root.gTimeEnd=getTimer(); timeCount=_root.gTimeEnd-_root.gTimeStart; trace("you last:"+String(timeCount)+"secs."); trace2("You lasted:"+String(timeCount)/1000+"secs."); /*start the end mc _root.gNextScence=0; _root.gIntervalID=setInterval(showEnd,_root.fps,_root.mcEndName,_root.result); */ } }5实验结论: 通过该模型,实现了一个粒子系统的基本运作模式,该运作模式同样适用于其它的粒子系统,只要在最关键的运动及显示部分加以变换即可. |