App crush while running a simple ball app [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am trying to launch a very basic app - a ball that should bounce on the screen but I am getting an error while trying to launch app on device.
Here's my code, I may have some errors but please explain to me what are they and how could I fix them, I'm new to android development..
public class Ball {
float x;
float y;
boolean movingRight;
boolean movingBottom;
float screenWidth;
float screenHeight;
public Ball(float x, float y, float screenWidth, float screenHeight) {
this.x = x;
this.y = y;
this.screenWidth = screenWidth;
this.screenHeight = screenHeight - 150;
this.movingBottom = false;
this.movingRight = false;
}
public void move() {
if (movingRight)
this.x++;
else
this.x--;
if (movingBottom)
this.y++;
else
this.y--;
if (this.x >= this.screenWidth)
this.movingRight = false;
else if (this.x <= 1)
this.movingRight = true;
if (this.y >= this.screenHeight)
this.movingBottom = false;
else if (this.y <= 1)
this.movingBottom = true;
}
public float getX(){
return this.x;
}
public float getY() {
return this.y;
}
public class MySurfaceView extends SurfaceView{
private Ball ball;
private SurfaceHolder holder;
Paint paint;
public Paint getBallPaint()
{
if(paint == null)
{
paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(3);
}
return this.paint;
}
public MySurfaceView(Context context) {
super(context);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas c = holder.lockCanvas(null);
draw(c);
holder.unlockCanvasAndPost(c);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
}
#Override
public void draw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.drawCircle(ball.x,ball.y,15,getBallPaint());
}
}
public class GameLoopThread extends Thread {
private MySurfaceView view;
private boolean running = false;
public GameLoopThread(MySurfaceView view) {
this.view = view;
}
public void setRunning(boolean run) {
running = run;
}
#Override
public void run() {
while (running) {
Canvas c = null;
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.draw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
}
}
}
public class MainActivity extends ActionBarActivity {
Ball ball;
MySurfaceView mySurfaceView;
GameLoopThread gameLoopThread;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int screenWidth;
screenWidth = getWindowManager().getDefaultDisplay().getWidth();
int screenHeight;
screenHeight = getWindowManager().getDefaultDisplay().getHeight();
ball = new Ball(screenWidth / 2, screenHeight / 2, screenWidth,screenHeight);
gameLoopThread = new GameLoopThread(mySurfaceView);
gameLoopThread.start();
mySurfaceView = new MySurfaceView(this);
setContentView(mySurfaceView);
}

I cannot tell if there are other errors but most obvious one is that you are using mySurfaceView before you have created it.
You should change initialization order to:
mySurfaceView = new MySurfaceView(this);
setContentView(mySurfaceView);
gameLoopThread = new GameLoopThread(mySurfaceView);
gameLoopThread.start();

Related

Bitmap doesn't seem to update when I try to rotate it in my canvas

I have an object on my canvas that I need to rotate based on user input. When the user touches the screen, and then moves their finger, the app calculates the angle between the two touch events, and that is the angle I need my Bitmap to face.
Here is a screenshot with a test Bitmap, I need the nose of the plane to face the direction determined by the input, and then update constantly as the input changes.
This GameView class is set at the ContentView for my activity:
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
MainThread thread;
private Player player;
private Point playerPoint;
private float originX;
private float originY;
private float currX;
private float currY;
private float playerAngle;
public GameView(Context context){
super(context);
getHolder().addCallback(this);
thread = new MainThread(getHolder(),this);
setBackgroundColor(getResources().getColor(R.color.background));
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}
#Override
public void surfaceCreated(SurfaceHolder holder) {
int width = this.getWidth();
int height = this.getHeight();
playerPoint = new Point(width/2, height*3/5);
player = new Player(this.getContext(), playerPoint,
getResources().getColor(R.color.colorAccent));
thread = new MainThread(getHolder(), this);
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder){
boolean retry = true;
while(retry){
try{
thread.setRunning(false);
thread.join();
}catch(Exception e){
e.printStackTrace();
}
retry = false;
}
}
#Override
public boolean onTouchEvent(MotionEvent event){
if(event.getAction() == MotionEvent.ACTION_DOWN){
//System.out.println("Down");
originX = event.getX();
originY = event.getY();
}
currX = event.getX();
currY = event.getY();
//return super.onTouchEvent(event);
return true;
}
public float getTouchAngle(){
float dX = currX - originX;
float dY = currY - originY;
double angle = Math.atan2(dX,-dY);
angle *= 180;
angle /= Math.PI;
return (float) angle;
}
public void update(){
playerAngle = getTouchAngle();
//System.out.println(playerAngle);
player.update(playerAngle);
}
#Override
public void draw(Canvas canvas){
super.draw(canvas);
player.draw(canvas);
}
}
I have my MainThread which just calls the update and draw methods for the GameView class:
public class MainThread extends Thread {
public static final int MAX_FPS = 30;
private double averageFPS;
private SurfaceHolder holder;
private GameView gameView;
private boolean running;
public static Canvas canvas;
public void setRunning(boolean b){
this.running = b;
}
public MainThread(SurfaceHolder holder, GameView gameView){
super();
this.holder = holder;
this.gameView = gameView;
//canvas = null;
}
#Override
public void run(){
long startTime;
long timeMillis = 1000/MAX_FPS;
long waitTime;
int frameCount = 0;
long totalTime = 0;
long targetTime = 1000/MAX_FPS;
while(running){
startTime = System.nanoTime();
canvas = null;
try{
canvas = this.holder.lockCanvas();
synchronized (holder){
this.gameView.update();
this.gameView.draw(canvas);
}
}catch(Exception e){
e.printStackTrace();
} finally {
if(canvas !=null){
try{
holder.unlockCanvasAndPost(canvas);
}catch(Exception e){
e.printStackTrace();
}
}
}
timeMillis = (System.nanoTime() - startTime/1000000);
waitTime = targetTime - timeMillis;
try{
if(waitTime > 0){
this.sleep(waitTime);
}
}catch(Exception e){
e.printStackTrace();
}
totalTime += System.nanoTime() - startTime;
frameCount++;
if(frameCount == MAX_FPS){
averageFPS = 1000 / ((totalTime/frameCount)/1000000);
frameCount = 0;
totalTime = 0;
//System.out.println(averageFPS);
}
}
}
}
And then I have my Player class, which is where I have been trying to get the Bitmap rotation to update:
public class Player implements GameObject {
//private Rect rect;
private int color;
private Paint paint;
private float angle;
private Bitmap icon;
private Point pos;
//private Matrix matrix;
public Player(Context context, Point pos, int color){
//this.rect = rect;
this.pos = pos;
this.color = color;
paint = new Paint();
//paint.setColor(color);
//paint.setStyle(Paint.Style.FILL);
paint.setFilterBitmap(true);
icon = BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_action_name);
//matrix = new Matrix();
}
#Override
public void draw(Canvas canvas){
//Matrix matrix = new Matrix();
//matrix.setRotate(angle, 100, 100);
//canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.rotate(-angle,pos.x,pos.y);
System.out.println(angle);
canvas.drawBitmap(icon,pos.x-50,pos.y-50,paint);
//canvas.restore();
}
#Override
public void update(){
}
public void update(float angle){
this.angle = angle;
}
}
I originally tried to perform the rotation using a Matrix, and I had it working at first, but then I made changes and haven't been able to get it to rotate at all since.
I can tell that the angle is getting computed properly, and the angle variable in the Player class is getting updated, because after a touch event, if I switch to a different app then go back into this activity, the bitmap is facing the correct direction. It just isn't updating in realtime anymore. I have no clue what I did.
(all the commented lines are me trying to tweak things to fix it)
I found the issue. After changing up my code several times to try and get my canvas to update, I tried commenting out the setBackgroundColor() method in my GameView class, and it suddenly started working again. Now I just set the background color on the Canvas itself and it works as it should. If anyone could explain why, I'd love to hear more

