onDraw(Canvas canvas) never reached? - java

Can anyone help, my app does not seem to do the onDraw() in the GraView class, even if .invalidate is called upon from either inside or outside the class. I managed to figure out with system.err that it does invalidate the view, however it never gets in the onDraw( ), even though the rest of the app keeps running. I found a lot of solutionssuggesting putting setWillNotDraw(false) in the constructor, but that did not solve anything.
GravIO.java File:
package dabawi.gravitas;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class GravIO extends Activity implements Runnable, OnTouchListener {
public final static int clock = 1000;
private GravEngine engine;
private GraView TV;
private SensorManager mSensorManager;
private Sensor mSensor;
private Thread t1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
t1 = new Thread(this);
t1.start();
engine = new GravEngine();
TV = new GraView(this, engine);
setContentView(TV);
TV.setOnTouchListener(this);
TV.setVisibility(View.VISIBLE);
//mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
System.err.println("Starting Engine") ;
run();
}
#Override
public void run() {
while (true) {
try {
System.err.println("Tik") ;
engine.tick();
TV.invalidate();
Thread.sleep(GravIO.clock);
} catch (InterruptedException ex) {
System.err.println("faal");
}
}
}
#Override
public boolean onTouch(View view, MotionEvent event) {
engine.switchGravity();
return true;
}
}
GraView.java File:
package dabawi.gravitas;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
#SuppressLint({ "DrawAllocation", "ViewConstructor" })
public class GraView extends View {
private GravEngine engine;
private int screenWidth, screenHeight, ySpace = 5, xSpace, scale;
private Paint paint;
private int xLoc, yLoc;
private boolean xWall = false, yWall = false;
public GraView(Context context, GravEngine engine) {
super(context);
setWillNotDraw(false);
this.engine = engine;
calcScale(context);
}
#Override // We think the problem is with this method, that it is never called upon.
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
System.err.println("Calculating position");
calcPos();
canvas = new Canvas();
// drawing background
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
canvas.drawPaint(paint);
drawGame(canvas);
}
private void drawGame(Canvas canvas) {
drawRoom(canvas);
drawPlayer(canvas);
}
#SuppressWarnings("deprecation")
private void calcScale(Context context) {
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
Display d = wm.getDefaultDisplay();
screenWidth = d.getWidth();
screenHeight = d.getHeight();
scale = screenHeight / ySpace;
xSpace = screenWidth / scale;
}
private void calcPos() {
xLoc = (engine.getxPlayer() / GravEngine.roomScaling);
yLoc = (engine.getyPlayer() / GravEngine.roomScaling);
if (xLoc < (xSpace + 1) / 2) {
xLoc = (xSpace + 1) / 2;
xWall = true;
} else if (xLoc > (GravRoom.xSize - ((xSpace + 1) / 2))) {
xLoc = GravRoom.xSize - ((xSpace + 1) / 2);
xWall = true;
} else {
xWall = false;
}
if (yLoc < (ySpace + 1) / 2) {
yLoc = (ySpace + 1) / 2;
yWall = true;
} else if (yLoc > (GravRoom.xSize - ((ySpace + 1) / 2))) {
xLoc = GravRoom.ySize - ((ySpace + 1) / 2);
yWall = true;
} else {
yWall = false;
}
}
private void drawPlayer(Canvas canvas) {
float xPos = engine.getxPlayer() / GravEngine.roomScaling, yPos = engine
.getyPlayer() / GravEngine.roomScaling;
if (xWall) {
}
if (yWall) {
}
paint.setColor(Color.BLUE);
int left = (int) (xPos * scale), top = (int) (yPos * scale);
int right = left + (GravEngine.pxSize / GravEngine.roomScaling) * scale;
int bot = top + (GravEngine.pySize / GravEngine.roomScaling) * scale;
canvas.drawRect(left, top, right, bot, paint);
}
private void drawRoom(Canvas canvas) {
for (int i = 0, x = xLoc - ((xSpace + 1) / 2); i < xSpace + 1; x++, i++) {
for (int j = 0, y = yLoc - ((ySpace + 1) / 2); i < ySpace + 1; y++, j++) {
drawRoomPart(x,y,i,j,canvas);
}
}
}
private void drawRoomPart(int x, int y, int i, int j, Canvas canvas) {
if (x >= 0 && y >= 0 && x < GravRoom.xSize && y < GravRoom.ySize) {
short type = engine.getRoom(engine.getCurrentRoom()).getGridPos(x,y);
if (type != 0) {
drawBlock(canvas, i, x, j, y, type);
}
}
}
private void drawBlock(Canvas canvas, int i, int x, int j, int y, short type) {
int left = i * scale, top = y * scale;
int right = left + scale;
int bot = top + scale;
paint.setColor(colorBlock(type));
canvas.drawRect(left, top, right, bot, paint);
System.err.println("Left" + left + " top: " + top + " right: "
+ right + " bot: " + bot);
}
private int colorBlock(short type) {
if (type == 1) {
return Color.DKGRAY;
} else if (type == 2) {
return Color.CYAN;
} else if (type == 3) {
return Color.GREEN;
} else if (type == 4) {
return Color.RED;
} else {
return Color.MAGENTA;
}
}
// private void imageBlock(short type) {
//
// }
}

Ouch !
Your call to your run method is executed in the UIThread (as the onCreate method), and it's doing an infinite loop in it.
Just add a println after the call and you will see that the UI thread is never released, your application should not even start !

You don't see any changes because you are creating a new canvas and drawing on that. To fix this, remove the line
canvas = new Canvas();
Also, you should initiate your Paint outside of the onDraw method (this is an optimization recommended by the Android documentation).

Related

Game Development lock canvas error

