In this post we are going to create a Stone class, stone class will be used to initialize our stone for the game. By creating a stone in a class we reduce the efforts to create stone again and again for different levels. We can just create a variable in GameScene and have our stone created. So lets start.
1. Create new class Stone
package com.mindew.fruitecollector;
import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.physics.PhysicsHandler;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
public class Stone extends Sprite{
private PhysicsHandler mPhysicsHandler;
private float originX, originY;
public Stone(float pX, float pY,Camera camera, ITextureRegion pTextureRegion,
VertexBufferObjectManager vbom) {
super(pX, pY, pTextureRegion, vbom);
// TODO Auto-generated constructor stub
mPhysicsHandler = new PhysicsHandler(this);
registerUpdateHandler(mPhysicsHandler);
originX = pX;
originY = pY;
this.setUserData("stone");
}
@Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY)
{
if (pSceneTouchEvent.isActionMove() || pSceneTouchEvent.isActionDown() || pSceneTouchEvent.isActionOutside())
{
float radius = 50;
Float distance = (pSceneTouchEvent.getX() - originX)*(pSceneTouchEvent.getX() - originX) + (pSceneTouchEvent.getY() - originY) * (pSceneTouchEvent.getY() - originY);
distance = (float) Math.sqrt(distance);
if(distance < radius)
{
this.setX(pSceneTouchEvent.getX() - this.getWidth() / 2);
this.setY(pSceneTouchEvent.getY() - this.getHeight() / 2);
}
}
else if (pSceneTouchEvent.isActionUp())
{
mPhysicsHandler.setVelocityX((originX - getX()) * 15);
mPhysicsHandler.setVelocityY((originY - getY()) * 10);
mPhysicsHandler.setAccelerationY(100);
}
return true;
}
}
1. Create new class Stone
package com.mindew.fruitecollector;
import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.physics.PhysicsHandler;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
public class Stone extends Sprite{
private PhysicsHandler mPhysicsHandler;
private float originX, originY;
public Stone(float pX, float pY,Camera camera, ITextureRegion pTextureRegion,
VertexBufferObjectManager vbom) {
super(pX, pY, pTextureRegion, vbom);
// TODO Auto-generated constructor stub
mPhysicsHandler = new PhysicsHandler(this);
registerUpdateHandler(mPhysicsHandler);
originX = pX;
originY = pY;
this.setUserData("stone");
}
@Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY)
{
if (pSceneTouchEvent.isActionMove() || pSceneTouchEvent.isActionDown() || pSceneTouchEvent.isActionOutside())
{
float radius = 50;
Float distance = (pSceneTouchEvent.getX() - originX)*(pSceneTouchEvent.getX() - originX) + (pSceneTouchEvent.getY() - originY) * (pSceneTouchEvent.getY() - originY);
distance = (float) Math.sqrt(distance);
if(distance < radius)
{
this.setX(pSceneTouchEvent.getX() - this.getWidth() / 2);
this.setY(pSceneTouchEvent.getY() - this.getHeight() / 2);
}
}
else if (pSceneTouchEvent.isActionUp())
{
mPhysicsHandler.setVelocityX((originX - getX()) * 15);
mPhysicsHandler.setVelocityY((originY - getY()) * 10);
mPhysicsHandler.setAccelerationY(100);
}
return true;
}
}
Explanations: In above class originX and originY variables are used to get the original coordinates of the stone when it is first created, it might be very useful sometimes.
Then we defined the constructor for class and initialize the variables.
Then we are overriding the method called onAreaTouched and put the code for flinging the stone, by this code we can have a drag and throw effect for the stone.
So we are ready with our Stone class, now go back to the GameScene class and use it.
Define stone as,
Stone stone;
Create a method called createStone() as below,
public void createStone()
{
stone = new Stone(100,300,camera,resourcesManager.stone_region,vbom)
{
@Override
protected void onManagedUpdate(float pSecondsElapsed) {
// TODO Auto-generated method stub
super.onManagedUpdate(pSecondsElapsed);
if(this.mX + this.getWidth() < 0 || this.mX - this.getWidth() > 800 || this.mY + this.getWidth() < 0 || this.mY - this.getWidth() > 480)
{
this.detachSelf();
levelfail.display(levelID,GameScene.this, camera);
registerTouchArea(levelfail.yes);
registerTouchArea(levelfail.no);
}
}
};
attachChild(stone);
stone.setCullingEnabled(true);
registerTouchArea(stone);
}
Now create a fruit,
Sprite fruit;
And create a method called createFruit()
public void createFruit()
{
fruit = new Sprite(600,150,resourcesManager.fruite_region,vbom)
{
@Override
protected void onManagedUpdate(float pSecondsElapsed) {
// TODO Auto-generated method stub
super.onManagedUpdate(pSecondsElapsed);
if(stone.collidesWith(this) )
{
//totalApple += 1;
addToScore(100);
//SaveManager.getInstance().setLevelOneScore(score);
//SaveManager.getInstance().setTotalApple(totalApple);
this.setIgnoreUpdate(true);
// levelCompleteWindow.display(StarsCount.THREE, GameScene.this, camera,1);
//registerTouchArea(levelCompleteWindow.replay);
// registerTouchArea(levelCompleteWindow.home);
//registerTouchArea(levelCompleteWindow.next);
final FixtureDef PLAYER_FIX = PhysicsFactory.createFixtureDef(100.0f,0.3f, 0.0f);
Body body = PhysicsFactory.createCircleBody(physicsWorld, fruite,BodyType.DynamicBody, PLAYER_FIX);
physicsWorld.registerPhysicsConnector(new PhysicsConnector(fruite,body, true, false));
final FixtureDef PLAYER_FIX2 = PhysicsFactory.createFixtureDef(100.0f,0.3f, 0.0f);
Body stonebody = PhysicsFactory.createCircleBody(physicsWorld, stone,BodyType.DynamicBody, PLAYER_FIX2);
physicsWorld.registerPhysicsConnector(new PhysicsConnector(stone,stonebody, true, false));
}
}
};
fruit.setCullingEnabled(true);
attachChild(fruit);
}
Finally go to createScene() method and put our created methods inside it,
public void createScene() {
// TODO Auto-generated method stub
createBackground();
createHUD();
createPhysics();
createStone();
createFruite();
createWalls();
setTouchAreaBindingOnActionDownEnabled(true);
}
setTouchAreaBindingOnActionDownEnabled(true); method is very useful when you do not want any interruption while dealing with single sprite or object.
So we are done, run the project and see if you can drag and throw the stone freely. The result you should see is when you fling/throw the stone and if it collides with fruit score 100 should be added to score text. Both fruit and stone should get fall down to the ground to simulate physics environment.
In the next post we are going to see how to load levels from .lvl files.
In the next post we are going to see how to load levels from .lvl files.
Enjoy!