Android Game Development

28
Android Game Development Android Game Engine – Game logic

description

Android Game Development. Android Game Engine – Game logic. Base project. Download our base project and open it in NetBeans cg.iit.bme.hu/ gamedev /KIC/11_AndroidDevelopment/11_05_Android_AnimationScripts_Final.zip Change the android sdk location path - PowerPoint PPT Presentation

Transcript of Android Game Development

Page 1: Android  Game  Development

Android Game Development Android Game Engine – Game logic

Page 2: Android  Game  Development

Base projectDownload our base project and open it in

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

11_AndroidDevelopment/11_05_Android_AnimationScripts_Final.zip

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

Start an emulatorBuildRun

Page 3: Android  Game  Development

Character2D I.Animated character with basic animations

StandWalkJump

Compound physics shape (box + circle)Contact check

Is character grounded? -> can jump

Page 4: Android  Game  Development

Character2D II. Create Character2D class in PlatformGame package

public class Character2D extends GenericGameObject{ protected Fixture footShape; protected Material material; protected boolean grounded = false; protected float characterHeight = 1; protected float characterWidth = 0.75f; protected float speed = 1.0f; protected float maxSpeed = 1.0f; protected float sliding = 0.0f; protected float bouncing = 0.0f; protected float jumpStrength = 1.0f; protected float mass = 0.2f; protected static int STATE_STAND = 0; protected static int STATE_MOVE = 1; protected static int STATE_JUMP = 2; //protected static int STATE_SHOOT = 3; //protected static int STATE_DIE = 4; protected int state = -1;

Page 5: Android  Game  Development

Character2D III.public Character2D(String name, String materialName, float height, float width){ super(name, null, null); characterHeight = height; characterWidth = width; Vector3 scale = new Vector3(width,height,1.0f); width *= 0.6f; try{ MeshEntity me = new MeshEntity(name + "_MeshEntity", "UnitQuad", scale); me.setMaterial(materialName); material = MaterialManager.getSingleton().get(materialName); BodyDef bd = new BodyDef(); FixtureDef fd = new FixtureDef(); bd.type = BodyType.DYNAMIC; Body body = PhysicsEngine2D.getSingleton().createBody(bd); body.setBullet(true); PolygonShape s = new PolygonShape(); s.setAsBox(width, height - width); fd.density = 1; fd.friction = 0.0f; //this probably has no effect fd.restitution = bouncing; fd.shape = s; body.createFixture(fd); CircleShape s2 = new CircleShape(); s2.m_radius = width; s2.m_p.y = -height + width; fd.shape = s2; footShape = body.createFixture(fd); body.setFixedRotation(true); Physics2DObject po = new Physics2DObject(body); mass = po.getBody().getMass(); reInit(me, po); po.limitVelocity(new Vector3(0.1f * maxSpeed, -1.0f, -1.0f)); po.setUserData(this); } catch(Exception e){ android.util.Log.e("Character2D init",e.toString()); } changeState(STATE_STAND); }

Page 6: Android  Game  Development

Character2D IV. public void setSpeed(float v){ speed = v; } public void setJumpStrength(float v){ jumpStrength = v; } public void setSpeedLimit(float v){ maxSpeed = v; } public void setBouncing(float v){ for(Fixture f = ((Physics2DObject)physicsO).getBody().getFixtureList(); f != null; f = f.getNext()) { f.setRestitution(bouncing); } bouncing = v; } public void setDensity(float v){ for(Fixture f = ((Physics2DObject)physicsO).getBody().getFixtureList(); f != null; f = f.getNext()){ f.setDensity(v); } ((Physics2DObject)physicsO).getBody().resetMassData(); mass = ((Physics2DObject)physicsO).getBody().getMass(); } public void setSliding(float v){ sliding = v;}

Page 7: Android  Game  Development

Character2D V.public void update(float t, float dt) { super.update(t,dt); computeGrounded(); if(grounded){ if(state == STATE_JUMP) changeState(STATE_STAND); if(physicsO.getVelocity().length() > 0.01) changeState(STATE_MOVE); else changeState(STATE_STAND); physicsO.setLinearDamping(0); } else{ physicsO.setLinearDamping(0.0f); } } public void move(float amount){ physicsO.addForce(amount * 5 * speed * mass, 0, 0); ((AnimatedTexture)material.getTexture()).lookLeft(amount > 0); }

Page 8: Android  Game  Development

Character2D VI.private void computeGrounded() { Vector3 prevPos = physicsO.getPosition(); grounded = false; Physics2DObject po = (Physics2DObject) physicsO; Body b = po.getBody(); Contact c = PhysicsEngine2D.getSingleton().getContacts(); while(c != null) { if(c.isTouching() && (c.m_fixtureA == footShape || c.m_fixtureB == footShape)) { WorldManifold manifold = new WorldManifold(); c.getWorldManifold(manifold); boolean below = true;

//it should have only one contact point below = (manifold.points[0].y < (prevPos.y() -(characterHeight - characterWidth))); if(below){ grounded = true; break; } } c = c.m_next; } }

Page 9: Android  Game  Development

Character2D VII.public void jump(float amount){ if(grounded && amount > 0.1f) { Vector3 lastPos = physicsO.getPosition(); physicsO.moveToPos(lastPos.x(), lastPos.y() + 0.05f*characterHeight, lastPos.z()); physicsO.addForce(0, 6 * jumpStrength * mass, 0); changeState(STATE_JUMP); } } protected void changeState(int newState) { if(newState == state) return; AnimatedTexture tex = (AnimatedTexture) material.getTexture(); if(newState == STATE_STAND){ tex.playAnimation("stand"); } else if(newState == STATE_MOVE){ tex.playAnimation("walk"); } else if(newState == STATE_JUMP){ tex.playAnimation("jump"); } state = newState; }}

Page 10: Android  Game  Development

GenericGameObject Add new method

public void reInit(MeshEntity entity, PhysicsObject po) { if (entity != null) { if (renderO != null) { this.renderNode.detachObject(renderO); } this.renderO = entity; if (this.renderNode == null) { this.renderNode =

SceneManager.getSingleton().getRootNode().createChild(); } this.renderNode.attachObject(this.renderO); } if (po != null) { this.physicsO = po; } }

Page 11: Android  Game  Development

MainCharacter I. Create MainCharacter class

public class MainCharacter extends Character2D implements PhysicsContactEventListener{

protected Quad tmpQuad = new Quad("mytmpquad"); protected int score = 0; protected int life = 3; protected Level level; public int getScore(){ return score; } public int getLife(){ return life; } public MainCharacter(Level level){ super("mainCharacter", "g_DarkMan", 0.5f, 0.4f); this.level = level; setType(ObjectType.MainCharacter); PhysicsEngine2D.getSingleton().registerContactListener(this); setBouncing(0.99f); setSliding(0.99f); setSpeed(1.0f); setSpeedLimit(2.0f); setJumpStrength(1.0f); setDensity(30); }

Page 12: Android  Game  Development

MainCharacter II.public void onContact(PhysicsObject other) { GameObject GO; try{ GO = (GameObject) other.getUserData(); } catch(Exception e) { android.util.Log.d("MainCharacter", "User data of contact physics object is not a GameObject"); return; } switch(GO.getType()) { case Monster:{ life--; level.removeGameObject(GO.getName()); level.removeGameObject(GO.getName() + "_controller"); break; } case Pit:{ life=-1; } case Item:{ score+=20; level.removeGameObject(GO.getName()); } default:{ break; } } } public PhysicsObject getObject() { return physicsO; }}

Page 13: Android  Game  Development

MainEngine I.New member variables

protected MainCharacter character;private float characterMove = 0;private float characterJump = 0;

init()level = LG.generate(); try{ character = new MainCharacter(this.level); character.setPosition(LG.getPlayerStartPos().x, LG.getPlayerStartPos().y, 0); level.addGameObject(character); }catch(Exception e){ android.util.Log.e("MainEngine init","Unable to create main

character", e); }

Page 14: Android  Game  Development

MainEngine II.public void update() {…character.move(characterMove); characterMove = 0; character.jump(characterJump); characterJump = 0; level.preUpdate(t, dt); PhysicsEngine2D.getSingleton().update(dt); level.update(t, dt); float cX = character.getPosition().x(); camera.getParent().setPosition(cX, 0, 12);//render

Page 15: Android  Game  Development

MainEngine III.protected float lastX = 0; protected float lastY = 0; public boolean onTouchEvent(MotionEvent e) { if(e.getAction() == MotionEvent.ACTION_MOVE){ float x = e.getX(); float y = e.getY(); float dx = (x - lastX) * 0.01f; float dy = (y - lastY) * -1f; if(Math.abs(dy) < 10) dy = 0; lastY = e.getY(); characterMove = dx; characterJump = dy; }else if(e.getAction() == MotionEvent.ACTION_DOWN){ lastX = e.getX(); lastY = e.getY(); } return true; }

Page 16: Android  Game  Development

Build and run

Page 17: Android  Game  Development

Monster I.public class Monster extends Character2D implements PhysicsContactEventListener{ protected Level level; public Monster(String name, String materialname, Level level){ super(name, materialname, 0.5f, 0.45f); this.level = level; setType(ObjectType.Monster); PhysicsEngine2D.getSingleton().registerContactListener(this); } public void onContact(PhysicsObject other) { GameObject GO; try{ GO = (GameObject) other.getUserData(); } catch(Exception e){ android.util.Log.d("Monster", "User data of contact physics object is not a GameObject"); return; } switch(GO.getType()){ case UsefulThings: { //android.util.Log.e("Monster", "collided with useful thing"); // check if monster is hit from above for example, then remove it //level.removeGameObject(name); break; } } } public PhysicsObject getObject() { return physicsO; }}

Page 18: Android  Game  Development

TargetedCharacterControllerpublic class TargetedCharacterController extends GameObject{ protected GenericGameObject target; protected Character2D character; protected float range = 3.0f; public TargetedCharacterController(Character2D c, GenericGameObject target, float

range){ super(c.getName() + "_controller"); this.target = target; character = c; this.range = range; } public void preUpdate(float t, float dt){ Vector3 tpos = target.getPosition(); Vector3 cpos = character.getPosition(); Vector dir = tpos.sub(cpos); float l = dir.length(); if(l < range) character.move(Math.signum(dir.d[0])); }}

Page 19: Android  Game  Development

LevelGeneratorprotected Character2D mainCharacter;public LevelGenerator(Level level, float maxCameraFov, float cameraAspect, float maxCameraDistance,

Character2D mainCharacter) {…this.mainCharacter = mainCharacter; }…protected void generateMonster(float x, float y)throws Exception{ try{ Character2D monster = new Monster("monster_" + monsterCount, "Monster", level); monsterCount++; monster.setType(GameObject.ObjectType.Monster); monster.setSpeed(0.6f); monster.setSpeedLimit(1.0f); TargetedCharacterController monsterControll = new TargetedCharacterController(monster, mainCharacter, 4); monster.setPosition(x, y, 0); level.addGameObject(monster); level.addGameObject(monsterControll); } catch (Exception ex) { android.util.Log.e("LevelGenerator", "Unable to create monster"); } }

Page 20: Android  Game  Development

MainEngine Init()try{ level = new Level(); character = new MainCharacter(level); LevelGenerator LG = new LevelGenerator(level, 0.5f,

ratio,12.0f, character); LG.generate(); character.setPosition(LG.getPlayerStartPos().x,

LG.getPlayerStartPos().y, 0); level.addGameObject(character); }catch(Exception e){ android.util.Log.e("MainEngine init","Unable to create main

character", e); }Update//SceneManager.getSingleton().render();SceneManager.getSingleton().zOrderedRender();

Page 21: Android  Game  Development

Build and run

Page 22: Android  Game  Development

LevelGenerator - items protected void createItem(float x, float y) throws Exception{ CircleShape shape = new CircleShape(); shape.m_radius = 0.2f; BodyDef bd = new BodyDef(); bd.type = BodyType.KINEMATIC; FixtureDef fd = new FixtureDef(); fd.shape = shape; fd.restitution = 0; fd.isSensor = true; Body body = PhysicsEngine2D.getSingleton().createBody(bd); body.createFixture(fd); try{ MeshEntity itemME = new MeshEntity("item_" + itemCount, "UnitQuad"); itemME.setMeshScale(0.2f, 0.2f, 1); itemME.setMaterial("g_Item"); Physics2DObject itemPhy = new Physics2DObject(body); GenericGameObject item = new GenericGameObject("item_" + itemCount, itemME,itemPhy); item.setType(GameObject.ObjectType.Item); item.setPosition(x, y + 0.4f, 0); level.addGameObject(item); } catch(Exception e){ android.util.Log.e("LevelGenerator", "Unable to create item object: " + e.toString()); } itemCount++; }

Page 23: Android  Game  Development

Build and run

Page 24: Android  Game  Development

HUDWrite game related information to screenLifeScoreGame Over…

We can use the SpriteMap and the StringDrawer class

Page 25: Android  Game  Development

MainEngine I.New member variable

SpriteMap HUDTex;Init()

HUDTex = (SpriteMap) TextureManager.getSingleton().get("g_HUD");

HUDTex.addLiteral("score", 0, 0, 0.65f, 0.187f);//numbersfor(int i = 0; i < 10; ++i){ HUDTex.addLiteral(""+i, i*0.1f, 0.187f, (i+1)*0.1f, 0.38f);}HUDTex.addLiteral("Game Over", 0, 0.39f, 1.0f, 0.62f);HUDTex.addLiteral("Life", 0, 0.62f, 0.4f, 0.82f);HUDTex.addLiteral("heart", 0.52f, 0.66f, 0.74f, 0.85f);

Page 26: Android  Game  Development

MainEngine II.Update()

SceneManager.getSingleton().zOrderedRender();level.postUpdate(t, dt);float to = 0; //offsetto += HUDTex.draw("score", to, 0.95f, 0.05f, true, true);to += 0.02;StringDrawer.drawString(HUDTex, "" + character.getScore(), to,

0.95f, 0.05f);to = 0.7f;to += HUDTex.draw("Life", to, 0.95f, 0.05f, true, true);for(int i = 0; i < character.getLife(); ++i){ to += HUDTex.draw("heart", to, 0.95f, 0.05f, true, true);}if(character.getLife() < 0){ HUDTex.draw("Game Over", 0.5f, 0.5f, 0.1f, false, false);}

Page 27: Android  Game  Development

Build and run

Page 28: Android  Game  Development

The End