[Insert a Title Here]:
[UPDATE 29/05/2012: Added an extra Bonus chapter about creating explosions with particle system]
[UPDATE 24/05/2012: I changed some stuff in the EnemyLayer class and added a whole new section at the end of this tutorial, make sure you have those changes before submitting bug reports :P]
Well .. didn’t know what to call this title so yeah .. anyway, this project will be my own space invaders clone , it’s not the whole thing but I had some stuff in mind before doing it and they were accomplished here, so here they are.
- Make a game without using any external images [I do put weird challenges for myself I know]
- Make sure that the game code is neat and well written in OOP
- Include at least a full structure of the game , doesn’t have to have everything working though
Not using sprites got the advantage of reducing file size .. but I can assure you that the final project looks ugly :P.
I also used this project as an excuse to use AndEngine GLES2.0 and get used to it [I started with GLES1.0 then ported it to GLES2.0] so if you are just learning about andEngine you can start with this project directly with using AndEngine GLES2.0 [even though I do recommend going over my list of tutorials if you haven’t already].
I should also note that this tutorial could be kinda dull at the beginning [till the writing of this line , I’m not sure how I’m gonna organize the tutorial so let’s hope what I write would make sense].
Gearing up:
As with before , you should have AndEngine installed , we’ll be using AndEngine GLES2.0 for this [writing that name every time is not that fun >_>] so if you don’t have that installed you can follow any tutorials online , or use my tutorial for setting up AndEngine GLES2.0.
Just make sure that it’s all working before proceeding, my awesome space ship will wait for you.
Note that as that we’ll be having lots of classes, so I’ll try to finish each class and not come back to it .. this style might not be the same type as my previous tutorials but it’s an experiment and let’s hope [again] that it works :D.
Small Activity is small:
We’ll only be using one Activity and will be switching between scenes, so create a new Java class and call it “BaseActivity” [cause I said so] then make it extends “SimpleBaseGameActivity”, you’ll notice that the default methods are different from the old version of AndEngine.
Add those to the top of your class
static final int CAMERA_WIDTH = 800; static final int CAMERA_HEIGHT = 480; public Font mFont; public Camera mCamera; //A reference to the current scene public Scene mCurrentScene; public static BaseActivity instance;
Notice that I used static dimensions for the camera, this is better than the way I used before because this way will have openGL scale up/down everything depending on the screen size so you don’t really have to worry about screen sizes.
We’ll be using Font later on to write text, so we’ll add it here.
mCurrentScene is an object of type Scene that’ll be used to reference the top Scene , will prove to be useful later on.
This Activity will be a singleton [if you are not familiar with the concept you’ll probably understand it while we work on it].
Next, let’s get to the onCreateEngineOptions() method
public EngineOptions onCreateEngineOptions() { instance = this; mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT); return new EngineOptions(true, ScreenOrientation.LANDSCAPE_SENSOR, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), mCamera); }
We let the instance object reference to this activity, the rest is straight forward.
For onCreateResources() method
protected void onCreateResources() { mFont = FontFactory.create(this.getFontManager(),this.getTextureManager(), 256, 256,Typeface.create(Typeface.DEFAULT, Typeface.BOLD), 32); mFont.load(); }
We don’t have any resources [no images , remember ? :P]
We’ll just have to create the mFont object and load it, I’ve decided to make it use the default font and bold it, text size is 32.
As for the onCreateScene:
protected Scene onCreateScene() { mEngine.registerUpdateHandler(new FPSLogger()); mCurrentScene = new Scene(); mCurrentScene.setBackground(new Background(0.09804f, 0.7274f, 0.8f)); return mCurrentScene; }
Completely self explanatory , we create a new scene and chose it’s background color [I put random numbers :P] and returned it.
with this, you should be able to run the code and get a colored background [not very interesting so far , ‘eh ?]
Before we are done with this class , let’s add 2 more methods:
public static BaseActivity getSharedInstance() { return instance; } // to change the current main scene public void setCurrentScene(Scene scene) { mCurrentScene = scene; getEngine().setScene(mCurrentScene); }
getSharedInstance() will return the current instance for BaseActivity so we can get access to it [the 2nd part of making this a singleton class] and the setCurrentScene() would replace the scene and update mCurrentScene to the new scene.
Splash all around the place:
Every game got a splash screen , why won’t ours have one too ? there is no reason not to so we’ll create a simple splash scene where we’ll have the game’s name animate coming from both sides.
It’s a bad idea/habit to have text strings hard-coded in the source code, so we’ll use strings.xml file, open it and add those 2 elements:
<string name="title_1">Jim</string> <string name="title_2">Vaders</string>
Or you could chose your own name, whatever makes you happy and sleep at night like a baby :D.
Create a new Class, call it “SplashScene”, and make it extends Scene then add this line at top:
BaseActivity activity;
Then inside the constructor, we’ll have it like this:
setBackground(new Background(0.09804f, 0.6274f, 0)); activity = BaseActivity.getSharedInstance(); Text title1 = new Text(0, 0, activity.mFont, activity.getString(R.string.title_1), activity.getVertexBufferObjectManager()); Text title2 = new Text(0, 0, activity.mFont, activity.getString(R.string.title_2), activity.getVertexBufferObjectManager());
Now we have activity object reference our BaseActivity singleton class and then initialize the Text objects, each would use the strings we put in strings.xml.
We have both texts at position 0,0 at first , we’ll change them on this following part so add those next
title1.setPosition(-title1.getWidth(), activity.mCamera.getHeight() / 2); title2.setPosition(activity.mCamera.getWidth(), activity.mCamera.getHeight() / 2); attachChild(title1); attachChild(title2); title1.registerEntityModifier(new MoveXModifier(1, title1.getX(), activity.mCamera.getWidth() / 2 - title1.getWidth())); title2.registerEntityModifier(new MoveXModifier(1, title2.getX(), activity.mCamera.getWidth() / 2));
Here we changed the positions of each text object to be aligned on the center and placed right outside the screen on both side then we attached both texts and added a MoveXModifier so it moves horizontally from both sides meeting at the center, not so flashy but it does the job and make you feel it’s from outerspace and stuff [not really ..].
Okay , let’s make this work .. go back into BaseActivity [this is the last changes in it , I promise] and change your onCreateScene() to this
mEngine.registerUpdateHandler(new FPSLogger()); mCurrentScene = new SplashScene(); return mCurrentScene;
We simply used the SplashScene as the starting scene here , and we got our awesome moving splash scene thingie and you can close this class for good.
Test and see what you get, it should be something like this:
Main Menu:
Main menu comes after the splash screen , right ?
Let’s create our main menu then .. no fancy effects or options , it’ll just have one option that says “start” and when clicked the game starts .. good enough if you ask me [yeah I’m that lazy].
Create a new class called MainMenuScene that extends MenuScene and implements IOnMenuItemClickListener then add those 2 lines at top:
BaseActivity activity; final int MENU_START = 0;
The MENU_START int variable is a flag for our start button , if you add some other button then you’ll need to add some other flag.
Now let’s go to the constructor and write this in it:
super(BaseActivity.getSharedInstance().mCamera); activity = BaseActivity.getSharedInstance(); setBackground(new Background(0.09804f, 0.6274f, 0.8784f)); IMenuItem startButton = new TextMenuItem(MENU_START, activity.mFont, activity.getString(R.string.start), activity.getVertexBufferObjectManager()); startButton.setPosition(mCamera.getWidth() / 2 - startButton.getWidth() / 2, mCamera.getHeight() / 2 - startButton.getHeight() / 2); addMenuItem(startButton); setOnMenuItemClickListener(this);
You should send the current camera to the super class for it to work.
Rremember to add an item in strings.xml for the text written on the start [mine is start , you could put “start!” or “kill all aliens !” or whatever ]
Background colors are random numbers [not really , this was taken from the AndEngine examples ], the startButton is an IMenuItem with MENU_START as it’s flag , using our same font we created and the text from strings.xml.
Position it at the center, add it as a menu item , and then we just register the current scene as a MenuItemClickListener.
The class should have an overridden method called onMenuItemClicked(), have it look like this for now:
public boolean onMenuItemClicked(MenuScene arg0, IMenuItem arg1, float arg2, float arg3) { switch (arg1.getID()) { case MENU_START: return true; default: break; } return false; }
We just swallow the touch when the button is clicked , this would get changed later on to have the game start, now to test our main menu we have to open the SplashScene [again :D] and make some changes.
Before we do that, lemme explain a good habit with splash screens, usually splash screens are used to load the resources [if any] so that the user doesn’t have to wait a lot to launch the app/game , but instead he gets a splash screen while a background thread loads the resources, we’ll just put a place holder for that and you can play around with it later on if you want to load any resources for your game.
Fire up your SplashScene class and add a new method and call it loadResources() , put the following code in it [copy or type it , I prefer that you type it so you get an idea of what you are doing].
DelayModifier dMod = new DelayModifier(2, new IEntityModifierListener() { @Override public void onModifierStarted(IModifier arg0, IEntity arg1) { } public void onModifierFinished(IModifier arg0, IEntity arg1) { activity.setCurrentScene(new MainMenuScene()); } }); registerEntityModifier(dMod);
EDIT: if the above code doesn’t work with you for some reason [I got no idea why it doesn’t work in some cases] use this one and build on it
DelayModifier dMod = new DelayModifier(2){ @Override protected void onModifierFinished(IEntity pItem) { activity.setCurrentScene(new MainMenuScene()); } }; registerEntityModifier(dMod);
This is just a place holder, it just waits for 2 seconds and then tells the activity to change the scene to the MainMenuScene [yay we finally used setCurrentScene() :D] simple ‘eh ?
Call that method at the end of the constructor of SplashScene, test now and you should get the splash animation then the scene will change to the main menu scene with your start button.
Ships to Docks:
Let’s make our ship now, since we are being more OO .. the ship will have it’s own separate class, so let’s do this.
As that there should be only one ship on the screen at a time, and since that we’ll be accessing it a lot , we’ll make it a singleton class too.
Create a new class and call it “Ship”, make your class look like this:
public class Ship { public Rectangle sprite; public static Ship instance; Camera mCamera; public static Ship getSharedInstance() { if (instance == null) instance = new Ship(); return instance; } private Ship() { sprite = new Rectangle(0, 0, 70, 30, BaseActivity.getSharedInstance() .getVertexBufferObjectManager()); mCamera = BaseActivity.getSharedInstance().mCamera; sprite.setPosition(mCamera.getWidth() / 2 - sprite.getWidth() / 2, mCamera.getHeight() - sprite.getHeight() - 10); } }
The ship’s sprite will be a rectangle [too lazy to make a new shape ? :P] and I decided that it should have width of 70 pixels and height of 30 pixels .. you may have your rectangle err .. your awesome space ship look however you want though!
The initial position of the sprite is at the bottom center of the camera that we got from BaseActivity [notice that we didn’t attach it anywhere yet], the rest should be easy to understand.
We’ll come back to this class later on..
[WARNING: we will be jumping back and forth between classes a lot from now on, so you should pay attention and concentrate which is which]
Now we’ll need to have a scene for the actual game, we’ll call it something totally unrelated like … “GameScene” !
Sorry sorry .. lame joke I know ..
Anyway , create a new class called “GameScene” and make it extend Scene then add those 2 lines to the top:
public Ship ship; Camera mCamera;
The GameScene constructor should look like this:
public GameScene() { setBackground(new Background(0.09804f, 0.6274f, 0.8784f)); mCamera = BaseActivity.getSharedInstance().mCamera; ship = Ship.getSharedInstance(); attachChild(ship.sprite); }
We are using the same lame blue background for the GameScene [cause I’m too lazy to change that] and then create a new Ship object [we call the getSharedInstance() method which figures if we have an object or not, power of singleton !!] and attach the ship’s sprite to the scene [NOT the ship object , the sprite !].
Go back to MainMenuScene and modify your onMenuItemClicked() under the first case, it should be like this:
case MENU_START: activity.setCurrentScene(new GameScene()); return true;
You may run and see what you’ve done, you should navigate to the GameScene when you touch “start” and see your epic ship in all of it’s glory [just the looks]:
I Like To Move It Move It:
It’s been so boring and lame so far , right ? I mean the only thing that moved was the text .. and touching the start button [text thingie] is not that interactive , it shouldn’t be called interactive in the first place!!
Anyway .. let’s have the ship [aka white rectangular shape thingie] move with tilt action , using the device’s accelerometer.
We’ll keep the accelerometer’s speed data saved in the GameScene class, so add a new float to the GameScene class and call it “accelerometerSpeedX”, we’ll get back to this float later on.
Create a new class and call it “SensorListener”, make it implements “SensorEventListener” and add the unimplemented methods, then add those fields .. it should look like this:
static SensorListener instance; GameScene scene; public static SensorListener getSharedInstance() { if (instance == null) instance = new SensorListener(); return instance; } public SensorListener() { instance = this; scene = (GameScene) BaseActivity.getSharedInstance().mCurrentScene; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } @Override public void onSensorChanged(SensorEvent event) { }
The GameScene object scene is used to reference our GameScene, the rest doesn’t need to be explained.
Now go to onSensorChanged() and put this in:
synchronized (this) { switch (event.sensor.getType()) { case Sensor.TYPE_ACCELEROMETER: scene.accelerometerSpeedX = event.values[1]; break; default: break; } }
We used the synchronized block to make sure that we don’t get a concurrentModificationException .. as in make it thread safe in a way.
This should make accelerometerSpeedX in GameScene contain the value of the accelerometer X Speed which we will be using to determine how much to move the ship.
Now let’s create a method to move the ship .. open the Ship class and put this method in:
public void moveShip(float accelerometerSpeedX) { if (!moveable) return; if (accelerometerSpeedX != 0) { int lL = 0; int rL = (int) (mCamera.getWidth() - (int) sprite.getWidth()); float newX; // Calculate New X,Y Coordinates within Limits if (sprite.getX() >= lL) newX = sprite.getX() + accelerometerSpeedX; else newX = lL; if (newX <= rL) newX = sprite.getX() + accelerometerSpeedX; else newX = rL; // Double Check That New X,Y Coordinates are within Limits if (newX < lL) newX = lL; else if (newX > rL) newX = rL; sprite.setPosition(newX, sprite.getY()); } }
While we are at it , add a boolean variable called moveable and set it to true in the constructor, this flag is used to know if we wanna disable the movement of the ship without pausing the whole thing.. we will use it later on.
Regarding moveShip() method, it should basically get the accelerometer data when changed and it moves the ship according to the data you get, to be honest I didn’t write this part of the code ..
I got the one in this thread and modified it to work only on the x-axis, basically it computes where the sprite should go to then checks if it’s within the boundries or not [so it doesn’t leave the screeen], no big deal [The code on the first page doesn’t exactly work, I posted a modified code that works on the same thread in the 2nd page].
As that this method requires the data of accelerometerSpeedX we’ll call it from GameScene , open that class and add this method to it:
public void moveShip() { ship.moveShip(accelerometerSpeedX); }
Before we can have our white brick [aka ship] move around, we need to be able to call this method every frame so we’ll need an IUpdateHandler so create a new class and name it GameLoopUpdateHandler , make it implement IUpdateHandler then add the missing methods.
onUpdate will have one line which looks looks like this:
public void onUpdate(float pSecondsElapsed) { ((GameScene)BaseActivity.getSharedInstance().mCurrentScene).moveShip(); }
That’s a very bad practice, but I was kinda lazy to do it in any better way, basically I’m getting the mCurrentScene from BaseActivity and cast it to GameScene, [I know that at this point of the game the currentScene will be an instance of GameScene] and then call the moveShip() method inside the scene 😀
We still have to do some more preparations , go into GameScene and add those lines to the end of the constructor:
BaseActivity.getSharedInstance().setCurrentScene(this); sensorManager = (SensorManager) BaseActivity.getSharedInstance() .getSystemService(BaseGameActivity.SENSOR_SERVICE); SensorListener.getSharedInstance(); sensorManager.registerListener(SensorListener.getSharedInstance(), sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME); registerUpdateHandler(new GameLoopUpdateHandler());
We set the current scene to be the current GameScene [I know that we were doing that when we clicked on the start button, but that only sets it up AFTER this class is created as in after the constructor finishes being called , we need to change it in the middle] and then have our game listens to accelerometer sensor changes [and create a new SensorListener object so our accelerometerSpeedX gets updated].
At the end of this we register our GameLoopUpdateHandler() as an UpdateHandler.
It’s worth it now, you can move the ship around with tilting the device .. try it ! try it now .. I insist !
Pew Pew:
Let’s start shooting stuff now , shall we ?
We’ll need bullets , so let’s create bullets … create a new class and call it “Bullet” , your class will look like this:
public class Bullet { public Rectangle sprite; public Bullet() { sprite = new Rectangle(0, 0, 10, 10, BaseActivity.getSharedInstance() .getVertexBufferObjectManager()); sprite.setColor(0.09904f, 0f, 0.1786f); } }
Each bullet will be a 10×10 square, and I decided to change it’s color .. change the numbers for the color if you wanna mess with that.
Again, if you wanna use images instead, you could do so by just changing the type of sprite to Sprite and making adjustments inside this class, everything else should work fine regardless.
We’ll be using pools to reuse bullets .. you may wanna read my blog post about pools if you haven’t already.
Even though the post is a part of my old tutorial, it’d give you an idea of what pools are and what they are useful for.
Make a new class called BulletPool that extends GenericPool here’s my full class for you
public class BulletPool extends GenericPool { public static BulletPool instance; public static BulletPool sharedBulletPool() { if (instance == null) instance = new BulletPool(); return instance; } private BulletPool() { super(); } @Override protected Bullet onAllocatePoolItem() { return new Bullet(); } protected void onHandleRecycleItem(final Bullet b) { b.sprite.clearEntityModifiers(); b.sprite.clearUpdateHandlers(); b.sprite.setVisible(false); b.sprite.detachSelf(); } }
I won’t explain this, so if you don’t know what it is then please take a look at my post that I linked previously to get an idea of what pooling is [it’s almost the same code used in there].
First we’ll need to keep track of the bullets we shoot so we know when to remove them and when any bullet hits something [after we create some stuff to shoot].
[Note: if you already did my previous tutorials then this is similar, but I chose to have shooting before creating targets so that I’ll be done with the ship class faster].
So let’s go to GameScene and create a new linked list of Bullets and a count of them:
public LinkedList bulletList;
Then inside the constructor have this line:
bulletList = new LinkedList();
Which does it for this class for now , head back to your Ship class and add a new method called shoot():
// shoots bullets public void shoot() { if (!moveable) return; GameScene scene = (GameScene) BaseActivity.getSharedInstance().mCurrentScene; Bullet b = BulletPool.sharedBulletPool().obtainPoolItem(); b.sprite.setPosition(sprite.getX() + sprite.getWidth() / 2, sprite.getY()); MoveYModifier mod = new MoveYModifier(1.5f, b.sprite.getY(), -b.sprite.getHeight()); b.sprite.setVisible(true); b.sprite.detachSelf(); scene.attachChild(b.sprite); scene.bulletList.add(b); b.sprite.registerEntityModifier(mod); scene.bulletCount++; }
Check if the ship is not moveable then skip [it’s not moveable and shouldn’t be shooting anything too], we get the reference to the current scene [which is our GameScene] and obtain a bullet from the pool.
Set the bullet’s position to be on top of ship’s sprite position [and in the middle].
We create a new MoveYModifier, an entity modifier is a something that you register on entities [sprites/shapes/etc] and when you register them they do some modifications, there are modifiers that rotates and others moves entities in certain ways.
Our Modifier moves an entity along the Y axis by providing the duration it should move across between the initial and final positions you provide.
In our case we move the bullet’s sprite from it’s current position till it’s completely out of the screen.
The bullet is set to be visible and make it detach itself [I know this is already done in the pool , but for some reason it was nagging me sometimes about it having a parent when I attach it, so detaching again won’t hurt].
Attach the bullet to the scene and add it to the linked list, register the modifier [if we didn’t do this part the bullet won’t move, the modifier needs to be registered for it to work], and then incerement the bulletCount.
Before we can use this, we need to do some configurations [it’ll be short I promise].
Go to GameScene again, and make it implements IOnSceneTouchListener then add the missing methods, add this line to the constructor:
setOnSceneTouchListener(this);
And the new method would look like this:
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) { synchronized (this) { ship.shoot(); } return true; }
This just calls shoot() from here and returns true , telling the engine that we handled the touch event here and no need to send it to another place to be handled.
Okay .. I kinda lied .. there is a li’l bit more
Actually , if you fire up the game now it’ll work fine , but we didn’t clean up after the bullets [didn’t return them to the pool] defeating the purpose of having pools for reusability, so let’s do that before we end this section/chapter/finger .. whatever you wanna call it.
Add a new method in GameScene that would look like this
public void cleaner() { synchronized (this) { Iterator it = bulletList.iterator(); while (it.hasNext()) { Bullet b = it.next(); if (b.sprite.getY() <= -b.sprite.getHeight()) { BulletPool.sharedBulletPool().recyclePoolItem(b); it.remove(); continue; } } } }
Iterate over the linked list [using an iterator] and if the bullet went past the screen, return it to the pool [recycle it because we are enviromentalists and stuff] and then remove it from the linked list and continue [this continue will make sense later , I felt too lazy to remove it now and re-add it later on].
Now we just need to call this method, we’ll do that through GameLoopUpdateHandler just add this line inside the onUpdate method:
((GameScene)BaseActivity.getSharedInstance().mCurrentScene).cleaner();
You are ready to go , fire up the game and start shooting bullets into void preparing for the enemy strike !
Calm Down:
As you can see, the bullets shooting are happening too fast .. we need to have some sort of a cool down mechanism so there would be some minimum time between shooting bullets, let’s do this !
I’ll copy this part from my old tutorial , as that it’s the exact same class [and there is no need for me to write again , right ? :P].
So create a new class and call it CoolDown, this is the whole class for you
public class CoolDown { private boolean valid; private Timer timer; private long delay = 400; private static CoolDown instance = null; public static CoolDown getSharedInstance() { if (instance == null) { instance = new CoolDown(); } return instance; } private CoolDown() { timer = new Timer(); valid = true; } public boolean checkValidity() { if (valid) { valid = false; timer.schedule(new Task(), delay); return true; } return false; } class Task extends TimerTask { public void run() { valid = true; } } }
Even though this is a java thingie and not quite related to AndEngine directly, I’ll still explain it though.
I wanted to create a singleton class, so you only have one instance of this type in your whole program [special thanks to Mazyod, check out his blog, he blabbers about lots of useless stuff] thus it explains the getSharedInstance() method behavior [and why the constructor is private].
You call checkValidity() it should return to you true if you can have a bullet and false if you can’t, the valid flag is the one that decides it, if it’s true then it gets toggled and a timer gets a new Task that runs after a certain delay , 400ms in our case here [you can change that if you want] and then returns true telling you that you can have a bullet.
Task is a class that extends TimerTask, it just makes valid true again when called [will be called by the timer after 400ms].
Now just head to the onSceneTouchEvent method inside GameScene and add those 2 lines at the top:
if (!CoolDown.getSharedInstance().checkValidity()) return false;
This will make sure that you don’t shoot bullets to often , so spamming bullets would look like this
Layering Our Enemies:
Even though shooting bullets like this is fun [if you are not having fun so far then you should go and eat a potato] we still need to have something to it .. but let’s organize that first.
If you have ever played any invaders game, you’d notice that the enemies move together, to achieve that we’ll put some kind of Layer on Scene and have all the enemies added to it, so that when we move the layer all of the enemies move together ! [think of it as putting a table and placing everything on top of a table, if you move the table everything on the table moves too].
We got that figured out , let’s start making stuff!
I decided that each Enemy would have a health value of 2 [HP = 2], so you’d need to hit it twice for it to die, it’ll also be a square [what a surprise !] that rotates at all time [it’ll also have a random color I generated].
Anyway , let’s create a new class and call it Enemy, it has those lines at top:
public Rectangle sprite; public int hp; //the max health for each enemy protected final int MAX_HEALTH = 2;
MAX_HEALTH determines how many hits it needs to die , you can change this if you want.
Here’s the constructor and the initialization methods:
public Enemy() { sprite = new Rectangle(0, 0, 30, 30,BaseActivity.getSharedInstance().getVertexBufferObjectManager()); sprite.setColor(0.09904f, 0.8574f, 0.1786f); init(); } // method for initializing the Enemy object , used by the constructor and // the EnemyPool class public void init() { hp = MAX_HEALTH; sprite.registerEntityModifier(new LoopEntityModifier( new RotationModifier(5, 0, 360))); }
I’ll only explain the last line, we are registering a new Entity modifier [something like the MoveYModifier we used for bullets] that’s called LoopEntityModifier, this one takes other Modifiers as arguments and loops over them for a certain count number, and if not specified it’d loop forever.
We are giving the LoopEntityModifier a RotationModifier , telling it to rotate the sprite from 0′ to 360′ with a duration value of 5.
Add 2 more methods to your class:
public void clean() { sprite.clearEntityModifiers(); sprite.clearUpdateHandlers(); } // method for applying hit and checking if enemy died or not // returns false if enemy died public boolean gotHit() { synchronized (this) { hp--; if (hp <= 0) return false; else return true; } }
The clean() method just cleans the sprites, we’ll use that before we return enemies to the pool [yes we’ll have an EnemyPool class too] which will explain why we have this init() method too.
The gotHit() method gets called when you hit an Enemy with a bullet, it reduces it’s health and if the enemy dies then it returns false to the caller [which will take care of removing the enemy … we’ll get back to that later on].
Now we have our enemies created, let’s create that EnemyLayer class and make it extends Entity.
Add those lines to the top of the class:
private LinkedList enemies; public static EnemyLayer instance; public int enemyCount; public static EnemyLayer getSharedInstance() { return instance; }
I’m not explaining that [you should already know that by now] we’ll add some methods before we get into the real thing, let’s add an isEmpty method that tells us if the enemy layer is empty or not [if all enemies are killed or not].
public static boolean isEmpty() { if (instance.enemies.size() == 0) return true; return false; }
And another one that returns an iterator for the enemies linked list:
public static Iterator getIterator() { return instance.enemies.iterator(); }
Notice that both of them are static methods so you should expect that we’d use them from somewhere else.
Let’s get to the main thing now starting with the constructor
public EnemyLayer(int x) { enemies = new LinkedList(); instance = this; enemyCount = x; restart(); } public void restart(){ }
I decided to design this layer in a way that you can specify how many enemies you want, when creating a new EnemyLayer you’d provide it with how many enemies should it have and it’d arrange them in a proper way [but don’t overdo it and put lots of enemies, they’d overflow out of the screen] so the x parameter in the constructor defines how many you need, and the enemyCount variable saves that number for future usage [inside the restart method].
Let’s get to the restart() method where all the main work is in.
As that we will be using restart() method later on [as the name suggests] when we wanna restart the game, we’ll have to clear stuff at first like this:
enemies.clear(); clearEntityModifiers(); clearUpdateHandlers();
———————————————————————————————————————————————————————-
[Annoying note: in the middle of writing this I realised that I didn’t talk about the enemy pool and we’ll need to do use it, so I’m putting this part here :D]
Note: you can skip this part if you know how to do it yourself [it’s a good practice to do something by yourself :P]
EnemyPool is like the rest of the pools we used, but the version I made got some small changes [other than changing the type to Enemy].
Basically it’s just using one extra overriden method that gets called before obtaining an item from the pool
@Override protected void onHandleObtainItem(Enemy pItem) { pItem.init(); }
and changing the onHandleRecycleItem method to this one
/** Called when a projectile is sent to the pool */ protected void onHandleRecycleItem(final Enemy e) { e.sprite.setVisible(false); e.sprite.detachSelf(); e.clean(); }
The rest is the same as the BulletPool
[Annoying note: this ends the annoying note, back to EnemyLayer class]
———————————————————————————————————————————————————————-
A random method here:
public void purge() { detachChildren(); for (Enemy e : enemies) { EnemyPool.sharedEnemyPool().recyclePoolItem(e); } enemies.clear(); }
This would detach all children of the EnemyLayer , iterate over all enemies and recycle them all then clears the ArrayList.
I thought it’d be a good enterance effect to have the enemies [square thingies for now] move in the screen from random positions to their places [yes I’m that awesome, I think about awesome stuff like this when I’m not sleeping].
So in the restart() method we’ll iterate over the enemyCount variable, create new enemies, and place them at random spots outside the camera [so they are not viewable] then have them move to their correct places at once, let’s do that !
for (int i = 0; i < enemyCount; i++) { Enemy e = EnemyPool.sharedEnemyPool().obtainPoolItem(); float finalPosX = (i % 6) * 4 * e.sprite.getWidth(); float finalPosY = ((int) (i / 6)) * e.sprite.getHeight() * 2; Random r = new Random(); e.sprite.setPosition(r.nextInt(2) == 0 ? -e.sprite.getWidth() * 3 : BaseActivity.CAMERA_WIDTH + e.sprite.getWidth() * 3, (r.nextInt(5) + 1) * e.sprite.getHeight()); e.sprite.setVisible(true); attachChild(e.sprite); e.sprite.registerEntityModifier(new MoveModifier(2, e.sprite.getX(), finalPosX, e.sprite.getY(), finalPosY)); enemies.add(e); }
I’ll try to explain this [urgh .. ain’t that easy to explain >_<] we obtain an Enemy object from the pool, then we decide where it should be when it finishes it’s “fabulous” enterance animation in x and y.
ok .. that didn’t make a lot of sense .. we calculate where it goes to like this
I wanted to have a maximum of 6 enemies on each row , so I take count mod 6 [if you don’t know what mod is then you might wanna read about that or just play around with it to see what it does] then multiply it by 4 to have some gap between the enemies, multiply by the sprite’s width and you get the x position.
The y position figures out which row you need to put the enemy on with the division operation then puts a smaller gap between rows than we had between columns.
[Note: Those calculations were done regarding the resolution we chose when we created this project, if you chose a different resolution it may not look right here]
The rest is randomly choosing somewhere to place the enemy at [outside the camera] and then set it visible, then make it move from it’s current position to the final position and add it to our linked list.
After we are done with configuring the enemies, let’s finish configuring the Layer itself:
setVisible(true); setPosition(50, 30); MoveXModifier movRight = new MoveXModifier(1, 50, 120); MoveXModifier movLeft = new MoveXModifier(1, 120, 50); MoveYModifier moveDown = new MoveYModifier(1, 30, 100); MoveYModifier moveUp = new MoveYModifier(1, 100, 30); registerEntityModifier(new LoopEntityModifier( new SequenceEntityModifier(movRight, moveDown, movLeft, moveUp)));
The numbers above were mainly generated by trial & error and some math [which I forgot how I did and don’t feel like thinking anymore about this], but I’ll explain what they do.
I wanted to have the whole layer move in a rectangular like motion, thus explains the movRight,moveLeft,..etc modifiers.
A SequenceEntityModifier modifier takes a bunch of modifiers as arguments and runs them one by one, since we want them to move forever, we’ll place the SequenceEntityModifier inside a LoopEntityModifier and register it for the layer.
Before we close this class and never open again, add this one last 2 methods to it
public static void purgeAndRestart() { instance.purge(); instance.restart(); }
And override onDetach()
@Override public void onDetached() { purge(); super.onDetached(); }
which will make sure we clean up when detaching the EnemyLayer [will do that later on]
And we are done !
How do we test this ? easy go to the constructor of GameScene and add this line [I like to put it after setting the background color on top
// attaching an EnemyLayer entity with 12 enemies on it attachChild(new EnemyLayer(12));
You can see that I put 12 enemies, you may play around with it and change the number to see how it works, run the game and celebrate your work !
Kill The Squares:
Let’s now kill some squares ..err I mean aliens , to do so we have to detect when a bullet would hit something and when the alien loses all it’s health , it should be gone !
We’ll do most of the work in the cleaner() method inside GameScene, replace your current cleaner() method with this one
public void cleaner() { synchronized (this) { Iterator eIt = EnemyLayer.getIterator(); while (eIt.hasNext()) { Enemy e = eIt.next(); Iterator it = bulletList.iterator(); while (it.hasNext()) { Bullet b = it.next(); if (b.sprite.getY() BulletPool.sharedBulletPool().recyclePoolItem(b); it.remove(); continue; } if (b.sprite.collidesWith(e.sprite)) { if (!e.gotHit()) { EnemyPool.sharedEnemyPool().recyclePoolItem(e); eIt.remove(); } BulletPool.sharedBulletPool().recyclePoolItem(b); it.remove(); break; } } } } }
What that code does is , iterate over the enemies and for each enemy, you iterate over all the presented bullets, and as before, if the bullet left the screen then remove it and continue [that’s why we had a continue :D] if not then you check if this bullet collides with the enemy or not.
If the bullet collided, then you send a gotHit() method call for the enemy, if it returned false it means that the enemy’s hp went to 0 [or below] so we recycle it back to the pool and then we recycle the bullet and break out of the loop to go to the next enemy.
Simple ‘eh ? run it now and see what you did .. KILL THOSE ALINES NOW !! [remember, 2 hits to kill]
What’s My Purpose In Life ?:
The basic game mechanism is done, but let’s add some purpose to this game, we’ll calculate the accuracy of the player .. so the more misses he makes the lowest his accuracy is, and then you can restart the game to try again.
Add a new int to GameScene and call it missCount, then head to the Ship class and add a method called restart()
// resets the ship to the middle of the screen public void restart() { moveable = false; Camera mCamera = BaseActivity.getSharedInstance().mCamera; MoveXModifier mod = new MoveXModifier(0.2f, sprite.getX(), mCamera.getWidth() / 2 - sprite.getWidth() / 2) { @Override protected void onModifierFinished(IEntity pItem) { super.onModifierFinished(pItem); moveable = true; } }; sprite.registerEntityModifier(mod); }
What this method does is that it disables the movement of the ship with the accelerometer, then move the ship to the middle of the screen and renable the movement of the ship.
Then add this method to the GameScene class.
// method to reset values and restart the game public void resetValues() { missCount = 0; bulletCount = 0; ship.restart(); EnemyLayer.purgeAndRestart(); clearChildScene(); registerUpdateHandler(new GameLoopUpdateHandler()); }
Call this method from the constructor and remove the line where you register the UpdateHandler from the constructor.
And now whenever a bullet misses, you should increment the missCount [if you don’t know which part is that then you may need to pay more attention to what you type and stop copy pasting the code :P].
And as that we are restarting the EnemyLayer here, you might wanna remove the call for the restart() method inside the EnemyLayer constructor as this will do it for you.
We’ll now need to add a new scene to present the results, and we’ll call it … ResultScene ?
This new Scene will not replace the old one, it’ll hover over the old scene as an overlay .. so your ResultScene should extend CameraScene and while you are at it , make it implements IOnSceneTouchListener and add the missing methods [only one actually].
The results will be a text that moves slowly from the bottom of the screen to the middle, and you can’t do anything till the text reaches it’s final position .. then if you touch the screen it gets dismissed.
Use the constructor that takes Camera as a parameter, but first add those 2 lines:
boolean done; BaseActivity activity;
Let’s get back to the strings.xml file and add a new value that says “Accuracy” and with a tag of accuracy [or anything you want], The constructor would be like this:
public ResultScene(Camera mCamera) { super(mCamera); activity = BaseActivity.getSharedInstance(); setBackgroundEnabled(false); GameScene scene = (GameScene) activity.mCurrentScene; float accuracy = 1 - (float) scene.missCount / scene.bulletCount; if (Float.isNaN(accuracy)) accuracy = 0; accuracy *= 100; Text result = new Text(0, 0, activity.mFont, activity.getString(R.string.accureay) + ": " + String.format("%.2f", accuracy) + "%", BaseActivity .getSharedInstance().getVertexBufferObjectManager()); final int x = (int) (mCamera.getWidth() / 2 - result.getWidth() / 2); final int y = (int) (mCamera.getHeight() / 2 - result.getHeight() / 2); done = false; result.setPosition(x, mCamera.getHeight() + result.getHeight()); MoveYModifier mod = new MoveYModifier(5, result.getY(), y) { @Override protected void onModifierFinished(IEntity pItem) { done = true; } }; attachChild(result); result.registerEntityModifier(mod); setOnSceneTouchListener(this); }
You can see that we disabled the background making it as an overlay layer, the rest should be easy to understand, just notice that we have overridden a method inside the MoveYModifier to set the done flag to true when the movement is done, now the method onSceneTouchEvent would have those 4 lines:
if (!done) return true; ((GameScene) activity.mCurrentScene).resetValues(); return false;
Head back to the cleaner() method inside GameScene and add those lines on top inside of the synchronized block
// if all Enemies are killed if (EnemyLayer.isEmpty()) { setChildScene(new ResultScene(mCamera)); clearUpdateHandlers(); }
And we are done, run it and see the result of your work [also see how accurate you are at playing it :D]
Cleaning After Yourself:
Didn’t your mom teach you to clean after you are done working ? this is no exception !
we have to clean up when closing the game so the next time you run it it’ll work properly
[Thanks to BreakingFloor from the comments to notice a bug that caused this whole section thingie to be added]
GameScene again and add this detach() method:
public void detach() { Log.v("Jimvaders", "GameScene onDetached()"); clearUpdateHandlers(); for (Bullet b : bulletList) { BulletPool.sharedBulletPool().recyclePoolItem(b); } bulletList.clear(); detachChildren(); Ship.instance = null; EnemyPool.instance = null; BulletPool.instance = null; }
And inside BaseActivity class [sorry I lied we opened this again :P] override onBackPressed() [this one gets called when back button is pressed] to be like this:
@Override public void onBackPressed() { if (mCurrentScene instanceof GameScene) ((GameScene) mCurrentScene).detach(); mCurrentScene = null; SensorListener.instance = null; super.onBackPressed(); }
This would call detach() method if you were on the GameScene which detaches all children including the EnemyLayer calling onDetach() inside it cleaning it up 😀
BONUS ! Explosion Effect Using Particle System
Explosions are always a good thing , no exceptions ! so I added this chapter because I thought that the game was missing explosion.
I wrote a method that would create an explosion effect on any coordinate you provide on any target [Scene for example] you specify.
It’s a general method, you can place it in any class [I didn’t really think about where to put it] so I placed it in GameScene, add the following there
private void createExplosion(final float posX, final float posY, final IEntity target, final SimpleBaseGameActivity activity) { }
To create an explosion effect we would need 3 main things
- Particle emitter
- Particle system
- timeHandler to remove the system
But in our case, we’ll need to create an IEntityFactory too for our Rectangular particles .. it’s basically something that would provide small green rectangles to give an effect that the enemy exploded! [little shards of the enemy]
[NOTE: you can use sprites instead of small rectangles, Check the AndEngine Simple particle example in the AndEngine Examples to get an idea of how to use sprites, should be easy when you are done with this].
The following code does that
int mNumPart = 15; int mTimePart = 2; PointParticleEmitter particleEmitter = new PointParticleEmitter(posX,posY); IEntityFactory recFact = new IEntityFactory() { @Override public Rectangle create(float pX, float pY) { Rectangle rect = new Rectangle(posX, posY, 10, 10, activity.getVertexBufferObjectManager()); rect.setColor(Color.GREEN); return rect; } }; final ParticleSystem particleSystem = new ParticleSystem( recFact, particleEmitter, 500, 500, mNumPart);
We have 15 particles emitting at a rate of 500 [we set both the minimum and maximum rate to 500] you can mess around with those numbers to get different effects .. chose whatever you like [do that when we are done with this chapter so you can see the effect :P].
We’ll have our particles go into random directions while rotating and fade out [change Alpha value] at the same time, the particle system would last for a period of 2 seconds [the mTimePart] so we’ll have the particles fade out before the particle system gets removed so we don’t get a sudden disappearing effect.
particleSystem.addParticleInitializer(new VelocityParticleInitializer(-50, 50, -50, 50)); particleSystem.addParticleModifier(new AlphaParticleModifier(0,0.6f * mTimePart, 1, 0)); particleSystem.addParticleModifier(new RotationParticleModifier(0, mTimePart, 0, 360)); target.attachChild(particleSystem);
The velocity range is being set to -50 and 50 for x and y as max and min [it gets chosen by the system] for each particle so we may get any combination, that’s an Initializer so it modifies the particle before it gets emitted.
Next we have the the system change the Alpha value of each particle from visible 1 to invisible 0 , for a duration of 1.2 [0.6 * 2 = 1.2] seconds and have each particle rotate while moving too.
Even though this is happening very fast and people might not notice those stuff, but giving attention to small things makes a better product [says the guy who is using rectangles instead of image sprites :P]
Now we have to make sure we remove the particle system from the target [in our case we’ll be adding them to the EnemyLayer], we’ll do that using a timeHandler like we did with the CoolDown
target.registerUpdateHandler(new TimerHandler(mTimePart, new ITimerCallback() { @Override public void onTimePassed(final TimerHandler pTimerHandler) { particleSystem.detachSelf(); target.sortChildren(); target.unregisterUpdateHandler(pTimerHandler); } }));
Lastly , go to the part where you remove and recycle the the enemies inside the cleaner() method and add this line at the top of the if statement [before you recycle it !]
createExplosion(e.sprite.getX(), e.sprite.getY(), e.sprite.getParent(), BaseActivity.getSharedInstance());
You might also wanna clearUpdateHandler() on your onDetach() method inside the EnemyLayer class just to be safe, enjoy explosions !
Final words (and full project source code):
The tutorial ends here, remember that the whole idea of this project was to create a game without using any sprites and to use OOP, then I decided to write a tutorial about it .. so it may not be THAT good cause it wasn’t a tutorial in the first place.
I do feel that I didn’t give this tutorial the attention it needed and that it’s not that clear [and feels kinda boring] but that’s the best I could do at the moment.
The full project is available here or on github.
And as always, if there was something wrong or something unclear [or missing] then don’t hesitate to drop a comment telling me about it [even for spelling errors !].
Good luck in your games development !
Note: sometimes when closing the game it crashes [about once in 10 times] from inside the Engine’s code, I’m not exactly sure why is that happening and don’t really have the time to look at it for now .. if you figured why is this happening drop a comment explaining it and I’ll update the post and credit you.
Started with AndEngine last week and your tutorials are superb. Helped me with managing Bullets/Enemies and picked up some tips along the way. Great job!
Thanks, Jim. Another great tutorial !
I will see later… 🙂
Just wanted to say thanks again for taking the time out to do this Jim, I really appreciate it.
That one great tutorial Jim :p thanks
keep it up :p
I have an issue with your singleton declarations, Ship,SensorListener classes.
If you quit the game and run it again it throws exceptions ?
Well spotted !
Apparently when you quit the game it doesn’t remove those static objects [memory leak .. I always forget that Java got memory leakage too >_<]
just add this line before attaching the ship inside GameScene
ship.sprite.detachSelf();
I'll update the tutorial with those info
Also if you don’t mind SensorListener won’t work the second time too
I made some changes with the EnemyLayer and added a new section, check them out for a fix
Hi,
Thanks for the great tutorial,
I tried downloading the full project but the link doesn’t seem to be working. Any chance you can upload it again?
Thanks
The link works fine for me here, may you try downloading from a different browser ? [or is mediafire blocked for you ?]
Your right, I’ve been able to download it now.
I have no idea why it wasn’t working before (mediafire gave me a page telling me the file didn’t exist)!
Hi,
you made a good job I see
I tried to do like you but i don’t succes
I did all like you (Android 4.0, ADT 18.0, Eclipse Git addon, GLES2.0) but it still not working..!
I tried to take your all project and compile it but there always have errors and even if i tried to resolve then, i can’t make an .apk (“Conversion to Dalvik format failed with error 1”)…
I really hope you can help me.
Thank !
Sénastien
That error is usually caused by having 2 copies of the same library , try cleaning your project [project -> clean] and restarting eclipse
Make sure that the android SDK is working [hello world application is working] and tell me what happens
[Note: I edited your comment about the last part but I still have a copy, if that didn’t work I’ll try to help you .. test and tell me]
more info http://stackoverflow.com/questions/2680827/conversion-to-dalvik-format-failed-with-error-1-on-external-jar
Yes I already read it and do it… so many times… maybe I’m too beginner but it looks like easy !
Seriously I really would like your help, I think it will not take much time.
Thank for your answer,
Sébastien
Hmmm. Since the Android Emulator can’t run with AndEngine. How do you see the output?
you plug in your device (phone/tablet) to your computer , make sure the drivers are installed properly and run [make sure you are building to an SDK that’s less than your phone’s android version]
the game should run on your device directly
Actually you can run it on the Android Emulator with the latest version of the AVD. You just need to set enable GPU and it can run GLES2 AndEngine no problem!
I never tried that , but I’ll include your comment in the post
Thanks. Yep if you edit one of your existing virtual devices in AVD Manager or create a new one, under Hardware section you can click New -> select GPU emulation as property -> set Value to yes. This will allow GLES2 to run on the emulator; however, I believe that you need to disable Snapshot for this to work.
Where is the difference between SimpleBaseGameActivity and BaseGameActivity?
From the AndEngine source code for the SimpleBaseGameActivity “This class exists so that the callback parameters of the methods in {@link IGameInterface} get called automatically.”
SimpleBaseGameActivity extends BaseActivity
Ah ok, thanks jimmar.
And another question:
How could I replace the rectangle for a .png? (sprite of ship class)
Just replace the rectangle type of sprite to type of “Sprite”
check the AndEngine Sprite example on how to use sprites
https://github.com/nicolasgramlich/AndEngineExamples/blob/GLES2/src/org/andengine/examples/SpriteExample.java
you’ll need to load the sources, and modify the constructor to create a new sprite instead of the rectangle , the rest of the code should work properly
Very nice tutorial! Thank you, helped me a lot!
(Note: you have a few messed up if conditions:
in part about moving ‘ship’ using accelerometer
if (newX newX = sprite.getX() + accelerometerSpeedX;
else
newX = rL;
and in where you explain cleaner in GameScene
if (b.sprite.getY() BulletPool.sharedBulletPool().recyclePoolItem(b);
it.remove();
continue;
}
)
Thanks for pointing that out but in my defense I didn’t mess this up
it’s wordpress’ fault .. every now and then it decided to parse some parts of the code as HTML instead of text >_>
Just downloaded the whole tutorial why do you use import.org.anddev rather that import.org.andengine?
I don’t .. the code I have got import org.andengine [which class did you see that in ?]
and btw , I don’t add imports manually , eclipse manages that for me
In every class except in your cooldown class. BTW, I downloaded the tutorial via Github.
oh craps !
I put the wrong code on github >.< That's the version I first created for GLES1
delete your old fork and fork again , sorry about that
What do you mean by fork?
fork is for github users , if you do not use it then nvm .. just redownload the code
Hi… great tutorial)
How to do that – when i’m in a GameScene, and when i press back button on mobile – app close, but i want to get back in the meny, and then if i in meny, i press back button – the app will close?
sorry for my english, i’m from russia!
basically , in your onBackPressed method override inside the BaseActivity you’ll have to check which scene is your current and do what you want .. for example
if(mCurrentScene instanceof GameScene){
//..unload the GameScene attributes and clean it up then change the current scene to main menu
}
Can you write the detailed code for your example .. please)
this should work http://pastebin.com/F8zGHEym
I didn’t test it , but understand what’s happening and figure it out yourself .. that’s part of the learning process 😀
thx… but code.. doesn’t working .. ( app is closing with error
http://pastebin.com/TM0p9wQX – this code is working, but sometimes ship is not moving, or app crash with the error.. Is this code correct?
I’m new at programming.. sorry for attacking you with my questions.
if you are new to programming I suggest you work on that before getting into game programming
you should check the logCat and see what the error is and try to solve it .. sorry but I don’t provide personal tuition
So, I tried running different examples on AndEngine and I connected my own phone since it doesn’t run on an emulator. When I try to run it this error occurs “Android library projects cannot be launched”. But I successfully ran your tutorial. Great tutorial btw. 😀
Apparently you can run it on the emulator if you enabled GPU Acceleration on the Emulator
and thank you 😀
How will you enable the GPU acceleration? Sorry noob here. -_-
a quick google search got me those
https://plus.google.com/108967384991768947849/posts/DSi3oAuNnS7
or
https://developer.android.com/tools/devices/emulator.html#acceleration
this is wrong , cos activity.setCurrentScene takes other parameter type then MainMenuScene returns
DelayModifier dMod = new DelayModifier(2, new IEntityModifierListener() {
@Override
public void onModifierStarted(IModifier arg0, IEntity arg1) {
}
public void onModifierFinished(IModifier arg0, IEntity arg1) {
activity.setCurrentScene(new MainMenuScene());
}
});
registerEntityModifier(dMod);
it’s not wrong , setCurrentScene takes a Scene object , MainMenuScene extends MenuScene which extends Scene , so it should work
I try to run the tutorial, but when i type exactly the koskow code has posted, I have errors because not receive the second parameter, and eclipse try to resolv this deleting new IEntityModifierListener(){});
Can you helpme with this error, really can’t explain what is the reason of that error :S
I updated the post with another way of doing it , I’m not sure why this won’t work but the other method should work
go check it out 😀
Nice job there. How about a mouse joint app tutorial? Haha. Just saying. 🙂
so far I haven’t done any specific tutorials , all of mine are complete games [or something you’d call a game :P]
I’m currently busy working on lots of random stuff and doing other life stuff 😛
but maybe someday .. you never know 😀
Haha. Just sayin though because we’re doing a mouse joint based right now for our capstone project. And we’re having a hard time figuring it out how to use mouse joint. But yeah keep up the good work. 😀
Hey Jimmar,
im in the beginning and copied the code word for word but the splash doesnt turn to the main. so i cant get past that part. its supposed to take 2 seconds right. i test it and just sit here and it never takes it to the blue screen where it says start.
Maybe you didn’t register the entity modifier after you created it [the one that waits for 2 seconds]
you can also go to the github link [at the bottom of the post] and view my code for those certain classes , maybe you missed a part or something [sometimes wordpress messes up my code too .. so it could be wordpress’ fault]
Hello JiMMaR, thanks for your tutorials, they are really great 🙂
I have a question concerning the splash screen. I don’t understand how to load textures for the game. Could you provide an exemple? (in loadResources() of SplashScene)
If, for exemple, I want to have a sprite for my ship, how should I load it in SplashScene, and use it in my GameScene?
Thanks again for everything,
trifus
you can use this example to figure out how to load textures
https://github.com/nicolasgramlich/AndEngineExamples/blob/GLES2/src/org/andengine/examples/SpriteExample.java
there are also other examples in there for loading animated sprites , check them out !
Thanks for the quicke reply!
I’m not having a problem with the load of textures itself. I read your other tutorial (with the ninja) 🙂
My problem is to load a texture in SplashScene, and use it in another file (GameScene)
I must declare the ITexture and ITextureRegion in SplashScene, in loadResources(), I get it, but how use them in GameScene?
In the exemple you gave me:
final Sprite face = new Sprite(centerX, centerY, this.mFaceTextureRegion, this.getVertexBufferObjectManager());
Instead of this.mFaceTextureRegion, since it is not declared there, must I write SplashScene.mFaceTextureRegion? It must be static then?
My question seems odd, but I can’t figure the proper way to do it, I don’t know why 😀
for this you have 2 approaches
1 – have those objects declared as static variables , so you can access them as SplashScene.mFaceTextureRegion. [not recommended for big games]
2 – create a SINGLETON class to manage resources [i.e ResourceManager] and have all your texture variables in there, then set setters and getters to get them [or just make them public and access them directly] .. whichever you prefer
just make sure that your ResourceManager is a singleton, and you don’t create more than one instance of it !
and your question is not odd , it’s a game design problem 😀
Thanks! Perfect answer 🙂 That was I thought.
So my idea with the static variables was valid, but not the best one 😀
I will try a singleton class then.
Thank you for this quick and useful answer!
trifus
JiMMar great tutoral, but i would like to ask and say sth. You said that:
” have those objects declared as static variables , so you can access them as SplashScene.mFaceTextureRegion. [not recommended for big games]” well im not sure for that.
I red http://developer.android.com/guide/practices/performance.html#internal_get_set
and using static fields is recomended for that. Of course 2nd option (singleton) is usless as well. But i think in big projects is better using static fields to get sth.
and one more time thanks for great tut:)
regards Toby
That link was talking about the setters and getters and suggested that you should access the data directly when inside the class
and the next topic suggests that you use final static whenever possible over just static.
and that’s not recommended for big games cause you may have issues remembering where you saved your texture object , and if the main object class is not a singleton , there is a chance that you create another instance of it which means that this new instance won’t have the same objects in the first one which means the data you initialized won’t be usable from this new instance.
This is a matter of taste and habit too .. I’m currently going with the ResourceManager method, here’s an example of my class
http://pastebin.com/h1NiLNZM
thanks 🙂
hey jim fantastic job …(though i hav nt tried it yet….but atleast u gave a meaningful text which i can undrstnd….) !!!
wht abt a video tut abt it….it makes life more easy !!!
thnks bdw !!!
great one !!
I’m not a fan of video tutorials 😛 [specially for mere text programming that doesn’t include tricky UI]
I think you can find couple of video tutorials about AndEngine on youtube though
as u say sire….but i wish and hope u will continue to more complex tuts abt andengine….
(well i am tryng this thing now….lets c how it shapes out)
only use onModifierFinished or DeepCopy for animation trigger many times
Please help Me!
I’m not sure what you mean by this , could you clarify ?
sem = new SequenceEntityModifier(pem, am2) {
@Override
public void onModifierFinished(IModifier pModifier,
IEntity pItem) {
// TODO Auto-generated method stub
super.onModifierFinished(pModifier, pItem);
“AAAA”
}
};
mSpAttack.clearEntityModifiers();
mSpAttack.registerEntityModifier(sem);
=>> “AAAA” is worked but mSpAttack trigger only one times
sem = new SequenceEntityModifier(pem, am2) {
@Override
public void onModifierFinished(IModifier pModifier,
IEntity pItem) {
// TODO Auto-generated method stub
super.onModifierFinished(pModifier, pItem);
“AAAA”
}
};
mSpAttack.clearEntityModifiers();
mSpAttack.registerEntityModifier(sem.deepCopy());
=>> “AAAA” is not worked but mSpAttack trigger more times
JiMMaR Help Me! please!
HI, Are-you a link for library or jar is equal AndEngine ? please
I don’t really understand what you mean ..
but there is no jar file anymore .. you download the code and add it as a library to the project
here’s the tutorial of how to do that
https://jimmaru.wordpress.com/2012/04/23/setting-up-andengine-gles2-0/
Shouldn’t LoadResources() in the SplashScene class look more like this:
private void LoadResources(){
//TODO: this will be used to load
//images, music etc…
DelayModifier dMod = new DelayModifier(2);
dMod.addModifierListener(new IModifierListener(){
@Override
public void onModifierStarted(IModifier arg0, IEntity arg1){
}
@Override
public void onModifierFinished(IModifier arg0, IEntity arg1){
activity.setCurrentScene(new MainMenuScene());
}
});
registerEntityModifier(dMod);
}
LOVE the Tutorial BTW. I’m not trying to be a code troll, I was just having an issue implementing the method. 🙂
nobody considered you as a code troll 😛
and in AndEngine there are Modifiers and EntityModifiers, your method is correct but mine is correct too
there are lots of things with no right answer , both are correct 😀
Hello JiMMaR!
i have read this tutorial and was a great help for me, tried your approach of using scenes in a different class then extending it to scene class.
however, when adding sprites, activity(which is BaseActivity.getSharedInstanced).getTextureManager() results to a null pointer exceptions, is there a workaround for this. TIA.
nvm, i missed one line, and it bugged down everything.. 🙂
Hi, thanks for this tutorial, It’s help me so much. I think that you need to make more tutorials like this, or expanding this example with tutorials about how to manage assets and more, would be very useful 😀
Sir How can you fix the resolution for the android device ??
Thank you for your tutorial .. good job
you can set certain resolution [for example width = 800 , height = 480] and the game will be scaled up/down to match the device’s actual resolution
or you can work with equations on all positions and have couple of assets ready for it [lots of work, but better quality]
I have only skimmed through the code on github, but I noticed that there are a lot of circular dependencies. For an example, the GameScene has a Ship, but on the same time does the Ship know about the GameScene. This isn’t considered good coding practice, so you may want to read about it. 🙂 I guess this is a good starting point: http://en.wikipedia.org/wiki/Circular_dependency
sir Thank you for your great tutorial ..
very nice
sir can i request for make a tutorial for texturepacker for sprite
thank you sir more power 🙂
I’ve been thinkin about that for a while, I’ll consider it [not making any promises ]
Hi, mate.
I’m newbie, and I just learned this Andengine.
It’s awesome and I was interested to this tutorial, but It make me a little confused cause of just piece of code that I can read, not all project.
I got error, espessially when I create Create a new class called MainMenuScene that extends MenuScene and implements IOnMenuItemClickListener.
May I know whole of this source code?
At least Java on src folder project.
Thanks so much 🙂
that means that your class will be like
class MainMenuScene extends MenuScene implements iOnMenuItemClickListener{
}
the whole source code is available at the last section of the tutorial, I provided a mediafire link and a github link
you can download from both , and can also view the code on github
Question in this part for EnemyPool
@Override
protected void onHandleObtainItem(Enemy pItem) {
pItem.init();
}
Why did you need to call init()? why not just return an enemy object immediately since init() would be called in constructor Enemy() anyway?
@Override
protected Object onAllocatePoolItem() {
// TODO Auto-generated method stub
return new Enemy();
}
in Enemy(), init() is called.
That’s the point of using a pool , when you are returning an item to the pool it stays there till you call it again , with it’s same properties
when you call it back , onHandleObtainItem is called so we init it [constructor is not called again , this is a reused object]
when there are no items in the pool, onAllocatePoolItem gets called which creates a new object [and constructor gets called]
hope that cleared it 😀
oh didn’t realize it till now that the call back was onhandle and not onallocate. i get it now. thanks for the clarification! 😀
Hi Jim! Just one more question. Again about the pool. the method obtainPoolItem() calls both onHandleObtainItem and onAllocatePoolItem? The difference is just that onAllocatePoolItem is called if there is no item in the pool. And if there is an available item to be reused, onHandleObtainItem is called.Did i get that right? Just wanna ask why the bullet pool didn’t have onHandleObtainItem if it’s job is to reuse recycled items in the pool. Since Bulletpool only has onAllocatePoolItem, does that mean that it creates new Bullet items everytime shoot() is called? Thanks.
Notice that those methods are overriden , so they get called even if you didn’t write them [part of the GenericPool class]
the only reason BulletPool didn’t have onHandleObtainItem is because I’m initializing it in shoot() instead of doing that in the pool class
I’m kind of showing examples of how pools can be used in 2 places with 2 different cases and how you can initialize the object in the pool instead of doing that after obtaining it
Oh right since BulletPool is a sub class of Generic Pool. I totally get it now. Thank you very much for the effort of explaining. You really explain things in a way that could easily be understood. 😀 This will really help me out a lot!:D
Glad I could be of any help 😀
Hello JiMMaR I really aprecciate your tutorials and your help. Sorry for my english.I hope you understand 🙂 I follow all the steps like you explain but i got error when i run the proyect on android emulador couldnt start ,I select Gpu emulation as property but i get the same error,but this doesnt happend whit gles1… I try running on my smarthphone(ISC android 4.0.3 ) ,i can see the icon of android proyect but suddenly stop
By default GLES2.0 doesn’t support the emulator .. I suggest you just switch to using a smartphone
and I can’t really tell what the problem with your phone is , try reading the log and see if you did something wrong or not
I think you get Error because You don’t install AndEngine 2.0 and finally you place this project the same folder level of AndEngine……
http://perle-development.com/tutorials/setup/
Emulator run this project OK!
In my opinion I advise you following the tutorial above, testing step by step and looking sources code on gits together.
Firstly thanks for your great tutorial. This tutorial is awesome and helpful for me. I tried to used sprite instead of rectangle object and include explosion sound to Enemy class. It’s work well but doesn’t show ResultScene :(. ResultScene normally shown if not using sprite. My Enemy class look like below:
private BaseActivity activity;
public BitmapTextureAtlas mBitmapTextureAtlas;
public TextureRegion mTextureRegion;
public Sprite sprite;
public int hp;
protected final int MAX_HEALTH = 2;
public Enemy() {
activity = BaseActivity .getSharedInstance();
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath(“gfx/”);
mBitmapTextureAtlas = new BitmapTextureAtlas(
activity.getTextureManager(), 128, 256, TextureOptions.BILINEAR);
mTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(mBitmapTextureAtlas, activity, “bee.png”, 0, 0);
mBitmapTextureAtlas.load();
sprite = new Sprite(0, 0, mTextureRegion,
activity.getVertexBufferObjectManager());
init();
}
I guess my activity always load mBitmapTextureAtlas and EnemyLayer never empty right?
Do you have any idea?
Thank in advance.
you can check how many children and entity has [in this case EnemyLayer] by using EnemyLayer.getChildCount(), try printing that value to the log [using Debug.d()] every time an enemy is killed to check if that’s the problem or not
as for the way you are doing it , since you are using the same texture for all sprites , it’s better to load one texture region and use the same one for all sprites .. it’s better for the memory
Thank you Jim!
I have one more question:
firstly my MainMenuScene extends MenuScene
secondly in constructor MainMenuScene(), I have been created 3 ITextureRegions by 1 BitmapTextureAtlas then add them into addMenuItem();
unfortunately It’s only show the last ITextureRegion for all MenuItems. Why?
I tried to create 3 BitmapTextureAtlas corresponds it will display exactly what I want. yeah I know the second way it’s worked with bad performance. I wanna save my memory. What’s happened with MenuScene? This is a bug or I have something not right? my codes looks like bellow:
public MainMenuScene() {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath(“gfx/”);
this.mBitmapTextureAtlas = new BitmapTextureAtlas(
this.getTextureManager(), 256, 128, TextureOptions.BILINEAR);
this.mButton1ITextureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(this.mBitmapTextureAtlas, mActivity,
“button1.png”, 0, 0);
this.mButton2ITextureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(this.mBitmapTextureAtlas, mActivity,
“button2.png”, 0, 0);
this.mButton3ITextureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(this.mBitmapTextureAtlas, mActivity,
“button3.png”, 0, 0);
this.mBitmapTextureAtlas.load();
IMenuItem button1= new SpriteMenuItem(0,
this.mButton1ITextureRegion ,
mActivity.getVertexBufferObjectManager());
IMenuItem button2= new SpriteMenuItem(1,
this.mButton3ITextureRegion ,
mActivity.getVertexBufferObjectManager());
IMenuItem button3= new SpriteMenuItem(2,
this.mButton3ITextureRegion ,
mActivity.getVertexBufferObjectManager());
button1.setposition(x,y);
button2.setposition(x,y + 10);
button3.setposition(x,y + 30);
addMenuItem(button1);
addMenuItem(button2);
addMenuItem(button3);
}
Imagine the textureAtlas as a wall where you put posters on
you are putting your first poster [button1.png] on the top left corner [0,0]
then you put your 2nd poster [button2.png] on the top left corner too [0,0]
then you put your 3rd poster [button3.png] on the top left corner too [0,0]
so you are putting your posters above each others, you’ll only see the last one
create a texture atlas that can handle all 3 images [size wise] and then make sure you place them correctly so that there would be a padding between the sprites [2 pixels padding are enough]
Thank you Jim 🙂 I was succeed. Now I really know how BitMapTextureAtlas work!!!
I think if include javadocs Andengine becoming better.
While the shapes are simplistic; this tutorial showed me a lot in regards to making a new game. Thanks and great job
this project started as a challenge to myself to make a working game without using sprites .. then evolved into a tutorial somehow 😛
Thanks Jim. Help me a lot in learning AndEngine.
Keep up the good work. Cheers
Thanks bro for your works,I am on the way of learning your fabulous tutorial.
In Your ResourceManager Class Inside LoadMainMenu() I didn’t understand CONST.WIDTH, & CONST.HEIGHT? can u give us explanation? Is it the device width & height?
BuildableBitmapTextureAtlas texture = new BuildableBitmapTextureAtlas(
mEngine.getTextureManager(), CONST.WIDTH, CONST.HEIGHT);
it took me a while to figure out what you were talking about 😛
well .. I just put those values here as a starter , so it doesn’t matter .. testureAtlas is like a big board where you stick your sprites on it .. so you have to make it big enough for all of your sprites to fit but don’t use one that’s larger than 2048 x 2048 cause it won’t work on most devices
just put any value that you see fit for the sprites you have , you can always try or just go with the maximum at first then optimize later on [or calculate yourself]
Thanks for quick reply. I understand why BuildableBitmapTextureAtlas stands for.
what does this line do?
texture.build(new BlackPawnTextureAtlasBuilder(
0, 1, 4));
Here I’m using the BuildableBitmapTextureAtlas so when you want to use it you put that line
the first element is the border padding , the 2nd is padding/space between elements , the 3rd is the transparent padding around each elements
http://srcrr.com/android/AndEngine/GLES1/final/reference/org/andengine/opengl/texture/atlas/buildable/builder/BlackPawnTextureAtlasBuilder.html#BlackPawnTextureAtlasBuilder%28int,%20int,%20int%29
this is for GLES1 , but it’s the same in GLES2
you don’t have to use the BuildableBitmapTextureAtlas , you can use the normal one and arrange your textures manually
Hi great tutorial, I am having for some reason a problem with R.string.start on the public MainMenuScene its marking “start” and says “start cannot be resolved or is not a field” could you help me may be I forgot to add some thing
you imported the wrong R , make sure it says on top import com.yourprojectpackage.R and not android.R
I added the import but still getting the error, also I check the R.java and there is no “start”
Found my mistake I forgot the strings.xml step, thanks
Great JOb
I found this very interesting. Please I will be most grateful if you send the updated copy of the code to me through this address [email removed]
there is no updated copy , you can get the latest version from the github link that I provided, there is a download link inside so it shouldn’t be very hard to do
I have a custom scene called GameScene. I create a method LoadResources() inside it.It works fine.
public class GameScene extends Scene{
…
BaseActivity activity;
// Below two class is responsible for creating button,both extends TileSprite class
public RedButtonBean aRedButtonBean;
public BlueButtonBean aBlueButtonBean;
public GameScene() {
//inside constructor i call it
LoadResources();
aRedButtonBean = new RedButtonBean(0, 200, iRedTiledTextureRegion,
activity.getVertexBufferObjectManager(), instance);
attachChild(aRedButtonBean);
}
public void LoadResources() {
//inside this class
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath(“gfx/”);
activity = BaseActivity.getSharedInstance();
BuildableBitmapTextureAtlas texture = new BuildableBitmapTextureAtlas(
activity.getTextureManager(), 2048, 2048);
this.iRedTiledTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createTiledFromAsset(texture, activity,
“button_tiled_red.png”, 2, 1);
this.iBlueTiledTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createTiledFromAsset(texture, activity,
“button_tiled_blue.png”, 2, 1);
try {
texture.build(new BlackPawnTextureAtlasBuilder(
0, 1, 4));
texture.load();
} catch (TextureAtlasBuilderException e) {
e.printStackTrace();
}
}
}
}
Problem: When i put my LoadResources() method inside ResourceManager,i can’t call it. when i write like in GameScene Constructor
ResourceManager aResourceManager;
public GameScene() {
aResourceManager=ResourceManager.getInstance();
LoadResources(activity);
}
i got error. Null pointer exception. Can u help me how to use ResourceManager in My GameScene class?
are you sure that your ResourceManager class’s instance is decalred like this ?
private static final ResourceManager INSTANCE = new ResourceManager();
if you are not doing that then your INSTANCE is null by default
also please use pastebin to put code , don’t put long codes in the comments
get this error while trying to set up that basic soft blue background…
img: http://i48.tinypic.com/30bzosg.jpg
I can’t really tell what’s wrong , could be that’s because you didn’t import FontFactory yet … or could be that eclipse needs a restart
Problem:
I am trying to replace the sprite in ship class from rectangle to an animated sprite.. i have tested the animated sprite , its texture and its TiledTextureRegion in a seperate project and it works fine. But when i add this to the sprite in ship the game crashes with null pointer exception. Logcat reports the following:
java.lang.NullPointerException
at com.example.jimvaders.Ship.(Ship.java:33)
at com.example.jimvaders.Ship.getSharedInstance(Ship.java:27)
at com.example.jimvaders.GameScene.(GameScene.java:33)
The Texture and TiledTextureRegion are populated in onCreateResources() of BaseActivity.java.
the code for sprite constructor regarding the animatedSprite creation is :
sprite = new AnimatedSprite(0,0, BaseActivity.getSharedInstance().myTextureRegion,
BaseActivity.getSharedInstance().getVertexBufferObjectManager());
where myTextureRegion is a TiledTextureRegion from BaseActivity.
Any ideas how to use animated sprite in ship.java?
I tried using Sprite instead of AnimatedSprite and it works.. used the same spritesheet (with tiles) for the texture region of that sprite and it works.. why is animated sprite not working? please help!
switching between Sprite and AnimatedSprite should work .. it’s weird that it’s not working
can you send me your whole project via email ? [my email address is in the about page]
also include the full stackTrace of the Logcat in the email
Thanks for the reply JiMMaR, i got that working. Just one more question my enemy class uses a Sprite sprite; instead of rectangle. The texture regions are placed on a bitmapTextureAtlas inside OnCreateResources() of BaseActivity. I have tested them and they are working perfectly (given their manual positioning on atlas no problems there). So in constructor of Enemy.java i tried
sprite = new Sprite(0,0,activity.myTextureRegion.deepCopy(),activity.getVertexbuffer…..;
at this point the logcat gives the error onCreateScene failed.
Please if you don’t understand the problem above just give a hint on “how to access the texture regions created in onCreateResources() method of the baseActivity from another class such as Enemy.java in this tutorial?”
no need for deepCopy() [actually it was replaced by clone() if I remember correctly .. but you probably won’t need both of them anyway]
what you are doing should work fine, maybe if you gave me the exact error in logcat I could figure out what’s the problem exactly
Having a problem with the tilt movement, the square just stays there it doesn’t move if I tilt the device any help?
Any advice or tutorials you know of to implement physics box 2d in an object riented style like the one you taught? I am pretty proficient at AndEngine but am struggling to make a solid smotth transition into making my programs Oobject oriented.
I don’t think I can really help you in that .. also my code is not really that optimal in object oriented way , I learned lots of more stuff [and a lot more to go] about organizing classes [software engineering the code] and I did make some bad moves in my tutorials but it’s a good start
one of my friends had a rule that each class shouldn’t exceed about 350 line, that’s not really a strict rule but it can get you thinking in ways of how to try and optimize your work and restructure it
also try to always think about improvements , write your code in a way that if you need to add new features [new enemies].. it’ll be pretty easy [and the best would be if you didn’t need to change much from the existing code, have the classes work generally]
of course this would cause you trouble at first, some people argue that for small projects it’s not worth the time .. that could be true, but if you are just starting I think it’s good to learn how to do stuff the proper way, after all if you couldn’t do the small thing how are you gonna do the bigger ones ?
Thanks for the reply man I really appreciate you taking the time to respond. It has been tough getting started with andEngine even though I am a pretty proficient coder. I have ome along really well though. I have put about 3 days into it and cant believe how far I have come. Your tutorial has helped a ton. I still cant make graphics to save my life but other then that lol
Come Back again.mates.
Little question?
Can i use One BuildableBitmapTextureAtlas to load several textureRegion in different Scene in my Game ???
🙂
You can load whatever you want in the a TextureAtlas, they are not connected to having different scenes
if you are using small sprites , you might load all of your textures in one TextureAtlas and at once
I’m trying out your method of calling a class that extends Scene in my project but I am encountering an error. When I try to call the scene(well, class extends scene), I am getting a NullPointerException error.
This is how I’m calling the class
public void createGameScenes() {
//Create Game Scene
titleScene = new Game(engine, camera);
}
This is how I set current scene(error happens before I even get here)
public void setCurrentScene(SceneType scene) {
currentScene = scene;
switch (scene){
case SPLASH:
break;
case TITLE:
engine.setScene(titleScene);
break;
}
}
This is the class I’m calling
public class Game extends Scene{
// variable were here…
public Game(Engine engine, final SmoothCamera mCamera){
//code of game here…
}
}
Few more functions for game follow ()
What could be the reason I am getting a NullPointerException error?
forgot to mention, in the logcat. It says this:
12-19 11:54:22.212: E/AndroidRuntime(5934): java.lang.NullPointerException
12-19 11:54:22.212: E/AndroidRuntime(5934): at com.templateandroid.Game.(Game.java:111)
however, I have checked my code and I am sure that it shouldn’t be null…
My problem was slowly solved through studying the code a bit and a lot of help from the andengine forums XD Thanks again for the tutorial though, helped me start up on transitioning between scenes
did you forget to call the super function in the constructor ? or what was your issue ? 😛
The issue was in relation with the singleton thing. However in my case, I wanted to do it with passing BitmapTextureAtlas’es through classes. Didn’t think I had to singleton the entire class itself. Actually gonna try to implement that in my code now, but if ever that was the problem.
Great tutorial! I finished all and it worked with some minor changes.
I have a question thou. I hope you can answer…
If i want more enemies with different capabilities like other color, more life, bullets, different move pattern etc
How do i have to change the EnemyPool and the EnemyLayer?
Or do i have to make new pools and layers for each new enemy?
I tried to look up stuff about object pooling but those examples where about business applications not games. Well thank anyways!
here’s a quick solution to you so you don’t have to change much of the code
– create an interface class [call it iEnemy for example or something] and make it have all the necessary enemy methods
– create 2 classes [or more , depending on the number of enemies you have] I’ll go with EnemyRed and EnemyBlue , both should implement iEnemy [public class EnemyRed implements iEnemy] and you will probably have to create a Class called Enemy and make them [EnemyRed and EnemyBlue] extend this Enemy class
– have your EnemyPool be of type iEnemy [now this pool can take both EnemyRed and EnemyBlue]
you should have different functionalists included inside the EnemyRed/Blue classes , like how they attack and stuff .. for example you can have red shoot bullets while blue doesn’t
if you did that for example , you either have the enemies shoot something onUpdate inside the class , or implement a function shoot that gets called from somewhere else and have it empty inside blue
there are lots of ways .. but I just pointed out some
I hope that made sense 😛
Muchas gracias.
Es un gran tutorial XD
Espero hacer mi juego pronto XD
Thank you very much.
It’s a great tutorial XD
I hope soon make my game XD
Sit, you did it great, but I should tell you that this tutorial isnt for beginners 🙂 There’s a lot of implicit thing(such as calls that you don’t cite). But I think this is a great tutorial! You must translate it to other languages so more peoples can gain access to it!
Thank you for reading !!
There are some parts of the code that I didn’t include and just explained or said that you have to do [which is usually explained previously]
could you point out which part exactly makes you feel that this is not for beginners or if I didn’t explain something ? this is for beginners in AndEngine but not exactly for beginners in Java though
Hey I just wanted to say thank you for posting this tutorial. Guys like you are the ones that really make a difference in the world. When the time is right I hope to do the same.
Oh I’m also gonna buy your book.
I’m glad that I had an impact on someone 😀
it’s not exactly my book, but I assure you it’s pretty good .. thanks for passing by ^^
Quick question regarding this tutorial, I got the the part were you “Kill the squares” however after implementing it, when I shoot the boxes, they die but they don’t disappear. I know they die because i put a log message to output “collide!” when they are hit and if i position my ship to the edge and keep shooting, the “collide!” only outputs 4 times, which means 2 squares were killed and they don’t exist anymore, except they visually do.
Also in the tutorial, just after you introduce the purge() method, there are blocks of code(used to create the enemies and animate them into the game) under it that didn’t specify where they should be put. I ended up putting that code in the constructor.
I’m not sure if you have addressed any of these in the comments, to if you have let me know and I will go through the comments.
Side note: still waiting for the book you took part in too arrive tomorrow. Using this tutorial as a warm-up.
I think the problem may be that detach isn’t called after the square dies. Also I don’t think purgeAndRestart is ever called. I may be mistaken because I haven’t finished the tutorial yet.
Actually I have finished the tutorial now and everything turned out fine. I like the way the tutorial was made, you get the sense of accomplishment when you’re done because not every single step is provided. Also it didn’t hold your hand too much along the way. If this is a beginners tutorial then I definitely need to step my game up because it felt a shy away from advanced Java. I’m going to play around with it while I wait for the book and truly get started. I would advice everyone who do this tutorial to finish it first before looking at the source if you want to learn something.
good catch about the code block, I guess adding that “annoying note” in the middle causes some confusion , I added more clarifications now 😛
and yeah, the whole point of this tutorial is to be able to make a basic game, with setting small targets/goals so you feel accomplishments and that helps in driving you forward to continue [it’s long so I have to do that or the reader would get bored :P]
it’s supposed to be kinda for beginners in AndEngine [not beginners in java .. even though I do explain some basic java stuff here and there], I’m not an expert in writing tutorials I just thought I’d write something in a way that I’d like them to be [or maybe I got influenced by other tutorials .. meh]
anyway .. enough blabbering from me for now .. glad you enjoyed the tutorial 😀
Just got the Book, I’m already feeling special like I know stuff that many don’t 🙂
I cant get the text to show up for the SplashScene 😦 i did everything exactly how u did it
I can’t help you without seeing what you did
but first try and download the whole code and see if it’s the same or not .. you can paste your code on pastebin.com and put a link here so I view it after checking with the whole source code
Excellent work Jimmar!!!
Thanks Jim for such an awesome tutorial.I downloaded the whole code and ran it.But the problem is the ship is not moving at all.Please help me.
Hey jim can u teach how to make the enemy shoot against the player? I’m getting nuts trying do that, please can u help me? tks
Hey, I was wondering if I wanted to add a counter to tell you how long it took you to complete the level, how would I do that. Currently I have a System.CurrentTImeMillis at the beginning, and another System.CurrentTImeMillis at the end of the level (when there are no more enemies) and I subtract them and divide by 1000 to get seconds. But I cannot get it to work, I always get the same answer. Where would I put the code to get the time at the end. If Im doing it right at all?
while I cannot really help you in your way without seeing a code , I’ll give you another solution [kinda]
in a game that I made, I had to implement a timer to show the user how much time has elapsed and update it on the screen, to do that you use an IUpdateHandler [make a private class and have it implement IUpdateHandler] and override the onUpdate() method.
onUpdate gives you the time elapsed in seconds, so get a float and keep on adding till the game ends
you might want to look for more tutorials on using IUpdateHandler
thanks for passing by
DUDE , millions thanks for the “fablous” :] tutotrial
I tried to implement it with latest version of andenegine {Anchor Center}
I fixed all issues of the cordinates changes except this
float finalPosX = (i % 6) * 4 * e.sprite.getWidth();
float finalPosY = ((int) (i / 6)) * e.sprite.getHeight() * 2;
i tried lots of things , but ukh nothing worked , the enemies overalping each others without space just like this
****
** *
thanks again , your tutotrial helped me alot to start games development
starnge i replaced MoveModfier function with
e.sprite.registerEntityModifier(new MoveXModifier(2, randPosX, finalPosX));
e.sprite.registerEntityModifier(new MoveYModifier(2, randPosY, finalPosY));
and now enemies appear correct — time to shot some nasty aliens xP
Hey Alaric, i am also tring to convert this to Anchor Center. Can you show all of your restart method?
I want to add music to the start of the GameScene with the code youve provided. I have my Music set up in the BaseActivity. But I just need to know where to put the music.start() and music.stop() so that the music will start at the beginning of the game and end when the ResultScene shows up, and the music will restart when the Game restarts after the GameScene. I have my music set up with MusicFactory. Thanks! 🙂
Hi jimmar i make a game with help of yours, i have just a problem; i replace the rectangel(Enemy) for a sprite and make the same in Ship, when i tried to make a collision detection on class GameScene, in method cleaner(), if doesn´t detected the collision between ship.sprite and e.spriterojo so i called them. hier is some code….
if (b.sprite.collidesWith(e.spriterojo)) {
//e.spriterojo.setColor(Color.BLACK);
//collisionDetection();
if (!e.gotHit()) {
createExplosion(e.spriterojo.getX(), e.spriterojo.getY(),
e.spriterojo.getParent(),
BaseActivity.getSharedInstance());
EnemyPool.sharedEnemyPool().recyclePoolItem(e);
eIt.remove();
//mSound.play();
}
BulletPool.sharedBulletPool().recyclePoolItem(b);
it.remove();
break;
}else if(ship.sprite.collidesWith(e.spriterojo)){
resetValues();
}
}
}
how can i make collision between ship.sprite and e.spriterojo, thanks for any help
Hi Sir,
I am developing a live wallpaper based on Andengine GLES 2 Anchor centre branch with help of our Andengine development cook book .[ I am greatly thank full to all peoples behind the book its awsome!! ]. But I am suffering of texture loosing on low end device , I have posted the questions with all details and code in Andengine forum and Stack over flow , It will be very help full for me if I get any suggestions from you, Its my humble request for a look on the issue
these are the links to my posts
http://www.andengine.org/forums/live-wallpaper-extension/loosing-textures-on-low-end-devices-t12402.html
http://stackoverflow.com/questions/17259444/andengine-live-wallpaper-loosing-textures-on-low-end-device
hopefully
Renjith KN
everything works fine, but in catlog it keeps spamming error “recycled than obtained!”
But, everything runs fine, I’m just curious why it says that error?
everything works fine, but in logcat it keeps spamming error “More items recycled than obtained!”
But, everything runs fine. I’m just curious why it says that error?
This is a good tutorial. I have also written tutorials on Andengine on http://www.nerdyguru.com Please go through them. I am planning to write a complete game tutorial shortly.
I get an error in the first running:

