game level, game objects. base project download our base project and open it in netbeans...
TRANSCRIPT
Base projectDownload our base project and open it in
NetBeanscg.iit.bme.hu/gamedev/KIC/
11_AndroidDevelopment/11_02_Android_EngineBasics_Final.zip
Change the android sdk location pathPer-user properties (local.properties)sdk.dir=change path here
Start an emulatorBuildRun
Game levelsThe game is built up from game objects
(GameObject class)Game objects are the visible objects, the
actors of the gameThey are uniqueThey will be managed by the Level classOur levels will be generated proceduraly by
the LevelGenerator classThese classes are game specificPlace them to the PlatformGame package and
not to the Engine
GameObject Create the GameObject class
public class GameObject { public enum ObjectType{ Unknown, Ground, Pit, Floor1,
Floor2, MainCharacter, Monster, UsefulThings, Item } protected ObjectType type = ObjectType.Unknown; protected String name; public GameObject(String name){ this.name = name; initImpl(); } public void setType(ObjectType type){ this.type = type; } public ObjectType getType(){ return type; } public String getName() { return this.name; } public void preUpdate(float t, float dt){} public void update(float t, float dt){} public void postUpdate(float t, float dt){} public void destroy(){} protected void initImpl(){}}
GenericGameObject I. Create GenericGameObject class
public class GenericGameObject extends GameObject { protected MeshEntity renderO = null; protected SceneNode renderNode = null; public GenericGameObject(String name, MeshEntity entity) { super(name); if (entity != null) { this.renderO = entity; this.renderNode =
SceneManager.getSingleton().getRootNode().createChild(); this.renderNode.attachObject(this.renderO); } } public void destroy() { if (renderO != null) { renderNode.detachObject(renderO); renderNode.getParent().removeChild(renderNode); } }
GenericGameObject II.public void update(float t, float dt) { if (this.renderNode != null) { this.renderO.update(t, dt); } } public void setPosition(float x, float y, float z) { if (this.renderNode != null) { this.renderNode.setPosition(x, y, z); } } public void setOrientation(float yaw, float pitch, float roll) { if (this.renderNode != null) { this.renderNode.setOrientation(yaw, pitch, roll); } } public Vector3 getPosition() { return this.renderNode.getPosition(); } public Vector3 getVelocity() { return Vector3.ZERO; } public SceneNode getRenderNode() { return renderNode; }}
Level I. Create Level class
public class Level{ private HashMap<String, GameObject> gameObjectMap = new HashMap(); private LinkedList<GameObject> gameObjects = new LinkedList();
public void update(float t, float dt) { for (GameObject o : this.gameObjects) o.update(t, dt); } public void preUpdate(float t, float dt) { for (GameObject o : this.gameObjects) o.preUpdate(t, dt); } public void postUpdate(float t, float dt) { for (GameObject o : this.gameObjects) o.postUpdate(t, dt); }
Level II.public void addGameObject(GameObject o) throws Exception { if (this.gameObjectMap.containsKey(o.getName())) { throw new Exception("Unable to add game object. Game object with the same name already exists :
" + o.getName()); }
this.gameObjectMap.put(o.getName(), o); this.gameObjects.add(o); } public void removeGameObject(String name){ GameObject go = gameObjectMap.get(name); if(go != null) { this.gameObjectMap.remove(name); this.gameObjects.remove(go); go.destroy(); } }
public GameObject getGameObject(String name) { return (GameObject)this.gameObjectMap.get(name); }}
LevelGenerator I.Create LevelGenerator class
public class LevelGenerator { protected Level level; protected int levelSize = 30; protected float cameraFov; protected float cameraDist; protected float cameraAspect; public LevelGenerator(Level level, float cameraFov, float
cameraAspect, float cameraDistance, Character2D mainCharacter) { this.cameraFov = maxCameraFov; this.cameraDist = maxCameraDistance; this.cameraAspect = cameraAspect; this.level = level; } public Point getPlayerStartPos(){ return new Point(-levelSize + 1, 0);}
LevelGenerator II.protected void createMaterial(String name, String textureName, boolean blended, int
textureRepeat){ Texture t1 = new Texture(name); t1.setFileName(textureName); t1.setRepeatU(textureRepeat); t1.load(); TextureManager.getSingleton().add(t1); Material m1 = new Material(name); m1.setTexture(t1); m1.load(); if(blended) m1.setAlhpaBlendMode(Material.ALPHA_BLEND_MODE_BLEND); MaterialManager.getSingleton().add(m1); } protected void createMaterials(){ createMaterial("g_Background", "g_background.jpg", false, 1); createMaterial("g_Middleground", "g_middleground.png", true, levelSize / 10); createMaterial("g_Ground", "g_ground.jpg", false, 1); createMaterial("Platform", "platform1.png", false, 1); createMaterial("g_Item", "g_item.png", false, 1); createMaterial("g_Box", "g_box.jpg", false, 1); }
LevelGenerator III.protected GenericGameObject createPlane(String name, String
materialName, float scaleX, float scaleY) throws Exception{ MeshEntity me = new MeshEntity(name, "UnitQuad"); me.setMeshScale(scaleX, scaleY, 1); me.setMaterial(materialName); GenericGameObject go = new GenericGameObject(name, me); level.addGameObject(go); return go; }
LevelGenerator IV.public Level generate() { if (level == null) { level = new Level(); } createMaterials(); try { //set up backgrounds float backgroundDist1 = 1000; float background1Width = (float) (cameraAspect * Math.tan(cameraFov * 0.5f) * (backgroundDist1 +
cameraDist) + levelSize); float background1Height = (float) (Math.tan(cameraFov * 0.5f) * (backgroundDist1 + cameraDist)); GenericGameObject background1 = createPlane("background1", "g_Background", background1Width,
background1Height); background1.setPosition(0, 0, -backgroundDist1); float backgroundDist2 = 30; float background2Width = (float) (cameraAspect * Math.tan(cameraFov * 0.5f) * (backgroundDist2 +
cameraDist) + levelSize); float background2Height = (float) (Math.tan(cameraFov * 0.5f) * (backgroundDist2 + cameraDist)); GenericGameObject background2 = createPlane("background2", "g_Middleground", background2Width,
background2Height); background2.setPosition(0, 0, -backgroundDist2); } catch(Exception e) { android.util.Log.e("LevelGenerator", "unable to generate level " + e.toString()); } return level; }
Try our classes MainEngine:
public class MainEngine { private long timeStart = 0; private long lastTime = 0; Level level; Camera camera; public void init(float ratio) { GLES10.glClearColor(0.5F, 0.5F, 1.0F, 1.0F); GLES10.glHint(GLES10.GL_PERSPECTIVE_CORRECTION_HINT, GLES10.GL_NICEST); try { camera = new Camera("mainCamera"); camera.setType(Camera.TYPE_PERSECTIVE); camera.setPerspFov(0.5f); camera.setNear(0.1f); camera.setFar(1100.0f); camera.setAspect(ratio); SceneNode camNode = SceneManager.getSingleton().getRootNode().createChild(); camNode.attachObject(camera); }catch (Exception e){ android.util.Log.e("MainEngine init","Unable to create camera ", e); } LevelGenerator LG = new LevelGenerator(null, 0.5f, ratio,12.0f); level = LG.generate(); camera.getParent().setPosition(LG.getPlayerStartPos().x, 0, 12.0f); }
Try our classespublic void update() { //get elapsed time
… level.preUpdate(t, dt); //update state level.update(t, dt); //render GLES10.glClear(GLES10.GL_COLOR_BUFFER_BIT |
GLES10.GL_DEPTH_BUFFER_BIT); camera.apply(); SceneManager.getSingleton().render(); level.postUpdate(t, dt); }
Level generation I.LevelGenerator new member variables:protected MeshEntity groundME;protected MeshEntity floor1ME;protected MeshEntity floor2ME;// protected MeshEntity pitME;
Level generation II. LevelGenerator new method:protected void createMeshes(){ try{ groundME = new MeshEntity("ground", "UnitQuad"); groundME.setMeshScale(1.0f, 1, 1); groundME.setMaterial("g_Ground"); //pitME = new MeshEntity("pit", "UnitQuad"); //pitME.setMeshScale(1.0f, 1, 1); //pitME.setMaterial("Pit"); //also create this material!! floor1ME = new MeshEntity("floor1", "UnitQuad"); floor1ME.setMeshScale(1.0f, 0.1f, 1); floor1ME.setMaterial("Platform"); floor2ME = new MeshEntity("floor2", "UnitQuad"); floor2ME.setMeshScale(1.0f, 0.1f, 1); floor2ME.setMaterial("Platform"); //we can choose an other material too }catch(Exception e){ android.util.Log.e("LevelGenerator", "Unable to create mesh entities " + e.getMessage()); } }
Level generation III.LevelGenerator.generate() after createMaterials call:
createMeshes();LevelGenerator.generate() after background creation:
…for(int i = 0; i < 3; i++){ GenericGameObject groundL = new GenericGameObject("ground_l_" + i, groundME); groundL.setPosition(- levelSize - 2 * i - 1.0f, -3.f, 0); level.addGameObject(groundL); GenericGameObject groundR = new GenericGameObject("ground_r_" + i, groundME); groundR.setPosition(levelSize + 1.0f + 2.0f * i, -3.f, 0); level.addGameObject(groundR); }
Level generation IV. protected int groundCount = 0; protected void createGroundElement(float posX) throws Exception{ GenericGameObject ground = new GenericGameObject("ground_" +
groundCount, groundME); ground.setType(GameObject.ObjectType.Ground); ground.setPosition(posX, -3.f, 0); level.addGameObject(ground); groundCount++; } protected int pitCount = 0; protected void createPitElement(float posX) throws Exception{ GenericGameObject pit = new GenericGameObject("pit_" + pitCount, null);// , pitME); pit.setType(GameObject.ObjectType.Pit); pit.setPosition(posX, -4.5f, 0); level.addGameObject(pit); pitCount++; }
Level generation V. protected int floor1Count = 0; protected void createFloor1Element(float posX) throws Exception{ GenericGameObject floor1 = new GenericGameObject("floor1_" +
floor1Count, floor1ME); floor1.setType(GameObject.ObjectType.Floor1); floor1.setPosition(posX, -0.8f, 0); level.addGameObject(floor1); floor1Count++; } protected int floor2Count = 0; protected void createFloor2Element(float posX) throws Exception{ GenericGameObject floor2 = new GenericGameObject("floor2_" +
floor2Count, floor2ME); floor2.setType(GameObject.ObjectType.Floor2); floor2.setPosition(posX, 0.6f, 0); level.addGameObject(floor2); floor2Count++; }
Level generation VI. protected int monsterCount = 0; protected void generateMonster(float x, float
y)throws Exception{ } protected int itemCount = 0; protected void createItem(float x, float y)
throws Exception{ } protected int boxCount = 0; protected void createBox(float x, float y) throws
Exception{ }
Level generation VI. generate() after border floors generation: for(int i = 0; i < levelSize; ++i){ float posX = (float) i * 2 - (float) levelSize + 1.0f; double r = Math.random(); if(r > 0.2f || i < 3){ createGroundElement(posX); if(i > 3){ double rm = Math.random(); if(rm > 0.8f){ generateMonster(posX, -1.0f); } double ri = Math.random(); if(ri > 0.4f){ createItem(posX, -2.0f); }else if(ri > 0.2f){ createBox(posX, -2.0f); } } }…
Level generation VI. else{ createPitElement(posX); } r = Math.random(); if(r > 0.6f){ createFloor1Element(posX); double ri = Math.random(); if(ri > 0.4f){ createItem(posX, -0.8f); }else if(ri > 0.2f){ createBox(posX, -0.8f); } r = Math.random(); if(r > 0.7f){ createFloor2Element(posX); ri = Math.random(); if(ri > 0.4f){ createItem(posX, 0.6f); }else if(ri > 0.2f){ createBox(posX, 0.6f); } } } }
Explore the levelMainEngine onTouchEvent:
protected float lastX = 0; public boolean onTouchEvent(MotionEvent e) { if(e.getAction() == MotionEvent.ACTION_MOVE){ float x = e.getX(); float dx = (x - lastX) * 0.005f; Vector3 oldPos = camera.getParent().getPosition(); camera.getParent().setPosition(oldPos.x() + dx,
oldPos.y(), oldPos.z()); } if(e.getAction() == MotionEvent.ACTION_DOWN){ lastX = e.getX(); } return true; }