Remove the last color form bitmap Undo

Please I need the help regarding Undo method , I tried to implement it like the code below but it is not remove the last color,
Kindly help me to resolve it.
awaiting your kind response.
Thanks in Advance.
MainActivity
public class MainActivity extends AppCompatActivity implements
View.OnTouchListener {
Button red, blue, yellow, undo;
Paint paint;
private RelativeLayout drawingLayout;
private MyView myView;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
/**
* Called when the activity is first created.
*/
/*
*
* private ImageView imageView; private Canvas cv; private Bitmap mask,
* original, colored; private int r,g,b; private int sG, sR, sB;
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myView = new MyView(this);
drawingLayout = (RelativeLayout) findViewById(R.id.relative_layout);
drawingLayout.addView(myView);
red = (Button) findViewById(R.id.btn_red);
blue = (Button) findViewById(R.id.btn_blue);
yellow = (Button) findViewById(R.id.btn_yellow);
undo = (Button) findViewById(R.id.undo);
red.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
paint.setColor(Color.RED);
}
});
yellow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
paint.setColor(Color.YELLOW);
}
});
blue.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
paint.setColor(Color.BLUE);
}
});
undo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myView.onClickUndo();
}
});
}
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
// flood fill
public class MyView extends View {
final Point p1 = new Point();
Bitmap mBitmap;
ProgressDialog pd;
Canvas canvas;
private Path path;
// Bitmap mutableBitmap ;
public MyView(Context context) {
super(context);
paint = new Paint();
paint.setAntiAlias(true);
pd = new ProgressDialog(context);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5f);
mBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.gp1_1).copy(Bitmap.Config.ARGB_8888, true);
this.path = new Path();
}
public void onClickUndo() {
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size() - 1));
invalidate();
} else {
Toast.makeText(getContext(), getString(R.string.nomore), Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onDraw(Canvas canvas) {
this.canvas = canvas;
paint.setColor(Color.GREEN);
// int width = drawingLayout.getWidth();
// int height = drawingLayout.getHeight();
// float centerX = (width - mBitmap.getWidth()) * 0.5f;
//float centerY = (height - mBitmap.getHeight()) * 0.5f;
canvas.drawBitmap(mBitmap, 0, 0, paint);
///////////////////////////////
for (Path p : paths) {
canvas.drawPath(p, paint);
//////////////////////////
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
p1.x = (int) x;
p1.y = (int) y;
final int sourceColor = mBitmap.getPixel((int) x, (int) y);
final int targetColor = paint.getColor();
new TheTask(mBitmap, p1, sourceColor, targetColor).execute();
paths.add(path);
invalidate();
}
return true;
}
public void clear() {
path.reset();
invalidate();
}
public int getCurrentPaintColor() {
return paint.getColor();
}
class TheTask extends AsyncTask<Void, Integer, Void> {
Bitmap bmp;
Point pt;
int replacementColor, targetColor;
public TheTask(Bitmap bm, Point p, int sc, int tc) {
this.bmp = bm;
this.pt = p;
this.replacementColor = tc;
this.targetColor = sc;
pd.setMessage(getString(R.string.wait));
pd.show();
}
#Override
protected void onPreExecute() {
pd.show();
}
#Override
protected void onProgressUpdate(Integer... values) {
}
#Override
protected Void doInBackground(Void... params) {
FloodFill f = new FloodFill();
f.floodFill(bmp, pt, targetColor, replacementColor);
return null;
}
#Override
protected void onPostExecute(Void result) {
pd.dismiss();
invalidate();
}
}
}
public class FloodFill {
public void floodFill(Bitmap image, Point node, int targetColor,
int replacementColor) {
int width = image.getWidth();
int height = image.getHeight();
int target = targetColor;
int replacement = replacementColor;
if (target != replacement) {
Queue<Point> queue = new LinkedList<Point>();
do {
int x = node.x;
int y = node.y;
while (x > 0 && image.getPixel(x - 1, y) == target) {
x--;
}
boolean spanUp = false;
boolean spanDown = false;
while (x < width && image.getPixel(x, y) == target) {
image.setPixel(x, y, replacement);
if (!spanUp && y > 0
&& image.getPixel(x, y - 1) == target) {
queue.add(new Point(x, y - 1));
spanUp = true;
} else if (spanUp && y > 0
&& image.getPixel(x, y - 1) != target) {
spanUp = false;
}
if (!spanDown && y < height - 1
&& image.getPixel(x, y + 1) == target) {
queue.add(new Point(x, y + 1));
spanDown = true;
} else if (spanDown && y < height - 1
&& image.getPixel(x, y + 1) != target) {
spanDown = false;
}
x++;
}
} while ((node = queue.poll()) != null);
}
}
}
}
I guess you mean the undo method doesn't work. The possible reason is the previous drawing on the canvas is not removed. Try clearing the canvas before drawing in the onDraw() method.
#Override protected void onDraw(Canvas canvas) {
this.canvas = canvas;
canvas. drawColor(0,PorterDuff.Mode.CLEAR); //This clears the canvas.
paint.setColor(Color.GREEN);
//rest of the code
}
Seems it is impossible to return previous color it is required an array for each point to store the used color in every point.

Trying to create a moving sprite on a scrolling background

I got interested on Android, I'm new at it so I created a scrolling background and I want to put a sprite on it I already created a character class and the scroll background. I want to make the sprite move to the right but I'm getting error on my GamePanel.
The error is Non-static method(android.graphics.Canvas) cannot be referenced from a static context, what does it mean and How am I going to fix this and my make the sprite look like running to the right?
Here's my code:
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback {
public static final int WIDTH = 856;
public static final int HEIGHT = 480;
public static int Score =0;
public static int Highscore;
private MainThread thread;
private Background bg;
private Bitmap bmp;
public GamePanel(Context context) {
super(context);
getHolder().addCallback(this);
thread = new MainThread(getHolder(), this);
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while(retry) {
try {
thread.setRunning(false);
thread.join();
}catch(InterruptedException e) {
e.printStackTrace();
retry = false;
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
bg = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.gamebg));
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.deer);
bg.setVector(-5);
thread.setRunning(true);
thread.start();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
public void update() {
Score += 2;
if (Score > Highscore) {
Highscore = Score;
}
bg.update();
}
#SuppressLint("MissingSuperCall")
#Override
public void draw(Canvas canvas) {
final float scaleFactorX = (float)getWidth()/WIDTH;
final float scaleFactorY = (float)getHeight()/HEIGHT;
if(canvas !=null) {
final int savedState = canvas.save();
canvas.scale(scaleFactorX, scaleFactorY);
bg.draw(canvas);
canvas.restoreToCount(savedState);
Paint textpaint = new Paint();
textpaint.setTextSize(30);
canvas.drawText("Score:" +String.valueOf(Score), 0, 32, textpaint);
canvas.drawText("High Score: "+String.valueOf(Highscore), 0, 64, textpaint);
}
}
#Override
protected void onDraw(Canvas canvas) {
Character.onDraw(canvas);
}
}
You cannot access non static methods from a static context. So if you want to access a function or an object of the GamePanel class, you need to call this member by using the object instance of GamePanel class.
Just an example:
wrong:
GamePanel.draw(canvas);
correct:
GamePanel gamePanel = new GamePanel(this);
gamePanel.draw(canvas);

I want to add panning operation in this class

I am using rajawali library to load obj model in android, for that i use this camera class which contains guesture detector and guesture listener but I need to extra panning operation in this class:
public class ArcballCamera extends Camera
{
private Context mContext;
private ScaleGestureDetector mScaleDetector;
private View.OnTouchListener mGestureListener;
private GestureDetector mDetector;
private View mView;
private boolean mIsRotating;
private boolean mIsScaling;
private Vector3 mCameraStartPos;
private Vector3 mPrevSphereCoord;
private Vector3 mCurrSphereCoord;
private Vector2 mPrevScreenCoord;
private Vector2 mCurrScreenCoord;
private Quaternion mStartOrientation;
private Quaternion mCurrentOrientation;
private Object3D mEmpty;
private Object3D mTarget;
private Matrix4 mScratchMatrix;
private Vector3 mScratchVector;
private double mStartFOV;
public ArcballCamera(Context context, View view) {
this(context, view, null);
}
public ArcballCamera(Context context, View view, Object3D target) {
super();
mContext = context;
mTarget = target;
mView = view;
initialize();
addListeners();
}
private void initialize() {
mStartFOV = mFieldOfView;
mLookAtEnabled = true;
setLookAt(0, 0, 0);
mEmpty = new Object3D();
mScratchMatrix = new Matrix4();
mScratchVector = new Vector3();
mCameraStartPos = new Vector3();
mPrevSphereCoord = new Vector3();
mCurrSphereCoord = new Vector3();
mPrevScreenCoord = new Vector2();
mCurrScreenCoord = new Vector2();
mStartOrientation = new Quaternion();
mCurrentOrientation = new Quaternion();
}
#Override
public void setProjectionMatrix(int width, int height) {
super.setProjectionMatrix(width, height);
}
private void mapToSphere(final float x, final float y, Vector3 out)
{
float lengthSquared = x * x + y * y;
if (lengthSquared > 1)
{
out.setAll(x, y, 0);
out.normalize();
}
else
{
out.setAll(x, y, Math.sqrt(1 - lengthSquared));
}
}
private void mapToScreen(final float x, final float y, Vector2 out)
{
out.setX((2 * x - mLastWidth) / mLastWidth);
out.setY(-(2 * y - mLastHeight) / mLastHeight);
}
private void startRotation(final float x, final float y)
{
mapToScreen(x, y, mPrevScreenCoord);
mCurrScreenCoord.setAll(mPrevScreenCoord.getX(), mPrevScreenCoord.getY());
mIsRotating = true;
}
private void updateRotation(final float x, final float y)
{
mapToScreen(x, y, mCurrScreenCoord);
applyRotation();
}
private void endRotation()
{
mStartOrientation.multiply(mCurrentOrientation);
}
private void applyRotation()
{
if (mIsRotating)
{
mapToSphere((float) mPrevScreenCoord.getX(), (float) mPrevScreenCoord.getY(), mPrevSphereCoord);
mapToSphere((float) mCurrScreenCoord.getX(), (float) mCurrScreenCoord.getY(), mCurrSphereCoord);
Vector3 rotationAxis = mPrevSphereCoord.clone();
rotationAxis.cross(mCurrSphereCoord);
rotationAxis.normalize();
double rotationAngle = Math.acos(Math.min(1, mPrevSphereCoord.dot(mCurrSphereCoord)));
mCurrentOrientation.fromAngleAxis(rotationAxis, MathUtil.radiansToDegrees(rotationAngle));
mCurrentOrientation.normalize();
Quaternion q = new Quaternion(mStartOrientation);
q.multiply(mCurrentOrientation);
mEmpty.setOrientation(q);
}
}
#Override
public Matrix4 getViewMatrix() {
Matrix4 m = super.getViewMatrix();
if(mTarget != null) { mScratchMatrix.identity();
mScratchMatrix.translate(mTarget.getPosition());
m.multiply(mScratchMatrix);
}
mScratchMatrix.identity();
mScratchMatrix.rotate(mEmpty.getOrientation());
m.multiply(mScratchMatrix);
if(mTarget != null) {
mScratchVector.setAll(mTarget.getPosition());
mScratchVector.inverse();
mScratchMatrix.identity();
mScratchMatrix.translate(mScratchVector);
m.multiply(mScratchMatrix);
}
return m;
}
public void setFieldOfView(double fieldOfView) {
synchronized (mFrustumLock) {
mStartFOV = fieldOfView;
super.setFieldOfView(fieldOfView);
}
}
... In this method defined guesture detector and listeners, so i need to have panning here.
so anyone tell me how to use panning here...
private void addListeners() {
((Activity) mContext).runOnUiThread(new Runnable() {
#Override
public void run() {
mDetector = new GestureDetector(mContext, new GestureListener());
mScaleDetector = new ScaleGestureDetector(mContext, new ScaleListener());
mGestureListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
mScaleDetector.onTouchEvent(event);
if (!mIsScaling) {
mDetector.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
if (mIsRotating) {
endRotation();
mIsRotating = false;
}
}
}
return true;
}
};
mView.setOnTouchListener(mGestureListener);
}
});
}
public void setTarget(Object3D target) {
mTarget = target;
setLookAt(mTarget.getPosition());
}
public Object3D getTarget() {
return mTarget;
}
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
#Override
public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX, float distanceY) {
if(!mIsRotating) {
startRotation(event2.getX(), event2.getY());
return false;
}
mIsRotating = true;
updateRotation(event2.getX(), event2.getY());
return false;
}
}
private class ScaleListener
extends ScaleGestureDetector.SimpleOnScaleGestureListener
{
#Override
public boolean onScale(ScaleGestureDetector detector) {
double fov = Math.max(30, Math.min(100, mStartFOV * (1.0 / detector.getScaleFactor())));
setFieldOfView(fov);
return true;
}
#Override
public boolean onScaleBegin (ScaleGestureDetector detector) {
mIsScaling = true;
mIsRotating = false;
return super.onScaleBegin(detector);
}
#Override
public void onScaleEnd (ScaleGestureDetector detector) {
mIsRotating = false;
mIsScaling = false;
}
}
}**

Live Wallpaper with bouncing effect

I'm creating a life wallpaper for android which "ic_launcher" is able to bounce when it "hit" the left/right edge of the screen.
public class LiveWallpaperService extends WallpaperService
{
int x,y;
public void onCreate()
{
super.onCreate();
}
public void onDestroy()
{
super.onDestroy();
}
public Engine onCreateEngine()
{
return new MyWallpaperEngine();
}
class MyWallpaperEngine extends Engine
{
private final Handler handler = new Handler();
private final Runnable drawRunner = new Runnable() {
#Override
public void run() {
draw();
}
};
private boolean visible = true;
public Bitmap image1,backgroundImage;
MyWallpaperEngine()
{
image1 = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
backgroundImage = BitmapFactory.decodeResource(getResources(),R.drawable.pika);
x=130;
y=200;
}
public void onCreate(SurfaceHolder surfaceHolder)
{
super.onCreate(surfaceHolder);
}
#Override
public void onVisibilityChanged(boolean visible)
{
this.visible = visible;
if (visible)
{
handler.post(drawRunner);
}
else
{
handler.removeCallbacks(drawRunner);
}
}
#Override
public void onSurfaceDestroyed(SurfaceHolder holder)
{
super.onSurfaceDestroyed(holder);
this.visible = false;
handler.removeCallbacks(drawRunner);
}
public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels)
{
draw();
}
void draw()
{
final SurfaceHolder holder = getSurfaceHolder();
int xVelocity = 10;
Canvas c = null;
try
{
c = holder.lockCanvas();
c.drawColor(Color.BLACK);
if (c != null)
{
c.drawBitmap(backgroundImage, 0, 0, null);
c.drawBitmap(image1, x,y, null);
int width=c.getWidth();
x += xVelocity;
if(x>=width)
{xVelocity = -xVelocity;
}
}
}
finally
{
if (c != null)
holder.unlockCanvasAndPost(c);
}
handler.removeCallbacks(drawRunner);
if (visible)
{
handler.postDelayed(drawRunner, 10);
}
}
}
}
The ic_launcher won't bounce back when it met the edge of the screen(it just keep moving to the right until I can't see it any more), can some one help me about it? I guess the problem is in this few lines
int width=c.getWidth();
x += xVelocity;
if(x>=width)
{xVelocity = -xVelocity;
}
}
I'm still a newbie in android programming, Thanks for helping me :)
Following on from your comments: you are resetting velocity each time you call draw();
move
int xVelocity = 10;
so it is at the top with int x,y;
int x,y;
int xVelocity = 10;
int velValue = 10;
int velInvValue = -10;
Then keep some better inverse code like:
if(x >= width)
{
xVelocity = velInvValue;
}
else if(x <= 0)
{
xVelocity = velValue;
}
x += xVelocity;

Categories