Could you tell me how to fix this?
your screenshot doesn’t show much , I need to see the part of the logcat where it says what the problem is [did you make sure the engine works fine ? using the installing GLES2.0 tutorial ?]
I’m also interested in your attack on titans game 😛
Doesn’t work for me while loadResources() is mentioned. How come it works if it’s not called anywhere?
oh , you call that at the end of the constructor of SplashScene, apparently I forgot to mention that
I fixed it
Thanks for clarification. Cheers. 🙂
That is another graet Tutorial..thanks alot and please keep sharing your tutorials..again Thanks Alot and much appreciated..!!
Hi jimmar i make a game with help of yours, i have just a problem; i replace the rectangel(Enemy) for a sprite and make the same in Ship, when i tried to make a collision detection on class GameScene, in method cleaner(), if doesn´t detected the collision between ship.sprite and e.spriterojo so i called them. hier is some code….
if (b.sprite.collidesWith(e.spriterojo)) {
//e.spriterojo.setColor(Color.BLACK);
//collisionDetection();
if (!e.gotHit()) {
createExplosion(e.spriterojo.getX(), e.spriterojo.getY(),
e.spriterojo.getParent(),
BaseActivity.getSharedInstance());
EnemyPool.sharedEnemyPool().recyclePoolItem(e);
eIt.remove();
//mSound.play();
}
BulletPool.sharedBulletPool().recyclePoolItem(b);
it.remove();
break;
}else if(ship.sprite.collidesWith(e.spriterojo)){
resetValues();
}
}
}
how can i make collision between ship.sprite and e.spriterojo, thanks for any help
Hi jimmar
Awesome tutorial, i’m working on a similar project like this too. It helped me alots 😀
I have 2 question about this tutorial
1) Rectangle rect = new Rectangle(posX, posY, 10, 10, activity.getVertexBufferObjectManager());
I wonder if a particle system can hold more than 1 texture?, so it can emit particle with random texture? Or we have to create multi particle system? Also, you said that we can use Sprite instead of Rectangle? Can you show me the code use to create it? I’m using Gles2 anchor center branch
2) I’m working on the HP’s bar of character, Can i, somehow, implement the sprite’s drawMethod, to make it draw on every update?
Thanks
Hey Jimmar! Thanks for all the tutorials . They are very helpful.
Just wanted to share a new game i made:
https://play.google.com/store/apps/details?id=com.saikam.kodo
I made it all without using any images at all. Do u think such games can be made easier using AndEngine?
I just used android canvas and all the drawing, paint, etc.
Im a fan of yours n just wanted to show u my work. Keep up the good work.
good job man, I like it !
but if you are looking for a market point of view , people don’t care if your game uses images or not, they don’t care what kind of handicaps you put to yourself while making the game
they care that it’d be fun to play , and it’d look good
keep that in mind for future market releases
also using rectangles is good for prototyping , but if you wanna release a game get real art
I was following your tutorial to a T and when I got to the ship part it shows the ship at the top of the screen not the bottom. Any ideas on this?
AndEngine currently has 2 branches , AndEngine GLES2.0 and AndEngine Anchorcenter , if you are using Anchorcenter then it’s using a different coordinate system, you can either switch to the other branch or read this tutorial —> http://www.matim-dev.com/gles2-anchor-center.html
which explains the differences between both versions and change the code accordingly , shouldn’t be a very hard thing
good luck 😀
Yes that was it, didn’t realize I was using the other branch. Thanks and I went through the tutorial and that was fun! Good job on it and thanks for educating me on andEngine. Might give it a go for a fun test game.
Amazing work! But im noob with this and im having a doubt. Can this game be changed to work with the touch and drag system used in the ninja game? Im trying it introducing the IOnAreaTouchListener in the Ship class, and then overriding the onAreaTouched method. I dont know if this is the correct method. Thanks for the tutorials, theyre very helpfull.
if it worked then it works
nobody will check your game’s code when you release it 😉
Hy,
If you leave the particles for a longer time, you realise, that they are moving with the enemy layer. That’s not too “awsome”. So I updated the call of the “createExplosion()”.
createExplosion(
e.sprite.getX() + e.sprite.getWidth()/2 + e.sprite.getParent().getX(), //Add the parent’s actual X position
e.sprite.getY() + e.sprite.getHeight()/2 + e.sprite.getParent().getY(), //Add the parent’s actual Y position
e.sprite.getParent().getParent(), //The target is the EnemyLayer’s parent
BaseActivity.getSharedInstance());
Plus, I made some changes to the particle systems rectangle. It changes color from Green to Red
@Override
public Rectangle create(float pX, float pY) {
Rectangle rect = new Rectangle(posX, posY, 10, 10, activity.getVertexBufferObjectManager());
rect.setColor(Color.GREEN);
rect.registerEntityModifier(new ColorModifier(0.2f*mTimePart, Color.GREEN, Color.RED));
return rect;
}
yeah , I attached the them to the enemyLayer instead of the scene
good job on fixing that and making changes!
keep it up
thank Jim, great tutorial. But can u help me, i can’t get position Enemy as Ship, can u introduce me , thank u very much
I don’t think I understand your question
can you elaborate ?
Great tutorial, Jim \o/
I’m beginning with android games, and your code showed me how to is simple to develop a game. Now I’ll try to modify the code and improve some things: for start, sounds and scoreboard saved on database, and then I’ll have a awesome idea to the game hahaha
After finished, I’ll send the link to download the game
Thanks man!
I’m glad I was any help =3
Hey, man!
My first game using andengine and based on your tutorial:
https://play.google.com/store/apps/details?id=br.com.yesbr.motoristadarodada
Space Invaders is stopped for now, but I will soon finalize
Hello, I’ve noticed after adding the particle part that if you quit the game while particles are on the screen, it crashes instead of closing safely.
It throws me indexOutOfBoundsException. Probably because of the for loop in GameScene’s detach method but I’m not sure how to repair this.
I’ve noticed other discrepancies but I figured you’ve put them there to make sure we were following.
Anyhow, thanks a lot for the tutorial; this is really being helpful for me to get started with andEngine.
yeah , this tutorial has lots of bad habits and bad ways to solve some things 😛
I was still learning myself when I wrote it, so there are lots of bugs .. but the idea is to get started into AndEngine and structure your code in a proper way
use this as a homework for you to fix it 😛
Well it was very helpful anyway, helped me write my first game!
https://play.google.com/store/apps/details?id=com.tappagame.oilfactoryfree
well…i am new to programming thingie and just doing it for hobby thingie :P…but have to say commendable efforts and interactive and informal language makes your blog stand out…keep up the good work
My ship is on top of the screen shooting down and the enemies are not placed correctly. I assume the Y coord is different (0,0 == top_left not bottom left?). however thanks for the tutorial.
You are using the new Anchor-center branch of AndEngine that’s why
This tutorial is kinda outdated, they changed their coordinate system in that branch, so that’s why 😀
Here is my fix it for the new coordinate system. Hope this helps for updating this tut.
You just have to replace the the old code with this – good luck:
// SHIP
// constructor
sprite.setPosition( (mCamera.getWidth() / 2), (sprite.getHeight() + 10));
// shoot method
MoveYModifier mod = new MoveYModifier(1.5f, b.sprite.getY(), (mCamera.getHeight()+b.sprite.getHeight()) );
// moveShip method
int lL = (int) sprite.getWidth();
// ENEMYLAYER
// restart method (without enemy fly-in animation)
public void restart(){
enemies.clear();
clearEntityModifiers();
clearUpdateHandlers();
for (int i = 0; i < enemyCount; i++) {
Enemy e = (Enemy) EnemyPool.sharedEnemyPool().obtainPoolItem();
float finalPosX = 50+ (BaseActivity.CAMERA_WIDTH / 8) * (i % 6);
float finalPosY = (BaseActivity.CAMERA_HEIGHT – e.sprite.getHeight()*4) – ((int) (i / 6)) * e.sprite.getHeight() * 2;
e.sprite.setPosition(finalPosX, finalPosY);
attachChild(e.sprite);
enemies.add(e);
setVisible(true);
setPosition(0,0);
MoveXModifier movRight = new MoveXModifier(1, 50, 120);
MoveXModifier movLeft = new MoveXModifier(1, 120, 50);
MoveYModifier moveDown = new MoveYModifier(1, 30, 100);
MoveYModifier moveUp = new MoveYModifier(1, 100, 30);
registerEntityModifier(new LoopEntityModifier(
new SequenceEntityModifier(movRight, moveDown, movLeft, moveUp)));
}
}
thanks a lot sir …….
Why “activity= BaseActivity.getSharedInstance()” error
The detach method you create to fix the bug works sometimes, because if game is running and you press desktop button instead back button the method onBackPress is not called. You better call detach method in onPauseGame method from BaseActivity, or just call System.exit(0);
Congratulations for this tutorial, it helped me a lot and made me laugh sometimes =D