I want to move background with the bob(Android Game Character) moving for that I make a Dynamic object name Background
public static int BACKGROUND_MOVE=0;
public static int BACKGROUND_FALL=1;
public static final float BACKGROUND_MOVE_VELOCITY =3.5f;
public static float BOB_WIDTH =10.0f;
public static float BOB_HEIGHT =15.0f;
public static long startTime = 0;
public int state;
public float stateTime;
public BackGround(float x, float y)
{
super(x, y, BOB_WIDTH, BOB_HEIGHT);
state = BACKGROUND_MOVE;
stateTime = 0;
accel.set(0,-2);
velocity.y=3.5f;//55
}
public void update (float deltaTime)
{
//velocity.add(World.gravity.x, World.gravity.y * deltaTime);
velocity.add(accel.x * deltaTime,accel.y*deltaTime);
position.add(velocity.x * deltaTime, velocity.y * deltaTime);
if (velocity.y > 0 && state==Bob.BOB_STATE_HIT)//BOB_STATE_HIT is bob running //condition
{
if (state != BACKGROUND_MOVE)
{
state = BACKGROUND_MOVE;
stateTime = 0;
}
}
if (velocity.y > 0 && state != Bob.BOB_STATE_HIT)
{
if (state != BACKGROUND_FALL)
{
state = BACKGROUND_FALL;
stateTime = 0;
}
}
// if (velocity.y < 0 && state == BOB_STATE_HIT)
// {
// if (state != BOB_STATE_JUMP) {
// state = BOB_STATE_JUMP;
// stateTime = 0;
// }
//}
//if (position.y < 0) position.x = World.WORLD_WIDTH;
//if (position.x > World.WORLD_WIDTH) position.x = 0;
stateTime += deltaTime;
}
public void move()
{
if(state==BACKGROUND_MOVE)
{
startTime=System.nanoTime()/1000000000;
// state = BACKGROUND_MOVE;
velocity.y = BACKGROUND_MOVE_VELOCITY;
stateTime = 0;
}
}
similar to bob I amke object in World class and make an ArrayList Add Backgroung into that arraylist and at time of drawing get from arraylist and draw it...but no any effect show simply screen show and cross the rangeand red screen shown...please anyone help..
/*---------------background cam------*/
this.bcam = new OrthographicCamera(FRUSTUM_WIDTH,FRUSTUM_HEIGHT);
this.bcam.position.set(FRUSTUM_WIDTH,FRUSTUM_HEIGHT, 0);
this.batch = batch;
public void renderBackground()
{
GLCommon gl = Gdx.gl;
gl.glClearColor(1, 0, 0, 1);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
bcam.update();
batch.setProjectionMatrix(bcam.combined);
batch.disableBlending();
batch.begin();
if (world.objbackground.state ==BackGround.BACKGROUND_MOVE)
batch.draw(Assets.mainbackgroundRegion, cam.position.x - FRUSTUM_WIDTH / 2, cam.position.y - FRUSTUM_HEIGHT / 2, FRUSTUM_WIDTH, FRUSTUM_HEIGHT);
// else
// {
// batch.draw(Assets.touchbackgroundRegion, cam.position.x -
// FRUSTUM_WIDTH / 2, cam.position.y - FRUSTUM_HEIGHT / 2,
// FRUSTUM_WIDTH, FRUSTUM_HEIGHT);
// if (elapsed == 5)
// changebackground = 0;
// }
batch.end();
}
Either you want to move the background with Bob (1) or you want to have a fixed background (2):
(1): Set background's position to Bob's (probably with an offset, you can do that in the update function of the world), render using batch.draw(......, background.position.x, background.position.y).
(2): Throw away your complicated update methods in the BackGround object and use the render method as you do now.
But honestly, your intentions and explanations are not very clear, try to improve on that!
Related
I want to control my simple android game (arcanoid) with accelerometer. Paddle in game is now being controlled with touch screen event. I want to control it with accelerometer.
I tried to implement accelerometer into GameActivity class which is "controlling" BreakOutView class like this:
public class GameActivity extends Activity implements SensorEventListener {
// gameView will be the view of the Menu_Layout
// It will also hold the logic of the Menu_Layout
// and respond to screen touches as well
BreakOutView breakoutView;
private SensorManager sManager;
Sensor accelerometer;
Paddle paddle;
float x;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
breakoutView = new BreakOutView(this);
sManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); // zisk managera
if (sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
accelerometer = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
// Initialize gameView and set it as the view
setContentView(breakoutView);
}
// This method executes when the player starts the Game
#Override
protected void onResume() {
super.onResume();
sManager.registerListener(this,accelerometer,SensorManager.SENSOR_DELAY_NORMAL);
// Tell the gameView resume method to execute
breakoutView.resume();
}
// This method executes when the player quits the Menu_Layout
#Override
protected void onPause() {
super.onPause();
sManager.unregisterListener(this);
// Tell the gameView pause method to execute
breakoutView.pause();
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
{
x = sensorEvent.values[0];
if (x > 0) {
breakoutView.paddle.setMovementState(paddle.LEFT);
}
else { breakoutView.paddle.setMovementState(paddle.RIGHT);
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
}
This is code for BreakOutView class.
onTouchEvent method is now disabled because I want to use accelerometer to control Paddle in application.
public class BreakOutView extends SurfaceView implements Runnable{
// This is our thread
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.
SurfaceHolder ourHolder;
// A boolean which we will set and unset
// when the Menu_Layout is running- or not.
volatile boolean playing;
// Game is paused at the start
boolean paused = true;
// A Canvas and a Paint object
Canvas canvas;
Paint paint;
// This variable tracks the Menu_Layout frame rate
long fps;
Bitmap bitmapBob;
Bitmap bitmapBall;
Bitmap bitmapPaddal;
Bitmap bitmapBrick1;
Bitmap bitmapBrick2;
Bitmap bitmapBrick3;
// The size of the screen in pixels
int screenX;
int screenY;
// The players paddle
Paddle paddle;
// A ball
Ball ball;
// Up to 200 bricks
Brick[] bricks = new Brick[24];
int numBricks = 0;
// For sound FX
SoundPool soundPool;
int beep1ID = -1;
int beep2ID = -1;
int beep3ID = -1;
int loseLifeID = -1;
int explodeID = -1;
// The score
int score = 0;
int level = 1;
// Lives
int lives = 3;
Rect dest;
DisplayMetrics dm;
int densityDpi;
// When we initialize (call new()) on BreakOutView
// This special constructor method runs
public BreakOutView(Context context) {
super(context);
// The next line of code asks the
// SurfaceView class to set up our object.
// How kind.
// Initialize ourHolder and paint objects
ourHolder = getHolder();
paint = new Paint();
// Get a Display object to access screen details
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
// Load the resolution into a Point object
Point size = new Point();
// TODO target API < 13
display.getSize(size);
screenX = size.x;
screenY = size.y;
// using dpi to set sizes for objects
dm = context.getResources().getDisplayMetrics();
densityDpi = dm.densityDpi;
paddle = new Paddle(screenX, screenY, densityDpi);
// Create a ball
ball = new Ball(screenX, screenY);
// Load the sounds
// This SoundPool is deprecated but don't worry
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
try {
// Create objects of the 2 required classes
AssetManager assetManager = context.getAssets();
AssetFileDescriptor descriptor;
// Load our fx in memory ready for use
descriptor = assetManager.openFd("beep1.wav");
beep1ID = soundPool.load(descriptor, 0);
descriptor = assetManager.openFd("beep2.wav");
beep2ID = soundPool.load(descriptor, 0);
descriptor = assetManager.openFd("beep3.wav");
beep3ID = soundPool.load(descriptor, 0);
descriptor = assetManager.openFd("loseLife.wav");
loseLifeID = soundPool.load(descriptor, 0);
descriptor = assetManager.openFd("explode.wav");
explodeID = soundPool.load(descriptor, 0);
} catch (IOException e) {
// Print an error message to the console
Log.e("error", "failed to load sound files");
}
// Load Images from resource files
bitmapBob = BitmapFactory.decodeResource(this.getResources(), R.drawable.wall);
bitmapBall = BitmapFactory.decodeResource(this.getResources(), R.drawable.ball);
bitmapPaddal = BitmapFactory.decodeResource(this.getResources(), R.drawable.ball);
bitmapBrick1 = BitmapFactory.decodeResource(this.getResources(), R.drawable.brick_red);
bitmapBrick2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.brick_green);
bitmapBrick3 = BitmapFactory.decodeResource(this.getResources(), R.drawable.brick_monster);
//Make Sizes Depending on DPI
int heightX = densityDpi / 8;
float length_Paddal = densityDpi / 1.50f;
int height_Paddal = densityDpi / 7;
int brickWidth = screenX / 8;
int brickHeight = screenY / 10;
bitmapBall = getResizedBitmap(bitmapBall, heightX, heightX);
bitmapPaddal = getResizedBitmap(bitmapPaddal, length_Paddal, height_Paddal);
bitmapBrick1 = getResizedBitmap(bitmapBrick1, brickWidth, brickHeight);
bitmapBrick2 = getResizedBitmap(bitmapBrick2, brickWidth, brickHeight);
bitmapBrick3 = getResizedBitmap(bitmapBrick3, brickWidth, brickHeight);
// Create bricks for level 1
createBricksAndRestart(1);
}
public void createBricksAndRestart(int Xlevel) {
// Put the ball back to the start
ball.reset(screenX, screenY);
level = Xlevel;
switch (Xlevel) {
case 2:
// level 2
ball.xVelocity = 600;
ball.yVelocity = -1000;
break;
// level 3
case 3:
ball.xVelocity = 1000;
ball.yVelocity = -1400;
break;
// level 1
default:
ball.xVelocity = 400;
ball.yVelocity = -800;
break;
}
// Brick Size
int brickWidth = screenX / 8;
int brickHeight = screenY / 10;
// Build a wall of bricks
numBricks = 0;
for (int column = 0; column < 8; column++) {
for (int row = 0; row < 3; row++) {
bricks[numBricks] = new Brick(row, column, brickWidth, brickHeight);
numBricks++;
}
}
// if Game is over reset scores ,lives &Level
if (lives == 0) {
score = 0;
lives = 3;
level = 1;
}
}
#Override
public void run() {
while (playing) {
// Capture the current time in milliseconds in startFrameTime
long startFrameTime = System.currentTimeMillis();
// 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.
long timeThisFrame = System.currentTimeMillis() - startFrameTime;
if (timeThisFrame >= 1) {
fps = 1000 / timeThisFrame;
}
}
}
// Everything that needs to be updated goes in here
// Movement, collision detection etc.
public void update() {
// Move the paddle if required
paddle.update(fps);
ball.update(fps);
// Check for ball colliding with a brick
for (int i = 0; i < numBricks; i++) {
if (bricks[i].getVisibility()) {
if (RectF.intersects(bricks[i].getRect(), ball.getRect())) {
bricks[i].setInvisible();
ball.reverseYVelocity();
score = score + 10;
soundPool.play(explodeID, 1, 1, 0, 0, 1);
}
}
}
// Check for ball colliding with paddle
if (
ball.getRect().intersect(paddle.getRect()) ||
RectF.intersects(paddle.getRect(), ball.getRect()) ||
paddle.getRect().intersect(ball.getRect())
) {
ball.reverseYVelocity();
// ReverseX Direction + IncreaseX speed
if (paddle.getMovementState() == paddle.RIGHT && ball.xVelocity < 0 || paddle.getMovementState() == paddle.LEFT && ball.xVelocity > 0) {
ball.reverseXVelocity();
}
// SameX Direction + IncreaseX speed
else if (paddle.getMovementState() == paddle.RIGHT && ball.xVelocity > 0 || paddle.getMovementState() == paddle.LEFT && ball.xVelocity < 0) {
ball.sameXVelocity();
}
/*// Paddle is still, DecreaseX speed
else if (paddle.getMovementState() == paddle.STOPPED) {
ball.zeroXVelocity();
}*/
// Some intersection Bugs
ball.clearObstacleY(paddle.getRect().top - 20);
soundPool.play(beep1ID, 1, 1, 0, 0, 1);
}
// Bounce the ball back when it hits the bottom of screen
// And Lose a life
if (ball.getRect().bottom > screenY) {
ball.reverseYVelocity();
ball.clearObstacleY(screenY - 5);
// Lose a life
lives--;
soundPool.play(loseLifeID, 1, 1, 0, 0, 1);
if (lives == 0) {
paused = true;
//draw Loss;
canvas = ourHolder.lockCanvas();
paint.setColor(getResources().getColor(R.color.orange));
paint.setTextSize(getResources().getDimension(R.dimen.text_size_big));
canvas.drawText("أنت خسرت!",
screenX / 2 - (densityDpi / 1.90f), screenY / 2 + (densityDpi), paint);
ourHolder.unlockCanvasAndPost(canvas);
try {
// Wait 3 seconds then reset a new game
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Create bricks at level 1
createBricksAndRestart(1);
}
}
// Pause if cleared screen
if (score == numBricks * 10) {
// Create bricks at level 2
createBricksAndRestart(2);
// fix for a pause bug
// so that it won't Pause After finishing the Game
score = score + 10;
// Gift the player with 1 new live
lives = lives + 1;
} else if (score == (numBricks * 20) + 10) {
// Create bricks at level 3
createBricksAndRestart(3);
// fix for a pause bug
// so that it won't Pause After finishing the Game
score = score + 10;
// Gift the player with 2 new lives
lives = lives + 2;
}
// Pause if cleared screen
// if score equals to the whole Bricks scores after 3 levels
else if (score == (numBricks * 10 * 3) + 20) {
paused = true;
}
// Bounce the ball back when it hits the top of screen
if (ball.getRect().top < 0) {
ball.reverseYVelocity();
ball.clearObstacleY(40);
soundPool.play(beep2ID, 1, 1, 0, 0, 1);
}
// If the ball hits left wall bounce
if (ball.getRect().left < 0) {
ball.reverseXVelocity();
ball.clearObstacleX(2);
soundPool.play(beep3ID, 1, 1, 0, 0, 1);
}
// If the ball hits right wall Velocity
if (ball.getRect().right > screenX) {
ball.reverseXVelocity();
ball.clearObstacleX(screenX - 57);
soundPool.play(beep3ID, 1, 1, 0, 0, 1);
}
}
// Draw the newly updated scene
public void draw() {
// Make sure our drawing surface is valid or we crash
if (ourHolder.getSurface().isValid()) {
// Lock the canvas ready to draw
canvas = ourHolder.lockCanvas();
// Draw the background color
// canvas.drawColor(getResources().getColor(R.color.deeppurple));
dest = new Rect(0, 0, getWidth(), getHeight());
// Draw bob as background with dest size
canvas.drawBitmap(bitmapBob, null, dest, paint);
// Choose the brush color for drawing
paint.setColor(Color.argb(255, 255, 255, 255));
// Draw the ball
// canvas.drawCircle(ball.getRect().centerX(), ball.getRect().centerY(), 25, paint);
canvas.drawBitmap(bitmapBall, ball.getRect().left, ball.getRect().top, null);
// Draw the paddle
//canvas.drawRect(paddle.getRect(), paint);
canvas.drawBitmap(bitmapPaddal, paddle.getRect().left, paddle.getRect().top, null);
// Change the brush color for drawing
// paint.setColor(getResources().getColor(R.color.redorange));
// Draw the bricks if visible
for (int i = 0; i < numBricks; i++) {
if (bricks[i].getVisibility()) {
// canvas.drawRect(bricks[i].getRect(), paint);
switch (level) {
case 1:
canvas.drawBitmap(bitmapBrick1, bricks[i].getRect().left, bricks[i].getRect().top, null);
break;
case 2:
canvas.drawBitmap(bitmapBrick2, bricks[i].getRect().left, bricks[i].getRect().top, null);
break;
case 3:
canvas.drawBitmap(bitmapBrick3, bricks[i].getRect().left, bricks[i].getRect().top, null);
break;
}
}
}
// Choose the brush color for drawing
paint.setColor(Color.argb(255, 255, 255, 255));
// Draw the score
paint.setTextSize(getResources().getDimension(R.dimen.text_size));
// Score Text
canvas.drawText(
"النقاط: " + score
, screenX - (densityDpi / 1.50f), screenY / 2, paint);
// Lives Text
canvas.drawText("الصحة: " + lives
, densityDpi / 5, screenY / 2, paint);
// Levels Text
canvas.drawText("المرحلة: " + level
, screenX / 2 - (densityDpi / 5), screenY / 2 + (densityDpi / 5), paint);
// Has the player cleared the screen?
if (score >= (numBricks * 10 * 3) + 20) {
paint.setColor(getResources().getColor(R.color.colorAccent));
paint.setTextSize(getResources().getDimension(R.dimen.text_size_big));
canvas.drawText("أنت كسبت!", screenX / 2 - (densityDpi / 1.90f), screenY / 2 + (densityDpi / 1), paint);
}
// Draw everything to the screen
ourHolder.unlockCanvasAndPost(canvas);
}
}
// If GameActivity is paused/stopped
// shutdown our thread.
public void pause() {
playing = false;
try {
gameThread.join();
} catch (InterruptedException e) {
Log.e("Error:", "joining thread");
}
}
// If GameActivity is started
// start our thread.
public void resume() {
playing = true;
gameThread = new Thread(this);
gameThread.start();
}
// The SurfaceView class implements onTouchListener
// So we can override this method and detect screen touches.
/* #Override
public boolean onTouchEvent(MotionEvent motionEvent) {
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
// Player has touched the screen
case MotionEvent.ACTION_DOWN:
if (!(lives == 0)) {
paused = false;
}
// If touch motion > Half of the Screen
if (motionEvent.getX() > screenX / 2) {
// move paddle right
paddle.setMovementState(paddle.RIGHT);
} else {
// move paddle left
paddle.setMovementState(paddle.LEFT);
}
break;
// Player has removed finger from screen
case MotionEvent.ACTION_UP:
// paddle stopped
paddle.setMovementState(paddle.STOPPED);
break;
}
return true;
}*/
// Resize Bitmap function to Handle all the Images from resources the right size
public Bitmap getResizedBitmap(Bitmap bm, float newWidth, int newHeight) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = newWidth / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(
bm, 0, 0, width, height, matrix, false);
bm.recycle();
return resizedBitmap;
}
}
And this is code for Paddle class:
import android.graphics.RectF;
public class Paddle {
// Which ways can the paddle move
public final int STOPPED = 0;
public final int LEFT = 1;
public final int RIGHT = 2;
int scrX;
// RectF is an object that holds four coordinates - just what we need
private RectF rect;
// How long and high 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;
// Y is the top coordinate
private float y;
// This will hold the pixels per second speedthat the paddle will move
private float paddleSpeed;
// Is the paddle moving and in which direction
private int paddleMoving = STOPPED;
private int MYscreenDPI;
// This the the constructor method
// When we create an object from this class we will pass
// in the screen width and height
public Paddle(int screenX, int screenY, int screenDPI) {
// Dynamic size based on each device DPI
length = screenDPI / 2;
height = screenDPI / 5;
MYscreenDPI = screenDPI;
scrX = screenX;
// Start paddle in roughly the sceen centre
x = screenX / 2;
y = screenY - screenDPI / 4.50f;
rect = new RectF(x, y, x + length, y + height);
// How fast is the paddle in pixels per second
paddleSpeed = 800;
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
// This is a getter method to make the rectangle that
// defines our paddle available in BreakoutView class
public RectF getRect() {
return rect;
}
public int getMovementState() {
return paddleMoving;
}
// This method will be used to change/set if the paddle is going left, right or nowhere
public void setMovementState(int state) {
paddleMoving = state;
}
// This update method will be called from update in BreakoutView
// It determines if the paddle needs to move and changes the coordinates
// contained in rect if necessary
public void update(long fps) {
if (paddleMoving == LEFT) {
// to fix Paddle going off the Screen
if (x >= -MYscreenDPI / 10)
// Decrement position
x = x - paddleSpeed / fps;
}
if (paddleMoving == RIGHT) {
// to fix Paddle going off the Screen
if (x <= scrX - length - MYscreenDPI / 14)
// Increment position
x = x + paddleSpeed / fps;
}
// Apply the New position
rect.left = x;
rect.right = x + length;
}
}
When I tried to run it application is always crashing and not working. When I try to use onTouchEvent method to control paddle it is not crashing but accelerometer is not working.
I know that I'm doing something bad. I'm trying to figure it out for like one week but I don't know how to make it working.
If you can tell me any suggestions I will be really thankful. Thank you for all responses.
--EDIT--
Here is error message from logcat when I clicked on new game in emulator:
2019-04-13 17:30:55.116 7082-7082/com.kazaky.breakout E/SensorManager: Exception dispatching input event. 2019-04-13 17:30:55.122 7082-7082/com.kazaky.breakout E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.kazaky.breakout, PID: 7082
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
at com.kazaky.breakout.GameActivity.onSensorChanged(GameActivity.java:73)
at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:833)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:326)
at android.os.Looper.loop(Looper.java:160)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 2019-04-13 17:31:06.794 7082-7117/com.kazaky.breakout E/Surface: queueBuffer: error queuing buffer to SurfaceTexture, -19 2019-04-13 17:31:06.794 7082-7117/com.kazaky.breakout E/Surface: queueBuffer (handle=0xe9f16140) failed (No such device)
As suggested by the Stack Trace you are trying to access a null object, which in this case I'm guessing sensroEvent in onSensorChanged.
Add a nullability check and return if sensorEvent is null, like so:
if (sensorEvent == null) return
and write the rest of the function after the Guard Condition.
I am creating an application. If the custom View goes off the screen, a method is called. Here is my code for the custom View.
public class CustomView extends View {
private boolean bubbleOver;
private static final int BITMAP_SIZE = 64;
private static final int REFRESH_RATE = 40;
private final Paint mPainter = new Paint();
private ScheduledFuture<?> mMoverFuture;
private int mScaledBitmapWidth;
private Bitmap mScaledBitmap;
// location, speed and direction of the bubble
private float mXPos, mYPos, mDx, mDy, mRadius, mRadiusSquared;
private long mRotate, mDRotate;
CustomView (Context context, float x, float y) {
super (context);
// Create a new random number generator to randomize size, rotation, speed and direction
Random r = new Random ();
// Creates the bubble bitmap for this BubbleView
createScaledBitmap (r);
// Radius of the Bitmap
mRadius = mScaledBitmapWidth / 2;
mRadiusSquared = mRadius * mRadius;
// Adjust position to center the bubble under user's finger
mXPos = x - mRadius;
mYPos = y - mRadius;
// Set the BubbleView's speed and direction
setSpeedAndDirection(r);
// Set the BubbleView's rotation
setRotation(r);
mPainter.setAntiAlias(true);
}
private void setRotation(Random r) {
if (speedMode == RANDOM) {
// TODO - set rotation in range [1..3]
mDRotate = r.nextInt (3) + 1;
} else {
mDRotate = 0;
}
}
private void setSpeedAndDirection(Random r) {
// Used by test cases
switch (speedMode) {
case SINGLE:
mDx = 20;
mDy = 20;
break;
case STILL:
// No speed
mDx = 0;
mDy = 0;
break;
default:
// Limit movement speed in the x and y direction to [-3..3] pixels per movement.
mDx = r.nextFloat() * 6.0f - 3.0f;
mDy = r.nextFloat() * 6.0f - 3.0f;
}
}
private void createScaledBitmap (Random r) {
if (speedMode != RANDOM) {
mScaledBitmapWidth = BITMAP_SIZE * 3;
} else {
mScaledBitmapWidth = (r.nextInt(3) + 1) * BITMAP_SIZE;
}
mScaledBitmap = Bitmap.createScaledBitmap(mBitmap, mScaledBitmapWidth, mScaledBitmapWidth, true);
}
// Start moving the BubbleView & updating the display
private void start () {
// Creates a WorkerThread
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
// Execute the run() in Worker Thread every REFRESH_RATE milliseconds. Save reference to this job in mMoverFuture
mMoverFuture = executor.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
if (moveWhileOnScreen()) {
stop (false);
} else {
BubbleView.this.postInvalidate();
}
}
}, 0, REFRESH_RATE, TimeUnit.MILLISECONDS);
}
// Returns true if the BubbleView intersects position (x,y)
private synchronized boolean intersects(float x, float y) {
// TODO - Return true if the BubbleView intersects position (x,y)
if ((mXPos <= x) && (x <= mXPos + mScaledBitmapWidth) && (mYPos <= y) && (y <= mYPos + mScaledBitmapWidth)) {
return true;
}
return false;
}
// Cancel the Bubble's movement. Remove Bubble from mFrame.
// Play pop sound if the BubbleView was popped
private void stop (final boolean wasPopped) {
if (null != mMoverFuture && !mMoverFuture.isDone()) {
mMoverFuture.cancel(true);
}
// This work will be performed on the UI Thread
mFrame.post(new Runnable() {
#Override
public void run() {
mFrame.removeView(BubbleView.this);
if (wasPopped) {
mSoundPool.play(mSoundID, mStreamVolume, mStreamVolume, 1, 0, 1f);
}
}
});
}
// Change the Bubble's speed and direction
private synchronized void deflect(float velocityX, float velocityY) {
mDx = velocityX / REFRESH_RATE;
mDy = velocityY / REFRESH_RATE;
}
// Draw the Bubble at its current location
#Override
protected synchronized void onDraw(Canvas canvas) {
canvas.save();
mRotate += mDRotate;
canvas.rotate(mRotate, mXPos + (mScaledBitmapWidth / 2), mYPos + (mScaledBitmapWidth / 2));
canvas.drawBitmap(mScaledBitmap, mXPos, mYPos, mPainter);
canvas.restore();
}
// Returns true if the BubbleView is still on the screen after the move operation
private synchronized boolean moveWhileOnScreen() {
mXPos += mDx;
mYPos += mDy;
return isOutOfView();
}
// Return true if the BubbleView is off the screen after the move operation
private boolean isOutOfView() {
if ((mXPos + mDisplayWidth < 0) || (mYPos + mDisplayHeight < 0) || (mXPos> mDisplayWidth) || (mYPos > mDisplayHeight)) {
loseGame();
return true;
}
return false;
}
}
When the View goes off the screen, loseGame() is not called. Only if another CustomView is created, loseGame() is called.
You have wrong sum to check, try with mScaledBitmapWidth not the mDisplayWidth.
if ((mXPos + mScaledBitmapWidth < 0)
|| (mYPos + mScaledBitmapWidth < 0)
|| (mXPos> mDisplayWidth)
|| (mYPos > mDisplayHeight)
{
loseGame();
return true;
}
I have been developing a board game using hexagon boards in android, but when I move the board, the whole 'map' or dozens of entities starts to lag. I believe that it is the cause of using a for-loop, but I have no idea how to fix it. Im using the method of threaded drawing, dont know if it affects though.
I can clearly see lags on my cell phone when moving through the board.
My Game class:
public class Game extends SurfaceView implements SurfaceHolder.Callback {
// Game Vars
int mapWidth = 150, mapHeight = 150;
public static double hexagonSideLength = 80;
public static double cellWidth = 2 * hexagonSideLength, cellHeight = Math
.sqrt(3) * hexagonSideLength;
public static double downwardShift = (0.5) * (cellHeight);
public static double rightShift = hexagonSideLength / 2;
public static int boundaryWidth = 0, boundaryHeight = 0;
public static int error = (int) ((hexagonSideLength) * (0.06));
public static int buffer = 2;
public static int draws = 0;
// Touch Handle
// Offset to the upper left corner of the map
private int xOffset = 0;
private int yOffset = 0;
// last touch point
private int _xTouch = 0;
private int _yTouch = 0;
// scrolling active?
private boolean _isMoving = false;
public Cell[][] map;
private GameThread thread;
static String TAG = Game.class.getSimpleName();
Bitmap image[] = new Bitmap[100];
Paint paint;
public Game(Context context) {
super(context);
Log.i(TAG, "Loaded Game");
// adding the callback (this) to the surface holder to intercept events
getHolder().addCallback(this);
// make the GamePanel focusable so it can handle events
thread = new GameThread(getHolder(), this);
map = new Cell[mapWidth][mapHeight]; // Create new Map
boolean isShiftedDownwards = false;
for (int i = 0; i < mapWidth; i++) {
for (int j = 0; j < mapHeight; j++) {
map[i][j] = new Cell(j, i, isShiftedDownwards);
}
if (isShiftedDownwards == true)
isShiftedDownwards = false;
else
isShiftedDownwards = true;
}
if (mapWidth % 2 != 0) {
boundaryWidth = (int) ((((mapWidth - 1) / 2) * hexagonSideLength)
+ ((mapWidth / 2) * cellWidth) + (2) * hexagonSideLength);
} else {
boundaryWidth = (int) (((((mapWidth - 1) / 2) * hexagonSideLength) + ((mapWidth / 2) * cellWidth)) + (1.5) * hexagonSideLength);
}
boundaryHeight = (int) (mapHeight * cellHeight + 0.5 * cellHeight);
setFocusable(true);
image[0] = Bitmap.createBitmap(BitmapFactory.decodeResource(
this.getResources(), R.drawable.hexagonrgb));
image[1] = Bitmap.createScaledBitmap(image[0], (int) cellWidth + error,
(int) cellHeight + error, false);
Log.i(TAG, "Got Resources");
paint = new Paint();
Log.i(TAG, "Prepared paint");
}
// called every Frame
#Override
protected void onDraw(Canvas canvas) {
Log.i(TAG, "onDraw Called");
// BG
canvas.drawColor(Color.BLACK);
// Resize
// Redraw Map
draws = 0;
for (int column = updateArea(0); column < updateArea(1); column++) {
for (int row = updateArea(2); row < updateArea(3); row++) {
canvas.drawBitmap(image[1], map[column][row].x - xOffset,
map[column][row].y - yOffset, paint);
paint.setColor(Color.WHITE);
canvas.drawText(row + "," + column, map[column][row].x
- xOffset + 80, map[column][row].y - yOffset + 80,
paint);
draws++;
}
}
/** Log */
paint.setColor(Color.WHITE);
paint.setTextSize(20);
canvas.drawText("xOffset: " + xOffset, 0, 30, paint);
canvas.drawText("yOffset: " + yOffset, 0, 50, paint);
canvas.drawText("activeTitlesX: " + updateArea(0) + " - "
+ updateArea(1), 0, 70, paint);
canvas.drawText("activeTitlesY: " + updateArea(2) + " - "
+ updateArea(3), 0, 90, paint);
canvas.drawText("DimX: " + MainActivity.DimX, 0, 110, paint);
canvas.drawText("DimY: " + MainActivity.DimY, 0, 130, paint);
canvas.drawText("Draws: " + draws, 0, 150, paint);
Log.i(TAG, "Cleared canvas");
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
// called by thread
public static void update() {
Log.i(TAG, "Updated Game");
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
Log.i(TAG, "Thread Started");
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// try again shutting down the thread
}
}
Log.i(TAG, "Thread Destroyed");
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// touch down
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// start of a new event, reset the flag
_isMoving = false;
// store the current touch coordinates for scroll calculation
_xTouch = (int) event.getX();
_yTouch = (int) event.getY();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
// touch starts moving, set the flag
_isMoving = true;
// get the new offset
xOffset += _xTouch - (int) event.getX();
yOffset += _yTouch - (int) event.getY();
// secure, that the offset is never out of view bounds
if (xOffset < 0) {
xOffset = 0;
} else if (xOffset > boundaryWidth - getWidth()) {
xOffset = boundaryWidth - getWidth();
}
if (yOffset < 0) {
yOffset = 0;
} else if (yOffset > boundaryHeight - getHeight()) {
yOffset = boundaryHeight - getHeight();
}
// store the last position
_xTouch = (int) event.getX();
_yTouch = (int) event.getY();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
/*
* // touch released if (!_isMoving) { // calculate the touched cell
* int column = (int) Math.ceil((_xOffset + event.getX()) /
* _cellSize) - 1; int row = (int) Math.ceil((_yOffset +
* event.getY()) / _cellSize) - 1; Cell cell =
* _mapCells.get(row).get(column); // show the id of the touched
* cell Toast.makeText(getContext(), "Cell id #" + cell._id,
* Toast.LENGTH_SHORT).show(); }
*/
}
return true;
}
public int updateArea(int i) {
switch (i) {
case 0: // Left
return Math.max(
(int) (xOffset / (cellWidth - rightShift)) - buffer, 0);
case 1: // Right
return Math
.min((int) (xOffset / (cellWidth - rightShift) + (int) (MainActivity.DimX / (cellWidth - rightShift)))
+ buffer, mapWidth);
case 2: // Up
return Math.max((int) (yOffset / cellHeight) - buffer, 0);
case 3: // Down
return Math.min(((int) (yOffset / cellHeight))
+ (int) (MainActivity.DimY / cellHeight) + buffer,
mapHeight);
}
return 0;
}
/* CELL CLASS */
class Cell {
int x, y;
boolean isShiftedDown;
public Cell(int row, int col, boolean isShifted) {
if (col % 2 != 0) {
isShiftedDown = true;
y = (int) (row * Game.cellHeight + Game.downwardShift);
x = (int) (col * Game.cellWidth - col * Game.rightShift);
Log.i("Shift", "Shifted" + Game.downwardShift);
} else {
isShiftedDown = false;
y = (int) (row * Game.cellHeight);
x = (int) (col * Game.cellWidth - col * Game.rightShift);
Log.i("Shift", "Not Shifted");
}
}
}
}
Thanks in Advance :)
Basic algorithmic analysis shows you are doing this operation:
map[i][j] = new Cell(j, i, isShiftedDownwards);
22500 times. Do you really need to create a new object each time, or can you just change a variable in an existing object?
Update:
for (int column = updateArea(0); column < updateArea(1); column++) {
for (int row = updateArea(2); row < updateArea(3); row++) {
canvas.drawBitmap(image[1], map[column][row].x - xOffset,
map[column][row].y - yOffset, paint);
paint.setColor(Color.WHITE);
canvas.drawText(row + "," + column, map[column][row].x
- xOffset + 80, map[column][row].y - yOffset + 80,
paint);
draws++;
}
}
So this is the double for-loop in question. I'm going to run with the assumption that this needs to be run as many times as it runs. Can the function calls in the loop statements be reduced to variables prior to the loop (they are evaluated with each loop)? This paint.setColor(Color.WHITE); should not be called on each iteration. If you need to change to white after the very first draw, just make a second paint object on startup and and change it before you enter the loop.
If this doesn't help, you need to determine if you can iterate over a smaller area.
Update 2
Rewrite your for loops like so
int minCol = updateArea(0);
int maxCol = updateArea(1);
int minRow = updateArea(2);
int maxRow = updateArea(3);
for(int column = minCol; column < maxCol; column++)
for (int row = minRow; column < maxRow; row++)
....
This will represent a significant reduction in the operations in each iteration.
Here is the image URL for the alphabetical list view. I couldn't post it here as stackoverflow restricts me not having more reputations.
http://www.freeimagehosting.net/hwg9g
How to show this alphabetical scrollview in the left side of the screen. I have got a sample application from internet for alphabetical scrollview and i have implemented with my project :-( As a beginner i do not understand their way of coding. They have used drawRoundRect method to draw this. I regret drawRoundRect and some paint stuffs are not familiar to me..!
public class IndexScroller {
private float mIndexbarWidth;
private float mIndexbarMargin;
private float mPreviewPadding;
private float mDensity;
private float mScaledDensity;
private float mAlphaRate;
private int mState = STATE_HIDDEN;
private int mListViewWidth;
private int mListViewHeight;
private int mCurrentSection = -1;
private boolean mIsIndexing = false;
private ListView mListView = null;
private SectionIndexer mIndexer = null;
private String[] mSections = null;
private RectF mIndexbarRect;
private static final int STATE_HIDDEN = 0;
private static final int STATE_SHOWING = 1;
private static final int STATE_SHOWN = 2;
private static final int STATE_HIDING = 3;
public IndexScroller(Context context, ListView lv) {
mDensity = context.getResources().getDisplayMetrics().density;
mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
mListView = lv;
setAdapter(mListView.getAdapter());
mIndexbarWidth = 20 * mDensity;
mIndexbarMargin = 10 * mDensity;
mPreviewPadding = 5 * mDensity;
}
public void draw(Canvas canvas) {
if (mState == STATE_HIDDEN)
return;
// mAlphaRate determines the rate of opacity
Paint indexbarPaint = new Paint();
indexbarPaint.setColor(Color.BLACK);
indexbarPaint.setAlpha((int) (64 * mAlphaRate));
indexbarPaint.setAntiAlias(true);
canvas.drawRoundRect(mIndexbarRect, 5 * mDensity, 5 * mDensity,
indexbarPaint);
if (mSections != null && mSections.length > 0) {
// Preview is shown when mCurrentSection is set
if (mCurrentSection >= 0) {
Paint previewPaint = new Paint();
previewPaint.setColor(Color.BLACK);
previewPaint.setAlpha(96);
previewPaint.setAntiAlias(true);
previewPaint.setShadowLayer(3, 0, 0, Color.argb(64, 0, 0, 0));
Paint previewTextPaint = new Paint();
previewTextPaint.setColor(Color.WHITE);
previewTextPaint.setAntiAlias(true);
previewTextPaint.setTextSize(50 * mScaledDensity);
float previewTextWidth = previewTextPaint
.measureText(mSections[mCurrentSection]);
float previewSize = 2 * mPreviewPadding
+ previewTextPaint.descent()
- previewTextPaint.ascent();
RectF previewRect = new RectF(
(mListViewWidth - previewSize) / 2,
(mListViewHeight - previewSize) / 2,
(mListViewWidth - previewSize) / 2 + previewSize,
(mListViewHeight - previewSize) / 2 + previewSize);
canvas.drawRoundRect(previewRect, 5 * mDensity, 5 * mDensity,
previewPaint);
canvas.drawText(
mSections[mCurrentSection],
previewRect.left + (previewSize - previewTextWidth) / 2
- 1,
previewRect.top + mPreviewPadding
- previewTextPaint.ascent() + 1,
previewTextPaint);
}
Paint indexPaint = new Paint();
indexPaint.setColor(Color.WHITE);
indexPaint.setAlpha((int) (255 * mAlphaRate));
indexPaint.setAntiAlias(true);
indexPaint.setTextSize(12 * mScaledDensity);
float sectionHeight = (mIndexbarRect.height() - 2 * mIndexbarMargin)
/ mSections.length;
float paddingTop = (sectionHeight - (indexPaint.descent() - indexPaint
.ascent())) / 2;
for (int i = 0; i < mSections.length; i++) {
float paddingLeft = (mIndexbarWidth - indexPaint
.measureText(mSections[i])) / 2;
canvas.drawText(mSections[i], mIndexbarRect.left + paddingLeft,
mIndexbarRect.top + mIndexbarMargin + sectionHeight * i
+ paddingTop - indexPaint.ascent(), indexPaint);
}
}
}
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// If down event occurs inside index bar region, start indexing
if (mState != STATE_HIDDEN && contains(ev.getX(), ev.getY())) {
setState(STATE_SHOWN);
// It demonstrates that the motion event started from index bar
mIsIndexing = true;
// Determine which section the point is in, and move the list to
// that section
mCurrentSection = getSectionByPoint(ev.getY());
mListView.setSelection(mIndexer
.getPositionForSection(mCurrentSection));
return true;
}
break;
case MotionEvent.ACTION_MOVE:
if (mIsIndexing) {
// If this event moves inside index bar
if (contains(ev.getX(), ev.getY())) {
// Determine which section the point is in, and move the
// list to that section
mCurrentSection = getSectionByPoint(ev.getY());
mListView.setSelection(mIndexer
.getPositionForSection(mCurrentSection));
}
return true;
}
break;
case MotionEvent.ACTION_UP:
if (mIsIndexing) {
mIsIndexing = false;
mCurrentSection = -1;
}
if (mState == STATE_SHOWN)
setState(STATE_HIDING);
break;
}
return false;
}
public void onSizeChanged(int w, int h, int oldw, int oldh) {
mListViewWidth = w;
mListViewHeight = h;
mIndexbarRect = new RectF(w - mIndexbarMargin - mIndexbarWidth,
mIndexbarMargin, w - mIndexbarMargin, h - mIndexbarMargin);
}
public void show() {
if (mState == STATE_HIDDEN)
setState(STATE_SHOWING);
else if (mState == STATE_HIDING)
setState(STATE_HIDING);
}
public void hide() {
if (mState == STATE_SHOWN)
setState(STATE_HIDING);
}
public void setAdapter(Adapter adapter) {
if (adapter instanceof SectionIndexer) {
mIndexer = (SectionIndexer) adapter;
mSections = (String[]) mIndexer.getSections();
}
}
private void setState(int state) {
if (state < STATE_HIDDEN || state > STATE_HIDING)
return;
mState = state;
switch (mState) {
case STATE_HIDDEN:
// Cancel any fade effect
mHandler.removeMessages(0);
break;
case STATE_SHOWING:
// Start to fade in
mAlphaRate = 0;
fade(0);
break;
case STATE_SHOWN:
// Cancel any fade effect
mHandler.removeMessages(0);
break;
case STATE_HIDING:
// Start to fade out after three seconds
mAlphaRate = 1;
fade(5000);
break;
}
}
private boolean contains(float x, float y) {
// Determine if the point is in index bar region, which includes the
// right margin of the bar
return (x >= mIndexbarRect.left && y >= mIndexbarRect.top && y <= mIndexbarRect.top
+ mIndexbarRect.height());
}
private int getSectionByPoint(float y) {
if (mSections == null || mSections.length == 0)
return 0;
if (y < mIndexbarRect.top + mIndexbarMargin)
return 0;
if (y >= mIndexbarRect.top + mIndexbarRect.height() - mIndexbarMargin)
return mSections.length - 1;
return (int) ((y - mIndexbarRect.top - mIndexbarMargin) / ((mIndexbarRect
.height() - 2 * mIndexbarMargin) / mSections.length));
}
private void fade(long delay) {
mHandler.removeMessages(0);
mHandler.sendEmptyMessageAtTime(0, SystemClock.uptimeMillis() + delay);
}
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (mState) {
case STATE_SHOWING:
// Fade in effect
mAlphaRate += (1 - mAlphaRate) * 0.2;
if (mAlphaRate > 0.9) {
mAlphaRate = 1;
setState(STATE_SHOWN);
}
mListView.invalidate();
fade(10);
break;
case STATE_SHOWN:
// If no action, hide automatically
setState(STATE_HIDING);
break;
case STATE_HIDING:
// Fade out effect
mAlphaRate -= mAlphaRate * 0.2;
if (mAlphaRate < 0.1) {
mAlphaRate = 0;
setState(STATE_HIDDEN);
}
mListView.invalidate();
fade(10);
break;
}
}
};
It would be really nice if you help me to show this alphabetical scroll bar in the left side of the screen.
I got that this way,
public void onSizeChanged(int w, int h, int oldw, int oldh) {
mListViewWidth = w;
mListViewHeight = h;
mIndexbarRect = new RectF(mIndexbarMargin, mIndexbarMargin,
mIndexbarMargin + mIndexbarWidth, h - mIndexbarMargin);
}
This is the method to draw the rectangle in left side of the screen.
private boolean contains(float x, float y) {
return (x <= mIndexbarRect.right && y >= mIndexbarRect.top && y <= mIndexbarRect.top
+ mIndexbarRect.height());
}
It will work smoothly if you change the function to the below. sorry for the posting this answer little late.
please check out : Indexable list view
For my android game I use Libgdx and I detect the collision between Bob (Omino) and Plant (Pianta) with this code that works fine :
Assets.class
pianta = new Animation(0.5f,new TextureRegion(items, 160, 384, 64, 96),
new TextureRegion(items, 224, 384, 64, 96));
Pianta.class
public class Pianta extends GameObject {
public static final float PIANTA_WIDTH = 2;
public static final float PIANTA_HEIGHT = 3;
public static float stateTime;
public Pianta(float x, float y) {
super(x, y, PIANTA_WIDTH, PIANTA_HEIGHT);
stateTime = 0;
}
public void update(float deltaTime) {
stateTime += deltaTime;
}
}
World.class
Pianta pianta1_0 = new Pianta(x+10,2.2f);
piante.add(pianta1_0);
private void collisionPiante(){
int len = piante.size();
for(int i=0;i<len;i++){
if(OverlapTester.overlapRectangles(piante.get(i).bounds,omino.bounds)){
omino.ominoMorto();
}
}
}
WorldRender.class
private void renderPiante() {
TextureRegion keyFrame;
int len = world.piante.size();
for(int i = 0; i < len; i++) {
Pianta pianta = world.piante.get(i);
keyFrame = Assets.pianta.getKeyFrame(Pianta.stateTime, Animation.ANIMATION_LOOPING);
batcher.draw(keyFrame,pianta.position.x, pianta.position.y, 2, 3);
}
}
but if you watch the image 2 below, you can see that Bob hit but there isn't collision with stone (Pietra) !!
This is the code :
Assets.class
pietra1 = new TextureRegion(items,288,416,128,64);
Pietra.class
public class Pietra extends GameObject {
public static float PIETRA_WIDTH = 4;
public static float PIETRA_HEIGHT = 2;
public Pietra(float x, float y) {
super(x, y, PIETRA_WIDTH, PIETRA_HEIGHT);
}
}
World.class
Pietra pietra1_0 = new Pietra(x+25,2.2f);
pietre.add(pietra1_0);
private void collisionPietre(){
int len2 = pietre.size();
for(int l=0;l<len2;l++){
if(OverlapTester.overlapRectangles(pietre.get(l).bounds,omino.bounds)){
omino.ominoMorto();
}
}
}
WorldRender.class
private void renderPietre() {
int len = world.pietre.size();
for(int i = 0; i < len; i++) {
Pietra pietra = world.pietre.get(i);
batcher.draw(Assets.pietra1,pietra.position.x, pietra.position.y, 4, 2);
}
}
OverlapTester
public class OverlapTester {
public static boolean overlapRectangles (Rectangle r1, Rectangle r2) {
if (r1.x < r2.x + r2.width && r1.x + r1.width > r2.x && r1.y < r2.y + r2.height && r1.y + r1.height > r2.y)
return true;
else
return false;
}
Someone can tell me why the collision with the plant works fine and with stone Bob hit even if there is no collision? as you can see the code is the same, the only difference is that the plant is an animated object while the stone isn't.
Check your OverlapTester. This is how Libgdx does it in the Rectangle.java class:
/** #param rectangle the other {#link Rectangle}
* #return whether this rectangle overlaps the other rectangle. */
public boolean overlaps (Rectangle rectangle) {
return !(x > rectangle.x + rectangle.width || x + width < rectangle.x || y > rectangle.y + rectangle.height || y + height < rectangle.y);
}
If I understood right overlapRectangles checks the case if rectangle is totally inside. It is not probably thing you want.
LibGDX has special functionality for collision checking. Please, check http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/math/Intersector.html
You may wish to replace your OverlapTester with the Rectangle's helper function contains. For instance:
World Class
if(OverlapTester.overlapRectangles(piante.get(i).bounds,omino.bounds)){
omino.ominoMorto();
}
Can be:
if (piante.get(i).bounds.contains(omino.bounds)) {
omino.ominoMorto();
}