i keep getting error draw to canvas
Error
The error keep happening when I tried to draw to the canvas the player after the user move the joystick
it always writes me "cant lock canvas ,canvas already locked"
i'm kind of beginner in game development and sorry if the question is a little unclear if you need more details just say and I will send you more info
Main class - the main activity
package app.shahardagan.Raven;
import android.graphics.Point;
import android.os.Bundle;
import android.app.Activity;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class Main extends Activity {
RelativeLayout layout_joystick;
ImageView image_joystick, image_border;
GameEngine gameEngine;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get a Display object to access screen details
Display display = getWindowManager().getDefaultDisplay();
// Load the resolution into a Point object
Point size = new Point();
size.set(display.getWidth(),display.getHeight());
layout_joystick = (RelativeLayout)findViewById(R.id.layout_joystick);
gameEngine = new GameEngine(this,size.x,size.y);
setContentView(gameEngine);
}
#Override
protected void onResume(){
super.onResume();
gameEngine.resume();
}
#Override
protected void onPause(){
super.onPause();
gameEngine.pause();
}
}
GameEngine class - responsible to draw the player and update the game
package app.shahardagan.Raven;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class GameEngine extends SurfaceView implements Runnable {
JoyStickClass js;
// This is our thread
private Thread gameThread = null;
// This is new. We need a SurfaceHolder
// When we use Paint and Canvas in a thread
// We will see it in action in the draw method soon.
private SurfaceHolder ourHolder;
// A boolean which we will set and unset
// when the game is running- or not.
private volatile boolean playing;
// Game is paused at the start
private boolean paused = true;
// A Canvas and a Paint object
private Canvas canvas;
private Paint paint;
// How wide and high is the screen?
private int screenX;
private int screenY;
// This variable tracks the game frame rate
private long fps;
// This is used to help calculate the fps
private long timeThisFrame;
private Context context;
private Player player;
private Drawable playerImage;
public GameEngine(Context context, int x, int y) {
// This calls the default constructor to setup the rest of the object
super(context);
this.context = context;
// Initialize ourHolder and paint objects
ourHolder = getHolder();
paint = new Paint();
// Initialize screenX and screenY because x and y are local
screenX = x;
screenY = y;
prepareLevel();
}
private void prepareLevel(){
player = new Player(context,screenX,screenY);
}
public void PlayerControls(Context context,RelativeLayout layout_joystick, ImageView image_joystick, ImageView image_border){
js = new JoyStickClass(context, layout_joystick, R.drawable.image_button);
js.setStickSize(150, 150);
js.setLayoutSize(500, 500);
js.setLayoutAlpha(150);
js.setStickAlpha(100);
js.setOffset(90);
js.setMinimumDistance(50);
layout_joystick.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent arg1) {
js.drawStick(arg1);
if(arg1.getAction() == MotionEvent.ACTION_DOWN || arg1.getAction() == MotionEvent.ACTION_MOVE) {
int direction = js.get8Direction();
if(direction == JoyStickClass.STICK_UP) {
} else if(direction == JoyStickClass.STICK_UPRIGHT) {
player.setMovementState(Player.UP);
} else if(direction == JoyStickClass.STICK_RIGHT) {
} else if(direction == JoyStickClass.STICK_DOWNRIGHT) {
} else if(direction == JoyStickClass.STICK_DOWN) {
} else if(direction == JoyStickClass.STICK_DOWNLEFT) {
} else if(direction == JoyStickClass.STICK_LEFT) {
} else if(direction == JoyStickClass.STICK_UPLEFT) {
} else if(direction == JoyStickClass.STICK_NONE) {
}
} else if(arg1.getAction() == MotionEvent.ACTION_UP) {
}
return true;
}
});
}
// Runs when the OS calls onPause on BreakoutActivity method
public void pause() {
playing = false;
try {
gameThread.join();
} catch (InterruptedException e) {
Log.e("Error:", "joining thread");
}
}
// Runs when the OS calls onResume on BreakoutActivity method
public void resume() {
playing = true;
gameThread = new Thread(this);
gameThread.start();
}
#Override
public void run() {
while (playing) {
// Capture the current time in milliseconds in startFrameTime
long startFrameTime = System.currentTimeMillis();
// Update the frame
// Update the frame
if(!paused){
update();
}
// Draw the frame
draw();
// Calculate the fps this frame
// We can then use the result to
// time animations and more.
timeThisFrame = System.currentTimeMillis() - startFrameTime;
if (timeThisFrame >= 1) {
fps = 1000 / timeThisFrame;
}
}
}
private void draw() {
// Make sure our drawing surface is valid or game will crash
if (ourHolder.getSurface().isValid()) {
// Lock the canvas ready to draw
canvas = ourHolder.lockCanvas();
// Draw the background color
canvas.drawColor(Color.argb(255, 26, 128, 182));
// Draw everything to the screen
// Choose the brush color for drawing
paint.setColor(Color.argb(255, 255, 255, 255));
canvas.drawBitmap(player.getBitmap(),player.getX(),screenY - player.getHeight(),paint);
}
}
private void update() {
player.update(fps);
}
}
Player class - the player class methods
package app.shahardagan.Raven;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.RectF;
public class Player {
// RectF is an object that holds four coordinates - just what we need
private RectF rect;
private Bitmap bitmap;
// How long will our paddle will be
private float length;
private float height;
// X is the far left of the rectangle which forms our paddle
private float x;
private float y;
// Which ways can the player move
final int STOPPED = 0;
public static final int UP = 1;
public static final int UPRIGHT = 2;
public static final int RIGHT = 3;
public static final int DOWNRIGHT = 4;
public static final int DOWN = 5;
public static final int DOWNLEFT = 6;
public static final int LEFT = 7;
public static final int UPLEFT = 8;
// Is the paddle moving and in which direction
private int playerMoving = STOPPED;
private int playerSpeed;
public Player(Context context,int screenX, int screenY){
rect = new RectF();
length =screenX/10;
height = screenX/10;
x = screenX;
y= 0;
bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.eagle_fly);
bitmap = Bitmap.createScaledBitmap(bitmap,(int)length,(int)height,false);
playerSpeed = 350;
}
public RectF getRect(){
return rect;
}
public Bitmap getBitmap(){
return bitmap;
}
public float getX(){ return x; }
public float getHeight(){return height;}
private float getLength(){return length;}
public void setMovementState(int state){
playerMoving = state;
}
void update(long fps){
if(playerMoving == LEFT){
x = x - playerSpeed / fps;
}
if(playerMoving == RIGHT){
x = x + playerSpeed / fps;
}
rect.top = y;
rect.bottom = y+ height;
rect.left = x;
rect.right = x + length;
}
}
Joy stick class
package app.shahardagan.Raven;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
public class JoyStickClass {
public static final int STICK_NONE = 0;
public static final int STICK_UP = 1;
public static final int STICK_UPRIGHT = 2;
public static final int STICK_RIGHT = 3;
public static final int STICK_DOWNRIGHT = 4;
public static final int STICK_DOWN = 5;
public static final int STICK_DOWNLEFT = 6;
public static final int STICK_LEFT = 7;
public static final int STICK_UPLEFT = 8;
private int STICK_ALPHA = 200;
private int LAYOUT_ALPHA = 200;
private int OFFSET = 0;
private Context mContext;
private ViewGroup mLayout;
private LayoutParams params;
private int stick_width, stick_height;
private int position_x = 0, position_y = 0, min_distance = 0;
private float distance = 0, angle = 0;
private DrawCanvas draw;
private Paint paint;
private Bitmap stick;
private boolean touch_state = false;
public JoyStickClass (Context context, ViewGroup layout, int stick_res_id) {
mContext = context;
stick = BitmapFactory.decodeResource(mContext.getResources(),
stick_res_id);
stick_width = stick.getWidth();
stick_height = stick.getHeight();
draw = new DrawCanvas(mContext);
paint = new Paint();
mLayout = layout;
params = mLayout.getLayoutParams();
}
public void drawStick(MotionEvent arg1) {
position_x = (int) (arg1.getX() - (params.width / 2));
position_y = (int) (arg1.getY() - (params.height / 2));
distance = (float) Math.sqrt(Math.pow(position_x, 2) + Math.pow(position_y, 2));
angle = (float) cal_angle(position_x, position_y);
if(arg1.getAction() == MotionEvent.ACTION_DOWN) {
if(distance <= (params.width / 2) - OFFSET) {
draw.position(arg1.getX(), arg1.getY());
draw();
touch_state = true;
}
} else if(arg1.getAction() == MotionEvent.ACTION_MOVE && touch_state) {
if(distance <= (params.width / 2) - OFFSET) {
draw.position(arg1.getX(), arg1.getY());
draw();
} else if(distance > (params.width / 2) - OFFSET){
float x = (float) (Math.cos(Math.toRadians(cal_angle(position_x, position_y))) * ((params.width / 2) - OFFSET));
float y = (float) (Math.sin(Math.toRadians(cal_angle(position_x, position_y))) * ((params.height / 2) - OFFSET));
x += (params.width / 2);
y += (params.height / 2);
draw.position(x, y);
draw();
} else {
mLayout.removeView(draw);
}
} else if(arg1.getAction() == MotionEvent.ACTION_UP) {
mLayout.removeView(draw);
touch_state = false;
}
}
public int[] getPosition() {
if(distance > min_distance && touch_state) {
return new int[] { position_x, position_y };
}
return new int[] { 0, 0 };
}
public int getX() {
if(distance > min_distance && touch_state) {
return position_x;
}
return 0;
}
public int getY() {
if(distance > min_distance && touch_state) {
return position_y;
}
return 0;
}
public float getAngle() {
if(distance > min_distance && touch_state) {
return angle;
}
return 0;
}
public float getDistance() {
if(distance > min_distance && touch_state) {
return distance;
}
return 0;
}
public void setMinimumDistance(int minDistance) {
min_distance = minDistance;
}
public int getMinimumDistance() {
return min_distance;
}
public int get8Direction() {
if(distance > min_distance && touch_state) {
if(angle >= 247.5 && angle < 292.5 ) {
return STICK_UP;
} else if(angle >= 292.5 && angle < 337.5 ) {
return STICK_UPRIGHT;
} else if(angle >= 337.5 || angle < 22.5 ) {
return STICK_RIGHT;
} else if(angle >= 22.5 && angle < 67.5 ) {
return STICK_DOWNRIGHT;
} else if(angle >= 67.5 && angle < 112.5 ) {
return STICK_DOWN;
} else if(angle >= 112.5 && angle < 157.5 ) {
return STICK_DOWNLEFT;
} else if(angle >= 157.5 && angle < 202.5 ) {
return STICK_LEFT;
} else if(angle >= 202.5 && angle < 247.5 ) {
return STICK_UPLEFT;
}
} else if(distance <= min_distance && touch_state) {
return STICK_NONE;
}
return 0;
}
public int get4Direction() {
if(distance > min_distance && touch_state) {
if(angle >= 225 && angle < 315 ) {
return STICK_UP;
} else if(angle >= 315 || angle < 45 ) {
return STICK_RIGHT;
} else if(angle >= 45 && angle < 135 ) {
return STICK_DOWN;
} else if(angle >= 135 && angle < 225 ) {
return STICK_LEFT;
}
} else if(distance <= min_distance && touch_state) {
return STICK_NONE;
}
return 0;
}
public void setOffset(int offset) {
OFFSET = offset;
}
public int getOffset() {
return OFFSET;
}
public void setStickAlpha(int alpha) {
STICK_ALPHA = alpha;
paint.setAlpha(alpha);
}
public int getStickAlpha() {
return STICK_ALPHA;
}
public void setLayoutAlpha(int alpha) {
LAYOUT_ALPHA = alpha;
mLayout.getBackground().setAlpha(alpha);
}
public int getLayoutAlpha() {
return LAYOUT_ALPHA;
}
public void setStickSize(int width, int height) {
stick = Bitmap.createScaledBitmap(stick, width, height, false);
stick_width = stick.getWidth();
stick_height = stick.getHeight();
}
public void setStickWidth(int width) {
stick = Bitmap.createScaledBitmap(stick, width, stick_height, false);
stick_width = stick.getWidth();
}
public void setStickHeight(int height) {
stick = Bitmap.createScaledBitmap(stick, stick_width, height, false);
stick_height = stick.getHeight();
}
public int getStickWidth() {
return stick_width;
}
public int getStickHeight() {
return stick_height;
}
public void setLayoutSize(int width, int height) {
params.width = width;
params.height = height;
}
public int getLayoutWidth() {
return params.width;
}
public int getLayoutHeight() {
return params.height;
}
private double cal_angle(float x, float y) {
if(x >= 0 && y >= 0)
return Math.toDegrees(Math.atan(y / x));
else if(x < 0 && y >= 0)
return Math.toDegrees(Math.atan(y / x)) + 180;
else if(x < 0 && y < 0)
return Math.toDegrees(Math.atan(y / x)) + 180;
else if(x >= 0 && y < 0)
return Math.toDegrees(Math.atan(y / x)) + 360;
return 0;
}
private void draw() {
try {
mLayout.removeView(draw);
} catch (Exception e) { }
mLayout.addView(draw);
}
private class DrawCanvas extends View{
float x, y;
private DrawCanvas(Context mContext) {
super(mContext);
}
public void onDraw(Canvas canvas) {
canvas.drawBitmap(stick, x, y, paint);
}
private void position(float pos_x, float pos_y) {
x = pos_x - (stick_width / 2);
y = pos_y - (stick_height / 2);
}
}
}
In your draw() method, you're locking the Canvas, but not unlocking the Canvas after you finish drawing. So, when you re-enter your draw method, the Canvas is still locked from the previous call.
You likely need to add unlockCanvasAndPost(Canvas canvas) after you finish drawing. See the full docs here.

