Score is a drawable image
private Bitmap Scores;
private boolean running =true;
private SurfaceView mySurfaceHolder;
Scores.decodeResource(myContext.getResource(), R.drawable.score);
//this is just the run procedure
#Override
public void onRun()
{
while(running){
Canvas c = null;
try{
c = mySurfaceHolder.lockCanvas(null);
synchronize(mySurfaceHolder){
drawScore(c); //here is where i call my method..
}
}finally{
mySurfaceHolder.unlockCanvasAndPost(c);
}
}
//the pontsGain and onTitle are both boolean variables so please don't get confuse
//and pointScoreAtY is an integer that will allocate my specific position in screen
private void drawScore(Canvas c)
{
try{
if(pointsGain && !onTitle)
{
pointScoreAtY = (int)(FingerY -(Scores.getHeight()/2)-100);
int i=100;
do{
try{
c.drawBitmap(Scores, (FingerX -(Scores.getWidth()/2))+200,pointScoreAtY, null);
invalidate();
pointScoreAtY -=i;
}catch(Exception e){}
}while(i-->0);
pointsGain = false;
}
}catch(Exception e){}
}
This specific function is drawing a bitmap into the screen at current location but it is not what i am looking to do... for example my main goal is when a character on my game gets hit i want to show a scorePoint and animate it so that it can go up and disappear from screen.
You can add animation to your imageview like this:
TranslateAnimation anim = new TranslateAnimation( 0, xDest - originalPos[0] , 0, yDest - originalPos[1] );
anim.setDuration(1000);
anim.setFillAfter( true );
view.startAnimation(anim);
For more animation details check android developer site:
http://developer.android.com/training/animation/index.html
Related
I am beginner to Animation in Android.
I want to set animation like Pendulum(Swing left to right) to image in my Activity.
what I have done so far is:
Animation anim = new RotateAnimation(0, 30, 0, 0);
anim.setRepeatMode(Animation.REVERSE);
anim.setInterpolator(new AccelerateDecelerateInterpolator());
anim.setDuration(1500);
anim.setFillAfter(true);
But it doesn't work at all...
can anybody suggest me how to do Animation?
Thank You....
I had the exact same problem, and ended up with an xml-only solution: http://blog.sqisland.com/2012/01/android-pendulum-animation.html
This will help you ::
AnimationDrawable Tranninganimation5;
Tranninganimation1 = new AnimationDrawable();
new playninzi().execute();
animation.setOneShot(false);
Tranninganimation1.setOneShot(false);
private class playninzi extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(
Signs_main_page.this);
protected void onPreExecute() {
this.dialog.setMessage("Please Wait...");
this.dialog.show();
try {
for (int i = 1; i < 25; i++) {
Bitmap bitmap = BitmapFactory
.decodeStream((InputStream) new URL(
"http://203.a44.115.55/MRESC/images/test/girl2/"
+ "girl-1000" + i + ".png")
.getContent());
Drawable frame = new BitmapDrawable(bitmap);
animation.addFrame(frame, 50);
}
} catch (Exception e) {
}
#Override
protected Void doInBackground(Void... arg0) {
return null;
}
protected void onPostExecute(final Void unused) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
in this example i have attach image from server but you can also set it drawable and display animation
If I were you, and doing such complex animations, I would try looking into the simply API of canvas to draw and animate objects. Take a look at lunarLandar for an example.
Would be very simple, if you control the actual placement of the object, to simply create a formula that adjusts the X & Y of the object.
Sudo:
-If object is going right, and is left of center, decrease it's Y value.
-If object is going right, and is right of center, increase it's Y value.
-If the object is going left, and is right of center, decrease it's Y value.
-If the object is going left, and is left of center, increase it's Y value.
When using invalidate the history of previous drawing actions are gone. I want to create an animation where I draw some new pixels after a certain delay.
I have tried using a Bitmap to remember the previous set pixels, but it won't load on the canvas, it throws an exception, see code below (commented not working).
I tried using invalidate but it completely wipes out the previous set pixels.
#Override
protected void onDraw(Canvas canvas) {
int colorWhite = getResources().getColor(android.R.color.white);
int colorBlack = getResources().getColor(android.R.color.black);
//not working
//Bitmap bmp = Bitmap.createBitmap(300,300, Bitmap.Config.ARGB_8888);
//canvas.setBitmap(bmp);
try
{
if(board == null) {
Ant ant = new Ant(new Position(430,430), new TurnDegree(0));
board = new Board(ant, 15000);
board.moveAnt();
}
MarkedPosition position = board.positions().get(count);
if(position.isMarked()) {
paint.setColor(colorWhite);
} else {
paint.setColor(colorBlack);
}
paint.setStrokeWidth(5);
System.out.println(position.position().x());
canvas.drawRect(position.position().x(), position.position().y(),
position.position().x() + 5, position.position().y() + 5, paint);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
invalidate();
}
}, 100);
}
catch(Exception e){
System.out.println("Error");
}
count++;
}
How can I create a sort of animation which draws new pixels to the screen after a certain delay, without having to repaint all pixels which I set previously?
you can store your previous pixels in ArrayList. after invalidate redraw all the points from ArrayList
make Arraylist of rect
ArrayList<Rect> allRects = new ArraList();
add when you draw rect on cavas
Rect rect = new Rect(position.position().x(), position.position().y(),
position.position().x() + 5, position.position().y() + 5);
canvas.drawRect(rect);
allRects.add(rect);
after invalidate again draw all rect using for loop
for (i = 0; i< allRects.size(); i++){
canvas.drawRect(allRects.get(i));
}
Presently I'm trying to implement simple game using libgdx for Android Platform. I have implemented the game but don't know how to pause and resume game based on user input.Kindly suggest idea as well as some practical code to implement the same.I am using simple game code demonstrated in libgdx library. Thank you.
Here is the code :
public class Drop implements ApplicationListener {
Texture dropImage;
Texture bucketImage;
Sound dropSound;
Music rainMusic;
SpriteBatch batch;
OrthographicCamera camera;
Rectangle bucket;
Array<Rectangle> raindrops;
long lastDropTime;
#Override
public void create() {
// load the images for the droplet and the bucket, 64x64 pixels each
dropImage = new Texture(Gdx.files.internal("droplet.png"));
bucketImage = new Texture(Gdx.files.internal("bucket.png"));
// load the drop sound effect and the rain background "music"
dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav"));
rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));
// start the playback of the background music immediately
rainMusic.setLooping(true);
rainMusic.play();
// create the camera and the SpriteBatch
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
batch = new SpriteBatch();
// create a Rectangle to logically represent the bucket
bucket = new Rectangle();
bucket.x = 800 / 2 - 64 / 2; // center the bucket horizontally
bucket.y = 20; // bottom left corner of the bucket is 20 pixels above the bottom screen edge
bucket.width = 64;
bucket.height = 64;
// create the raindrops array and spawn the first raindrop
raindrops = new Array<Rectangle>();
spawnRaindrop();
}
private void spawnRaindrop() {
Rectangle raindrop = new Rectangle();
raindrop.x = MathUtils.random(0, 800-64);
raindrop.y = 480;
raindrop.width = 64;
raindrop.height = 64;
raindrops.add(raindrop);
lastDropTime = TimeUtils.nanoTime();
}
#Override
public void render() {
// clear the screen with a dark blue color. The
// arguments to glClearColor are the red, green
// blue and alpha component in the range [0,1]
// of the color to be used to clear the screen.
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// tell the camera to update its matrices.
camera.update();
// tell the SpriteBatch to render in the
// coordinate system specified by the camera.
batch.setProjectionMatrix(camera.combined);
// begin a new batch and draw the bucket and
// all drops
batch.begin();
batch.draw(bucketImage, bucket.x, bucket.y);
for(Rectangle raindrop: raindrops) {
batch.draw(dropImage, raindrop.x, raindrop.y);
}
batch.end();
// process user input
if(Gdx.input.isTouched()) {
Vector3 touchPos = new Vector3();
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
bucket.x = touchPos.x - 64 / 2;
}
if(Gdx.input.isKeyPressed(Keys.LEFT)) bucket.x -= 200 * Gdx.graphics.getDeltaTime();
if(Gdx.input.isKeyPressed(Keys.RIGHT)) bucket.x += 200 * Gdx.graphics.getDeltaTime();
// make sure the bucket stays within the screen bounds
if(bucket.x < 0) bucket.x = 0;
if(bucket.x > 800 - 64) bucket.x = 800 - 64;
// check if we need to create a new raindrop
if(TimeUtils.nanoTime() - lastDropTime > 1000000000) spawnRaindrop();
// move the raindrops, remove any that are beneath the bottom edge of
// the screen or that hit the bucket. In the later case we play back
// a sound effect as well.
Iterator<Rectangle> iter = raindrops.iterator();
while(iter.hasNext()) {
Rectangle raindrop = iter.next();
raindrop.y -= 200 * Gdx.graphics.getDeltaTime();
if(raindrop.y + 64 < 0) iter.remove();
if(raindrop.overlaps(bucket)) {
dropSound.play();
iter.remove();
}
}
}
#Override
public void dispose() {
// dispose of all the native resources
dropImage.dispose();
bucketImage.dispose();
dropSound.dispose();
rainMusic.dispose();
batch.dispose();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
The most simple thing is, that you add an Enum:
public enum State
{
PAUSE,
RUN,
RESUME,
STOPPED
}
And modify your rendermethod
private State state = State.RUN;
#Override
public void render()
{
switch (state)
{
case RUN:
//do suff here
break;
case PAUSE:
//do stuff here
break;
case RESUME:
break;
default:
break;
}
}
Use the callback from android too. For example use the callbacks from libgdx to change the state:
#Override
public void pause()
{
this.state = State.PAUSE;
}
#Override
public void resume()
{
this.state = State.RESUME;
}
Also add something like a setMethod for the state so you can change it on userevent.
public void setGameState(State s){
this.state = s;
}
You can use states, with enums or constants. and only update in the Running state. Something like this:
public enum State{
Running, Paused
}
State state = State.Running;
#Override
public void render(){
switch(state){
case Running:
update();
break;
case Paused:
//don't update
break;
}
draw();
}
public void update(){
//your update code
}
public void draw(){
//your render code
}
I don't have the rep to reply to comments, but the flickering of items is something I ran into before.
You are no longer clearing the screen and redrawing the sprites in your render when its paused right? If I am not mistaken if you glClear and redraw the srpites in every render i think it will stop
Even more simple, see here: https://github.com/libgdx/libgdx/wiki/Continuous-&-non-continuous-rendering
In your ApplicationListener's create method, just put
Gdx.graphics.setContinuousRendering(false);
Gdx.graphics.requestRendering();
Set up a boolean
public boolean paused = false;
Then for example a button listener to pause/resume on a button press
buttonPause.addListener(new ChangeListener() {
public void changed (ChangeEvent event, Actor actor) {
// set paused true or false here
}
});
Then right at the end of your render method, just add:
if (!paused) {
Gdx.graphics.requestRendering();
}
The render method is now paused/resumed.
I tried using this approach:
I made GAME_PAUSED a boolean , If it is true don't update your screen or camera . Otherwise update Camera .
boolean GAME_PAUSED = false;
if (GAME_PAUSED) {
//Do not update camera
batch.begin();
resumeButton.draw(batch);
batch.end();
} else {
//Update Camera
Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1/60f, 8, 3);
camera.update();
debugRenderer.render(world, camera.combined);
//Do your game running
}
I am beginner to Animation in Android.
I want to set animation like Pendulum(Swing left to right) to image in my Activity.
what I have done so far is:
Animation anim = new RotateAnimation(0, 30, 0, 0);
anim.setRepeatMode(Animation.REVERSE);
anim.setInterpolator(new AccelerateDecelerateInterpolator());
anim.setDuration(1500);
anim.setFillAfter(true);
But it doesn't work at all...
can anybody suggest me how to do Animation?
Thank You....
I had the exact same problem, and ended up with an xml-only solution: http://blog.sqisland.com/2012/01/android-pendulum-animation.html
This will help you ::
AnimationDrawable Tranninganimation5;
Tranninganimation1 = new AnimationDrawable();
new playninzi().execute();
animation.setOneShot(false);
Tranninganimation1.setOneShot(false);
private class playninzi extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(
Signs_main_page.this);
protected void onPreExecute() {
this.dialog.setMessage("Please Wait...");
this.dialog.show();
try {
for (int i = 1; i < 25; i++) {
Bitmap bitmap = BitmapFactory
.decodeStream((InputStream) new URL(
"http://203.a44.115.55/MRESC/images/test/girl2/"
+ "girl-1000" + i + ".png")
.getContent());
Drawable frame = new BitmapDrawable(bitmap);
animation.addFrame(frame, 50);
}
} catch (Exception e) {
}
#Override
protected Void doInBackground(Void... arg0) {
return null;
}
protected void onPostExecute(final Void unused) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
in this example i have attach image from server but you can also set it drawable and display animation
If I were you, and doing such complex animations, I would try looking into the simply API of canvas to draw and animate objects. Take a look at lunarLandar for an example.
Would be very simple, if you control the actual placement of the object, to simply create a formula that adjusts the X & Y of the object.
Sudo:
-If object is going right, and is left of center, decrease it's Y value.
-If object is going right, and is right of center, increase it's Y value.
-If the object is going left, and is right of center, decrease it's Y value.
-If the object is going left, and is left of center, increase it's Y value.
I'm new to Android and let me first tell you what I'm trying to achieve. Using sockets, I'm sending pictures from my computer's webcam every 50ms. In Android app, I've created my display that extends View. I've added this view to FrameLayout. Parallel thread is receiving images from server app (desktop) and refreshing my display.
On this image I want to display some accelerometer data that refreshes every... Well it's set to SENSOR_DELAY_FASTEST. So I also created another display that extends View, and also I add it to another FrameLayout. Now I set my main.xml to overlap those FrameLayouts..
I'm getting my image from desktop application, I'm drawing accelerometer data, and It's overlapped, but the issue is.. It's flickering. Can anyone help? Or suggest something.. As I've pointed out, I'm new with Android.
Thanks..
This is a simple override that draws an image. - And and the method that calls for a redraw.
#Override
protected void onDraw(Canvas canvas){
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
paint.setARGB(10, 255, 255, 255);
if(Core.pic != null) {
canvas.drawBitmap(Core.pic, 0, 0, paint);
}
}
Here is a different class that calls for redraw when new image is available:
protected static volatile Bitmap pic;
public static void refreshDisplay(Bitmap img){
pic = img;
if(cameraDisplay != null) {
try{
cameraDisplay.invalidate();
}
catch(Exception e){
e.printStackTrace();
}
}
}
And here is a threaded class that ready port every 50ms:
while(running){
opt.inDither = true;
opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
if(in != null){
byte[] recieve = new byte[7000];
try {
in.read(recieve, 0, 7000);
Core.pic = BitmapFactory.decodeByteArray(recieve, 0, 7000, opt);
} catch (IOException e) {}
}
try {
sleep(50);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
This alone works fine. When I overlap this views then it flickers. In the similar way I'm reading accelerometer data and draw it:
public void onAccelerationChanged(float x, float y, float z) {
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
velocityBars.DrawVelocity(x, -z);
}
else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
velocityBars.DrawVelocity(y, -z);
}
}
velocityBars is my variable that is type of my custom View. This method DrawVelocity invokes the invalidate() method. This forces redraw.