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;
}
Related
I am a beginner working with graphics. Right now I have an image displayed in random places on the screen. What I would like to do that if the image is touched, it should be replaced by another image. How can I do that?
Another thing I currently am using a class within a class.Thanks
public class MainActivity extends ActionBarActivity implements OnTouchListener{
MyGameGraphics myGraphics;
TextView tvScore, tvPlayerScore;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tvScore = (TextView)findViewById(R.id.showScore);
tvPlayerScore = (TextView)findViewById(R.id.playerScore);
myGraphics = new GraphicsMain(this);
myGraphics.setOnTouchListener(this);
setContentView(myGraphics);
}
#Override
protected void onPause(){
super.onPause();
myGraphics.pause();
}
#Override
protected void onResume(){
super.onResume();
myGraphics.resume();
}
#Override
public boolean onTouch(View arg0, MotionEvent event) {
// TODO Auto-generated method stub
// How to change image using touch event here?
return false;
}
public class MyGameGraphics extends SurfaceView implements Runnable {
SurfaceHolder ourHolder;
Thread ourThread = null;
Boolean isRunning = false;
int[] images = new int[]{R.drawable.image1, R.drawable.image2};
public MyGameGraphics(Context context) {
super(context);
ourHolder = getHolder();
}
public void pause(){
isRunning = false;
while(true){
try {
ourThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
ourThread = null;
}
public void resume(){
isRunning = true;
ourThread = new Thread(this);
ourThread.start();
}
#Override
public void run() {
while(isRunning){
if(!ourHolder.getSurface().isValid())
continue;
Canvas ourCanvas = ourHolder.lockCanvas();
ourCanvas.drawRGB(0, 0, 0);
Random rn = new Random();
int location = rn.nextInt(12);
for(int i = 0; i < 500; i++){
try {
Random rn2 = new Random();
int generateWidthLocation = rn2.nextInt(420);
int generateHeightLocation = rn2.nextInt(600);
Bitmap btmp = BitmapFactory.decodeResource(getResources(), images[location]);
ourCanvas.drawBitmap(btmp, generateWidthLocation, generateHeightLocation, null);
ourThread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
ourHolder.unlockCanvasAndPost(ourCanvas);
}
}
}
}
In the OnTouch method, the event parameter has two functions : event.getX() and event.getY().
Then you just need to keep the generateWidthLocation and generateHeightLocation for the current position and you can easily determine if the image is touched or not (you also need to keep the height/width of the image).
You might need to check if the OnTouch method is called when the user touches the screens, moves his finger or stops to touch it : event.getAction() which is either MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE or MotionEvent.ACTION_UP.
EDIT : In your MyGameGraphics add the following properties :
int[] images = new int[] { R.drawable.image1, R.drawable.image2 };
int currentXImageLocation = 0;
int currentYImageLocation = 0;
int currentImageWidth = 0;
int currentImageHeight = 0;
And after ourCanvas.drawBitmap(btmp, generateWidthLocation, generateHeightLocation, null); add :
currentXImageLocation = generateWidthLocation;
currentYImageLocation = generateHeightLocation;
currentImageHeight = btmp.getHeight();
currentImageWidth = btmp.getWidth();
Then add this function in your MyGameGraphics class :
public boolean isImageTouched(float x, float y)
{
boolean result = false;
if(x > currentXImageLocation && x < currentXImageLocation + currentImageWidth
&& y > currentYImageLocation && y < currentYImageLocation + currentImageHeight)
{
result = true;
}
return result;
}
And finally in the OnTouch method :
#Override
public boolean onTouch(View arg0, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
if(myGraphics.isImageTouched(event.getX(), event.getY()))
{
//Image was touched, do something...
}
}
return true;
}
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
}
Currently I am working on live wallpaper and I am stuck at a point. Actually, my live wallpaper only works when I touch the screen, but it doesn't change continuously. There is a problem in my loop.
class Diwali extends Engine {
private boolean mVisible;
private final Runnable diwaliImg = new Runnable() {
public void run() {
drawFrame();
}
};
int i=0;
int[] pirates = {
R.drawable.a1, R.drawable.a2,
R.drawable.a3, R.drawable.a4,
R.drawable.a5, R.drawable.a6,
R.drawable.a7, R.drawable.a8,
R.drawable.a9, R.drawable.a10,
R.drawable.a11, R.drawable.a12,
R.drawable.a13, R.drawable.a14
};
#Override
public void onCreate(SurfaceHolder holder){
super.onCreate(holder);
}
#Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(diwaliImg);
}
#Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
if (visible) {
drawFrame();
} else {
mHandler.removeCallbacks(diwaliImg);
}
}
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
drawFrame();
}
#Override
public void onSurfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
super.onSurfaceCreated(holder);
}
#Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(diwaliImg);
}
#Override
public void onOffsetsChanged(float xOffset, float yOffset, float xStep,float yStep, int xPixels, int yPixels) {
drawFrame();
}
#Override
public void onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
}
private void drawFrame() {
// TODO Auto-generated method stub
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
drawPirate(c);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(diwaliImg);
}
private void drawPirate(Canvas c) {
// TODO Auto-generated method stub
Bitmap icon = BitmapFactory.decodeResource(getResources(),pirates[i]);
i++;
if (i == 13) {
i = 0;
}
Matrix matrix = new Matrix();
c.drawBitmap(icon, matrix, null);
icon.recycle();
}
}
After adding this
if (mVisible) {
Handler.postDelayed(diwaliImg,80);
}
At the end draw frame() my problem was solved.
There is no loop in your code. You need to call drawFrame() repeatedly.
To achieve this you may use separate thread for animation. I recommend you my wallpaper template available on GitHub.
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 am working on frame animation in which i am using thread but thread is throwing me error .
my code is as follow ....
public class Newton_LawsActivity extends Activity implements OnTouchListener, OnGestureListener,OnDoubleTapListener {
/** Called when the activity is first created. */
OnTouchListener l;
ImageView animation;
ImageView hideimage;
TextView t;
Thread timer;
int Rid;
double pixel;
String law="null";
private GestureDetector gestureDetector;
float x,y;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gestureDetector = new GestureDetector(this);
// the frame-by-frame animation defined as a xml file within the drawable folder
animation = (ImageView)findViewById(R.id.image);
//animation.setBackgroundResource(R.drawable.anatomy_5);
hideimage=(ImageView)findViewById(R.id.imagein);
t=(TextView) findViewById(R.id.t);
animation.setBackgroundResource(R.anim.startanimation);
final AnimationDrawable newtonAnimation = (AnimationDrawable) animation.getBackground();
AnimationStart(newtonAnimation);
animation.setOnTouchListener(this);
}
public void AnimationStart(final AnimationDrawable newanimation){
timer=new Thread(){
#Override
public void run(){
try{
}catch(Exception e){}
finally{
Newton_LawsActivity.this.runOnUiThread(new Runnable() {
public void run(){
newanimation.start();
}});
}
}
};
timer.start();
}
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
Toast.makeText(this, "animation", Toast.LENGTH_LONG).show();
return gestureDetector.onTouchEvent(event);
}
private void animationswitch(float x, float y) {
// TODO Auto-generated method stub
pixel = getmaskpixel(x,y,animation,hideimage);
Log.w("DEBUG","which is null:pixel" + pixel );
if (pixel==-583672){
animation.setBackgroundResource(R.anim.firstlaw_01);
final AnimationDrawable firstlaw_01 = (AnimationDrawable) animation.getBackground();
law="firstlaw_02";
firstlaw_01.start();
animationstop_01();
}
t.setText(Double.toString(pixel));
}
private double getmaskpixel(float x, float y, ImageView view,ImageView hideimage) {
// TODO Auto-generated method stub
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.touchnewtonfinal415);
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) view.getWidth()) / width;
float scaleHeight = ((float) view.getHeight()) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// matrix.postRotate(90);
// recreate the new Bitmap
Bitmap bitmap = Bitmap.createBitmap(bm, 0, 0, width, height,matrix, false);
Log.w("DEBUG","which is null:image " + hideimage.getWidth() + " OR " +hideimage.getHeight() );
double bmWidth = view.getWidth();
double bmHeight = view.getHeight();
if ( x < 0 || y < 0 || x > hideimage.getWidth() || y >hideimage.getHeight()){
return 0; //Invalid, return 0
}else{
//Convert touched x, y on View to on Bitmap
int xBm = (int)(x * (bmWidth / hideimage.getWidth()));
int yBm = (int)(y * (bmHeight / hideimage.getHeight()));
return bitmap.getPixel((int)xBm,(int) yBm);
}
}
public boolean onSingleTapUp(MotionEvent e) {
return false;
// TODO Auto-generated method stub
}
#Override
public boolean onDown(MotionEvent arg0) {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onLongPress(MotionEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onShowPress(MotionEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public boolean onDoubleTap(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onDoubleTapEvent(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// TODO Auto-generated method stub
x=e.getX();
y= e.getY();
Log.w("DEBUG","which is null:image " + x + " OR " +y);
animationswitch(x, y);
return true;
}
void animationstop_01(){
if(law=="firstlaw_02"){
timer=new Thread(){
#Override
public void run(){
try{
Thread.sleep(8750);
}catch(Exception e){}
finally{
Log.w("debug","it is firstlaw_02");
animation.setBackgroundResource(R.anim.firstlaw_02);
final AnimationDrawable firstlaw_02 = (AnimationDrawable) animation.getBackground();
law="firstlaw_03";
AnimationStart(firstlaw_02);
}};
};
timer.start();
}
}
}
it is throwing me following error..
06-06 14:15:00.668: E/AndroidRuntime(966): FATAL EXCEPTION: Thread-10
06-06 14:15:00.668: E/AndroidRuntime(966): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.View.invalidate(View.java:5139)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.View.setBackgroundDrawable(View.java:7486)
06-06 14:15:00.668: E/AndroidRuntime(966): at android.view.View.setBackgroundResource(View.java:7395)
06-06 14:15:00.668: E/AndroidRuntime(966): at Newtons.law.Newton_LawsActivity$2.run(Newton_LawsActivity.java:183)
Change your animationstop_01 method to:
void animationstop_01(){
if(law=="firstlaw_02"){
timer=new Thread(){
#Override
public void run(){
try{
Thread.sleep(8750);
}catch(Exception e){
}finally{
Log.w("debug","it is firstlaw_02");
Newton_LawsActivity.this.runOnUiThread(new Runnable() {
public void run(){
animation.setBackgroundResource(R.anim.firstlaw_02);
final AnimationDrawable firstlaw_02 = (AnimationDrawable) animation.getBackground();
law="firstlaw_03";
AnimationStart(firstlaw_02);
}
});
}
};
};
timer.start();
}
}
Error is inside the mehod name animationstop_01() where you are trying,
animation.setBackgroundResource(R.anim.firstlaw_02);
put that inside runOnUiThread()
try this:
animation.post(new Runnable() {
public void run() {
animation.setBackgroundResource(R.anim.firstlaw_02);
}
});
In that way you are posting it to the UI thread. View can only be changed from the original thread that created the View.