Rect.intersects not working

I understand that this is technically a repeat question, but all of the similar questions include code I do not understand, so I decided to ask the question using code I understand.
I am attempting to make a flappy bird style game to try android programing and I cannot get Rect.intersects to change the player's score when the player collides with an object (cloud)
Thanks in advance!!
View class:
package com.gregsapps.fallingbird;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.View;
public class GameView extends View{
private Bird bird;
private boolean runOnce = false;
private Context context;
private Paint red;
ArrayList<Cloud> clouds = new ArrayList<Cloud>();
private int cloudDelay;
private Collision collision;
//private Paint textPaint;
public GameView(Context context) {
super(context);
this.context = context;
this.setDrawingCacheEnabled(true);
red = new Paint();
red.setColor(Color.RED);
red.setTextSize(100f);
collision = new Collision();
//textPaint.setColor(Color.BLACK);
//textPaint.setTextAlign(Align.RIGHT);
// TODO add setup code
}
protected void onDraw(Canvas canvas){
update(canvas);
System.out.println(bird.score);
//TODO add drawing code
this.buildDrawingCache();
//bird.canvasImage = this.getDrawingCache(true);
canvas.drawColor(Color.rgb(10, 255, 255));
canvas.drawRect(bird.birdRect, red);
canvas.drawBitmap(bird.image, bird.x, bird.y, null);
for(int i = 0; i < clouds.size(); i++){
System.out.println("Drawing cloud");
Cloud cloud = (Cloud) clouds.get(i);
cloud.move(5);
System.out.println(cloud.leftX + "/t" + cloud.rightX);
canvas.drawRect(cloud.rightCloud, red);
canvas.drawRect(cloud.leftCloud, red);
canvas.drawBitmap(cloud.image, cloud.leftX, cloud.leftY, null);
canvas.drawBitmap(cloud.image, cloud.rightX, cloud.rightY, null);
if(cloud.leftY <= -144)clouds.remove(cloud);
if(bird.y > cloud.leftY + bird.height) bird.score++;
if(Rect.intersects(bird.birdRect, cloud.leftCloud)){
bird.score = 0;
}
else if(Rect.intersects(bird.birdRect, cloud.rightCloud)){
bird.score = 0;
}
}
canvas.drawLine(canvas.getWidth()/2 - 1, 0, canvas.getWidth()/2 - 1, canvas.getHeight(), red);
cloudDelay --;
if(cloudDelay <= 0){
System.out.println("new cloud");
Cloud cloud = new Cloud(com.gregsapps.fallingbird.R.drawable.cloud, context);
System.out.println("added");
clouds.add(cloud);
cloudDelay = 175;
}
canvas.drawText(Integer.toString(bird.score/12), 50, 100, red);
invalidate();
}
private void update(Canvas canvas){
//TODO add code to update stuff
if(runOnce == false){
bird = new Bird(canvas, com.gregsapps.fallingbird.R.drawable.bird, context);
runOnce = true;
StaticVarHandler.canvasHeight = canvas.getHeight();
StaticVarHandler.canvasWidth = canvas.getWidth();
}
bird.move();
}
}
Cloud class:
package com.gregsapps.fallingbird;
import java.util.Random;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
public class Cloud {
public int leftX;
public int leftY;
public int rightX;
public int rightY;
private Random random;
public Bitmap image;
private Context context;
public Rect leftCloud;
public Rect rightCloud;
public int height;
public int width;
Cloud(int image, Context context){
this.context = context;
this.image = BitmapFactory.decodeResource(this.context.getResources(), R.drawable.cloud);
random = new Random();
leftX = random.nextInt(StaticVarHandler.canvasWidth-(StaticVarHandler.birdWidth*2));
rightX = leftX + StaticVarHandler.birdWidth*2;
rightY = leftY = StaticVarHandler.canvasHeight+this.image.getHeight();
leftX -= this.image.getWidth();
leftCloud = new Rect(leftX, leftY, this.image.getWidth(), this.image.getHeight());
rightCloud = new Rect(rightX, rightY, this.image.getWidth(), this.image.getHeight());
}
public void move(int scrollSpeed){
leftCloud.offset(0, -scrollSpeed);
rightCloud.offset(0, -scrollSpeed);
leftY-=scrollSpeed;
rightY-=scrollSpeed;
}
}
Bird class:
package com.gregsapps.fallingbird;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
public class Bird {
public int x;
public int y;
private int speed;
public Bitmap image;
Context context;
private int gravity;
public int width;
public int height;
private int canvasWidth;
private int canvasHeight;
public Bitmap canvasImage;
public boolean touch;
public int touchX;
public int touchY;
private int gravDelay = 0;
private int jump = 0;
public int score;
public Rect birdRect;
Bird(Canvas canvas, int image, Context context){
this.context = context;
this.image = BitmapFactory.decodeResource(this.context.getResources(), image);
x = canvas.getWidth()/2 - this.image.getWidth()/2;
y = 10;
speed = this.image.getWidth()/10;
//setup gravity, speed, width and height attributes
speed = canvas.getWidth()/25;
gravity = speed/10;
StaticVarHandler.birdWidth = width = this.image.getWidth();
height = this.image.getHeight();
canvasWidth = canvas.getWidth();
canvasHeight = canvas.getHeight();
System.out.println(canvasWidth);
System.out.println(canvas.getWidth());
birdRect = new Rect(x, y, this.image.getWidth(), this.image.getHeight());
}
public void move(){
gravDelay --;
jump --;
if(StaticVarHandler.touch) jump = 3;
if(jump >= 0){
if(StaticVarHandler.touchX < canvasWidth/2){
x -= speed/3;
}
if(StaticVarHandler.touchX > canvasWidth/2){
x += speed/3;
}
StaticVarHandler.touch = false;
if(jump == 0) gravDelay = 7;
}
else if(gravDelay <= 0){
System.out.println("GRAVITY");
if(x+width/2 < canvasWidth/2){
x += gravity;
//code to move bird via gravity
}
if(x+width/2 > canvasWidth/2){
x -= gravity;
//same as above but other side
}
gravDelay = 1;
}
if(x <= 0){
score = 0;
x = 0;
}
else if(x+width >= canvasWidth){
score = 0;
x = canvasWidth - width;
}
birdRect.offsetTo(x-1, y-1);
}
private void collisionCheck(){
if(longEquation()){
}
}
}
I think I found your problem.
birdRect = new Rect(x, y, this.image.getWidth(), this.image.getHeight());
and
leftCloud = new Rect(leftX, leftY, this.image.getWidth(), this.image.getHeight());
rightCloud = new Rect(rightX, rightY, this.image.getWidth(), this.image.getHeight());
Should not use getWidth() or getHeight() but should use x + width and y + height.
public Rect (int left, int top, int right, int bottom)
Added in API level 1 Create a new rectangle with the specified
coordinates. Note: no range checking is performed, so the caller must
ensure that left <= right and top <= bottom.
Parameters
left The X coordinate of the left side of the rectangle
top The Y coordinate of the top of the rectangle
right The X
coordinate of the right side of the rectangle
bottom The Y coordinate
of the bottom of the rectangle
This is from the documentation.

