2D physics. Base project Download our base project and open it in NetBeans...

24
Android Game Development 2D physics

Transcript of 2D physics. Base project Download our base project and open it in NetBeans...

Page 1: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

Android Game Development 2D physics

Page 2: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

Base projectDownload our base project and open it in

NetBeanscg.iit.bme.hu/gamedev/KIC/

11_AndroidDevelopment/11_03_Android_LevelsGameObjects_Final.zip

Change the android sdk location pathPer-user properties (local.properties)sdk.dir=change path here

Start an emulatorBuildRun

Page 3: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

PhysicsBox2D2D physics engineJava JBox2DAndroid version JBox2d4AndroidJBox2D4Android_2.1.2.jar should be copied

to the ./libs folder in our project folderCreate new package: Engine.Physics

Page 4: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

PhysicsObjectCreate PhysicsObject class in Physisc package

public abstract class PhysicsObject{ protected Object userData = 0; public Object getUserData(){return userData;} public void setUserData(Object data){userData = data;} public abstract void destroy(); public abstract Vector3 getPosition(); public abstract Vector3 getVelocity(); public abstract void limitVelocity(Vector3 limit); public abstract void setVelocity(float x, float y, float z); public abstract void setLinearDamping(float value); public abstract Quaternion getOrientation(); public void update(){} public abstract void addForce(float x, float y, float z); public abstract void moveToPos(float x, float y, float z); public abstract void rotateToAngles(float x, float y, float z); }

Page 5: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

PhysicsEngine2D I.Create PhysicsEngine2D class

public class PhysicsEngine2D { private static final PhysicsEngine2D instance = new

PhysicsEngine2D(); private World world = new World(new Vec2(0.0F, -10.0F), false); public static PhysicsEngine2D getSingleton(){ return instance; } private PhysicsEngine2D(){} public Body createBody(BodyDef def){ return this.world.createBody(def); } public void destroyBody(Body body){ world.destroyBody(body); }

Page 6: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

PhysicsEngine2D II. public void clear(){ Body nextB = world.getBodyList(); while(nextB != null) { Body b = nextB; nextB = b.getNext(); world.destroyBody(b); } } public void update(float dt){ this.world.step(dt, 6, 2); this.world.clearForces(); } public void setGravity(float x, float y) { this.world.setGravity(new Vec2(x, y)); }}

Page 7: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

Physics2DObject I. Create Ohysics2DObject class

public class Physics2DObject extends PhysicsObject{ Body body = null; Vector3 position = new Vector3(); Vector3 velocity = new Vector3(); Vector3 velocityLimit = new Vector3(-1,-1,-1); Quaternion orientation = new Quaternion(); String groupName = null;

public Physics2DObject(Body b) { this.body = b; this.position.set(b.getPosition().x, b.getPosition().y, 0.0F); this.orientation.set(0.0F, 0.0F, b.getAngle()); if(body.m_type != BodyType.DYNAMIC){ Fixture f = body.getFixtureList(); while(f!=null){ f.m_restitution = 0; f = f.getNext(); } } this.body.m_userData = this; }

Page 8: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

Physics2DObject II. public void destroy(){ PhysicsEngine2D.getSingleton().destroyBody(body); } public Body getBody(){return body;} public Vector3 getPosition(){return this.position;} public Vector3 getVelocity(){return new Vector3(this.velocity);} public void setVelocity(float x, float y, float z){ velocity.set(x,y,z); body.setLinearVelocity(new Vec2(x, y)); } public void limitVelocity(Vector3 limit){ velocityLimit.set(limit.x(), limit.y(), limit.z()); } public void setLinearDamping(float value)

{body.setLinearDamping(value);} public Quaternion getOrientation(){return this.orientation;}

Page 9: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

Physics2DObject III.public void update(){ this.velocity.set(body.getLinearVelocity().x, body.getLinearVelocity().y, 0); if(velocityLimit.x() > 0){ if(velocity.x() > velocityLimit.x()) body.setLinearVelocity(new Vec2(velocityLimit.x(), velocity.y())); if(velocity.x() < -velocityLimit.x()) body.setLinearVelocity(new Vec2(-velocityLimit.x(), velocity.y())); } if(velocityLimit.y() > 0){ if(velocity.y() > velocityLimit.y()) body.setLinearVelocity(new Vec2(velocity.x(), velocityLimit.y())); if(velocity.y() < -velocityLimit.y()) body.setLinearVelocity(new Vec2(velocity.x(), -velocityLimit.y())); } this.position.set(this.body.getPosition().x, this.body.getPosition().y, 0.0F); this.orientation.set(0.0F, 0.0F, this.body.getAngle()); this.velocity.set(body.getLinearVelocity().x, body.getLinearVelocity().y, 0); }

Page 10: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

Physics2DObject IV.public void addForce(float x, float y, float z) { body.applyLinearImpulse(new Vec2(x,y), new

Vec2(0.0f,0.0f)); } public void moveToPos(float x, float y, float z) { float angle = this.body.getAngle(); this.body.setTransform(new Vec2(x, y), angle); } public void rotateToAngles(float x, float y, float z) { Vec2 pos = this.body.getPosition(); this.body.setTransform(pos, z); } }//Physics2DObject end

Page 11: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

MainEngineMainEngine.update add new line:

level.preUpdate(t, dt);PhysicsEngine2D.getSingleton().update(dt);

level.update(t, dt);

Page 12: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

GenericGameObject I. Modify GenericGameObject to contain rigid body representation New member:

protected PhysicsObject physicsO = null; Constructor

