Wednesday, June 13, 2012

Intro to Android Game Programming – AndEngine

AndEngine is a game engine framework (http://www.andengine.org/) designed for producing games on Android. Originally developed by Nicholas Gramlich, it has some advanced features for producing awesome games.
In this example, I have designed a simple pool game with physics capabilities, such that effects of the accelerometer are taken into account but also touch events. When touching a specific billiard ball, and pulling down on it will cause it to shoot into other balls, with the collision detection taken care of.

Download: http://www.filefactory.com/file/cc0a5b1/n/SimplePool.zip
File: SimplePool.java

001import org.anddev.andengine.engine.Engine;
002import org.anddev.andengine.engine.camera.Camera;
003import org.anddev.andengine.engine.options.EngineOptions;
004import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
005import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
006import org.anddev.andengine.entity.Entity;
007import org.anddev.andengine.entity.primitive.Rectangle;
008import org.anddev.andengine.entity.scene.Scene;
009import org.anddev.andengine.entity.scene.Scene.IOnAreaTouchListener;
010import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
011import org.anddev.andengine.entity.scene.Scene.ITouchArea;
012import org.anddev.andengine.entity.shape.Shape;
013import org.anddev.andengine.entity.sprite.AnimatedSprite;
014import org.anddev.andengine.entity.sprite.Sprite;
015import org.anddev.andengine.entity.util.FPSLogger;
016import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
017import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
018import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
019import org.anddev.andengine.extension.physics.box2d.util.Vector2Pool;
020import org.anddev.andengine.input.touch.TouchEvent;
021import org.anddev.andengine.opengl.texture.Texture;
022import org.anddev.andengine.opengl.texture.TextureOptions;
023import org.anddev.andengine.opengl.texture.region.TextureRegion;
024import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
025import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
026import org.anddev.andengine.sensor.accelerometer.AccelerometerData;
027import org.anddev.andengine.sensor.accelerometer.IAccelerometerListener;
028import org.anddev.andengine.ui.activity.BaseGameActivity;
029 
030import android.hardware.SensorManager;
031import android.util.DisplayMetrics;
032 
033import com.badlogic.gdx.math.Vector2;
034import com.badlogic.gdx.physics.box2d.Body;
035import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
036import com.badlogic.gdx.physics.box2d.FixtureDef;
037 
038public class SimplePool extends BaseGameActivity implements IAccelerometerListener, IOnSceneTouchListener, IOnAreaTouchListener
039  {
040 
041    private Camera mCamera;
042    private Texture mTexture;
043    private Texture mBallYellowTexture;
044    private Texture mBallRedTexture;
045    private Texture mBallBlackTexture;
046    private Texture mBallBlueTexture;
047    private Texture mBallGreenTexture;
048    private Texture mBallOrangeTexture;
049    private Texture mBallPinkTexture;
050    private Texture mBallPurpleTexture;
051    private Texture mBallWhiteTexture;
052 
053    private TiledTextureRegion mBallYellowTextureRegion;
054    private TiledTextureRegion mBallRedTextureRegion;
055    private TiledTextureRegion mBallBlackTextureRegion;
056    private TiledTextureRegion mBallBlueTextureRegion;
057    private TiledTextureRegion mBallGreenTextureRegion;
058    private TiledTextureRegion mBallOrangeTextureRegion;
059    private TiledTextureRegion mBallPinkTextureRegion;
060    private TiledTextureRegion mBallPurpleTextureRegion;
061    private TiledTextureRegion mBallWhiteTextureRegion;
062 
063    private Texture mBackgroundTexture;
064    private TextureRegion mBackgroundTextureRegion;
065 
066    private PhysicsWorld mPhysicsWorld;
067 
068    private float mGravityX;
069    private float mGravityY;
070    private Scene mScene;
071 
072    private final int mFaceCount = 0;
073 
074    private final int CAMERA_WIDTH = 720;
075    private final int CAMERA_HEIGHT = 480;
076 
077    @Override
078    public Engine onLoadEngine()
079      {
080        DisplayMetrics dm = new DisplayMetrics();
081        getWindowManager().getDefaultDisplay().getMetrics(dm);
082 
083        this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
084        return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
085      }
086 
087    @Override
088    public void onLoadResources()
089      {
090        this.mTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
091        this.mBallBlackTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
092        this.mBallBlueTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
093        this.mBallGreenTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
094        this.mBallOrangeTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
095        this.mBallPinkTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
096        this.mBallPurpleTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
097        this.mBallYellowTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
098        this.mBallRedTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
099        this.mBallWhiteTexture = new Texture(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
100 
101        TextureRegionFactory.setAssetBasePath("gfx/");
102        mBallYellowTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mBallYellowTexture, this, "ball_yellow.png", 0, 0, 1, 1); // 64x32
103        mBallRedTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mBallRedTexture, this, "ball_red.png", 0, 0, 1, 1); // 64x32
104        mBallBlackTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mBallBlackTexture, this, "ball_black.png", 0, 0, 1, 1); // 64x32
105        mBallBlueTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mBallBlueTexture, this, "ball_blue.png", 0, 0, 1, 1); // 64x32
106        mBallGreenTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mBallGreenTexture, this, "ball_green.png", 0, 0, 1, 1); // 64x32
107        mBallOrangeTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mBallOrangeTexture, this, "ball_orange.png", 0, 0, 1, 1); // 64x32
108        mBallPinkTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mBallPinkTexture, this, "ball_pink.png", 0, 0, 1, 1); // 64x32
109        mBallPurpleTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mBallPurpleTexture, this, "ball_purple.png", 0, 0, 1, 1); // 64x32
110        mBallWhiteTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mBallWhiteTexture, this, "ball_white.png", 0, 0, 1, 1); // 64x32
111 
112        this.mBackgroundTexture = new Texture(512, 1024, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
113        this.mBackgroundTextureRegion = TextureRegionFactory.createFromAsset(this.mBackgroundTexture, this, "table_bkg.png", 0, 0);
114 
115        this.enableAccelerometerSensor(this);
116 
117        this.mEngine.getTextureManager().loadTextures(this.mBackgroundTexture, mBallYellowTexture, mBallRedTexture, mBallBlackTexture, mBallBlueTexture, mBallGreenTexture, mBallOrangeTexture, mBallPinkTexture, mBallPurpleTexture);
118      }
119 
120    @Override
121    public Scene onLoadScene()
122      {
123        this.mEngine.registerUpdateHandler(new FPSLogger());
124 
125        this.mPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false);
126 
127        this.mScene = new Scene();
128        this.mScene.attachChild(new Entity());
129 
130        this.mScene.setBackgroundEnabled(false);
131        this.mScene.setOnSceneTouchListener(this);
132        Sprite backgrund = new Sprite(0, 0, this.mBackgroundTextureRegion);
133        backgrund.setWidth(CAMERA_WIDTH);
134        backgrund.setHeight(CAMERA_HEIGHT);
135        backgrund.setPosition(0, 0);
136        this.mScene.getChild(0).attachChild(backgrund);
137 
138        final Shape ground = new Rectangle(0, CAMERA_HEIGHT, CAMERA_WIDTH, 0);
139        final Shape roof = new Rectangle(0, 0, CAMERA_WIDTH, 0);
140        final Shape left = new Rectangle(0, 0, 0, CAMERA_HEIGHT);
141        final Shape right = new Rectangle(CAMERA_WIDTH, 0, 0, CAMERA_HEIGHT);
142 
143        final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f);
144        PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef);
145        PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef);
146        PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
147        PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);
148 
149        this.mScene.attachChild(ground);
150        this.mScene.attachChild(roof);
151        this.mScene.attachChild(left);
152        this.mScene.attachChild(right);
153 
154        this.mScene.registerUpdateHandler(this.mPhysicsWorld);
155        this.mScene.setOnAreaTouchListener(this);
156 
157        return this.mScene;
158      }
159 
160    @Override
161    public void onLoadComplete()
162      {
163        setupBalls();
164 
165      }
166 
167    @Override
168    public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final ITouchArea pTouchArea, final float pTouchAreaLocalX, final float pTouchAreaLocalY)
169      {
170        if (pSceneTouchEvent.isActionDown())
171          {
172            final AnimatedSprite face = (AnimatedSprite) pTouchArea;
173            this.jumpFace(face);
174            return true;
175          }
176 
177        return false;
178      }
179 
180    @Override
181    public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent)
182      {
183        if (this.mPhysicsWorld != null)
184          {
185            if (pSceneTouchEvent.isActionDown())
186              {
187                // this.addFace(pSceneTouchEvent.getX(),
188                // pSceneTouchEvent.getY());
189                return true;
190              }
191          }
192        return false;
193      }
194 
195    @Override
196    public void onAccelerometerChanged(final AccelerometerData pAccelerometerData)
197      {
198        this.mGravityX = pAccelerometerData.getX();
199        this.mGravityY = pAccelerometerData.getY();
200 
201        final Vector2 gravity = Vector2Pool.obtain(this.mGravityX, this.mGravityY);
202        this.mPhysicsWorld.setGravity(gravity);
203        Vector2Pool.recycle(gravity);
204      }
205 
206    private void setupBalls()
207      {
208        final AnimatedSprite[] balls = new AnimatedSprite[9];
209 
210        final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
211 
212        AnimatedSprite redBall = new AnimatedSprite(10, 10, this.mBallRedTextureRegion);
213        AnimatedSprite yellowBall = new AnimatedSprite(20, 20, this.mBallYellowTextureRegion);
214        AnimatedSprite blueBall = new AnimatedSprite(30, 30, this.mBallBlueTextureRegion);
215        AnimatedSprite greenBall = new AnimatedSprite(40, 40, this.mBallGreenTextureRegion);
216        AnimatedSprite orangeBall = new AnimatedSprite(50, 50, this.mBallOrangeTextureRegion);
217        AnimatedSprite pinkBall = new AnimatedSprite(60, 60, this.mBallPinkTextureRegion);
218        AnimatedSprite purpleBall = new AnimatedSprite(70, 70, this.mBallPurpleTextureRegion);
219        AnimatedSprite blackBall = new AnimatedSprite(70, 70, this.mBallBlackTextureRegion);
220        AnimatedSprite whiteBall = new AnimatedSprite(70, 70, this.mBallWhiteTextureRegion);
221 
222        balls[0] = redBall;
223        balls[1] = yellowBall;
224        balls[2] = blueBall;
225        balls[3] = greenBall;
226        balls[4] = orangeBall;
227        balls[5] = pinkBall;
228        balls[6] = purpleBall;
229        balls[7] = blackBall;
230        balls[8] = whiteBall;
231 
232        for (int i = 0; i < 9; i++)
233          {
234            Body body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, balls[i], BodyType.DynamicBody, objectFixtureDef);
235            this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(balls[i], body, true, true));
236 
237            balls[i].animate(new long[] { 200, 200 }, 0, 1, true);
238            balls[i].setUserData(body);
239            this.mScene.registerTouchArea(balls[i]);
240            this.mScene.attachChild(balls[i]);
241          }
242      }
243 
244    private void jumpFace(final AnimatedSprite face)
245      {
246        final Body faceBody = (Body) face.getUserData();
247 
248        final Vector2 velocity = Vector2Pool.obtain(this.mGravityX * -50, this.mGravityY * -50);
249        faceBody.setLinearVelocity(velocity);
250        Vector2Pool.recycle(velocity);
251      }
252  }

No comments:

Post a Comment