Created
March 7, 2011 03:40
-
-
Save noonat/858031 to your computer and use it in GitHub Desktop.
Nape addCbPreBegin bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package { | |
import flash.Boot; | |
import flash.display.Sprite; | |
import flash.display.StageAlign; | |
import flash.display.StageQuality; | |
import flash.display.StageScaleMode; | |
import flash.events.Event; | |
import nape.callbacks.Callback; | |
import nape.callbacks.CbType; | |
import nape.dynamics.Arbiter; | |
import nape.geom.AABB; | |
import nape.geom.Vec2; | |
import nape.phys.Body; | |
import nape.phys.Material; | |
import nape.phys.Properties; | |
import nape.shape.Circle; | |
import nape.space.Space; | |
import nape.space.UniformSleepSpace; | |
import nape.util.Tools; | |
// Bug repro for http://deltaluca.me.uk/forum/index.php/t/140/a66603e8954afca0313f04df0a532584/ | |
// Flock should not collide with each other, but should collide with boxes. | |
[SWF(width="800", height="600", backgroundColor="#000000")] | |
public class Test extends Sprite { | |
static protected const BOX_TYPE:int = CbType.get(); | |
static protected const FLOCK_TYPE:int = CbType.get(); | |
static protected const FOLLOW_DISTANCE:Number = 16; | |
static protected const SEPARATION_DISTANCE:Number = 16; | |
protected var _flock:Array = []; | |
protected var _flockNeighbors:Array = []; | |
protected var _space:Space; | |
protected var _width:Number; | |
protected var _height:Number; | |
function Test() { | |
new Boot(); | |
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); | |
} | |
// Add a bunch of random boxes in the middle. These are static objects | |
// that the flock should collide with. | |
protected function addBoxes():void { | |
for (var i:int = 0; i < 16; ++i) { | |
var w:Number = 16 + Math.random() * 16; | |
var h:Number = 16 + Math.random() * 16; | |
var sprite:Sprite = new Sprite; | |
sprite.graphics.beginFill(0x666666); | |
sprite.graphics.drawRect(-w / 2, -h / 2, w, h); | |
sprite.graphics.endFill(); | |
addChild(sprite); | |
var x:Number = Math.random() * _width; | |
var y:Number = (_height / 2) - 32 + Math.random() * 64; | |
var body:Body = Tools.createBox( | |
x, y, w, h, 0, 0, 0, false, Material.Steel, 0xffffffff, 0); | |
body.assignGraphic(sprite); | |
body.cbType = BOX_TYPE; | |
body.calcProperties(); | |
body.update(); | |
body.stopAll() | |
_space.addObject(body); | |
} | |
} | |
// Add some bodies for our flock. Members of the flock should not | |
// collide with one another, but use a sensor to detect their neighbors. | |
protected function addFlock():void { | |
var properties:Properties = new Properties(0.3, 0.3); | |
for (var i:uint = 0; i < 32; ++i) { | |
var sprite:Sprite = new Sprite; | |
sprite.graphics.lineStyle(2, 0xffffff); | |
sprite.graphics.drawCircle(0, 0, 3); | |
addChild(sprite); | |
var colliderShape:Circle = new Circle( | |
4, new Vec2(0, 0), Material.Wood, 0xffffffff, 0); | |
var neighborShape:Circle = new Circle( | |
32, new Vec2(0, 0), Material.Wood, 0, 1); | |
var x:Number = Math.random() * _width; | |
var y:Number = Math.random() * _height; | |
var body:Body = new Body(x, y, properties); | |
body.assignGraphic(sprite); | |
body.addShape(colliderShape); | |
body.addShape(neighborShape); | |
body.cbType = FLOCK_TYPE; | |
body.data = i; | |
body.calcProperties(); | |
body.update(); | |
_flock[i] = body; | |
_flockNeighbors[i] = []; | |
_space.addObject(body); | |
} | |
} | |
// Add a body to another's neighbor list. | |
protected function addFlockNeighbor(index1:uint, index2:uint):void { | |
var neighbor:Body = _flock[index2]; | |
var neighborIndex:int = _flockNeighbors[index1].indexOf(neighbor); | |
if (neighborIndex === -1) { | |
_flockNeighbors[index1].push(neighbor); | |
} | |
} | |
// Remove a body from another's neighbor list. | |
protected function removeFlockNeighbor(index1:uint, index2:uint):void { | |
var neighbor:Body = _flock[index2]; | |
var neighborIndex:int = _flockNeighbors[index1].indexOf(neighbor); | |
if (neighborIndex !== -1) { | |
_flockNeighbors[index1].splice(neighborIndex, 1); | |
} | |
} | |
protected function onAddedToStage(event:Event):void { | |
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); | |
addEventListener(Event.ENTER_FRAME, onEnterFrame); | |
stage.frameRate = 60; | |
stage.align = StageAlign.TOP_LEFT; | |
stage.quality = StageQuality.BEST; | |
stage.scaleMode = StageScaleMode.NO_SCALE; | |
_width = stage.stageWidth; | |
_height = stage.stageHeight; | |
graphics.beginFill(0); | |
graphics.drawRect(0, 0, _width, _height); | |
graphics.endFill(); | |
// Setup the space | |
_space = new UniformSleepSpace(new AABB(-_width, -_height, _width * 2, _height * 2), 16); | |
addBoxes(); | |
addFlock(); | |
_space.addCbPreBegin(FLOCK_TYPE, FLOCK_TYPE, function(a:Arbiter):int { | |
trace('Ignoring flock collision'); | |
return Callback.IGNORE; | |
}); | |
_space.addCbSenseBegin(FLOCK_TYPE, FLOCK_TYPE); | |
_space.addCbSenseEnd(FLOCK_TYPE, FLOCK_TYPE); | |
} | |
protected function onEnterFrame(event:Event):void { | |
_space.step(1 / 60, 4, 4); | |
// Update the neighbor lists. | |
while (!_space.callbacks.empty()) { | |
var cb:Callback = _space.callbacks.front(); | |
switch (cb.type) { | |
case Callback.SENSE_BEGIN: | |
if (cb.obj_arb) { | |
addFlockNeighbor(cb.obj_arb.p1.data, cb.obj_arb.p2.data); | |
} | |
break; | |
case Callback.SENSE_END: | |
if (cb.obj_arb) { | |
removeFlockNeighbor(cb.obj_arb.p1.data, cb.obj_arb.p2.data); | |
} | |
break; | |
} | |
_space.callbacks.pop(); | |
} | |
graphics.clear(); | |
graphics.beginFill(0); | |
graphics.drawRect(0, 0, _width, _height); | |
graphics.endFill(); | |
graphics.lineStyle(1, 0xff0000); | |
// Update the body velocities. | |
for (var i:uint = 0; i < _flock.length; ++i) { | |
var body:Body = _flock[i]; | |
var forceX:Number = stage.mouseX - body.px; | |
var forceY:Number = stage.mouseY - body.py; | |
var distance:Number = Math.sqrt(forceX * forceX + forceY * forceY); | |
if (distance > 0) { | |
forceX /= distance; | |
forceY /= distance; | |
} | |
var force:Number = distance / FOLLOW_DISTANCE; | |
if (force > 1) { | |
force = 1; | |
} | |
forceX *= force; | |
forceY *= force; | |
if (!body.live) _space.wakeObject(body); | |
body.applyRelativeForce(forceX * 1e6, forceY * 1e6, 0, 0); | |
for each (var neighbor:Body in _flockNeighbors[i]) { | |
graphics.moveTo(body.px, body.py); | |
graphics.lineTo(neighbor.px, neighbor.py); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment