[PushButton Engine] Box2D
LEFT or RIGHT :: move
SPACE or UP :: jump
< thanks >
http://www.xllusion.net/ed/2010/04/17/pushbutton-box2d-tutorial/
/**
* Copyright paq ( http://wonderfl.net/user/paq )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/kmY2
*/
package
{
import com.pblabs.box2D.Box2DManagerComponent;
import com.pblabs.box2D.Box2DSpatialComponent;
import com.pblabs.box2D.CircleCollisionShape;
import com.pblabs.box2D.PolygonCollisionShape;
import com.pblabs.engine.core.InputMap;
import com.pblabs.engine.core.ObjectType;
import com.pblabs.engine.entity.IEntity;
import com.pblabs.engine.entity.PropertyReference;
import com.pblabs.engine.PBE;
import com.pblabs.rendering2D.SimpleShapeRenderer;
import com.pblabs.rendering2D.ui.SceneView;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
/**
* PushButton Engine でBox2D
* まんまこれです。 http://www.xllusion.net/ed/2010/04/17/pushbutton-box2d-tutorial/
* @author paq89
*/
[SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="60")]
public class Main extends Sprite
{
private var _manager:Box2DManagerComponent;
// コンストラクタ
public function Main():void
{
PBE.startup(this);
// シーンを作ります
var sceneView:SceneView = new SceneView();
sceneView.width = stage.stageWidth;
sceneView.height = stage.stageHeight;
PBE.initializeScene(sceneView);
// マネージャを作ります
_manager = new Box2DManagerComponent();
var entity:IEntity = PBE.allocateEntity();
entity.addComponent(_manager, "Manager");
entity.initialize("SpatialManager");
// プレイヤーを作る
createPlayer();
// 壁を作る
createWall(0, 120, 300, 30);
createWall(70, 70, 100, 30);
createWall(-70, 0, 70, 30);
createWall(0, -70, 40, 30);
createWall(120, -90, 40, 30);
}
private function createPlayer():void
{
// プレイヤーを作ります
var spatial:Box2DSpatialComponent = new Box2DSpatialComponent();
spatial.spatialManager = _manager;
spatial.canMove = true; // 移動を許可する
spatial.canRotate = true; // 回転を許可する
spatial.canSleep = false; // 寝るな寝るんじゃない!
spatial.position = new Point(0, 0); // プレイヤーの位置 0,0で中心
spatial.size = new Point(40, 40); // プレイヤーの大きさ
// コリジョンタイプを指定
spatial.collisionType = new ObjectType("Player");
// コリジョンタイプが壁の場合はぶつかる
spatial.collidesWithTypes = new ObjectType("Wall");
// Box2D用のシェイプを作ります
var shape:CircleCollisionShape = new CircleCollisionShape();
shape.radius = 1.0;
shape.density = 1;
// 先ほど作ったシェイプをプレイヤーを紐付ける
spatial.collisionShapes = [];
spatial.collisionShapes.push(shape);
// レンダラーを作ります
var renderer:SimpleShapeRenderer = new SimpleShapeRenderer();
renderer.fillColor = 0xDDDDDD; // 色
renderer.isCircle = true; // 描画するものは丸い
renderer.lineColor = 0x000000; // 線の色
renderer.scene = PBE.scene; // シーンを指定
// プロパティを紐付ける
renderer.positionProperty = new PropertyReference("@Spatial.position");
renderer.rotationProperty = new PropertyReference("@Spatial.rotation");
renderer.sizeProperty = new PropertyReference("@Spatial.size");
// キーボード入力
var gameInput:GameInput = new GameInput();
gameInput.inputMap = new InputMap();
gameInput.velocityReference = new PropertyReference("@Spatial.linearVelocity")
// エンティティを作成
var entity:IEntity = PBE.allocateEntity();
entity.addComponent(spatial, "Spatial");
entity.addComponent(gameInput, "Input");
entity.addComponent(renderer, "Render");
entity.initialize("Player");
}
private function createWall(x:Number, y:Number, width:Number, height:Number):void
{
// 壁を作ります
var spatial:Box2DSpatialComponent = new Box2DSpatialComponent();
spatial.spatialManager = _manager;
spatial.canMove = false; // 移動を許可しない
spatial.canRotate = false; // 回転を許可しない
spatial.position = new Point(x, y); // 位置
spatial.size = new Point(width, height); // 大きさ
// コリジョンタイプを指定
spatial.collisionType = new ObjectType("Wall");
// コリジョンタイプがプレイヤーの場合はぶつかる
spatial.collidesWithTypes = new ObjectType("Player");
// Box2D用のシェイプを作ります
var shape:PolygonCollisionShape = new PolygonCollisionShape();
shape.vertices = [new Point( -1, -1), new Point(1, -1), new Point(1, 1), new Point( -1, 1)];
shape.density = 1;
// 先ほど作ったシェイプをプレイヤーを紐付ける
spatial.collisionShapes = [];
spatial.collisionShapes.push(shape);
// レンダラーを作ります
var renderer:SimpleShapeRenderer = new SimpleShapeRenderer();
renderer.fillColor = 0xDDDDDD; // 色
renderer.isCircle = false; // 描画するものは丸くない
renderer.isSquare = true; // 描画するものは四角い
renderer.lineColor = 0x000000; // 線の色
renderer.scene = PBE.scene; // シーンを指定
// プロパティを紐付ける
renderer.positionProperty = new PropertyReference("@Spatial.position");
renderer.rotationProperty = new PropertyReference("@Spatial.rotation");
renderer.sizeProperty = new PropertyReference("@Spatial.size");
// エンティティを作成
var entity:IEntity = PBE.allocateEntity();
entity.addComponent(spatial, "Spatial");
entity.addComponent(renderer, "Render");
entity.initialize("Wall");
}
}
}
import com.pblabs.box2D.CollisionEvent;
import com.pblabs.engine.components.TickedComponent;
import com.pblabs.engine.core.InputKey;
import com.pblabs.engine.core.InputMap;
import com.pblabs.engine.entity.PropertyReference;
import com.pblabs.engine.PBE;
import flash.geom.Point;
class GameInput extends TickedComponent
{
public var velocityReference:PropertyReference;
private var _inputMap:InputMap;
private var _left:Number = 0;
private var _right:Number = 0
private var _onGround:int = 0
private var _jump:Number = 0;
public function get inputMap():InputMap { return _inputMap; }
public function set inputMap(value:InputMap):void
{
_inputMap = value;
if (_inputMap != null)
{
_inputMap.mapKeyToHandler(InputKey.LEFT, onLeft);
_inputMap.mapKeyToHandler(InputKey.RIGHT, onRight);
_inputMap.mapKeyToHandler(InputKey.SPACE, onJump);
_inputMap.mapKeyToHandler(InputKey.UP, onJump);
}
}
override public function onTick(tickRate:Number):void
{
var move:Number = _right - _left;
var velocity:Point = owner.getProperty(velocityReference);
velocity.x = move * 100
if (_jump > 0)
{
velocity.y -= 200;
_jump = 0;
}
owner.setProperty(velocityReference, velocity);
}
override protected function onAdd():void
{
super.onAdd();
owner.eventDispatcher.addEventListener(CollisionEvent.COLLISION_EVENT, onCollision);
owner.eventDispatcher.addEventListener(CollisionEvent.COLLISION_STOPPED_EVENT, onCollisionEnd);
}
override protected function onRemove():void
{
super.onRemove();
owner.eventDispatcher.removeEventListener(CollisionEvent.COLLISION_EVENT, onCollision);
owner.eventDispatcher.removeEventListener(CollisionEvent.COLLISION_STOPPED_EVENT, onCollisionEnd);
}
private function onLeft(value:Number):void
{
_left = value;
}
private function onRight(value:Number):void
{
_right = value;
}
private function onJump(value:Number):void
{
if (_onGround > 0) _jump = value;
}
private function onCollision(e:CollisionEvent):void
{
if (PBE.objectTypeManager.doesTypeOverlap(e.collidee.collisionType, "Wall"))
{
if (e.normal.y > 0.7) _onGround++;
}
if (PBE.objectTypeManager.doesTypeOverlap(e.collider.collisionType, "Wall"))
{
if (e.normal.y < -0.7) _onGround++;
}
}
private function onCollisionEnd(e:CollisionEvent):void
{
if (PBE.objectTypeManager.doesTypeOverlap(e.collidee.collisionType, "Wall"))
{
if (e.normal.y > 0.7) _onGround--;
}
if (PBE.objectTypeManager.doesTypeOverlap(e.collider.collisionType, "Wall"))
{
if (e.normal.y < -0.7) _onGround--;
}
}
}