Move background vertically in andengine - android

I want to move background vertically.I tried it but it's not working.By applying below code image background remain still.I tried it by changing it's direction here (bgEntity = new VerticalParallaxEntity(0.0f, background, direction)) but cause no effect.
autoParallaxBackground = new VerticalParallaxBackground(0, 0, 0);
background = new Sprite(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT,
this.mParallaxLayerBack, this.vbom);
bgEntity = new VerticalParallaxEntity(0.0f, background, 1);
autoParallaxBackground.attachVerticalParallaxEntity(bgEntity);
autoParallaxBackground.attachVerticalParallaxEntity(bgEntity);
mainScene.setBackground(autoParallaxBackground);
I used this class :
public class VerticalParallaxBackground extends ParallaxBackground {
public static int SCROLL_DOWN = -1;
public static int SCROLL_UP = 1;
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private final ArrayList<VerticalParallaxEntity> mParallaxEntities = new ArrayList<VerticalParallaxEntity>();
private int mParallaxEntityCount;
protected float mParallaxValue;
// ===========================================================
// Constructors
// ===========================================================
public VerticalParallaxBackground(float red, float green, float blue) {
super(red, green, blue);
// TODO Auto-generated constructor stub
}
// ===========================================================
// Getter & Setter
// ===========================================================
public void setParallaxValue(final float pParallaxValue) {
this.mParallaxValue = pParallaxValue;
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
#Override
public void onDraw(final GLState pGLState, final Camera pCamera) {
super.onDraw(pGLState, pCamera);
final float parallaxValue = this.mParallaxValue;
final ArrayList<VerticalParallaxEntity> parallaxEntities = this.mParallaxEntities;
// Log.d("VAPB", "VAPB onDraw pre entity");
for (int i = 0; i < this.mParallaxEntityCount; i++) {
parallaxEntities.get(i).onDraw(pGLState, pCamera, parallaxValue);
}
}
// ===========================================================
// Methods
// ===========================================================
public void attachVerticalParallaxEntity(
final VerticalParallaxEntity pParallaxEntity) {
this.mParallaxEntities.add(pParallaxEntity);
this.mParallaxEntityCount++;
}
public boolean detachVerticalParallaxEntity(
final VerticalParallaxEntity pParallaxEntity) {
this.mParallaxEntityCount--;
final boolean success = this.mParallaxEntities.remove(pParallaxEntity);
if (success == false) {
this.mParallaxEntityCount++;
}
return success;
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
public static class VerticalParallaxEntity {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
final float mParallaxFactor;
final IAreaShape mShape;
private int direction;
// ===========================================================
// Constructors
// ===========================================================
public VerticalParallaxEntity(final float pParallaxFactor,
final IAreaShape pShape) {
this.mParallaxFactor = pParallaxFactor;
this.mShape = pShape;
this.direction = VerticalParallaxBackground.SCROLL_DOWN;
}
public VerticalParallaxEntity(final float pParallaxFactor,
final IAreaShape pShape, int direction) {
this.mParallaxFactor = pParallaxFactor;
this.mShape = pShape;
this.direction = direction;
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
// ===========================================================
// Methods
// ===========================================================
public void onDraw(final GLState pGL, final Camera pCamera,
final float pParallaxValue) {
pGL.pushModelViewGLMatrix();
final float cameraHeight = pCamera.getHeight();
final float shapeHeightScaled = this.mShape.getHeightScaled();
float baseOffset = (pParallaxValue * this.mParallaxFactor)
% shapeHeightScaled;
while (baseOffset > 0) {
baseOffset -= shapeHeightScaled;
}
pGL.translateModelViewGLMatrixf(0, (direction * baseOffset), 0);
float currentMaxY = baseOffset;
do {
this.mShape.onDraw(pGL, pCamera);
pGL.translateModelViewGLMatrixf(0,
(direction * shapeHeightScaled), 0);
currentMaxY += shapeHeightScaled;
} while (currentMaxY < (cameraHeight + shapeHeightScaled));
// Added shapeHeightScaled to cameraHeight so the drawing flows in
// instead of popping in.
pGL.popModelViewGLMatrix();
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
}
Any suggestions?
Thanks in advance!

I can't add a comment to the previous answer so I'll just add to it here.
You need to use AutoVerticalParallaxBackground. This is not provided by default with the game engine but AndAppsUK has created the classes for us (both AutoVerticalParallaxBackground and VerticalParallaxBackground) - http://www.andengine.org/forums/post306324.html#p31347
After you have added the class to your code, simply change this line
autoParallaxBackground = new VerticalParallaxBackground(0, 0, 0);
to (notice the extra argument for the change speed and the different class)
autoParallaxBackground = new AutoVerticalParallaxBackground(0, 0, 0, 15);
Also, change the speed value on your VerticalParallaxEntity to like 0.2f
bgEntity = new VerticalParallaxEntity(0.2f, background, 1);
Then a little bit of experimentation should get you the result you want.
Hope this helps.

It looks like you've done everything right. Just increase the parallax factor here:
bgEntity = new VerticalParallaxEntity(0.0f, background, 1);
0.0f - is no factor so it doesn't move
You can also try
new VerticalParallaxBackground(0, 0, 0, 5);
where the last argument are changes per sec

Related

Andengine micro lags with Fixed step engine

My problem is that my game had micro lags when I was using the Limited FPS engine because the delta time was too inconsistent.
I described this Problem here: Andengine PhysicsHandler makes player look laggy
Now I am using the Fixed step engine to get a consistent delta time but now its lagging even more.
Maybe I did some mistakes with the game desing.
Here is the Code:
For the Fixed step engine I use this line:
#Override
public Engine onCreateEngine(EngineOptions pEngineOptions)
{
return new FixedStepEngine(pEngineOptions, 60);
}
For the player I am using these two classes (Blocks is the game grid):
public abstract class ActorObject extends AnimatedSprite {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
public PhysicsHandler mPhysicsHandler;
public Camera camera;
// ===========================================================
// Constructors
// ===========================================================
public ActorObject(final float pX, final float pY, final ITiledTextureRegion pTiledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager, Camera camera) {
super(pX, pY, pTiledTextureRegion, pVertexBufferObjectManager);
this.mPhysicsHandler = new PhysicsHandler(this);
this.camera=camera;
this.registerUpdateHandler(this.mPhysicsHandler);
//updater=new Updater(this.camera,this);
this.registerUpdateHandler(new IUpdateHandler() {
#Override
public void onUpdate(final float pSecondsElapsed) {
onMove(pSecondsElapsed);
}
#Override
public void reset() {
// TODO Auto-generated method stub
}});
}
public void onMove(float pSecondsElapsed){};
}
public class Player extends ActorObject {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
public int direction;
public int desDirection;
public boolean canmove_vert;
public boolean canmove_hor;
Blocks[][] block;
boolean final_goal=false;
GameScene gm;
Rectangle rects;
Rectangle rects2;
VertexBufferObjectManager pVertexBufferObjectManager;
private int lastX;
private int lastY;
// ===========================================================
// Constructors
// ===========================================================
public Player(final float pX, final float pY, final VertexBufferObjectManager pVertexBufferObjectManager, Blocks[][] block2, int i, int p,final Camera camera,final GameScene gm) {
super(pX, pY, ResourcesManager.getInstance().player_region, pVertexBufferObjectManager,camera);
block=block2;
this.pVertexBufferObjectManager=pVertexBufferObjectManager;
this.gm=gm;
rects=new Rectangle(this.getX(),this.getY(),78,78,ResourcesManager.getInstance().vbom);
rects2=new Rectangle(this.getX(),this.getY(),2f,2f,ResourcesManager.getInstance().vbom);
canmove_hor=false;
canmove_vert=false;
direction=Globals.RIGHT;
setCullingEnabled(true);
final long[] PLAYER_ANIMATE = new long[] { 130, 130, 130,130, 130, 130,130, 130, 130,130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,130,130 };
// animate(PLAYER_ANIMATE, 0, 21, true);
}
// ===========================================================
// Methods
// ===========================================================
public Rectangle getBounds(){
return rects;
}
public Rectangle getSmallBounds(){
return rects2;
}
public void setDirection(int dir){
direction=dir;
}
#Override
public void onMove(final float sec){
rects.setX(this.getX());
rects.setY(this.getY());
rects2.setPosition(this.getX(), this.getY());
for(int i=0;i<Globals.OFFSETX;i++){
for(int p=0;p<Globals.OFFSETY;p++){
if(this.getBounds().collidesWith(block[i][p].getBounds())){
this.mPhysicsHandler.setVelocity(0, 0);
this.loadLastPos();
}
else if(this.getSmallBounds().collidesWith(block[i][p].getSmallBounds())){
switch(desDirection){
case Globals.LEFT:
if(block[i][p].links_frei){
direction=Globals.LEFT;
desDirection=Globals.NICHTS;
this.setPosition(block[i][p].x, block[i][p].y);
this.mPhysicsHandler.setVelocityY(0);
this.mPhysicsHandler.setVelocityX(-150);
this.setRotation(270);
}
break;
case Globals.RIGHT:
if(block[i][p].rechts_frei){
direction=Globals.RIGHT;
desDirection=Globals.NICHTS;
this.setPosition(block[i][p].x+1, block[i][p].y+1);
this.mPhysicsHandler.setVelocityY(0);
this.mPhysicsHandler.setVelocityX(150);
this.setRotation(90);
}
break;
case Globals.UP:
if(block[i][p].oben_frei){
direction=Globals.UP;
desDirection=Globals.NICHTS;
this.setPosition(block[i][p].x+1, block[i][p].y+1);
this.mPhysicsHandler.setVelocityY(-150);
this.mPhysicsHandler.setVelocityX(0);
this.setRotation(0);
}
break;
case Globals.DOWN:
if(block[i][p].unten_frei){
direction=Globals.DOWN;
desDirection=Globals.NICHTS;
this.setPosition(block[i][p].x+1, block[i][p].y+1);
this.mPhysicsHandler.setVelocityY(150);
this.mPhysicsHandler.setVelocityX(0);
this.setRotation(180);
}
break;
}
}
}
}
this.saveLastPos();
}//end onmove
public void saveLastPos(){
lastX=(int) this.getX();
lastY=(int) this.getY();
}
public void loadLastPos() {
this.setX((float)lastX);
this.setY((float)lastY);
}
I am not using the Physics Box 2d extension.
Does anyone have a solution for this?
Try using the following engine. It's a custom engine I use in all my Andengine projects that allows for a smooth gameplay at a set step/rate without skipping, and it's more predictable than the other engines.
public class FixedStepMaxFPSEngine extends Engine {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private final long mStepLength;
private long mSecondsElapsedAccumulator;
private final UpdateHandlerList mConstantUpdateHandlers = new UpdateHandlerList(8);
// ===========================================================
// Constructors
// ===========================================================
/**
* Create a new Fixed Step Max FPS engine.
* #param pEngineOptions {#link EngineOptions} Engine options to use.
* #param pStepsPerSecond {#link integer} How many updates a second?
*/
public FixedStepMaxFPSEngine(EngineOptions pEngineOptions, final int pStepsPerSecond) {
super(pEngineOptions);
this.mStepLength = TimeConstants.NANOSECONDS_PER_SECOND / pStepsPerSecond;
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
#Override
public void onUpdate(final long pNanosecondsElapsed) throws InterruptedException {
this.mSecondsElapsedAccumulator += pNanosecondsElapsed;
final long stepLength = this.mStepLength;
while(this.mSecondsElapsedAccumulator >= stepLength) {
final float pSecondsElapsed = stepLength * TimeConstants.SECONDS_PER_NANOSECOND;
this.onConstantUpdateUpdateHandlers(pSecondsElapsed);
this.mSecondsElapsedAccumulator -= stepLength;
}
super.onUpdate(pNanosecondsElapsed);
}
protected void onConstantUpdateUpdateHandlers(final float pSecondsElapsed) {
this.mConstantUpdateHandlers.onUpdate(pSecondsElapsed);
}
/**
* Register an {#link IUpdateHandler} to be updated using our constant game speed.
* #param pUpdateHandler {#link IUpdateHandler} to update.
* #see FixedStepMaxFPSEngine
*/
public void registerConstantUpdateHandler(final IUpdateHandler pUpdateHandler) {
this.mConstantUpdateHandlers.add(pUpdateHandler);
}
/**
* Unregister a {#link IUpdateHandler} from being updated using our constant game speed.
* #param pUpdateHandler {#link IUpdateHandler} to unregister.
*/
public void unregisterConstantUpdateHandler(final IUpdateHandler pUpdateHandler) {
this.mConstantUpdateHandlers.remove(pUpdateHandler);
}
/**
* Clear all {#link IUpdateHandler} registered for constant game speed updates.
*/
public void clearConstantUpdateHandlers() {
this.mConstantUpdateHandlers.clear();
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}

android Andengine surfaceGestureDetector

I try to use SurfaceGestureDetector This class use only SurfaceGestureDetector and not work. i a msg "03-14 20:40:47.746: I/AndEngine(8963): org.anddev.andengine.input.touch.TouchEvent$TouchEventPool was exhausted, with 0 item not yet recycled. Allocated 1 more." Only Tag Log.d("test", "TouchEvent"); work
public class MainActivity extends BaseGameActivity {
// ===========================================================
// Constants
// ===========================================================
private static final int CAMERA_WIDTH = 480;
private static final int CAMERA_HEIGHT = 320;
// ===========================================================
// Fields
// ===========================================================
private Camera mCamera;
//private Texture mTexture, mBatTexture;
//private TiledTextureRegion mBatTextureRegion;
//private TextureRegion mSplashTextureRegion;
private Handler mHandler;
//static protected Music mMusic;
private Scene mScene;
private SurfaceGestureDetector surfaceGestureDetector;
private TouchEvent pSceneTouchEvent;
// ===========================================================
// Constructors
// ===========================================================
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
#Override
public Engine onLoadEngine() {
mHandler = new Handler();
this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
}
#Override
public void onLoadResources() {
}
#Override
public Scene onLoadScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
this.mScene = new Scene();
setupGestureDetaction();
return mScene;
}
#Override
public void onLoadComplete() {
//mHandler.post(mLaunchTask);
}
private Runnable mLaunchTask = new Runnable() {
public void run() {
Intent myIntent = new Intent(MainActivity.this, TMXTiledMapExample.class);
MainActivity.this.startActivity(myIntent);
}
};
private void setupGestureDetaction(){
surfaceGestureDetector = new SurfaceGestureDetector(1f) {
#Override
protected boolean onSingleTap() {
// TODO Auto-generated method stub
Log.d("test", "onSingleTap");
return true;
}
#Override
protected boolean onDoubleTap() {
Log.d("test", "onDoubleTap");
// TODO Auto-generated method stub
return false;
}
#Override
protected boolean onSwipeUp() {
// TODO Auto-generated method stub
return false;
}
#Override
protected boolean onSwipeDown() {
// TODO Auto-generated method stub
return false;
}
#Override
protected boolean onSwipeLeft() {
// TODO Auto-generated method stub
return false;
}
#Override
protected boolean onSwipeRight() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onManagedTouchEvent(TouchEvent pSceneTouchEvent) {
return super.onManagedTouchEvent(pSceneTouchEvent);
}
#Override
public boolean onSceneTouchEvent(Scene pScene,
TouchEvent pSceneTouchEvent) {
Log.d("test", "TouchEvent");
return super.onSceneTouchEvent(pScene, pSceneTouchEvent);
//return false;
}
};
// if (pSceneTouchEvent!=null){
// TouchEvent.recycle(pSceneTouchEvent);}
surfaceGestureDetector.setEnabled(true);
mScene.setOnSceneTouchListener(surfaceGestureDetector);
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
This question is old as i write this reply, but the log message you show above is a not an error message. It is an appropriate message letting you know that the Object Pool for touch events did not contain any touches, so it created more.
This is a normal message from Andengine, and you will see it when you first start using touches, but less as the app runs, because the pool size will grow, and so a touch will be recycled rather than created.

Setting size of a triangle (Android)

So, I have created an android activity that draws a triangle on the canvas. I also added 4 menus(Color, Enlarge, Shrink, and Reset) to the VM. The color works fine but I'm not quite sure how to resize a triangle in android once that menu button is pressed.The assignment says to just fix the top point of the triangle, and then change the coordinates of the bottom two points of the triangle. Can anyone point me in the right direction on how to do that in Android?
Here's my code, although the implementation of enlarge, shrink, and reset are set up to work with a circle(project I did before), not a triangle. Please note that the "Color" menu works so no need to do that.
public class MainActivity extends Activity
{
final Context context = this;
private Graphics graphic;
private Dialog radiusDialog; //Creates dialog box declaration
private SeekBar red;
private SeekBar green;
private SeekBar blue;
private Button radiusButton;
private TextView progress1;
private TextView progress2;
private TextView progress3;
private TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
graphic = new Graphics(this); //Create new instance of graphics view
setContentView(graphic); //Associates customized view with current screen
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) //This acts as a menu listener to override
{
switch(item.getItemId()) //returns menu item
{
case R.id.Color:
showDialog();
break;
case R.id.Shrink:
graphic.setRadius(graphic.getRadius() -1);
graphic.invalidate();
break;
case R.id.Enlarge:
graphic.setRadius(graphic.getRadius() +1);
graphic.invalidate();
break;
case R.id.Reset:
graphic.setColor(Color.CYAN);
graphic.setRadius(75);
graphic.invalidate();
break;
}
return super.onOptionsItemSelected(item);
}
void showDialog() //creates memory for dialog
{
radiusDialog = new Dialog(context);
radiusDialog.setContentView(R.layout.draw_layout); //binds layout file (radius) with current dialog
radiusDialog.setTitle("Select Color:");
red = (SeekBar)radiusDialog.findViewById(R.id.seekBar1);
green = (SeekBar)radiusDialog.findViewById(R.id.seekBar2);
blue = (SeekBar)radiusDialog.findViewById(R.id.seekBar3);
progress1 = (TextView)radiusDialog.findViewById(R.id.textView2);
progress2 = (TextView)radiusDialog.findViewById(R.id.textView4);
progress3 = (TextView)radiusDialog.findViewById(R.id.textView6);
mychange redC = new mychange();
red.setOnSeekBarChangeListener(redC);
mychange greenC = new mychange();
green.setOnSeekBarChangeListener(greenC);
tv = (TextView)radiusDialog.findViewById(R.id.textView7);
mychange c = new mychange();
blue.setOnSeekBarChangeListener(c);
radiusButton = (Button) radiusDialog.findViewById(R.id.button1);
radiusButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int color = Color.rgb(red.getProgress(), green.getProgress(), blue.getProgress());
radiusDialog.dismiss();
setContentView(R.layout.activity_main);
setContentView(graphic);
graphic.setColor(color);//Create new instance of graphics view
graphic.invalidate();
}
});
radiusDialog.show(); //shows dialog on screen
}
public class mychange implements OnSeekBarChangeListener{
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
int color = Color.rgb(red.getProgress(), green.getProgress(), blue.getProgress());
tv.setBackgroundColor(color);
progress1.setText(String.valueOf(red.getProgress()));
progress2.setText(String.valueOf(green.getProgress()));
progress3.setText(String.valueOf(blue.getProgress()));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
}
Graphics Class to draw triangle
public class Graphics extends View
{
private Paint paint;
private int radius;
private int color;
public void setColor(int color)
{
this.color = color;
}
public Graphics(Context context) //creates custom view (constructor)
{
super(context);
paint = new Paint(); //create instance of paint
color = Color.CYAN;
paint.setStyle(Paint.Style.FILL); //draw filled shape
radius = 75;
}
#Override
protected void onDraw(Canvas canvas) //override onDraw method
{
super.onDraw(canvas);
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
Path path = new Path();
path.moveTo(230, 200);
path.lineTo(330, 300);
path.lineTo(130, 300);
path.close();
canvas.drawPath(path, paint);
}
void setRadius(int radius)
{
this.radius = radius;
invalidate(); //just like repaint method
}
public int getRadius()
{
return radius;
}
}
If the top coordinate remains fixed, you can change the height of the triangle to shrink/enlarge it.
Lets say the triangle is equilateral - all 3 sides have the same length. In this case:
So if the top vertex coordinates are (x, y), the bottom coordinates will be:
(x - side / 2, y + h)
And:
(x + side / 2, y + h)
So your path code should be written as:
float side = Math.sqrt(3) / 2 * height;
Path path = new Path();
path.moveTo(x, y);
path.lineTo(x - side / 2, y + height);
path.lineTo(x + side / 2, y + height);
path.close();

AndEngine - SpriteGroup blinks on newly attachChild

I'm using the last version of the AndEngine, branch GLES2, with two devices: HTC Desire and a Galaxy Nexus.
I have a problem when using a SpriteGroup with Sprites scrolling down on the screen. New sprites are attached to a SpriteGroup on the top of the screen and detached when they go off the bottom. And I use a pool to avoid using to much memory.
As soon as there are some sprites detached, some newly attached sprites begin to blink randomly for a few frames. This is very annoying and I have no idea why...
I tried to setVisible(false) the sprites when recycling them, I also tried without the pool but it doesn't change a thing.
I think that SpriteGroup may have a bug, but not sure where. I tried to attach the children in SpriteGroup in the begin() method to be sure it didn't happen during the loop of onUpdateSpriteBatch(), without luck.
Here is an example based on the AndEngineExamples project. You can directly replace the SpriteBatchExample class, launch the project and go to Simple/Drawing a SpriteBatch, to see the problem.
Thanks in advance for any idea !
package org.andengine.examples;
import java.util.Iterator;
import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.timer.ITimerCallback;
import org.andengine.engine.handler.timer.TimerHandler;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.sprite.batch.SpriteGroup;
import org.andengine.entity.util.FPSLogger;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.andengine.util.adt.list.SmartList;
import org.andengine.util.adt.pool.GenericPool;
public class SpriteBatchExample extends SimpleBaseGameActivity {
// ===========================================================
// Constants
// ===========================================================
private static final int CAMERA_WIDTH = 720;
private static final int CAMERA_HEIGHT = 480;
// ===========================================================
// Fields
// ===========================================================
private BitmapTextureAtlas mBitmapTextureAtlas;
private ITextureRegion mFaceTextureRegion;
private float mSecondsElapsedSinceLastGeneration = 0;
// ===========================================================
// Constructors
// ===========================================================
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
#Override
public EngineOptions onCreateEngineOptions() {
final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
}
#Override
public void onCreateResources() {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 32, 32, TextureOptions.BILINEAR);
this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "face_box.png", 0, 0);
this.mBitmapTextureAtlas.load();
}
#Override
public Scene onCreateScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene();
scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));
final SpriteGroup spriteGroup = new SpriteGroup(this.mBitmapTextureAtlas, 500, this.getVertexBufferObjectManager());
spriteGroup.setPosition(0, 0);
scene.attachChild(spriteGroup);
final SpritePool lPool = new SpritePool(mFaceTextureRegion, getVertexBufferObjectManager());
final SmartList<Sprite> lSpriteList = new SmartList<Sprite>();
final float lCharactersPeriod = 0.4f;
scene.registerUpdateHandler(new TimerHandler(0.05f, true, new ITimerCallback() {
#Override
public void onTimePassed(final TimerHandler pTimerHandler) {
final float lSecondsElapsedSinceLastUpdate = 0.1f;
final Iterator<Sprite> li = lSpriteList.iterator();
while (li.hasNext()) {
final Sprite lChar = li.next();
boolean lRemoveChar = false;
// Character destruction OR movement
final float lY = lChar.getY();
if (lY > CAMERA_HEIGHT) {
lRemoveChar = true;
} else {
lChar.setPosition(lChar.getX(), lY + 60 * lSecondsElapsedSinceLastUpdate);
}
if (lRemoveChar) {
// Remove character from scene
lChar.detachSelf();
lPool.recyclePoolItem(lChar);
li.remove();
}
}
// Character generation
mSecondsElapsedSinceLastGeneration += lSecondsElapsedSinceLastUpdate;
if (mSecondsElapsedSinceLastGeneration > lCharactersPeriod) {
// generate sprite
final Sprite lSprite = lPool.obtainPoolItem();
lSprite.setPosition((float) Math.random() * CAMERA_WIDTH, 0);
spriteGroup.attachChild(lSprite);
lSpriteList.add(lSprite);
mSecondsElapsedSinceLastGeneration -= lCharactersPeriod;
}
}
}));
return scene;
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
static class SpritePool extends GenericPool<Sprite> {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private final VertexBufferObjectManager mVertexBufferObjectManager;
private ITextureRegion mFaceTextureRegion;
// ===========================================================
// Constructors
// ===========================================================
public SpritePool(final ITextureRegion pFaceTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {
mFaceTextureRegion = pFaceTextureRegion;
mVertexBufferObjectManager = pVertexBufferObjectManager;
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
#Override
protected Sprite onAllocatePoolItem() {
final Sprite lSprite = new Sprite(50, 0, mFaceTextureRegion, mVertexBufferObjectManager);
lSprite.setIgnoreUpdate(true);
return lSprite;
}
#Override
protected void onHandleRecycleItem(final Sprite pSprite) {
}
#Override
protected void onHandleObtainItem(final Sprite pSprite) {
}
}
}
i had the same issue (last added visible sprite(s) in the group started blinking whenever i set any sprite to invisible), and solved it by overwriting those 2 methods in SpriteGroup:
SpriteGroup result = new SpriteGroup(atlas, capacity, vertexBufferObjectManager) {
#Override
protected boolean onUpdateSpriteBatch() {
return false;
}
#Override
protected void onManagedUpdate(float pSecondsElapsed) {
super.onManagedUpdate(pSecondsElapsed);
final SmartList<IEntity> children = this.mChildren;
if(children != null) {
final int childCount = children.size();
for(int i = 0; i < childCount; i++) {
this.drawWithoutChecks((Sprite)children.get(i));
}
submit();
}
};
source:
http://www.andengine.org/forums/gles2/blinking-last-sprite-in-spritegroup-t7617.html

Start animation with AndEngine Live Wallpaper extansion

I have code like this:
public class SnowFallService extends BaseLiveWallpaperService implements IOnAreaTouchListener{
// ===========================================================
// Constants
// ===========================================================
private static final int CAMERA_WIDTH = 480;
private static final int CAMERA_HEIGHT = 800;
private ArrayList<Sprite> allSnow = new ArrayList<Sprite>();
// ===========================================================
// Fields
// ===========================================================
private ScreenOrientation screenOrientation;
private static TextureRegion snowTexture;
private static TextureRegion backgroundTexture;
private static Textures texture = null;
private Scene mScene;
public org.anddev.andengine.engine.Engine onLoadEngine() {
return new org.anddev.andengine.engine.Engine(new EngineOptions(true, this.screenOrientation, new FillResolutionPolicy(), new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT)));
}
public void onLoadResources() {
texture = new Textures(this, getEngine());
}
public void onUnloadResources() {
}
public Scene onLoadScene() {
final Scene mScene = new Scene();
backgroundTexture = texture.getBackground();
mScene.attachChild(new Sprite(0, 0, backgroundTexture));
snowTexture = texture.getSnowTextureRegion();
mScene.registerUpdateHandler(new IUpdateHandler() {
private long lastRaindropAdd = 0;
#Override
public void onUpdate(final float pSecondsElapsed) {
int size = allSnow.size();
int tmpInt = 0;
Random randGen = new Random();
for (int i = 0; i < size; i++) {
if (allSnow.get(i) != null){
Sprite snow = allSnow.get(i);
tmpInt = randGen.nextInt(4);
snow.setPosition(snow.getX() + (randGen.nextInt(5) - randGen.nextInt(5)) * randGen.nextInt(3), snow.getY() + tmpInt);
if (snow.getY() > CAMERA_HEIGHT || snow.getX() > CAMERA_WIDTH) {
synchronized(snow) {
size--;
allSnow.remove(i);
mScene.detachChild(snow);
}
}
}
}
tmpInt = randGen.nextInt(5000);
if (System.currentTimeMillis() - lastRaindropAdd > tmpInt) {
lastRaindropAdd = System.currentTimeMillis();
tmpInt = randGen.nextInt(CAMERA_WIDTH);
Sprite snow = getRaindrop(tmpInt, 0);
allSnow.add(snow);
mScene.attachChild(snow);
}
}
#Override
public void reset() {
}
});
return mScene;
}
public void onLoadComplete() {
// TODO Auto-generated method stub
}
public void onPauseGame() {
// TODO Auto-generated method stub
}
public void onResumeGame() {
// TODO Auto-generated method stub
}
public Sprite getRaindrop(float x, float y) {
return (new Sprite(x, y, snowTexture.deepCopy()));
}
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,ITouchArea pTouchArea, float pTouchAreaLocalX, float pTouchAreaLocalY) {
if(pSceneTouchEvent.isActionDown()) {
// HERE I WANT PLACE CODE, THAT WILL START ANIMATION.
return true;
}
return false;
}
}
So how to start animation on click? I want to make something like small cartoon.
In your onLoadScene method after registering update handler disable it.
mUpdateHandler.setEnabled(false);
And in onAreaTouched method enable it.
mUpdateHandler.setEnabled(true);
Btw I think it's not good practice to create Random instance every time in onUpdate method.
Here Josh describes how to override onTouch method (andEngine does not handle touch events for livewallpaper correctly, so you have to do it on your own). In few words, all you have to do is to override following function in BaseWallpaperGLEngine class (class is a part of andEngine live wallpaper extension:
#Override
public void onTouchEvent (MotionEvent event)
{
}

Categories

Resources