大规模网格形碰撞检测

来源:互联网 发布:数据库维护需要什么 编辑:程序博客网 时间:2024/05/18 03:52

题目:

场景中有大小完全相同的100个正方体,且坐标一直在舞台内变化,请判断它们是否两两相撞。
 

先上效果图,用的网格型碰撞检测方法,参考了ActionScript3.0 高级动画教程 就是参考里面的做法。大概思路就是把屏幕分隔,根据坐标把物体放进不同的格子内,碰撞检测的时候遍历格子,首先进行格子内部物体的碰撞检测,然后检测格子内每个物体与周边格子物体的检测,至于周边之外的格子因为是碰撞不了的 所以也无需检测,主要是在这里节省了碰撞和循环次数。

 

 

下面是代码:

package {import flash.display.MovieClip;import classes.*;/** * ... * @author fengsser */public class Main extends MovieClip{//[SWF(width = "550", height = "400", backgroundColor = "0x000000", frameRate = "30")]public function Main() {var game:Game = new Game(this.stage);}}}


 

package classes{import flash.display.BitmapData;import flash.display.Stage;import flash.events.Event;import flash.display.DisplayObject;/** * ... * @author fengsser * 游戏入口 */public class Game {var _stage:Stage;var cubeArr:Vector.<DisplayObject>;//存放cube对象,Vctor对象代替数组增加效率var cubeNum:uint = 120;//方块总数//var sourceBMD:BitmapData;var cubeSize:int = 10;var girdCollision:GridCollision;public function Game(_stage:Stage) {this._stage = _stage;cubeArr = new Vector.<DisplayObject>();init();}public function init():void {//sourceBMD = new BitmapData(this.cubeSize,this.cubeSize, false, 0x0066ff);makeCube();//创建方块girdCollision = new GridCollision(this, 45);//网格碰撞类this._stage.addEventListener(Event.ENTER_FRAME, render);//渲染}public function makeCube():void {for (var i = 0; i < cubeNum; i++ ) {var cube:Cube = new Cube(this);cube.x = Math.round(Math.random()*(this._stage.stageWidth-cubeSize)+cubeSize/2);cube.y = Math.round(Math.random()*(this._stage.stageHeight-cubeSize)+cubeSize/2)cubeArr.push(cube);this._stage.addChild(cube);}}public function render(e:Event):void {for (var i in cubeArr) {var cube:Cube = cubeArr[i] as Cube;cube.run();//让方块移动girdCollision.checkGrid();//碰撞检测}}}}


 

package classes{import flash.display.Bitmap;import flash.display.BitmapData;/** * ... * @author fengsser * 方块类 *  */public class Cube extends Bitmap  {var game:Game;var dx:int = 2;var dy:int = 2;public function Cube(game:Game) {this.game = game;this.bitmapData = new BitmapData(game.cubeSize,game.cubeSize, false, 0x0066ff);//蓝色//this.bitmapData = game.sourceBMD;}public function run():void {dx = ((Math.random()*2-1 > 0 )?1:-1)*dx;dy = ((Math.random()*2-1 > 0 )?1:-1)*dy;var ndx = this.x + dx;var ndy = this.y + dy;if (ndx > game._stage.stageWidth - this.width ) {this.x = game._stage.stageWidth - this.width;}else if(ndx < 0 ) {this.x = 0;}else {this.x = ndx;}if (ndy > game._stage.stageHeight - this.height ) {this.y = game._stage.stageHeight - this.height;}else if(ndy < 0 ) {this.y = 0;}else {this.y = ndy;}}}}


 

package classes {/** * ... * @author fengsser * 网格碰撞检测类 *  */import flash.display.DisplayObject;import flash.geom.Rectangle; public class GridCollision {var row:int;var column:int;var girdArr:Vector.<Vector.<DisplayObject>>//碰撞辅助网格var game:Game;var girdSize:uint;var totle = 0;//统计内部循环次数var xunhuan =0;//统计总循环次数public function GridCollision(game:Game,girdSize:uint) {this.game = game;this.girdSize = girdSize;column = Math.ceil(game._stage.stageWidth / girdSize);row = Math.ceil(game._stage.stageHeight / girdSize);trace("column" + column);trace("row"+row);//checkGrid();}//分配网格protected function assignGird():void {girdArr = null;girdArr = new Vector.<Vector.<DisplayObject>>(row * column);for (var i in game.cubeArr) {var cube = game.cubeArr[i] as Cube;var index:int = ((Math.floor(cube.y / girdSize)) * column ) +(Math.floor(cube.x / girdSize));//trace("第"+i+"个方块在"+Math.floor(cube.x / girdSize));if (girdArr[index] == null) {girdArr[index] = new Vector.<DisplayObject>();}girdArr[index].push(cube);}}public function checkGrid(): void{assignGird();//每次检测前重新分配网格for(var i: int = 0; i < row; i++){for(var j: int = 0; j < column; j++){//遍历节点以及四周需要遍历的网格checkOneGird(i, j);checkTwoGird(i, j, i, j + 1);checkTwoGird(i, j, i + 1, j - 1);checkTwoGird(i, j, i + 1, j);checkTwoGird(i, j, i + 1, j + 1);}}//trace(totle);//trace(xunhuan);}//检测自身网格内的对象private function checkOneGird(i:uint, j:uint):void {xunhuan++;var index:int = i * column + j;if (girdArr[index] == null) {return;}//trace(index+"有"+ girdArr[index].length);for (i = 0; i < girdArr[index].length - 1; i++ ) {for (j = i + 1; j < girdArr[index].length; j++ ) {xunhuan++totle++;var cube1:Cube = girdArr[index][i] as Cube;var cube2:Cube = girdArr[index][j] as Cube;if (cube1.hitTestObject(cube2)) {//这里执行碰撞操作,我没抽象出来。碰撞后变色。if (cube1.bitmapData.getPixel(0, 0) == 0xff0000) {cube1.bitmapData.fillRect(new Rectangle(0, 0, cube1.width, cube1.height), 0x0066ff);}else {cube1.bitmapData.fillRect(new Rectangle(0, 0, cube1.width, cube1.height), 0xff0000);}if (cube2.bitmapData.getPixel(0, 0) == 0xff0000) {cube2.bitmapData.fillRect(new Rectangle(0, 0, cube1.width, cube1.height), 0x0066ff);}else {cube2.bitmapData.fillRect(new Rectangle(0, 0, cube1.width, cube1.height), 0xff0000);}//cube1.dx = cube1.dy = cube2.dx = cube2.dy = 0;}}}}private function checkTwoGird(x1:uint, y1:uint, x2:uint, y2:uint):void {xunhuan++;var index1:int = x1 * column + y1;var index2:int = x2 * column + y2;if(x2 >= row || x2 < 0 || y2 >= column) return;if (girdArr[index1] == null || girdArr[index2] == null) {return;}for (var i = 0; i < girdArr[index1].length; i++ ) {for (var j = 0 ; j < girdArr[index2].length; j++ ) {totle++;xunhuan++;var cube1:Cube = girdArr[index1][i] as Cube;var cube2:Cube = girdArr[index2][j] as Cube;if (cube1.hitTestObject(cube2)) {//这里执行碰撞操作,我没抽象出来。碰撞后变色。if (cube1.bitmapData.getPixel(0, 0) == 0xff0000) {cube1.bitmapData.fillRect(new Rectangle(0, 0, cube1.width, cube1.height), 0x0066ff);}else {cube1.bitmapData.fillRect(new Rectangle(0, 0, cube1.width, cube1.height), 0xff0000);}if (cube2.bitmapData.getPixel(0, 0) == 0xff0000) {cube2.bitmapData.fillRect(new Rectangle(0, 0, cube1.width, cube1.height), 0x0066ff);}else {cube2.bitmapData.fillRect(new Rectangle(0, 0, cube1.width, cube1.height), 0xff0000);}//cube1.dx = cube1.dy = cube2.dx = cube2.dy = 0;}}}}}}


100个方块的时候还是很畅顺的,但130之后开始有些掉帧,感觉哪里还是有必要改进一下

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机收所有短信时显示被隐藏怎么办 div放图片多出的空白怎么办 我14岁射精让我记忆力差了怎么办 qq闪退聊天记录全没了怎么办 木瓜奇迹忘记升级过头转职了怎么办 孩子进入青春期什么坏事都干怎么办 母狗狗第一次来月经应该怎么办图 社保断了想补缴怎么办?这些要知道 换工作社保断了一个月怎么办 北京社保中间断了几个月怎么办 农保和社保都交了医保怎么办 如果交了社保结婚生孩子断了怎么办 南京社保中间断了几个月怎么办 mu大师等级技能点加点太慢怎么办 永恒纪元戒不是本职业套装石怎么办 全民奇迹忘记在哪个区了怎么办 全民奇迹安卓的忘记那个区了怎么办 大天使之剑h5所在服人少怎么办 买的裙子因为好看没有勇气穿怎么办 魅蓝s6锁屏密码忘了怎么办 u盘被占用不能安全弹出怎么办 洛克王国得到了魔攻巨蟹座怎么办 在育碧下载游戏下一半不下了怎么办 轩辕传奇单机版忘记哪个区了怎么办 登腾讯游戏动态密码啥意思怎么办 说了不该说的话别人不原谅怎么办 轩辕传奇手游金币用错了怎么办 神秘时代4法杖按键冲突怎么办 孕2个月发烧38度怎么办 不知道怀孕喝了止咳糖浆怎么办? 小孩刮头发的备皮刀割住手怎么办? 天梭手表里面的刻度掉了怎么办 国战天下手游帐号丢失怎么办 肺力咳合剂一次喝了50多了怎么办 头孢和藿香正气水一起吃了怎么办 小儿胃蛋自酶合剂吃多了怎么办 刚出生的婴儿很容易被惊醒怎么办 1个多月的宝宝小腿不直怎么办 20个月宝宝腿不直小腿外八怎么办 小孩手青枝骨骨折拆石膏还弯怎么办 宝宝喝柴胡注射剂有不良反应怎么办