29
Android Game Development Android Game Engine – Advanced topics

Android Game Engine – Advanced topics. Base project Download our base project and open it in NetBeans cg.iit.bme.hu/gamedev/KIC/11_AndroidDevelopment/11

Embed Size (px)

Citation preview

Android Game Development Android Game Engine – Advanced topics

Base projectDownload our base project and open it in

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

11_AndroidDevelopment/11_05_Android_AnimationScripts_Base.zip

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

Start an emulatorBuildRun

AnimationChange of a value in timeWhat?

PositionColor orientation…

How to store?Can be multi dimensionalArray of floats

How to define the change of the valueKeyframe animationInterpolation (step/linear)

AnimationTrackData - AnimationTrackAnimationTrackData

Represents a keyframe animated valueStores a float array for each keyframeKeys are evenly placed in timeThe arrays should have the same size (the

dimension of the value)AnimationTrack

Represents a keyframe animationWorks on an AnimationTrackDataHandles animation timeUpdates current value (interpolation)Playback speed can be givenAnimation can loop

AnimationTrack examplefloat keys[][] = {{-1,0},{1,0},{-1,0}};AnimationTrackData atd = new AnimationTrackData(2);atd.addKeyframe(keys[0]);atd.addKeyframe(keys[1]);atd.addKeyframe(keys[2]);AnimationTrack animTrack = new AnimationTrack(atd);animTrack.setUseLinearInterpolation(true);animTrack. setLoop(true);//dt between two frames should be 0.5 sec.animTrack. setPlaybackSpeed(2.0);…animTrack.update(t,dt);float currentX = (animTrack. getCurrentValue())[0];float currentY = (animTrack. getCurrentValue())[1];mySceneNode.setPosition(currentX, currentY, 0);

AnimatedTextureA texture that contains frames of animationsCan contain several animations (assigned with a

unique name)Texture coordinates will be transformed with the

texture matrix to use only a subregion of the textureSubregion is defined with a bounding box (min/max

corners)The bounding box is calculated in each rendered

frame using an AnimationTrackAnimationTrackData contains 4 floats: minX, minY,

maxX, maxY

AnimatedTexture exampleAnimatedTexture at = new AnimatedTexture("myAnimTexture");AnimationTrackData atd = new AnimationTrackData(4);float keys0[] = {0.0f, 0.0f, 0.2f, 0.2f};float keys1[] = {0.2f, 0.0f, 0.4f, 0.2f};float keys2[] = {0.4f, 0.0f, 0.6f, 0.2f};float keys3[] = {0.0f, 0.0f, 0.2f, 0.2f};atd.addKeyframe(keys0);atd.addKeyframe(keys1);atd.addKeyframe(keys2);atd.addKeyframe(keys3);at.addAnimation("walk", atd, loopAnimation, animationPlaybackSpeed );at.setFileName("animtex.png");at.load();...at.lookLeft(true); //mirror subimage in the x directionat.playAnimation("walk");at.update(t, dt);

MeshEntitypublic void update(float t, float dt) { Texture texture = this.material.getTexture(); if(texture != null && texture instanceof

AnimatedTexture) ((AnimatedTexture) texture).update(t, dt); }

AnimatedTexture example

SpriteMap exampleAlso a texture that contains subimages defined with bounding

boxesEach subimage has its unique name (literal)The texture coordinates are transformed with the texture

matrixOnly one literal can be active at a timeCan draw the subimage to screen at a given position and with

a given height (width is adjusted to bounding box ratio)Can be used to store several small images in one texture

(these images are related)E.g.:

GUI strings Images of numbers or letters

This class can be extended to implement a bitmap font drawing (StringDrawer)

SpriteMap example

SpriteMap example

SpriteMap sm = new SpriteMap("MySMap"); sm.setFileName(“HUD.png"); sm.addLiteral("score", scoreMinX, scoreMinY, scoreMaxX,

scoreMaxY); sm.addLiteral("life", lifeMinX, lifeMinY, lifeMaxX, lifeMaxY); sm.load(); ... sm.draw("score", x, y, height, alignLeft, alignBottom);

StringDrawerpackage gamedev.android.UEngine.Engine;

import gamedev.android.UEngine.Engine.Resources.SpriteMap;

public class StringDrawer { public static void drawString(SpriteMap map, String s, float x,

float y, float h){ char[] chars = s.toCharArray(); float t = x; for(int i = 0; i < chars.length; i++) { t += map.draw(""+chars[i], t, y, h, true, true); } }}

Script loaders I.Store material and texture definitions in

scriptsEasier to editNot hardwired in codeHuman readable (no programming skills

needed)We will use XML files to store propertiesPlace new classes in new package:

Engine.Scripts

Script loaders II. ScriptLoader class

Base class XML pull parser, state machine handling

TextureScriptLoader loads a Texture, AnimatedTexture or SpriteMap

MaterialScriptLoader Loads a Material Usually refers to a texture name

KeyframeAnimationDataScriptLoader Loads an AnimationTrackData The data can be passed to an AnimationTrack or AnimatedTexture

