I'm trying put a LoopEntityModifier for a sprite to have continuous forward backward movement
But something is wrong with that.
Movement is not smooth.
I guess i'm making mistake on reseting loop.
How can i make smooth movement out of it.
LoopEntityModifier looper = new LoopEntityModifier (
new IEntityModifierListener(){
public void onModifierStarted(
IModifier<IEntity> pModifier, IEntity pItem) {
// TODO Auto-generated method stub
Log.d("Modifier","Modifier Started !!");
}
public void onModifierFinished(
IModifier<IEntity> pModifier, IEntity pItem) {
// TODO Auto-generated method stub
Log.d("Modifier","Modifier Finished !!");
pModifier.reset();
}
},
1,
new ILoopEntityModifierListener(){
public void onLoopStarted(
LoopModifier<IEntity> pLoopModifier, int pLoop,
int pLoopCount) {
// TODO Auto-generated method stub
Log.d("Modifier","Loop Started !!");
}
public void onLoopFinished(
LoopModifier<IEntity> pLoopModifier, int pLoop,
int pLoopCount) {
// TODO Auto-generated method stub
Log.d("Modifier","Loop Finished !!");
}
},
new SequenceEntityModifier(
//Forward
new MoveXModifier(.5f,mNextSprite.getX(),mNextSprite.getX()+50),
//Backward
new MoveXModifier(.5f,mNextSprite.getX(),mNextSprite.getX()-50))
);
mNextSprite.registerEntityModifier(looper);
You can use MoveByModifier. its work good.
new SequenceEntityModifier(
new MoveByModifier(0.5f, 100, 0),
new MoveByModifier(0.5f, -100, 0)
));
if you don't use then replace this in your code
new SequenceEntityModifier(
// Forward
new MoveXModifier(.5f, mNextSprite.getX(),
mNextSprite.getX() + 50),
// Backward
new MoveXModifier(.5f, mNextSprite.getX() + 50,
mNextSprite.getX())
LoopEntityModifier looper = new LoopEntityModifier (
new IEntityModifierListener(){
public void onModifierStarted(
IModifier<IEntity> pModifier, IEntity pItem) {
// TODO Auto-generated method stub
Log.d("Modifier","Modifier Started !!");
}
public void onModifierFinished(
IModifier<IEntity> pModifier, IEntity pItem) {
// TODO Auto-generated method stub
Log.d("Modifier","Modifier Finished !!");
pModifier.reset();
}
},
1,
new ILoopEntityModifierListener(){
public void onLoopStarted(
LoopModifier<IEntity> pLoopModifier, int pLoop,
int pLoopCount) {
// TODO Auto-generated method stub
Log.d("Modifier","Loop Started !!");
}
public void onLoopFinished(
LoopModifier<IEntity> pLoopModifier, int pLoop,
int pLoopCount) {
// TODO Auto-generated method stub
Log.d("Modifier","Loop Finished !!");
}
},
new SequenceEntityModifier(
// Forward
new MoveXModifier(.5f, mNextSprite.getX(),
mNextSprite.getX() + 50),
// Backward
new MoveXModifier(.5f, mNextSprite.getX() + 50,
mNextSprite.getX())
);
mNextSprite.registerEntityModifier(looper);
Thanks to Divyang Metalia's answer I came up with the following two methods to animate a continuous back and forth movement of a sprite. It uses the SequenceEntityModifier and simply resets it when it is finished. To stop the animation the method stopAnimation() clears all modifiers and resets the sprites position:
public void startAnimation() {
this.from = this.getX(); // just an example start point (global)
float to = from +100 ; // example end point for the animation
MoveXModifier rightMovement = new MoveXModifier(0.5f, from, to);
MoveXModifier leftMovement = new MoveXModifier(0.5f, to, from);
SequenceEntityModifier sequenceEntityModifier = new SequenceEntityModifier(rightMovement, leftMovement) {
#Override
protected void onModifierFinished(IEntity pItem) {
super.reset();
}
};
sequenceEntityModifier.setAutoUnregisterWhenFinished(false);
this.registerEntityModifier(sequenceEntityModifier);
}
public void stopAnimation() {
this.clearEntityModifiers();
this.setX(from);
}
Clarification: the methods are part of a Sprite extending class.
Related
public class PlayScreen implements Screen{
Stage stage;
LabelStyle style;
BitmapFont font;
TextureAtlas backbuttonatlas;
TextButtonStyle backbuttonstyle;
TextButton backbutton;
Skin backskin;
SpriteBatch batch;
Texture pibe;
Sprite sprite;
Vector2 position;
Game game;
Texture texture;
public PlayScreen(Game game){
this.game=game;
}
#Override
public void render(float delta) {
stage=new Stage();
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(Gdx.input.isKeyPressed(Keys.W))
{
position.x+=5f;
}
if(Gdx.input.isKeyPressed(Keys.A))
{
position.y-=5f;
}
if(Gdx.input.isKeyPressed(Keys.S))
{
position.x-=5f;
}
if(Gdx.input.isKeyPressed(Keys.D))
{
position.y+=5f;
}
if(Gdx.input.isTouched()==true)
{
if(Gdx.input.getY()>Gdx.graphics.getHeight()/2)
{
position.x-=5;
}
if(Gdx.input.getY()<Gdx.graphics.getHeight()/2)
{
position.x+=5;
}
if(Gdx.input.getX()>Gdx.graphics.getWidth()/2)
{
position.y+=5;
}
if(Gdx.input.getX()<Gdx.graphics.getWidth()/2)
{
position.y-=5;
}
if(Gdx.input.isKeyPressed(Keys.BACK))
{
game.setScreen(new MainMenu(game));
}
}
font = new BitmapFont(Gdx.files.internal("font.fnt"), false);
style = new LabelStyle(font, Color.WHITE);
backskin = new Skin();
backbuttonatlas = new TextureAtlas("buttons/backbutton.pack");
backskin.addRegions(backbuttonatlas);
backbuttonstyle = new TextButtonStyle();
backbuttonstyle.up = backskin.getDrawable("backbutton");
backbuttonstyle.over = backskin.getDrawable("backbuttonpressed");
backbuttonstyle.down = backskin.getDrawable("backbuttonpressed");
backbuttonstyle.font = font;
backbutton = new TextButton("", backbuttonstyle);
backbutton.setWidth((float) (Gdx.graphics.getHeight()/8));
backbutton.setHeight((float) (Gdx.graphics.getHeight()/8));
backbutton.setPosition((Gdx.graphics.getWidth()/20), (float) (Gdx.graphics.getHeight()-(Gdx.graphics.getWidth()/8)));
backbutton.addListener(new InputListener(){
public boolean touchDown(InputEvent event, float x, float y, int pointer, int backbutton) {
game.setScreen(new MainMenu(game));
return true;
};});
batch=new SpriteBatch();
stage.addActor(backbutton);
Gdx.input.setInputProcessor(stage);
batch.begin();
batch.draw(texture, 0, 0, Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
batch.draw(pibe,(position.y/2-pibe.getWidth()/2),(position.x/2-pibe.getHeight()/2));
batch.end();
stage.act();
stage.draw();
}
#Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void show() {
texture = new Texture("cielo.png");
pibe = new Texture("superman (100x52).jpg");
position = new Vector2(Gdx.graphics.getHeight(),Gdx.graphics.getWidth());
}
#Override
public void hide() {
// TODO Auto-generated method stub
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
}
My LibGDX Game, collapse after a few minutes and I don't know why. I have read a little about the problem, and it says that the solution is to "dispose" the bitmapfont, or something like that. I'm new in LibGDX and I don't understand so much. A full explanation is appreciated. Sorry for my poor English.
This is the Play Class. Please, need help. Thanks.
you have to put your "creating" stuff like batch = new SpriteBatch() inside
#Override
public void create() {
)
you create billions of SpriteBatches that causes a memory issue.
Render is called each time the device is ready to update the screen. You are creating new objects each frame. Some of them must be disposed of manually, which means calling the .dispose() method of that object.
call
font.dispose();
when you are finished with the font to prevent it eating up all the memory.
Ideally you'd want to create that font outside of the render loop.
You should create your objects in the constructor, so that they are not recreated every single frame. Unless of course that is intended behavior.
Try something like this
public class PlayScreen implements Screen{
Stage stage;
LabelStyle style;
BitmapFont font;
TextureAtlas backbuttonatlas;
TextButtonStyle backbuttonstyle;
TextButton backbutton;
Skin backskin;
SpriteBatch batch;
Texture pibe;
Sprite sprite;
Vector2 position;
Game game;
Texture texture;
public PlayScreen(Game game){
this.game=game;
font = new BitmapFont(Gdx.files.internal("font.fnt"), false);
style = new LabelStyle(font, Color.WHITE);
stage=new Stage();
backskin = new Skin();
backbuttonatlas = new TextureAtlas("buttons/backbutton.pack");
backskin.addRegions(backbuttonatlas);
backbuttonstyle = new TextButtonStyle();
backbuttonstyle.up = backskin.getDrawable("backbutton");
backbuttonstyle.over = backskin.getDrawable("backbuttonpressed");
backbuttonstyle.down = backskin.getDrawable("backbuttonpressed");
backbuttonstyle.font = font;
backbutton = new TextButton("", backbuttonstyle);
backbutton.setWidth((float) (Gdx.graphics.getHeight()/8));
backbutton.setHeight((float) (Gdx.graphics.getHeight()/8));
backbutton.setPosition((Gdx.graphics.getWidth()/20), (float) (Gdx.graphics.getHeight()-(Gdx.graphics.getWidth()/8)));
backbutton.addListener(new InputListener(){
public boolean touchDown(InputEvent event, float x, float y, int pointer, int backbutton) {
game.setScreen(new MainMenu(game));
return true;
};});
batch=new SpriteBatch();
stage.addActor(backbutton);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(Gdx.input.isKeyPressed(Keys.W))
{
position.x+=5f;
}
if(Gdx.input.isKeyPressed(Keys.A))
{
position.y-=5f;
}
if(Gdx.input.isKeyPressed(Keys.S))
{
position.x-=5f;
}
if(Gdx.input.isKeyPressed(Keys.D))
{
position.y+=5f;
}
if(Gdx.input.isTouched()==true)
{
if(Gdx.input.getY()>Gdx.graphics.getHeight()/2)
{
position.x-=5;
}
if(Gdx.input.getY()<Gdx.graphics.getHeight()/2)
{
position.x+=5;
}
if(Gdx.input.getX()>Gdx.graphics.getWidth()/2)
{
position.y+=5;
}
if(Gdx.input.getX()<Gdx.graphics.getWidth()/2)
{
position.y-=5;
}
if(Gdx.input.isKeyPressed(Keys.BACK))
{
game.setScreen(new MainMenu(game));
}
}
Gdx.input.setInputProcessor(stage);
batch.begin();
batch.draw(texture, 0, 0, Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
batch.draw(pibe,(position.y/2-pibe.getWidth()/2),(position.x/2-pibe.getHeight()/2));
batch.end();
stage.act();
stage.draw();
}
#Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void show() {
texture = new Texture("cielo.png");
pibe = new Texture("superman (100x52).jpg");
position = new Vector2(Gdx.graphics.getHeight(),Gdx.graphics.getWidth());
}
#Override
public void hide() {
// TODO Auto-generated method stub
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
I want do a animate scroll like Jquery´s (in this web page works when you click in top menu´s options) in android. is it possible? I have seen that exists scrollTo but is possible to do with animation and not like jumps. Thank you very much.
Using ObjectAnimator, This is a sample for scrolling to top :
public void scroolToTop() {
int x = 0;
int y = 0;
ObjectAnimator xTranslate = ObjectAnimator.ofInt(mScrollView, "scrollX", x);
ObjectAnimator yTranslate = ObjectAnimator.ofInt(mScrollView, "scrollY", y);
AnimatorSet animators = new AnimatorSet();
animators.setDuration(1000L);
animators.playTogether(xTranslate, yTranslate);
animators.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationRepeat(Animator arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animator arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationCancel(Animator arg0) {
// TODO Auto-generated method stub
}
});
animators.start();
}
Hi im having a bit of problems getting my sprite to fade back in. Im using paralell entity modifiers, scaling and fading after which the sprite gets new X and Y cordinates and fades in and scales back up. It doesnt work and i think it might have something to do with the onUpdate method.
XOsprite = new Sprite(x, y, XO, engine.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(final TouchEvent te, final float xVal,
final float yVal) {
XOsprite.registerEntityModifier(downOut); //kill sprite
isKilled = true;
XOsprite.registerUpdateHandler(new IUpdateHandler() {
#Override
public void reset() {
// TODO Auto-generated method stub
}
#Override
public void onUpdate(float pSecondsElapsed) {
// TODO Auto-generated method stub
totalElapsedTime += pSecondsElapsed;
if(totalElapsedTime >= 3.0f){
BaseGameActivity gameActivity = (BaseGameActivity) activity;
gameActivity.runOnUpdateThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
if(isKilled){
reviveSprite();
isKilled = false;
}
}
});
}
//reset();
}
});
return true;
}
};
XOsprite.registerEntityModifier(inUp);
gameScene.attachChild(XOsprite);
gameScene.registerTouchArea(XOsprite);
return gameScene;
}
-edit- more code
public void reviveSprite(){
setSprites();
XOsprite.unregisterEntityModifier(downOut);
XOsprite.registerEntityModifier(inUp);
}
public void setSprites(){
if (rand.nextInt(2) == 0) {
XO = X;
} else {
XO = O;
}
x = rand.nextInt(MainActivity.CAM_WIDTH);
y = rand.nextInt(MainActivity.CAM_HEIGHT);
}
you are already on the UpdateThread, so no need to do this
gameActivity.runOnUpdateThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
if(isKilled){
reviveSprite();
isKilled = false;
}
}
});
just do this
if(isKilled){
reviveSprite();
isKilled = false;
}
I want an animated splash screen like fade in fade out for which I am doing in resize method as follows
public class SplashScreen extends GamePlayScreen {
#Override
public void resize(int width, int height) {
super.resize(width, height);
stage.clear();
Drawable splashDrawable = new TextureRegionDrawable(region);
splashImage = new Image(splashDrawable, Scaling.stretch);
splashImage.setFillParent(true);
splashImage.getColor().a = 0f;
splashImage.addAction(Actions.sequence(Actions.fadeIn(0.75f),
Actions.delay(1.75f), Actions.fadeOut(0.75f),
new Action() {
#Override
public boolean act(float delta) {
// the last action will move to the next screen
System.out.println("moving to next screen");
splashGameObj.setScreen(new GamePlayScreen(
splashGameObj));
return true;
}
}));
stage.addActor(splashImage);
}
}
Try changing your new Action() to new RunnableAction(){ public void run(){.....
Herer are more actions also some other explanation how they work. refare to an other question.
->Actions
Also take a look at:
screen2D, libgdx wiki about actions
Declare this variable
private Stage stage;
#Override
public void render(float delta) {
// TODO Auto-generated method stub
update();
draw(delta);
}
private void draw(float delta) {
// TODO Auto-generated method stub
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
stage.act(delta);
stage.draw()
}
#Override
public void resize(int width, int height) {
stage.setViewport( width, height, true );
}
#Override
public void show() {
// TODO Auto-generated method stub
stage = new Stage();
Gdx.input.setInputProcessor(stage);
Image splashImage = new Image(region);
splashImage.addAction( Actions.sequence( Actions.fadeOut( 0.0001f ), Actions.fadeIn( 5f ),
Actions.run(onSplashFinishedRunnable) ) );
stage.addActor(splashImage);
}
Runnable onSplashFinishedRunnable = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
splashGameObj.setScreen(new GamePlayScreen(splashGameObj));
}
};
I try to set ViewHelper.setPivotY(test, 0); in method onClick() but it doesn't work. The animation still scale to the centerY. Here is my code. I don't know where I am wrong?
public class NewClassTest extends Activity{
LinearLayout test;
FrameLayout content;
Button btn;
boolean toggle = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.test_activity);
test = (LinearLayout) findViewById(R.id.test);
content = (FrameLayout) findViewById(R.id.content);
content.setVisibility(View.INVISIBLE);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
// ViewHelper.setPivotY(test, 0); does not work
runAnimation(toggle);
toggle = !toggle;
}
});
ViewHelper.setPivotY(test, 0); // work
}
private void runAnimation(boolean in){
AnimatorSet animSet = new AnimatorSet();
ObjectAnimator anim = null, anim2 = null;
// ViewHelper.setPivotY(test, 0); also does not work
if(in){
anim = ObjectAnimator.ofFloat(test, "scaleY", 1, 1 - (((float)content.getHeight()) / ((float) test.getHeight())));
anim2 = ObjectAnimator.ofFloat(content, "translationY", content.getHeight(), 0);
animSet.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
// TODO Auto-generated method stub
content.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animator animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animator animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationCancel(Animator animation) {
// TODO Auto-generated method stub
}
});
}else {
anim = ObjectAnimator.ofFloat(test, "scaleY", 1 - ((float)content.getHeight()) / ((float) test.getHeight()), 1);
anim2 = ObjectAnimator.ofFloat(content, "translationY", 0, content.getHeight());
animSet.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationRepeat(Animator animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animator animation) {
// TODO Auto-generated method stub
content.setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationCancel(Animator animation) {
// TODO Auto-generated method stub
}
});
}
animSet.setDuration(1000).play(anim2).with(anim);
animSet.start();
}
Thank for your help!.
Happen to me also. test it on HTC One S with android 4.1 and that wasn't worked, but in Samsung Galaxy I with android 2.2 it worked as expected.
Changed it to ViewHelper.setPivotY(test, 0.00000001f); solved it =\
Don't know if it's a bug of HTC, android or nineoldandroids