Box2Dでドミノ Box2Dでドミノ hokori forked:0favorite:12lines:187license : MIT License modified : 2009-05-28 00:08:27 Embed Tweet //Box2Dでドミノ package { import Box2D.Collision.b2Bound; import Box2D.Dynamics.b2World; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef import Box2D.Dynamics.Joints.b2Joint; import Box2D.Dynamics.Joints.b2DistanceJoint; import Box2D.Dynamics.Joints.b2DistanceJointDef; import Box2D.Dynamics.Joints.b2JointEdge; import Box2D.Dynamics.Joints.b2RevoluteJointDef; import Box2D.Collision.b2AABB; import Box2D.Collision.Shapes.b2Shape; import Box2D.Collision.Shapes.b2CircleDef; import Box2D.Collision.Shapes.b2PolygonDef; import Box2D.Common.Math.b2Vec2; import flash.events.Event; import flash.display.Sprite; public class Sample06 extends Sprite { private const STAGE_W:int = 465; private const STAGE_H:int = 465; private var m_disp_grp:Sprite; public function Sample06() { //Box2D初期設定 this.B2Base(); //表示用まとめSprite m_disp_grp= new Sprite(); this.addChild(m_disp_grp); this.init(); this.addEventListener(Event.ENTER_FRAME, update, false, 0, true); } //いろいろ作成 private function init():void { var kabe_color:uint = 0x55BBFF; var tana_color:uint = 0x55BBFF; var domino_color:uint = 0xFFDD55; var ball_color:uint = 0x99FFBB; //上下左右の壁 this.makeBox(0, STAGE_H / 2, 0, STAGE_W, 10, kabe_color); this.makeBox(0, STAGE_H / 2, STAGE_H, STAGE_W, 10, kabe_color); this.makeBox(0, 0, STAGE_W / 2, 10, STAGE_H, kabe_color); this.makeBox(0, STAGE_W, STAGE_W / 2, 10, STAGE_H, kabe_color); //棚 var tana_w:int = 420; var tana_h:int = 10; var tana_space_w:int = 45; var tana_y_step:int = 465 / 5; for (var t:int = 1; t < 5 ; t++) { if((t % 2) == 0){ this.makeBox(0, STAGE_W / 2 + tana_space_w, t * tana_y_step, tana_w, tana_h, tana_color); }else{ this.makeBox(0, STAGE_W / 2 - tana_space_w, t * tana_y_step, tana_w, tana_h, tana_color); } } //ドミノ var domino_w:int = 5; var domino_h:int = 50; var domino_y_start:int = tana_y_step - domino_h / 2; var domino_x_start:int = 45; var domino_x_step:int = 40; var domino_x:int = 0; var domino_y:int = 0; var domino_num:int = 8; for (var d:int = 0; d < 5 ; d++) { domino_x = domino_x_start; if((d % 2) != 0){ domino_x = STAGE_W - (domino_num * domino_x_step) + tana_space_w - domino_x_start; } domino_y = domino_y_start + tana_y_step * d; for (var i:int = 0; i < domino_num; i++) { this.makeBox(1, domino_x, domino_y, domino_w, domino_h, domino_color); domino_x += domino_x_step; } } //途中のボール for (var b:int = 0; b < 4 ; b++) { var ball_x:Number = tana_space_w + domino_x_start; if((b % 2) == 0){ ball_x = STAGE_W - tana_space_w - domino_x_start; } var ball_y:Number = domino_y_start + tana_y_step * b; this.makeBall(1, ball_x, ball_y - 5, 20, ball_color); } //最初のボール this.makeBall(1, 40, 10, 20, 0x00FF33); //最後のぐるぐる var pole:b2Body = this.makeBox(1, STAGE_W - 75, tana_y_step * 5 - 45, 60, 5, 0xBBFF66); var j_def:b2RevoluteJointDef = new b2RevoluteJointDef; j_def.Initialize(m_b2_world.GetGroundBody(), pole, pole.GetPosition()); m_b2_world.CreateJoint(j_def); //跳ね返りの強いボール this.makeBall(1, STAGE_W - 75, tana_y_step * 5 - 45, 10, 0x0033FF, 3); } private function makeBox(density:Number, x:int, y:int, w:int, h:int, color:int):b2Body { var disp:Sprite = new Sprite(); disp.graphics.beginFill(color); disp.graphics.drawRect( - w / 2, - h / 2, w, h); disp.graphics.endFill(); var body:b2Body = this.makeB2BodyBox(w, h, x, y, rotation, density , 0.5, 0.5, disp, m_disp_grp); return body; } private function makeBall(density:Number, x:int, y:int, size:int, color:int, tobihane:Number = 1):b2Body { var disp:Sprite = new Sprite(); disp.graphics.beginFill(color); disp.graphics.drawCircle(0, 0, size / 2); disp.graphics.endFill(); var body:b2Body = this.makeB2BodyCircle(size, x, y, density , 0.5, tobihane, disp, m_disp_grp); return body; } private function update(e:Event):void{ var self:Sample06 = this; this.m_b2_world.Step(this.m_b2_timeStep, this.m_b2_iterations); for (var bb:b2Body = this.m_b2_world.m_bodyList; bb; bb = bb.m_next){ if (bb.m_userData is Sprite){ bb.m_userData.x = bb.GetPosition().x * m_b2_physcale; bb.m_userData.y = bb.GetPosition().y * m_b2_physcale; bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI); } } } //----------------------------------------------------------------------------------- //Box2D用まとめ //----------------------------------------------------------------------------------- protected var m_b2_world:b2World; protected var m_b2_physcale:Number = 10; protected var m_b2_iterations:int = 10; protected var m_b2_timeStep:Number = 24.0; public function B2Base(fps:int = 24, physcale:Number = 10, gravity:Number = 10):void{ this.m_b2_timeStep = 1.0 / fps; this.m_b2_physcale = physcale; this.createB2World(gravity); } private function createB2World(gravity:Number):void { var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set(-1000, -1000); worldAABB.upperBound.Set(1000, 1000); var vec_gravity:b2Vec2 = new b2Vec2(0.0, 10.0); var doSleep:Boolean = true; this.m_b2_world = new b2World(worldAABB, vec_gravity, doSleep); } protected function makeB2BodyBox(w:int, h:int, x:Number, y:Number, angle:Number, density:Number, friction:Number, restitution:Number, viewdata:Sprite = null, viewgroup:Sprite = null) :b2Body { var b2_boxdef:b2PolygonDef = this.createB2BoxDef(w, h, density, friction, restitution); var b2_bodydef:b2BodyDef = this.createB2BodyDef(x, y, angle, viewdata, viewgroup); var b2_body:b2Body = this.m_b2_world.CreateBody(b2_bodydef); b2_body.CreateShape(b2_boxdef); b2_body.SetMassFromShapes(); return b2_body; } protected function makeB2BodyCircle(radius:int, x:Number, y:Number, density:Number, friction:Number, restitution:Number, viewdata:Sprite = null, viewgroup:Sprite = null) :b2Body { var b2_boxdef:b2CircleDef = this.createB2CircleDef(radius, density, friction, restitution); var b2_bodydef:b2BodyDef = this.createB2BodyDef(x, y, 0, viewdata, viewgroup); var b2_body:b2Body = this.m_b2_world.CreateBody(b2_bodydef); b2_body.CreateShape(b2_boxdef); b2_body.SetMassFromShapes(); return b2_body; } private function createB2BoxDef(width:int, height:int, density:Number, friction:Number, restitution:Number):b2PolygonDef { var boxdef:b2PolygonDef = new b2PolygonDef(); boxdef.SetAsBox(width / 2 / this.m_b2_physcale, height/ 2 / this.m_b2_physcale); boxdef.density = density; boxdef.friction = friction; boxdef.restitution = restitution; return boxdef; } private function createB2CircleDef(diameter:int, density:Number, friction:Number, restitution:Number):b2CircleDef { var cdef:b2CircleDef = new b2CircleDef(); cdef.radius = diameter / 2 / this.m_b2_physcale; cdef.density = density; cdef.friction = friction; cdef.restitution = restitution; return cdef; } private function createB2BodyDef(x:Number, y:Number, angle:Number, viewdata:Sprite = null, viewgroup:Sprite = null):b2BodyDef { var bodydef:b2BodyDef = new b2BodyDef(); bodydef.position.Set(x / this.m_b2_physcale, y / this.m_b2_physcale); bodydef.angle = angle * Math.PI / 180; bodydef.allowSleep = true; if(viewdata != null){ bodydef.userData = viewdata; bodydef.userData.width = viewdata.width; bodydef.userData.height = viewdata.height; if(viewgroup != null){ viewgroup.addChild(bodydef.userData); } } return bodydef; } protected function createB2Vec(x:Number, y:Number):b2Vec2 { var vec:b2Vec2 = new b2Vec2(x / this.m_b2_physcale, y / this.m_b2_physcale); return vec; } } } Code Fullscreen Preview Fullscreen matacat ongaeshi ketatony nilab fantasista Giggle : Box2D fokhei : box2d ish_xxxx : box2dおもしろい enjoy_tpm : すごすぎる。 nyamogera : びっくり! soundkitchen.. : ざわ最後が衝撃的 clockmaker : 最後が衝撃 Box2D ざわ density friction angle b2BodyDef b2Vec2 b2PolygonDef b2RevoluteJointDef userData allowSleep Initialize restitution Set SetAsBox rotation height width Math.PI addEventListener addChild Boolean