forked from: [Box2D]ダンボー遊び!
根本的に書き直した。(あまり意味はない)
* ドラッグで動かせるようにした。
* ダンボーを増やした。
* 何となく手をブラブラ(体から取れそう)
*
* 倒れても、自動で立ち上がるようになっています。(なんかカワイイ)
* たまに倒れたままの事がある。
*
* ダンボー同士がぶつかり合うとケンカになります。注意を。
* ケンカをするとまれに足が骨折します。(足をつかむと完治します。)
*
* ボール遊びが好きなようで、ボールを与えると投げて遊びます。
*
*
* 左にスライドする現象はとりあえずOKかな。
*
// forked from pboy2000's forked from: [Box2D]ダンボー遊び!forked from :(略)ダンボーを作った
// forked from paq's [Box2D]ダンボー遊び!forked from :(略)ダンボーを作った
// forked from rsakane's Box2Dジョイントの練習でダンボーを作った(何故か左にスライド)
/*
* 根本的に書き直した。(あまり意味はない)
* ドラッグで動かせるようにした。
* ダンボーを増やした。
* 何となく手をブラブラ(体から取れそう)
*
* 倒れても、自動で立ち上がるようになっています。(なんかカワイイ)
* たまに倒れたままの事がある。
*
* ダンボー同士がぶつかり合うとケンカになります。注意を。
* ケンカをするとまれに足が骨折します。(足をつかむと完治します。)
*
* ボール遊びが好きなようで、ボールを与えると投げて遊びます。
*
*
* 左にスライドする現象はとりあえずOKかな。
*
*/
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Dynamics.Joints.*;
import Box2D.Dynamics.Contacts.*;
import Box2D.Common.*;
import Box2D.Common.Math.*;
[SWF(backgroundColor="0x5060c0", frameRate=60)]
public class Main extends Sprite {
public var m_sprite:Sprite;
public var m_world:b2World;
public var m_physScale:Number = 30.0;
public var m_iterations:int = 10;
public var m_timeStep:Number = 1.0/60.0;
public var m_mouseJoint:b2MouseJoint;
static public var mouseXWorldPhys:Number;
static public var mouseYWorldPhys:Number;
static public var mouseXWorld:Number;
static public var mouseYWorld:Number;
private var mousePVec:b2Vec2 = new b2Vec2();
private var mouseDown:Boolean = false;
private var ball:b2Body;
public function Main():void {
//コンテナ
m_sprite = new Sprite();
addChild(m_sprite);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.CLICK, onMouseUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
stage.addEventListener(Event.MOUSE_LEAVE, onMouseLeave);
addEventListener(Event.ENTER_FRAME, update, false, 0, true);
//WORLD
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-1000.0, -1000.0);
worldAABB.upperBound.Set(1000.0, 1000.0);
var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);
var doSleep:Boolean = true;
m_world = new b2World(worldAABB, gravity, doSleep);
//デバック用
var dbgDraw:b2DebugDraw= new b2DebugDraw();
var dbgSprite:Sprite= new Sprite();
m_sprite.addChild(dbgSprite);
dbgDraw.m_sprite= dbgSprite;
dbgDraw.m_drawScale= 30.0;
dbgDraw.m_fillAlpha = 0.3;
dbgDraw.m_lineThickness= 1.0;
dbgDraw.m_alpha=1.0;
dbgDraw.m_xformScale=1.0;
dbgDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
m_world.SetDebugDraw(dbgDraw);
createDunbor(232/m_physScale, 1.1);
createDunbor(232/m_physScale, 3.5);
createDunbor(232/m_physScale, 5.1);
ball = createOtherObject();
createWall();
}
private function createOtherObject():b2Body {
var circ:b2CircleDef = new b2CircleDef();
var bd:b2BodyDef = new b2BodyDef();
var body:b2Body;
circ.radius = 35 / m_physScale;
circ.density = 0.125;
circ.friction = 0.7;
circ.restitution = 0.5;
bd = new b2BodyDef();
bd.position.Set(50 / m_physScale, 100 / m_physScale);
var circbd:b2Body = m_world.CreateBody(bd);
circbd.CreateShape(circ);
circbd.SetMassFromShapes();
return circbd;
}
private function createBox(userData:Sprite, x:Number, y:Number, angle:Number, width:Number, height:Number,
density:Number, friction:Number, restitution:Number):b2Body {
var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.position.Set(x, y);
bodyDef.angle = angle;
bodyDef.userData = userData;
if (userData) addChild(userData);
var polygon:b2PolygonDef = new b2PolygonDef();
polygon.SetAsBox(width, height);
polygon.density = density;
polygon.friction = friction;
polygon.restitution = restitution;
var body:b2Body = m_world.CreateBody(bodyDef);
body.CreateShape(polygon);
body.SetMassFromShapes();
return body;
}
private function createJoint(body1:b2Body, x1:Number, y1:Number,
body2:b2Body, x2:Number, y2:Number):b2Joint {
var joint:b2DistanceJointDef = new b2DistanceJointDef();
joint.Initialize(body1, body2, new b2Vec2(x1, y1), new b2Vec2(x2, y2));
return m_world.CreateJoint(joint);
}
private function createDunbor(x:Number,y:Number):void {
// 頭
var body1:b2Body = createBox(new Head(), x, y, 0, 0.85, 0.52, 0.15, 0.4, 2);
// 体
var body2:b2Body = createBox(new Body(), x, y+1.1, 0, 0.55, 0.61, 0.98, 0.4, 5);
// 左足
var body3:b2Body = createBox(null, x-0.3, y+2.1, 0, 0.2, 0.33, 10, 0.4, 0.3);
// 右足
var body4:b2Body = createBox(null, x+0.3, y+2.1, 0, 0.2, 0.33, 10, 0.4, 0.3);
// 左手
var body5:b2Body = createBox(null, x-0.8, y+0.85, 30 * Math.PI / 180, 0.2, 0.4, 1, 0.6, 0.3);
// 右手
var body6:b2Body = createBox(null, x+0.8, y+0.85, 330 * Math.PI / 180, 0.2, 0.4, 1, 0.6, 0.3);
// 頭と体をジョイント
createJoint(body1, x-0.4, y+0.5, body2, x-0.4, y+0.51);
createJoint(body1, x+0.4, y+0.5, body2, x+0.4, y+0.51);
// 体と左足をジョイント
createJoint(body2, x-0.5, y+1.7, body3, x-0.5, y+1.71);
createJoint(body2, x-0.1, y+1.7, body3, x-0.1, y+1.71);
// 体と右足をジョイント
createJoint(body2, x+0.5, y+1.7, body4, x+0.5, y+1.71);
createJoint(body2, x+0.1, y+1.7, body4, x+0.1, y+1.71);
// 体と左手をジョイント
createJoint(body2, x-0.51, y+0.5, body5, x-0.51, y+0.51);
// 体と右手をジョイント
createJoint(body2, x+0.51, y+0.5, body6, x+0.51, y+0.51);
}
private function createWall():void
{
var wallObject:b2PolygonDef = new b2PolygonDef();
wallObject.density = 0.0;
var wallDef:b2BodyDef = new b2BodyDef();
var wallBody:b2Body;
//Left
wallDef.position.Set(-6 / m_physScale, 465/2 / m_physScale);
wallObject.SetAsBox(10/2 / m_physScale, 465/2 / m_physScale);
wallBody = m_world.CreateBody(wallDef);
wallBody.CreateShape(wallObject);
wallBody.SetMassFromShapes();
//Right
wallDef.position.Set((465+14/2) / m_physScale, 465/2 / m_physScale);
wallObject.SetAsBox(10/2 / m_physScale, 465/2 / m_physScale);
wallBody = m_world.CreateBody(wallDef);
wallBody.CreateShape(wallObject);
wallBody.SetMassFromShapes();
//Top
wallDef.position.Set(465/2 / m_physScale, -7 / m_physScale);
wallObject.SetAsBox(465/2 / m_physScale, 10/2 / m_physScale);
wallBody = m_world.CreateBody(wallDef);
wallBody.CreateShape(wallObject);
wallBody.SetMassFromShapes();
//Bottom
wallDef.position.Set(465/2 / m_physScale, (465-10/2) / m_physScale);
wallObject.SetAsBox(465/2 / m_physScale, 10/2 / m_physScale);
wallBody = m_world.CreateBody(wallDef);
wallBody.CreateShape(wallObject);
wallBody.SetMassFromShapes();
}
private function update(event:Event):void {
m_world.Step(m_timeStep, m_iterations);
m_sprite.graphics.clear();
UpdateMouseWorld();
MouseDrag();
for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next) {
if (bb.m_userData is Sprite) {
bb.m_userData.x = bb.GetPosition().x * 30;
bb.m_userData.y = bb.GetPosition().y * 30;
bb.m_userData.rotation = bb.GetAngle() * 180 / Math.PI;
}
var a:Number = Math.abs(bb.GetAngle() * 180 / Math.PI) % 360;
if (a <= 30) {
var dx:Number = ball.GetPosition().x - bb.GetPosition().x;
var dy:Number = ball.GetPosition().y - bb.GetPosition().y;
bb.ApplyForce(new b2Vec2(dx * 2, dy * 2), bb.GetPosition());
}
}
// joints
for (var jj:b2Joint = m_world.m_jointList; jj; jj = jj.m_next){
DrawJoint(jj);
}
}
private function onMouseDown(event:MouseEvent):void
{
mouseDown = true;
}
private function onMouseUp(event:MouseEvent):void
{
mouseDown = false;
}
private function onMouseMove(event:MouseEvent):void
{
if (mouseDown != event.buttonDown){
mouseDown = event.buttonDown;
}
}
public function onMouseLeave(e:Event):void
{
mouseDown = false;
MouseDrag();
}
//======================
// Update mouseWorld
//======================
public function UpdateMouseWorld():void {
mouseXWorldPhys = (mouseX)/m_physScale;
mouseYWorldPhys = (mouseY)/m_physScale;
mouseXWorld = (mouseX);
mouseYWorld = (mouseY);
}
//======================
// Mouse Drag
//======================
public function MouseDrag():void {
// mouse press
if (mouseDown && !m_mouseJoint){
var body:b2Body = GetBodyAtMouse();
if (body)
{
var md:b2MouseJointDef = new b2MouseJointDef();
md.body1 = m_world.GetGroundBody();
md.body2 = body;
md.target.Set(mouseXWorldPhys, mouseYWorldPhys);
md.maxForce = 300.0 * body.GetMass();
md.timeStep = m_timeStep;
m_mouseJoint = m_world.CreateJoint(md) as b2MouseJoint;
body.WakeUp();
}
}
// mouse release
if (!mouseDown){
if (m_mouseJoint)
{
m_world.DestroyJoint(m_mouseJoint);
m_mouseJoint = null;
}
}
// mouse move
if (m_mouseJoint)
{
var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
m_mouseJoint.SetTarget(p2);
}
}
//======================
// GetBodyAtMouse
//======================
public function GetBodyAtMouse(includeStatic:Boolean = false):b2Body {
// Make a small box.
mousePVec.Set(mouseXWorldPhys, mouseYWorldPhys);
var aabb:b2AABB = new b2AABB();
aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001);
aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001);
// Query the world for overlapping shapes.
var k_maxCount:int = 10;
var shapes:Array = new Array();
var count:int = m_world.Query(aabb, shapes, k_maxCount);
var body:b2Body = null;
for (var i:int = 0; i < count; ++i)
{
if (shapes[i].GetBody().IsStatic() == false || includeStatic)
{
var tShape:b2Shape = shapes[i] as b2Shape;
var inside:Boolean = tShape.TestPoint(tShape.GetBody().GetXForm(), mousePVec);
if (inside)
{
body = tShape.GetBody();
break;
}
}
}
return body;
}
//======================
// Draw Joint
//======================
public function DrawJoint(joint:b2Joint):void {
var b1:b2Body = joint.m_body1;
var b2:b2Body = joint.m_body2;
var x1:b2Vec2 = b1.m_linearVelocity;
var x2:b2Vec2 = b2.m_linearVelocity;
var p1:b2Vec2 = joint.GetAnchor1();
var p2:b2Vec2 = joint.GetAnchor2();
m_sprite.graphics.lineStyle(1,0x44aaff,1/1);
switch (joint.m_type) {
case b2Joint.e_distanceJoint:
case b2Joint.e_mouseJoint:
m_sprite.graphics.moveTo(p1.x * m_physScale, p1.y * m_physScale);
m_sprite.graphics.lineTo(p2.x * m_physScale, p2.y * m_physScale);
break;
case b2Joint.e_pulleyJoint:
var pulley:b2PulleyJoint = joint as b2PulleyJoint;
var s1:b2Vec2 = pulley.m_groundAnchor1;
var s2:b2Vec2 = pulley.m_groundAnchor2;
m_sprite.graphics.moveTo(s1.x * m_physScale, s1.y * m_physScale);
m_sprite.graphics.lineTo(p1.x * m_physScale, p1.y * m_physScale);
m_sprite.graphics.moveTo(s2.x * m_physScale, s2.y * m_physScale);
m_sprite.graphics.lineTo(p2.x * m_physScale, p2.y * m_physScale);
break;
default:
if (b1 == m_world.m_groundBody){
m_sprite.graphics.moveTo(p1.x * m_physScale, p1.y * m_physScale);
m_sprite.graphics.lineTo(x2.x * m_physScale, x2.y * m_physScale);
}
else if (b2 == m_world.m_groundBody){
m_sprite.graphics.moveTo(p1.x * m_physScale, p1.y * m_physScale);
m_sprite.graphics.lineTo(x1.x * m_physScale, x1.y * m_physScale);
}
else{
m_sprite.graphics.moveTo(x1.x * m_physScale, x1.y * m_physScale);
m_sprite.graphics.lineTo(p1.x * m_physScale, p1.y * m_physScale);
m_sprite.graphics.lineTo(x2.x * m_physScale, x2.y * m_physScale);
m_sprite.graphics.lineTo(p2.x * m_physScale, p2.y * m_physScale);
}
}
}
}
}
import flash.display.Sprite;
class Head extends Sprite {
public function Head() {
graphics.beginFill(0x000000);
graphics.drawCircle(-30, -10, 10);
graphics.drawCircle( 30, -10, 10);
graphics.beginFill(0x802030);
graphics.moveTo( 0, 8);
graphics.lineTo(-18, 5);
graphics.lineTo( 0, 25);
graphics.lineTo( 18, 5);
graphics.endFill();
scaleX = scaleY = 0.4;
}
}
class Body extends Sprite {
public function Body() {
graphics.beginFill(0x777777);
graphics.drawCircle(30, -45, 8);
graphics.endFill();
graphics.beginFill(0x000000);
graphics.drawRect(26, -45, 8, 2);
graphics.endFill();
scaleX = scaleY = 0.333;
}
}