public GenericGameObject(String name, MeshEntity entity, PhysicsObject po) { super(name); if (entity != null) { this.renderO = entity; this.renderNode =

SceneManager.getSingleton().getRootNode().createChild(); this.renderNode.attachObject(this.renderO); }

if (po != null) { this.physicsO = po; this.physicsO.setUserData(this); } }

Page 13: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

GenericGameObject II.public void destroy(){ if(renderO != null){ renderNode.detachObject(renderO);

renderNode.getParent().removeChild(renderNode); } if(physicsO != null) { physicsO.destroy(); } }

Page 14: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

GenericGameObject III.public void update(float t, float dt) { if (this.physicsO != null) { this.physicsO.update(); if (this.renderNode != null) { this.renderNode.setPosition(this.physicsO.getPosition()); this.renderNode.setOrientation(this.physicsO.getOrientation()); this.renderO.update(t, dt); } } } public Vector3 getPosition() { return this.physicsO.getPosition(); } public Vector3 getVelocity() { return this.physicsO.getVelocity(); }

Page 15: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

GenericGameObject IV.public void setPosition(float x, float y, float z) { if (this.physicsO != null) this.physicsO.moveToPos(x, y, z); if (this.renderNode != null) this.renderNode.setPosition(x, y, z); }

public void setOrientation(float yaw, float pitch, float roll) { if (this.physicsO != null) this.physicsO.rotateToAngles(yaw, pitch, roll); if (this.renderNode != null) this.renderNode.setOrientation(yaw, pitch, roll); }

Page 16: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

LevelGenerator I. createPlane()

GenericGameObject go = new GenericGameObject(name, me, null); New method

protected Physics2DObject createStaticPhyBox(float w, float h) { PolygonShape shape = new PolygonShape(); shape.setAsBox(w, h); BodyDef bd = new BodyDef(); bd.type = BodyType.STATIC; FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.restitution = 0; Body body = PhysicsEngine2D.getSingleton().createBody(bd); body.createFixture(fd); return new Physics2DObject(body); }

Page 17: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

LevelGenerator II.protected void createGroundElement(float posX) throws Exception{ Physics2DObject groundPhy = createStaticPhyBox(1.0f, 1); GenericGameObject ground = new GenericGameObject("ground_" + groundCount, groundME,

groundPhy);…}protected void createPitElement(float posX) throws Exception{ Physics2DObject pitPhy = createStaticPhyBox(1.0f, 0.2f); GenericGameObject pit = new GenericGameObject("pit_" + pitCount, null, pitPhy);…}protected void createFloor1Element(float posX) throws Exception{ Physics2DObject floorPhy = createStaticPhyBox(1.0f, 0.1f); GenericGameObject floor1 = new GenericGameObject("floor1_" + floor1Count, floor1ME,

floorPhy); …}protected void createFloor2Element(float posX) throws Exception{ Physics2DObject floorPhy = createStaticPhyBox(1.0f, 0.1f); GenericGameObject floor2 = new GenericGameObject("floor2_" + floor2Count, floor2ME,

floorPhy); …}

Page 18: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

LevelGenerator III.protected int boxCount = 0; protected void createBox(float x, float y) { PolygonShape shape = new PolygonShape(); shape.setAsBox(0.3f, 0.3f); BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.restitution = 0.13f; fd.density = 100.0f; fd.friction = 0.5f; Body body = PhysicsEngine2D.getSingleton().createBody(bd); body.createFixture(fd); try{ MeshEntity itemME = new MeshEntity("box_" + boxCount, "UnitQuad"); itemME.setMeshScale(0.3f, 0.3f, 1); itemME.setMaterial("g_Box"); Physics2DObject itemPhy = new Physics2DObject(body); GenericGameObject item = new GenericGameObject("box_" + boxCount, itemME, itemPhy); item.setType(GameObject.ObjectType.UsefulThings); item.setPosition(x, y + 0.5f, 0); level.addGameObject(item); } catch(Exception e) { android.util.Log.e("LevelGenerator", "Unable to create item object: " + e.toString()); } boxCount++; }

Page 19: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

LevelGenerator IV.public Level generate(){…GenericGameObject groundL = new

GenericGameObject("ground_l_" + i, groundME, null);…GenericGameObject groundR = new

GenericGameObject("ground_r_" + i, groundME, null);… createBox(-levelSize + 3, 10); createBox(-levelSize + 3.2f, 13); createBox(-levelSize + 2.8f, 16);for(int i = 0; i < levelSize; ++i){…. }

Page 20: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

Build and run

Page 21: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

Make the simulation more stablePhysics2DEngine:public void update(float dt){ float maxDt = 0.09f; while(dt > maxDt){ this.world.step(maxDt, 5, 2); dt -= maxDt; } this.world.step(dt, 5, 2); this.world.clearForces(); }

Play with these parameters!!

Page 22: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

Build and run

Page 23: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

Border: invisible physics boxesLevelGenerator.generate

public Level generate() {…//generate background…Physics2DObject bPhy = createStaticPhyBox(1.0f, 10);GenericGameObject b1 = new GenericGameObject("border1",null,bPhy);b1.setPosition(-levelSize - 1, 0, 0); level.addGameObject(b1);

Physics2DObject bPhy2 = createStaticPhyBox(1.0f, 10);GenericGameObject b2 = new GenericGameObject("border2",null,bPhy2);b2.setPosition(levelSize + 1, 0, 0); level.addGameObject(b2);

for(int i = 0; i < 3; i++)

Page 24: 2D physics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11 _03_Android_LevelsGameObjects_Final.zip.

The End