ClassCastException when calling constructor for custom Button class

I`m playing with some simple Android app code but there is problem related to all layouts in code.
This is error when I open layout in eclipse
The following classes could not be instantiated:
- com.android2.calculator3.view.ColorButton (Open Class, Show Error Log)
See the Error Log (Window > Show View) for more details.
Tip: Use View.isInEditMode() in your custom views to skip code when shown in Eclipse
java.lang.ClassCastException: com.android.layoutlib.bridge.android.BridgeContext cannot be cast to com.android2.calculator3.Calculator
at com.android2.calculator3.view.ColorButton.<init>(ColorButton.java:39)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0( at sun.reflect.NativeConstructorAccessorImpl.newInstance( at sun.reflect.DelegatingConstructorAccessorImpl.newInstance( at java.lang.reflect.Constructor.newInstance( at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.instantiateClass(ProjectCallback.java:442)
at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.loadView(ProjectCallback.java:194)
at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:207)
at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:132)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:806)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:782)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:809)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:782)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:809)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:782)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:809)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:782)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:809)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:782)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:385)
And this is my code in Colorbutton.java
package com.android2.calculator3.view;
import java.util.regex.Pattern;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;
import com.android2.calculator3.Calculator;
import com.android2.calculator3.EventListener;
import calculator.app.R;
/**
* Button with click-animation effect.
*/
class ColorButton extends Button {
int CLICK_FEEDBACK_COLOR;
static final int CLICK_FEEDBACK_INTERVAL = 10;
static final int CLICK_FEEDBACK_DURATION = 350;
float mTextX;
float mTextY;
long mAnimStart;
EventListener mListener;
Paint mFeedbackPaint;
Paint mHintPaint = new Paint();
Rect bounds = new Rect();
float mTextSize = 0f;
public ColorButton(Context context, AttributeSet attrs) {
super(context, attrs);
Calculator calc = (Calculator) context;
init(calc);
mListener = calc.mListener;
setOnClickListener(mListener);
setOnLongClickListener(mListener);
}
private void init(Calculator calc) {
Resources res = getResources();
CLICK_FEEDBACK_COLOR = res.getColor(R.color.magic_flame);
mFeedbackPaint = new Paint();
mFeedbackPaint.setStyle(Style.STROKE);
mFeedbackPaint.setStrokeWidth(2);
getPaint().setColor(res.getColor(R.color.button_text));
mHintPaint.setColor(res.getColor(R.color.button_hint_text));
mAnimStart = -1;
}
private void layoutText() {
Paint paint = getPaint();
if(mTextSize != 0f) paint.setTextSize(mTextSize);
float textWidth = paint.measureText(getText().toString());
float width = getWidth() - getPaddingLeft() - getPaddingRight();
float textSize = getTextSize();
if(textWidth > width) {
paint.setTextSize(textSize * width / textWidth);
mTextX = getPaddingLeft();
mTextSize = textSize;
}
else {
mTextX = (getWidth() - textWidth) / 2;
}
mTextY = (getHeight() - paint.ascent() - paint.descent()) / 2;
if(mHintPaint != null) mHintPaint.setTextSize(paint.getTextSize() * 0.8f);
}
#Override
protected void onTextChanged(CharSequence text, int start, int before, int after) {
layoutText();
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if(changed) layoutText();
}
private void drawMagicFlame(int duration, Canvas canvas) {
int alpha = 255 - 255 * duration / CLICK_FEEDBACK_DURATION;
int color = CLICK_FEEDBACK_COLOR | (alpha << 24);
mFeedbackPaint.setColor(color);
canvas.drawRect(1, 1, getWidth() - 1, getHeight() - 1, mFeedbackPaint);
}
#Override
public void onDraw(Canvas canvas) {
if(mAnimStart != -1) {
int animDuration = (int) (System.currentTimeMillis() - mAnimStart);
if(animDuration >= CLICK_FEEDBACK_DURATION) {
mAnimStart = -1;
}
else {
drawMagicFlame(animDuration, canvas);
postInvalidateDelayed(CLICK_FEEDBACK_INTERVAL);
}
}
else if(isPressed()) {
drawMagicFlame(0, canvas);
}
CharSequence hint = getHint();
if(hint != null) {
String[] exponents = hint.toString().split(Pattern.quote("^"));
int offsetX = getContext().getResources().getDimensionPixelSize(R.dimen.button_hint_offset_x);
int offsetY = (int) ((mTextY + getContext().getResources().getDimensionPixelSize(R.dimen.button_hint_offset_y) - getTextHeight(mHintPaint,
hint.toString())) / 2)
- getPaddingTop();
float textWidth = mHintPaint.measureText(hint.toString());
float width = getWidth() - getPaddingLeft() - getPaddingRight() - mTextX - offsetX;
float textSize = mHintPaint.getTextSize();
if(textWidth > width) {
mHintPaint.setTextSize(textSize * width / textWidth);
}
for(String str : exponents) {
if(str == exponents[0]) {
canvas.drawText(str, 0, str.length(), mTextX + offsetX, mTextY - offsetY, mHintPaint);
offsetY += getContext().getResources().getDimensionPixelSize(R.dimen.button_hint_exponent_jump);
offsetX += mHintPaint.measureText(str);
}
else {
canvas.drawText(str, 0, str.length(), mTextX + offsetX, mTextY - offsetY, mHintPaint);
offsetY += getContext().getResources().getDimensionPixelSize(R.dimen.button_hint_exponent_jump);
offsetX += mHintPaint.measureText(str);
}
}
}
CharSequence text = getText();
canvas.drawText(text, 0, text.length(), mTextX, mTextY, getPaint());
}
private int getTextHeight(Paint paint, String text) {
mHintPaint.getTextBounds(text, 0, text.length(), bounds);
int height = bounds.height();
String[] exponents = text.split(Pattern.quote("^"));
for(int i = 1; i < exponents.length; i++) {
height += getContext().getResources().getDimensionPixelSize(R.dimen.button_hint_exponent_jump);
}
return height;
}
public void animateClickFeedback() {
mAnimStart = System.currentTimeMillis();
invalidate();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event);
switch(event.getAction()) {
case MotionEvent.ACTION_UP:
if(isPressed()) {
animateClickFeedback();
}
else {
invalidate();
}
break;
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_CANCEL:
mAnimStart = -1;
invalidate();
break;
}
return result;
}
}
I can not figure out whats going wrong here?
Your error log does most of the work for you:
java.lang.ClassCastException: com.android.layoutlib.bridge.android.BridgeContext cannot be cast to com.android2.calculator3.Calculator
at com.android2.calculator3.view.ColorButton.<init>(ColorButton.java:39)
Essentially, you are attempting to cast BridgeContext to Calculator, which I assume refers to this line in your constructor:
public ColorButton(Context context, AttributeSet attrs) {
super(context, attrs);
Calculator calc = (Calculator) context; //This Line
init(calc);
mListener = calc.mListener;
setOnClickListener(mListener);
setOnLongClickListener(mListener);
}
For this to work, your context argument needs to inherit from Calculator. A simple test would be:
if (context instanceof Calculator) {
Calculator calc = (Calculator) context;
} else {
Log.e("Log Tag", context.toString() + " must inherit from Calculator class");
}
or, with a try/catch block:
try {
Calculator calc = (Calculator) context;
} catch (ClassCastException e) {
Log.e("Log Tag", context.toString() + " must inherit from Calculator class");
e.printStackTrace();
}
Edit:
A possible fix for your situation could be the following amendments to your constructor:
public ColorButton(Context context, AttributeSet attrs, Caculator calculator) {
super(context, attrs);
Calculator calc = calculator;
init(calc);
mListener = calc.mListener;
setOnClickListener(mListener);
setOnLongClickListener(mListener);
}
Of course, this is because I know nothing of your custom Calculator class (i.e., whether it is even a sublcass of Context). This method will bypass the context casting completely, so you can pass whatever you like for your first argument for as long as it inherits from the Context class (most commonly an Activity).

For loops wont stop

2 part question here. I'm having some trouble here with my for loops. The basic idea of my code is that whenever checkX and checkY are called they compare the x of the touch and the x of the player then if the players x is less than the touchx then it increments the player x by 1 until the player x equals touch x. Its the exact same thing for checky. Everything works fine, the problem is that it never stops. The player just keeps moving on the exact same path.
Heres the player class
package com.gametest;
import java.util.concurrent.CopyOnWriteArrayList;
import com.gametest.GameSurfaceView.MyView;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
public class Player {
int ID;
static int x, y, width, height, widthEnd, currentFrame, boundsX, boundsY,
dirTimer, dir, simx, simy;
static Bitmap currentSprite, playerSprite, deathSprite;
static MyView mv;
public Player(MyView v, Bitmap orb, Bitmap explosion, int screenWidth,
int screenHeight) {
// TODO Auto-generated constructor stub
playerSprite = orb;
deathSprite = explosion;
currentSprite = playerSprite;
mv = v;
height = playerSprite.getHeight();
width = playerSprite.getWidth() / 3;
currentFrame = 1;
}
public static void sprite_draw(Canvas canvas,
CopyOnWriteArrayList<Sprite> copy) {
// TODO Auto-generated method stub
x = (mv.getWidth() / 2) - 50;
y = (mv.getHeight() / 2) - 50;
currentFrame = currentFrame + 1;
if (currentFrame > 3) {
currentFrame = 1;
}
widthEnd = (currentFrame * width) + width;
boundsX = x + width;
boundsY = y + height;
Rect src = new Rect(currentFrame * width, 0, widthEnd, height);
Rect dst = new Rect(x, y, boundsX, boundsY);
canvas.drawBitmap(currentSprite, src, dst, null);
for (Sprite s : copy) {
if (s.x + 50 > x && s.x + 50 < boundsX && s.y + 50 > y
&& s.y + 50 < boundsY) {
GameSurfaceView.damagePlayer();
};
}
}
public void checkX(Integer touchx) {
if (touchx > x) {
for (int newx = x; newx < touchx; newx++) {
GameSurfaceView.setDirection(1, 0);
try {
mv.t.sleep (10);
} catch (InterruptedException e) {
}
}
}
if (touchx < x ) {
for (int newx = x; newx > touchx; newx--) {
GameSurfaceView.setDirection(-1, 0);
try {
mv.t.sleep (10);
} catch (InterruptedException e) {
}
}
}
}
public void checkY(int touchy) {
if (touchy > y) {
for (int newy = y; newy < touchy; newy++) {
GameSurfaceView.setDirection(0, 1);
try {
mv.t.sleep (10);
} catch (InterruptedException e) {
}
}
}
if (touchy < y) {
for (int newy = y; newy > touchy; newy--) {
GameSurfaceView.setDirection(0, -1);
try {
mv.t.sleep (10);
} catch (InterruptedException e) {
}
}
}
}
}
And in case its needed here is the surface view class
package com.gametest;
import java.util.concurrent.CopyOnWriteArrayList;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
public class GameSurfaceView extends Activity implements OnTouchListener {
double ran;
int touchX, touchY, screenWidth, screenHeight, objX, objY;
static boolean canUpdate;
static int enemyCount, score, playerHealth, test1, test2;
static MyView v;
static Bitmap orb, orb2, explosion;
static CopyOnWriteArrayList<Sprite> copy = new CopyOnWriteArrayList<Sprite>();
static String hpString;
static Player player;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
v = new MyView(this);
v.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent me) {
touchX = (int) me.getX();
touchY = (int) me.getY();
for (Sprite sprite : copy) {
sprite.checkTouch(touchX, touchY);
player.checkY(touchY);
player.checkX(touchX);
}
return true;
}
});
canUpdate = true;
screenWidth = v.getWidth();
screenHeight = v.getHeight();
playerHealth = 250;
hpString = "Health " + playerHealth;
ran = 0;
score = 0;
test1 = 5000;
test2 = 5000;
orb = BitmapFactory.decodeResource(getResources(), R.drawable.blue_orb);
orb2 = BitmapFactory.decodeResource(getResources(), R.drawable.red_orb);
explosion = BitmapFactory.decodeResource(getResources(), R.drawable.explosion);
player = new Player(v, orb2, explosion, screenWidth, screenHeight);
createEnemies();
setContentView(v);
}
private void createEnemies() {
if (enemyCount < 5) {
screenWidth = v.getWidth();
screenHeight = v.getHeight();
int listLength = copy.size();
copy.add(new Sprite(v, orb, explosion, screenWidth, screenHeight, listLength));
enemyCount = enemyCount + 1;
}
}
public static void checkECount(int id) {
canUpdate = false;
copy.remove(id);
enemyCount = enemyCount - 1;
int index = 0;
for(Sprite s : copy) {
s.ID = index;
index++;
}
score = score + 10;
canUpdate = true;
}
#Override
protected void onPause() {
super.onPause();
v.pause();
}
#Override
protected void onResume() {
super.onResume();
v.resume();
}
public class MyView extends SurfaceView implements Runnable {
Thread t = null;
SurfaceHolder holder;
boolean isItOk = false;
public MyView(Context context) {
super(context);
holder = getHolder();
}
#Override
public void run() {
while (isItOk == true) {
if (!holder.getSurface().isValid()) {
continue;
}
Canvas c = holder.lockCanvas();
if(canUpdate){
canvas_draw(c);
}
holder.unlockCanvasAndPost(c);
try {
t.sleep (50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
protected void canvas_draw(Canvas canvas) {
canvas.drawARGB(255, 50, 10, 10);
String ranString = "Score " + score;
ran = Math.random() * 5;
String t = "max1" + test1;
String t2 = "max2" + test2;
if (ran > 3) {
createEnemies();
}
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(15);
canvas.drawText(hpString, 10, 25, paint);
canvas.drawText(ranString, 10, screenHeight - 25, paint);
for (Sprite sprite : copy) {
sprite.sprite_draw(canvas);
}
Player.sprite_draw(canvas, copy);
}
public void pause() {
isItOk = false;
while (true) {
try {
t.join();
} catch (InterruptedException e) {
}
break;
}
t = null;
}
public void resume() {
isItOk = true;
t = new Thread(this);
t.start();
}
}
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
return false;
}
public static void damagePlayer() {
hpString = "Health " + playerHealth;
playerHealth = playerHealth - 5;
if(playerHealth<0){
hpString = "game over";
}
}
public static void setDirection(int i, int j) {
if(i == 0 && j == -1){
for(Sprite s: copy){
s.y++;
}
}
if(i == 0 && j == 1){
for(Sprite s: copy){
s.y--;
}
}
if(i == -1 && j == 0){
for(Sprite s: copy){
s.x++;
}
}
if(i == 1 && j == 0){
for(Sprite s: copy){
s.x--;
}
}
}
}
So the first part of my question is can anyone tell me why the for loops wont stop looping. And the second part of my question is how can I force the checkX and checkY methods to restart if the player selects a different point before he makes it to the first location.
Check and see if your problem lies with your signature in your checkX and checkY functions. Integer is a class, and int is a primitive type, so you can't do something like Integer n = 1, but you can do int n = 1.
public void checkX(int touchx)
public void checkY(int touchx)

How can I implement Declaration to bouncy ball?

i am trying to implement Deceleration on the bouncy ball. i am able to move the ball up and down but i wanted to add Declaration so when i drop the ball from height it jumps then strike the ground bounce once again and slowly slowly its speed decreases and stop at the end.
Here is My code
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.widget.ImageView;
public class AnimatedView extends ImageView{
private Context mContext;
int x = -1;
int y = -1;
private int xVelocity = 0;
private int yVelocity = 25;
private Handler h;
private final int FRAME_RATE = 20;
public AnimatedView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
h = new Handler();
}
private Runnable r = new Runnable() {
#Override
public void run() {
invalidate();
}
};
protected void onDraw(Canvas c) {
BitmapDrawable ball = (BitmapDrawable) mContext.getResources().getDrawable(R.drawable.ball);
if (x<0 && y <0) {
x = this.getWidth()/2;
y = this.getHeight()/2;
} else {
x += xVelocity;
y += yVelocity;
if ((x > this.getWidth() - ball.getBitmap().getWidth()) || (x < 0)) {
xVelocity = xVelocity*-1;
}
if ((y > this.getHeight() - ball.getBitmap().getHeight()) || (y < 0)) {
yVelocity = yVelocity*-1;
}
}
c.drawBitmap(ball.getBitmap(), x, y, null);
h.postDelayed(r, FRAME_RATE);
}
Hope Anyone Can Help me.
Thanks in Advance
Acceleration is to velocity as velocity is to position. You just need to do what you're doing with your position to your velocity.
The simplest solution is to add
yVelocity += yAccel;
to the top of onDraw where yAccel is a int that you want added to the yVelocity every tick. Based on your velocity values
private int yAccel = -2;
might be appropriate.
edit: You should also add checks to ensure the ball does not go into the ground. I added these in the blocks that reverse the velocity, the following code works for me. If it don't work for you, there might be something wrong with another part of your project.
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.widget.ImageView;
public class AnimatedView extends ImageView {
private Context mContext;
int x = -1;
int y = -1;
private int xVelocity = 0;
private int yVelocity = 25;
private int yAccel = 2;
private Handler h;
private final int FRAME_RATE = 20;
public AnimatedView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
h = new Handler();
}
private Runnable r = new Runnable() {
#Override
public void run() {
invalidate();
}
};
protected void onDraw(Canvas c) {
yVelocity += yAccel;
BitmapDrawable ball = (BitmapDrawable) mContext.getResources()
.getDrawable(R.drawable.cakes);
if (x < 0 && y < 0) {
x = this.getWidth() / 2;
y = this.getHeight() / 2;
} else {
x += xVelocity;
y += yVelocity;
if ((x > this.getWidth() - ball.getBitmap().getWidth()) || (x < 0)) {
xVelocity = xVelocity * -1;
x = Math.min(this.getWidth() - ball.getBitmap().getWidth(), x);
x = Math.max(0, x);
}
if ((y > this.getHeight() - ball.getBitmap().getHeight())
|| (y < 0)) {
yVelocity = (int)(yVelocity * -0.8f);
y = Math.min(this.getHeight() - ball.getBitmap().getHeight(), y);
y = Math.max(0, y);
}
}
c.drawBitmap(ball.getBitmap(), x, y, null);
h.postDelayed(r, FRAME_RATE);
}
}

Categories