大规模网格形碰撞检测
来源:互联网 发布:数据库维护需要什么 编辑:程序博客网 时间: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之后开始有些掉帧,感觉哪里还是有必要改进一下
- 大规模网格形碰撞检测
- Ogre碰撞检测,精确到物体网格三角面
- [OpenGL] 二维游戏:网格布局与碰撞检测
- Unity3D 网格碰撞器Mesh Collider之间和原型碰撞器(Box Collider等)的碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- TeeChart7 Pro中FastLine最多可添加的点数
- 游戏设计的秘密
- dig源码分析
- 表格的样式,留着慢慢看吧
- 比酒量问题与二叉树搜索和路径问题
- 大规模网格形碰撞检测
- 微软正式宣布 Windows Phone 7.8 功能及上市时间
- 关于RGB、YUY2、YUYV、YVYU、UYVY、AYUV DirectShow中常见的RGB/YUV格式
- 转载:悲情英雄40年:AMD的兴起、衰落、未来
- 雅虎 CEO 梅耶尔一句话23个单词彻底撕碎了 RIM
- sql语句字符串处理大全
- 微软下一代操作系统代号 Blue 或免费提供
- freebsd 安装mysql5.1
- Win8首月卖了4千万份 销售超Win 7