MeshEntityScriptLoader Loads a MeshEntity Refers to a material name and a mesh name

Physics2DObjectScriptLoader Loads a Physics2DObject Box and circle shapes can be defined Friction, density, restitution and type (static/dynamic/kinematic) can be given

Script loaders III.Game related script loaders are in PlatformGame

packageGameObjectScriptLoader

Loads a game objectMeshEntity and Physics2DObject can be definedInitial position and orientation can be defined

LevelScriptLoaderLoads a levelLevel scripts list gameobjects

Resource managers with script loadingpublic class TextureManager extends ResourceManager<Texture>{ private TextureScriptLoader loader = new TextureScriptLoader(); protected Texture loadImpl(String name){ this.loader.loadScript(name + ".texture.xml"); return this.loader.getTexture(); }}

public class MaterialManager extends ResourceManager<Material>{

private MaterialScriptLoader loader = new MaterialScriptLoader(); protected Material loadImpl(String name){ this.loader.loadScript(name + ".material.xml"); return this.loader.getMaterial(); }}

Texture script examples<texture name="Brick">

<file filename = "brick.jpg"/></texture>

<texture name="g_Item"><file filename = "g_item.png"/>

</texture>

Material script examples<material name="Basic" lighting="false"></material>

<material name="Brick“ ><texture_unit texture = "Brick"/>

</material>

<material name="g_Item" lighting="false" blending="blend"><texture_unit texture = "g_Item"/>

</material>

MeshEntity script example<meshentity name = "Ground"

meshname="UnitQuad" material="Basic"></meshentity>

Physics2DObject script examples

<physics2dobject><aabox dim ="50 10"/>

</physics2dobject>

<physics2dobject density="2" friction="0.8" restitution="0.3" type="dynamic">

<aabox dim ="0.5 0.5" /></physics2dobject>

GameObject script example

<gameobject name="MyBox" position="0 4 0" rotation="0 0 0" scale="0.5 0.5 1" ><meshentity name = "MyBox" meshname="UnitQuad" material="Brick"></meshentity><physics2dobject density="2" friction="0.8" restitution="0.3" type="dynamic">

<aabox dim ="0.5 0.5" /></physics2dobject>

</gameobject>

AnimatedTexture script example<animtexture name="g_DarkMan">

<file filename = "g_darkman.png"/> <animation name="stand" loop="true" speed="5.0"> <key value="0 0 0.33 0.5"/> <key value="0 0 0.33 0.5"/> </animation> <animation name="walk" loop="true" speed="5.0"> <key value="0 0 0.33 0.5"/> <key value="0.33 0 0.66 0.5"/> <key value="0.66 0 1.0 0.5"/> <key value="0 0.5 0.33 1.0"/> <key value="0 0 0.33 0.5"/> </animation> <animation name="jump" loop="true" speed="5.0"> <key value="0 0 0.33 0.5"/> <key value="0.33 0 0.66 0.5"/> <key value="0.66 0 1.0 0.5"/> <key value="0 0.5 0.33 1.0"/> <key value="0 0 0.33 0.5"/> </animation></animtexture>

Excersise

Change material and texture loading in LevelGenerator to use the automatic load from script functionality of material and texture managers !! (We have to write the scripts too)

Physics contact events I.Create new class in Physics package:

public interface PhysicsContactEventListener {

public abstract void onContact(PhysicsObject other);

public abstract PhysicsObject getObject(); }

Physics contact events II. PhysicsEngine2D:

public class PhysicsEngine2D{ class ContactEvent{ public PhysicsContactEventListener listener; public PhysicsObject otherObject; public ContactEvent(PhysicsContactEventListener l, PhysicsObject o){ listener = l; otherObject = o; } };

private LinkedList<ContactEvent> contactEvents = new LinkedList<ContactEvent>();

Physics contact events III.class MyContactListener implements ContactListener{ public void beginContact(Contact contact) { PhysicsObject o1 = (PhysicsObject) contact.m_fixtureA.m_body.m_userData; PhysicsObject o2 = (PhysicsObject) contact.m_fixtureB.m_body.m_userData;

for(PhysicsContactEventListener l : contactEventListeners) { if(o1 == l.getObject()) contactEvents.add(new ContactEvent(l, o2)); if(o2 == l.getObject()) contactEvents.add(new ContactEvent(l, o1)); } } public void endContact(Contact contact) { } public void preSolve(Contact contact, Manifold manifold) { } public void postSolve(Contact contact, ContactImpulse impulse) { } };

private LinkedList<PhysicsContactEventListener> contactEventListeners = new LinkedList<PhysicsContactEventListener>();

Physics contact events IV. private PhysicsEngine2D(){ world.setContactListener(new MyContactListener()); }

public Contact getContacts(){ return world.getContactList(); }

public void update(float dt) { … for(ContactEvent e : contactEvents){ e.listener.onContact(e.otherObject); } contactEvents.clear(); }

public void registerContactListener(PhysicsContactEventListener l){ contactEventListeners.add(l); }

The End