Some awesome games use a 2D physics engine to handle collision but display a 3D View. I’ve worked since a long time on a 2D engine, in which I would like to add this 3D View. However I’m not as familiar with 3D as I should. I know that we use the project / unproject to “exchange” coordinnates between 2D and 3D space, but I’m a bit lost.
So far I’ve been able to display Box2D debug view and my 3D objects at the same position, but if I add a camera to follow my object, I can’t have my 3D objects position identical to my Box2D debug view objects.
Here is my game state :
package {
import com.citrusengine.objects.platformer.box2d.Coin;
import away3d.debug.AwayStats;
import away3d.entities.Mesh;
import away3d.materials.ColorMaterial;
import away3d.primitives.CubeGeometry;
import com.citrusengine.core.State;
import com.citrusengine.math.MathVector;
import com.citrusengine.objects.platformer.box2d.Hero;
import com.citrusengine.objects.platformer.box2d.Platform;
import com.citrusengine.physics.Box2D;
import com.citrusengine.view.CitrusView;
import com.citrusengine.view.away3dview.Away3DView;
import flash.geom.Rectangle;
public class Away3DGameState extends State {
public function Away3DGameState() {
super();
}
override public function initialize():void {
super.initialize();
addChild(new AwayStats((view as Away3DView).viewRoot));
var cube1:Mesh = new Mesh(new CubeGeometry(100, 100, 0), new ColorMaterial(0x0000FF));
var cube2:Mesh = new Mesh(new CubeGeometry(30, 30, 0), new ColorMaterial(0xFFFF00));
var cube3:Mesh = new Mesh(new CubeGeometry(3000, 10, 0), new ColorMaterial(0xFFFFFF));
var box2D:Box2D = new Box2D("box2D");
box2D.visible = true;
add(box2D);
var platform:Platform = new Platform("platB", {x:stage.stageWidth / 2, y:stage.stageHeight - 30, width:3000, height:10, view:cube3});
add(platform);
var hero:Hero = new Hero("hero", {x:150, y:50, width:100, height:100, view:cube1});
add(hero);
var coin:Coin = new Coin("coin", {x:300, y:150, width:30, height:30, view:cube2});
add(coin);
view.setupCamera(hero, new MathVector(320, 240), new Rectangle(0, 0, 1550, 450), new MathVector(.25, .05));
}
// Make sure and call this override to specify Away3D view.
override protected function createView():CitrusView {
return new Away3DView(this);
}
}
}
My Away3D view :
package com.citrusengine.view.away3dview {
import away3d.cameras.Camera3D;
import away3d.cameras.lenses.OrthographicLens;
import away3d.containers.ObjectContainer3D;
import away3d.containers.Scene3D;
import away3d.containers.View3D;
import away3d.controllers.HoverController;
import com.citrusengine.view.CitrusView;
import com.citrusengine.view.ISpriteView;
import com.citrusengine.view.spriteview.Box2DDebugArt;
import flash.display.MovieClip;
import flash.display.Sprite;
public class Away3DView extends CitrusView {
private var _viewRoot:View3D;
private var _scene:Scene3D;
private var _camera:Camera3D;
private var _cameraController:HoverController;
private var _container:ObjectContainer3D;
public function Away3DView(root:Sprite) {
super(root, ISpriteView);
_scene = new Scene3D();
_container = new ObjectContainer3D();
_scene.addChild(_container);
_camera = new Camera3D();
_camera.lens = new OrthographicLens();
_viewRoot = new View3D(_scene, _camera);
_viewRoot.antiAlias = 4;
root.addChild(_viewRoot);
//_cameraController = new HoverController(_camera, null, 180, 0);
}
public function get viewRoot():View3D {
return _viewRoot;
}
public function get container():ObjectContainer3D {
return _container;
}
/**
* @inherit
*/
override public function update():void {
super.update();
_viewRoot.render();
//_container.rotationY++;
//_container.rotationZ++;
//_camera.lookAt(_container.position);
// Update Camera
if (cameraTarget) {
var diffX:Number = (-cameraTarget.x + cameraOffset.x) - _container.position.x;
var diffY:Number = (-cameraTarget.y + cameraOffset.y) - _container.position.y;
var velocityX:Number = diffX * cameraEasing.x;
var velocityY:Number = diffY * cameraEasing.y;
_container.x += velocityX;
_container.y += velocityY;
// Constrain to camera bounds
if (cameraBounds) {
if (-_container.x <= cameraBounds.left || cameraBounds.width < cameraLensWidth)
_container.x = -cameraBounds.left;
else if (-_container.x + cameraLensWidth >= cameraBounds.right)
_container.x = -cameraBounds.right + cameraLensWidth;
if (-_container.y <= cameraBounds.top || cameraBounds.height < cameraLensHeight)
_container.y = -cameraBounds.top;
else if (-_container.y + cameraLensHeight >= cameraBounds.bottom)
_container.y = -cameraBounds.bottom + cameraLensHeight;
}
}
//Update art positions
for each (var sprite:Away3DArt in _viewObjects) {
if (sprite.group != sprite.citrusObject.group)
updateGroupForSprite(sprite);
sprite.update(this);
}
}
}
}
And the Away3DArt update method :
public function update(stateView:Away3DView):void {
var pos3D:Vector3D;
var posX:Number, posY:Number;
if (content is Box2DDebugArt) {
(content as Box2DDebugArt).update();
var box2dDebugArt:b2DebugDraw = ((CitrusEngine.getInstance().state as State).getChildAt(2) as b2DebugDraw);
if (stateView.cameraTarget) {
box2dDebugArt.x = stateView.container.x;
box2dDebugArt.y = stateView.container.y;
}
box2dDebugArt.visible = _citrusObject.visible;
} else {
posX = _citrusObject.x;
posY = _citrusObject.y;
pos3D = stateView.viewRoot.unproject(posX, posY);
x = pos3D.x;
y = pos3D.y;
}
}
Any help will be very much appreciated, I’ve added the file in attachment.