I recently started using the Polygons but I'm have struggle as I'm trying to make a Polygon move towards the center of my screen, although I don't know how.
Here's the code I have(What I'm trying to accomplish here is to make the balls spawn randomly by every side of the screen and make them go towards the middle of the screen to collide against a square):
public class Game extends com.badlogic.gdx.Game implements Screen{
private SpriteBatch batch;
private Texture Ball;
private Texture Up;
private OrthographicCamera cam;
private int score;
private String showScore;
private BitmapFont scoreFont;
private Sprite upSprite;
private Polygon square;
private Array<Polygon> balls1;
private Array<Polygon> balls2;
private Array<Polygon> balls3;
private Array<Polygon> balls4;
private Polygon ball1 = new Polygon();
private Polygon ball2 = new Polygon();
private Polygon ball3 = new Polygon();
private Polygon ball4 = new Polygon();
#Override
public void create(){
batch = new SpriteBatch();
Ball = new Texture("energyball.png");
Up = new Texture("up.png");
upSprite = new Sprite(Up);
upSprite.setOriginCenter();
upSprite.setX(615);
upSprite.setY(340);
upSprite.setRegionWidth(64);
upSprite.setRegionHeight(64);
square = new Polygon(new float[] {
upSprite.getX(), upSprite.getY(),
upSprite.getX(), upSprite.getY() + upSprite.getHeight(),
upSprite.getX() + upSprite.getWidth(), upSprite.getY() + upSprite.getY(),
upSprite.getX() + upSprite.getWidth(), upSprite.getY()
});
cam = new OrthographicCamera();
cam.setToOrtho(false, 1280, 720);
upSprite.setPosition(upSprite.getX(), upSprite.getY());
square.setOrigin(upSprite.getX(), upSprite.getY());
// calls the functions to spawn balls randomly
balls1 = new Array<Polygon>();
balls2 = new Array<Polygon>();
balls3 = new Array<Polygon>();
balls4 = new Array<Polygon>();
score();
//if the screen is touched sprite rotates 90 degrees clockwise
Gdx.input.setInputProcessor(new InputAdapter() {
#Override
public boolean touchDown(int x, int y, int pointer, int button) {
return true;
}
#Override
public boolean touchUp(int x, int y, int pointer, int button) {
upSprite.rotate(-90);
square.rotate(-90f);
return true;
}
});
}
//shows score
private void score() {
score = -4;
showScore = "Score: 0";
scoreFont = new BitmapFont();
}
//creates the balls and sets their position as well as the random timer for each
private void spawnBalls1() {
ball1.setPosition(MathUtils.random(639, 641), 720);
ball1.setScale(32, 32);
balls1.add(ball1);
lastDropTime = TimeUtils.nanoTime();
}
private void spawnBalls2() {
ball2.setPosition(0, MathUtils.random(359, 361));
ball2.setScale(32, 32);
balls2.add(ball2);
lastDropTime = TimeUtils.nanoTime();
}
private void spawnBalls3() {
ball3.setPosition(MathUtils.random(639, 641), 0);
ball3.setScale(32, 32);
balls3.add(ball3);
lastDropTime = TimeUtils.nanoTime();
}
private void spawnBalls4() {
ball4.setPosition(1280, MathUtils.random(359, 361));
ball4.setScale(32, 32);
balls4.add(ball4);
lastDropTime = TimeUtils.nanoTime();
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
cam.update();
//draws the game itself as well as the balls on the screen
batch.setProjectionMatrix(cam.combined);
batch.begin();
upSprite.draw(batch);
//draws the balls
for (Polygon ball1 : balls1) {
batch.draw(Ball, ball1.getX(), ball1.getY());
}
for (Polygon ball2 : balls2) {
batch.draw(Ball, ball2.getX(), ball2.getY());
}
for (Polygon ball3 : balls3) {
batch.draw(Ball, ball3.getX(), ball3.getY());
}
for (Polygon ball4 : balls4) {
batch.draw(Ball, ball4.getX(), ball4.getY());
}
scoreFont.setColor(1, 1, 1, 1);
scoreFont.draw(batch, showScore, 25, 100);
batch.end();
// if the time minus the time of the last ball spawn is less than x then spawn another ball in a random place
if (TimeUtils.nanoTime() - lastDropTime > 1000000000) {
switch (MathUtils.random(4)) {
case 0:
spawnBalls1();
break;
case 1:
spawnBalls2();
break;
case 2:
spawnBalls3();
break;
case 3:
spawnBalls4();
break;
}
}
Iterator<Polygon> iter1 = balls1.iterator();
while(iter1.hasNext()) {
Polygon balls1 = iter1.next();
balls1.getY() -= 350 * Gdx.graphics.getDeltaTime();
if (Intersector.overlapConvexPolygons(balls1, square)) {
score++;
showScore = "Score: " + score;
iter1.remove();
}
}
Iterator<Polygon> iter2 = balls2.iterator();
while (iter2.hasNext()) {
Polygon balls2 = iter2.next();
balls2.x += 550 * Gdx.graphics.getDeltaTime();
if (Intersector.overlapConvexPolygons(balls2, square)) {
score++;
showScore = "Score: " + score;
iter2.remove();
}
}
Iterator<Polygon> iter3 = balls3.iterator();
while(iter3.hasNext()) {
Polygon balls3 = iter3.next();
balls3.y += 350 * Gdx.graphics.getDeltaTime();
if (Intersector.overlapConvexPolygons(balls3, square)) {
score++;
showScore = "Score: " + score;
iter3.remove();
}
}
Iterator<Polygon> iter4 = balls4.iterator();
while(iter4.hasNext()) {
Polygon balls4 = iter4.next();
balls4.x -= 550 * Gdx.graphics.getDeltaTime();
if (Intersector.overlapConvexPolygons(balls4, square)) {
score++;
showScore = "Score: " + score;
iter4.remove();
}
}
}
And I'm getting an error here:
balls1.getY() -= 350 * Gdx.graphics.getDeltaTime();
balls2.getX() += 550 * Gdx.graphics.getDeltaTime();
balls3.getY() += 350 * Gdx.graphics.getDeltaTime();
balls4.getX() -= 550 * Gdx.graphics.getDeltaTime();
Any help would be gladly appreciated.
Related
I've a sprite (rectangular) that rotates around its central point. I used:
setOriginCenter();
setRotation(angleDegrees);
That works fine.
I defined a DynamicBody (box2d) using a CircleShape.
In the update method of the sprite, I want to center the sprite (rotated sprite) with the center of the DynamicBody.
I tried several method but I can't get a solution:
This doesn't work
Rectangle rect = myRotatedSprite.getBoundingRectangle();
myRotatedSprite.setPosition(b2body.getPosition().x - rect.getWidth() / 2, b2body.getPosition().y - rect.getHeight() / 2);
This doesn't work
myRotatedSprite.setPosition(b2body.getPosition().x - myRotatedSprite.getWidth() / 2, b2body.getPosition().y - myRotatedSprite.getHeight() / 2);
This doesn't work
float rot = myRotatedSprite.getRotation();
myRotatedSprite.setRotation(0);
Rectangle rect = getBoundingRectangle();
myRotatedSprite.setPosition(b2body.getPosition().x - rect.width / 2,
b2body.getPosition().y - rect.height / 2);
myRotatedSprite.setRotation(rot);
myRotatedSprite.getBoundingRectangle();
What I am doing wrong ? It seems to me that getBoundingRectangle() is not correct when the sprite is rotated...
Here is my full code:
public class HeroBullet extends Weapon {
private static final String TAG = HeroBullet.class.getName();
private float stateTimer;
private Animation heroBulletAnimation;
private Vector2 tmp; // Temp GC friendly vector
public HeroBullet(PlayScreen screen, float x, float y, float width, float height, float circleShapeRadius, float angle, Animation animation) {
super(screen, x, y, circleShapeRadius > 0 ? circleShapeRadius : Constants.HEROBULLET_CIRCLESHAPE_RADIUS_METERS);
setOriginCenter();
width = width > 0 ? width : Constants.HEROBULLET_WIDTH_METERS;
height = height > 0 ? height : Constants.HEROBULLET_HEIGHT_METERS;
setBounds(getX(), getY(), width, height);
velocity = new Vector2(Constants.HEROBULLET_VELOCITY_X, Constants.HEROBULLET_VELOCITY_Y);
if (angle > 0) {
velocity.rotate(angle);
setRotation(angle);
}
if (animation != null) {
heroBulletAnimation = animation;
} else {
heroBulletAnimation = Assets.instance.heroBullet.heroBulletAnimation;
}
stateTimer = 0;
currentState = State.SHOT;
AudioManager.instance.play(Assets.instance.sounds.heroShoot, 0.2f, MathUtils.random(1.0f, 1.1f));
tmp = new Vector2();
}
#Override
protected void defineWeapon() {
BodyDef bdef = new BodyDef();
bdef.position.set(getX(), getY()); // In b2box the origin is at the center of the body
bdef.type = BodyDef.BodyType.DynamicBody;
b2body = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
CircleShape shape = new CircleShape();
shape.setRadius(circleShapeRadius);
fdef.filter.categoryBits = Constants.HERO_WEAPON_BIT; // Depicts what this fixture is
fdef.filter.maskBits = Constants.BORDERS_BIT |
Constants.OBSTACLE_BIT |
Constants.POWERBOX_BIT |
Constants.FINAL_ENEMY_LEVEL_ONE_BIT |
Constants.ENEMY_BIT; // Depicts what this Fixture can collide with
fdef.shape = shape;
b2body.createFixture(fdef).setUserData(this);
}
#Override
public void update(float dt) {
switch (currentState) {
case SHOT:
stateShot(dt);
break;
case ONTARGET:
stateOnTarget();
break;
case FINISHED:
break;
default:
break;
}
super.checkBoundaries();
}
private void stateShot(float dt) {
b2body.setLinearVelocity(velocity);
/* ***********
Here I want to center the sprite (rotated sprite) with the center of the DynamicBody, but I don't know how
******** */
setRegion((TextureRegion) heroBulletAnimation.getKeyFrame(stateTimer, true));
stateTimer += dt;
}
private void stateOnTarget() {
world.destroyBody(b2body);
currentState = State.FINISHED;
}
#Override
public void renderDebug(ShapeRenderer shapeRenderer) {
shapeRenderer.rect(getBoundingRectangle().x, getBoundingRectangle().y, getBoundingRectangle().width, getBoundingRectangle().height);
}
#Override
public void onTarget() {
currentState = State.ONTARGET;
}
public void draw(Batch batch) {
if (currentState == State.SHOT) {
super.draw(batch);
}
}
}
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 making a game and lately i have had a problem of making an image disappear. My code is as follows
package com.me.fixGame;
import java.util.Random;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
//import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.utils.Scaling;
import com.sun.jmx.snmp.tasks.Task;
public class fixGame implements ApplicationListener {
SpriteBatch batch;
SpriteBatch spriteBatch;
Texture trash;
Texture paper;
SpriteBatch spritebatch;
Vector2 position;
Vector2 pas;
boolean collide;
boolean countMe=false;
Vector2 size;
Vector2 size2;
Vector2 pos;
Rectangle bounds;
Rectangle bounds2;
float delay = 1; // seconds
boolean counted= false;
int score = 3;
//Texture Gogreen;
String myScore;
Texture background;
CharSequence str = "Lives left: 3"; // = myScore;
CharSequence line = "Score: 0"; // = myScore;
String myLife;
int life=0;
BitmapFont font;
float x;
float y;
boolean collision = false;
#Override
public void create() {
//Gogreen = new Texture(Gdx.files.internal("data/gogreenNow.jpg"));
background = new Texture(Gdx.files.internal("data/trash.png"));
x= background.getWidth();
y=background.getHeight();
//float delaySeconds = 1;
spriteBatch = new SpriteBatch();
trash = new Texture(Gdx.files.internal("data/trash.png"));
paper = new Texture(Gdx.files.internal("data/paper1.jpg"));
position = new Vector2(100, 50);
pos = new Vector2(54, 14);
batch = new SpriteBatch();
BitmapFont font = new BitmapFont();
size2 = new Vector2(trash.getWidth() ,trash.getHeight() );
//size2.y = trash.getHeight();
//size2.x = trash.getWidth();
size = new Vector2(paper.getWidth() ,paper.getHeight());
bounds= new Rectangle(pos.x, pos.y, size.x, size.y);
bounds2= new Rectangle(position.x, position.y, size2.x, size2.y);
}
#Override
public void dispose() {
}
public void update(){
bounds.set(pos.x, pos.y, size.x, size.y);
bounds2.set(position.x, position.y, size2.x, size2.y);
position.x = position.x -2- Gdx.input.getAccelerometerX();
}
#Override
public void render() {
if(bounds.overlaps(bounds2)){
collision=true;
counted=true;
}else{
collision=false;
}
if(collision==true){
}
if(pos.y<640){
counted=false;
} else if(pos.y > 640 && collision==false && counted==false){
counted=true;
score= score-1;
myScore = "Lives left: " + score;
str = myScore;
}
if(bounds.overlaps(bounds2)){
countMe=true;
life= life+50;
myLife = "Score: " + life;
line = myLife;
}
if(position.x<0){
position.x= position.x+11;
}
if(position.x>425){
position.x= position.x-11;
}
update();
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
pos.y=pos.y-12;
if(pos.y<0){
pos.y = 700;
Random randomGenerator = new Random();
pos.x = randomGenerator.nextInt(500);
}
BitmapFont font = new BitmapFont();
batch.begin();
batch.draw(background, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.draw(paper, pos.x, pos.y);
batch.draw(trash, position.x, position.y);
font.setScale(3);
font.setColor(0.0f, 0.0f, 1.0f,1.0f);
font.draw(batch, str, 200,900);
font.draw(batch, line, 200, 700);
batch.end();
font.dispose();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
I want to make my image called paper to disappear which I instantiate here.
x= background.getWidth();
y=background.getHeight();
//float delaySeconds = 1;
spriteBatch = new SpriteBatch();
trash = new Texture(Gdx.files.internal("data/trash.png"));
paper = new Texture(Gdx.files.internal("data/paper1.jpg"));
position = new Vector2(100, 50);
pos = new Vector2(54, 14);
batch = new SpriteBatch();
BitmapFont font = new BitmapFont();
And where i want it to disappear is below:
if(bounds.overlaps(bounds2)){
countMe=true;
life= life+50;
myLife = "Score: " + life;
line = myLife;
}
What i want to do is when the two objects overlap(bounds and bounds2) the score should be changed and one of the objects, the paper, should hide. How do i make an image hide?
Becuase you already are setting the collision state to a variable, in the render() method you just need to wrap the batch.draw() method. I've tested this code and it works. You also need to set collision to false when you set the paper back to the top, I'm guessing you want it to hide completely until it resets. Please note I've also made some small tweaks just so it's easier to test. If there are still runtime bugs it's not related to this change.
#Override
public void render() {
if (bounds.overlaps(bounds2)) {
collision = true;
counted = true;
}
if (pos.y < 640) {
counted = false;
} else if (pos.y > 640 && collision == false && counted == false) {
counted = true;
score = score - 1;
myScore = "Lives left: " + score;
str = myScore;
}
if (bounds.overlaps(bounds2)) {
countMe = true;
life = life + 50;
myLife = "Score: " + life;
line = myLife;
}
if (position.x < 0) {
position.x = position.x + 11;
}
if (position.x > 425) {
position.x = position.x - 11;
}
update();
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
pos.y = pos.y - 2;
if (pos.y < 0) {
pos.y = 700;
Random randomGenerator = new Random();
pos.x = 250;
collision = false;
}
BitmapFont font = new BitmapFont();
batch.begin();
batch.draw(background, 0, 0, Gdx.graphics.getWidth(),
Gdx.graphics.getHeight());
if (!collision) {
batch.draw(paper, pos.x, pos.y);
}
batch.draw(trash, position.x, position.y);
font.setScale(1.5f);
font.setColor(0.0f, 0.0f, 1.0f, 1.0f);
font.draw(batch, str, 20, 50);
font.draw(batch, line, 20, 100);
batch.end();
font.dispose();
}
I'm creating small balloon game. where balloons pop up randomly and disappear after a little while. When i clicked on them those i want to disappear them and show +1 instead of the balloon. When i click on the balloon, i want to deattach the balloon sprite.
My problem is when i call sprite.detachSelf() in the code, the sprite just disapears but actually the sprite hasn't being removed. It only becomes invisible. When i click again on that place the balloon appears, even after the balloon has disappear it shows +1. Which means i think the balloon hasn't deattached correctly.
Here is my code:
#Override
protected Scene onCreateScene() {
//this.mEngine.registerUpdateHandler(new FPSLogger());
scene = new Scene();
backgroundSprite = new Sprite(0, 0, this.mBackgroundTextureRegion,
getVertexBufferObjectManager());
backgroundSprite.setSize(CAMERA_WIDTH, CAMERA_HEIGHT);
scene.attachChild(backgroundSprite);
scene.unregisterTouchArea(backgroundSprite);
text = new Text(0, 0, font, "Score : 00",
getVertexBufferObjectManager());
scene.attachChild(text);
textTime = new Text(displayMetrics.widthPixels - 220, 0, font,
"00 : 60", getVertexBufferObjectManager());
scene.attachChild(textTime);
timer = new TimerClock(1, new TimerClock.ITimerCallback() {
TimerClock t = timer;
public void onTick() {
System.out.println("timer inside");
if (time > 0) {
time = time - 1;
System.out.println("timer inside : " + time);
scene.detachChild(textTime);
textTime = new Text(displayMetrics.widthPixels - 220, 0,
font, "00 : " + time,
getVertexBufferObjectManager());
if (time < 10) {
textTime.setColor(1, 0, 0);
}
scene.attachChild(textTime);
deleteSpriteSpawnTimeHandler(sprite);
}
else{
scene.unregisterUpdateHandler(this.t);
}
}
});
this.mEngine.registerUpdateHandler(timer);
createSpriteSpawnTimeHandler();
return scene;
}
private void deleteSpriteSpawnTimeHandler(final IEntity ball) {
TimerHandler spriteTimerHandler1;
final Engine e = mEngine;
this.getEngine().registerUpdateHandler(
spriteTimerHandler1 = new TimerHandler(0.5f, true,
new ITimerCallback() {
#Override
public void onTimePassed(
final TimerHandler spriteTimerHandler1) {
spriteTimerHandler1.reset();
deleteSprite(ball);
}
}));
}
private void gameOverSpawnTimeHandler() {
TimerHandler spriteTimerHandler1;
final Engine e = mEngine;
this.getEngine().registerUpdateHandler(
spriteTimerHandler1 = new TimerHandler(60, true,
new ITimerCallback() {
#Override
public void onTimePassed(
final TimerHandler spriteTimerHandler1) {
spriteTimerHandler1.reset();
timeDue = 0;
scene.detachChild(textComment);
textComment = new Text(CAMERA_WIDTH / 2 - 100,
CAMERA_HEIGHT / 2, font,
"Game Over...!!!",
getVertexBufferObjectManager());
textComment.setColor(1.0f, 0.0f, 0.0f);
scene.attachChild(textComment);
SharedPreferences myPrefs = getApplicationContext().getSharedPreferences("myPrefs",
MODE_WORLD_READABLE);
SharedPreferences.Editor prefsEditor = myPrefs.edit();
String score1 = myPrefs.getString("SCORE1", "0");
String score2 = myPrefs.getString("SCORE2", "0");
int scoreInt1 = Integer.parseInt(score1);
int scoreInt2 = Integer.parseInt(score2);
System.out.println("session in" + score1 + " "
+ score2);
currScore = totalScore;
if (currScore > scoreInt1 && currScore > scoreInt2) {
prefsEditor.clear();
prefsEditor.commit();
prefsEditor.putString("SCORE1", String.valueOf(currScore));
prefsEditor.putString("SCORE2", String.valueOf(scoreInt1));
prefsEditor.commit();
} else if (currScore < scoreInt1 && currScore > scoreInt2) {
prefsEditor.clear();
prefsEditor.commit();
prefsEditor.putString("SCORE1", String.valueOf(scoreInt1));
prefsEditor.putString("SCORE2", String.valueOf(currScore));
prefsEditor.commit();
} else {
}
}
}));
}
private void createSpriteSpawnTimeHandler() {
TimerHandler spriteTimerHandler;
final Engine e = mEngine;
this.getEngine().registerUpdateHandler(
spriteTimerHandler = new TimerHandler(0.75f, true,
new ITimerCallback() {
#Override
public void onTimePassed(
final TimerHandler spriteTimerHandler) {
spriteTimerHandler.reset();
// scene.detachChild(backgroundSprite);
// scene.attachChild(backgroundSprite);
// Random Position Generator
final float xPos = MathUtils.random(50.0f,
(CAMERA_WIDTH - 50.0f));
final float yPos = MathUtils.random(75.0f,
(CAMERA_HEIGHT - 75.0f));
gameOverSpawnTimeHandler();
if (timeDue > 0) {
createSprite(xPos, yPos);
}else{
//scene.unregisterUpdateHandler(spriteTimerHandler);
}
}
}));
}
private void createSpriteTextSpawnTimeHandler() {
TimerHandler spriteTimerHandler;
final Engine e = mEngine;
this.getEngine().registerUpdateHandler(
spriteTimerHandler = new TimerHandler(mEffectSpawnDelay, true,
new ITimerCallback() {
#Override
public void onTimePassed(
final TimerHandler spriteTimerHandler) {
spriteTimerHandler.reset();
if (totalScore > 50 && totalScore < 60) {
textComment = new Text(150, 100, font,
"Ohhhh...you are doing good.",
getVertexBufferObjectManager());
textComment.setColor(1.0f, 0.0f, 0.0f);
scene.attachChild(textComment);
}
deleteSpriteSpawnTimeHandler(textComment);
// e.getScene().detachChild(backgroundSprite);
// e.getScene().attachChild(backgroundSprite);
}
}));
}
private void createSprite(final float pX, final float pY) {
sprite = new Sprite(pX, pY, this.mrball, getVertexBufferObjectManager()) {
Engine e = mEngine;
TextureRegion gball = mgball;
float x = pX;
float y = pY;
private int score = totalScore;
private Text textComment;;
#Override
public boolean onAreaTouched(
org.andengine.input.touch.TouchEvent pSceneTouchEvent,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN) {
this.e.getScene().detachChild(this);
if (timeDue > 0) {
mBrushDrawingSound.play();
totalScore = totalScore + 1;
String score = "Score : " + totalScore;
scene.detachChild(text);
text = new Text(0, 0, font, score,
getVertexBufferObjectManager());
scene.attachChild(text);
//sprite.detachSelf();
createSpriteTextSpawnTimeHandler();
textScorePlus = new Text(x, y, font, "+1",
getVertexBufferObjectManager());
scene.attachChild(textScorePlus);
scene.unregisterTouchArea(textScorePlus);
deleteSpriteSpawnTimeHandler(textScorePlus);
}
} else if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP) {
}
// e.getScene().unregisterTouchArea(sprite);
return true;
}
};
spriteBalloon.add(sprite);
sprite.setSize(100, 100);
sprite.setAlpha(0.8f);
Random randomGenerator = new Random();
red = randomGenerator.nextInt(255);
green = randomGenerator.nextInt(255);
blue = randomGenerator.nextInt(255);
sprite.setColor(red, green, blue);
scene.registerTouchArea(sprite);
scene.attachChild(sprite);
deleteSpriteSpawnTimeHandler(sprite);
}
private void deleteSprite(IEntity pBall) {
IEntity gball = pBall;
scene.detachChild(gball);;
}
When you attach, you need to detach; when you scene.registerTouchArea(sprite), you need to scene.unregisterTouchArea(sprite).
I've just started with Android programming using eclipse and recently came across this problem. I have a bunch of sprites assigned to an arraylist. Now, I want to make it so that collision is detected automatically between sprites but the template I'm currently using can only detect collision between the surface's borders and the moving sprites. Each sprite's position and speed is generated randomly.
How can I change the update() function in my Sprite() class to detect collision between the moving sprites themselves and at the same changing/bouncing to the opposite direction?
Here's my Sprite class template:
package com.gameproject.cai_test;
import java.util.Random;
public Sprite(GameView gameView, Bitmap bmp) {
this.width = bmp.getWidth() / BMP_COLUMNS;
this.height = bmp.getHeight() / BMP_ROWS;
this.gameView = gameView;
this.bmp = bmp;
Random rnd = new Random();
x = rnd.nextInt(gameView.getWidth() - width);
y = rnd.nextInt(gameView.getHeight() - height);
xSpeed = rnd.nextInt(MAX_SPEED * 2) - MAX_SPEED;
ySpeed = rnd.nextInt(MAX_SPEED * 2) - MAX_SPEED;
}
private void update() {
if (x >= gameView.getWidth() - width - xSpeed || x + xSpeed <= 0) {
xSpeed = -xSpeed;
}
x = x + xSpeed;
if (y >= gameView.getHeight() - height - ySpeed || y + ySpeed <= 0) {
ySpeed = -ySpeed;
}
y = y + ySpeed;
currentFrame = ++currentFrame % BMP_COLUMNS;
}
public void onDraw(Canvas canvas) {
update();
int srcX = currentFrame * width;
int srcY = getAnimationRow() * height;
Rect src = new Rect(srcX, srcY, srcX + width, srcY + height);
Rect dst = new Rect(x, y, x + width, y + height);
canvas.drawBitmap(bmp, src, dst, null);
}
private int getAnimationRow() {
double dirDouble = (Math.atan2(xSpeed, ySpeed) / (Math.PI / 2) + 2);
int direction = (int) Math.round(dirDouble) % BMP_ROWS;
return DIRECTION_TO_ANIMATION_MAP[direction];
}
//gameplay operations
//only values from 0 to 9 will be picked; each assigned its own sprite in the list
public int randomValue(){
Random rnd = new Random();
RandomValue = rnd.nextInt(10);
return RandomValue;
}
//sequence operation from addition, subtraction, multiplication, and division
public int produceSum(){
int addOne = 0;
int addTwo = 0;
Sum = addOne + addTwo;
return Sum;
}
public int produceDiff(){
int deductOne = 0;
int deductTwo = 0;
Difference = deductOne - deductTwo;
return Difference;
}
public int produceProduct(){
int multiOne = 0;
int multiTwo = 0;
Product = multiOne * multiTwo;
return Product;
}
public int produceQuotient(){
int divideOne = 0;
int divideTwo = 0;
Quotient = divideOne / divideTwo;
return Quotient;
}
//each time this returns true, the game is reset with new operation
//compares the value of the bubble picked to the random number being compared through operations
public boolean compareBubbleValue(int randomBubble, int bubbleValue){
if (randomBubble == bubbleValue){
return true;
}
return false;
}
}
As you can see, the update() method only checks the collision between the moving sprites and the borders.
Okey, so lets name your array of sprites spriteArray and loop through it twice
public Rect getBounds(){ //put this in your sprite and enemy-class.
return new Rect(x, y, x+width, y+height);
}
Public void checkCollision(){
for (int i = 0; i<spriteArray.size(); i++){
Rect mySprite = spriteArray.get(i).getBounds(); //create rect for every sprite in array
for (int j = 0; j<spriteArray.size(); i++){
Rect myOtherSprite = spriteArray.get(i).getBounds();
if(mySprite.intersect(myOtherSprite)){ //check if they touch
//Todo code here
}
}
}
}
then you just put this method in your update-method.
Here's the coding for the GameView class (pardon the mess, it's a jumble of codes and comments):
package com.gameproject.cai_test;
public class GameView extends SurfaceView {
private Bitmap bmp;
private Bitmap background;
private Bitmap backgroundImage;
private Bitmap pop;
private SurfaceHolder holder;
private GameLoopThread gameLoopThread;
private List<Sprite> sprites = new ArrayList<Sprite>();
private List<TempSprite> temps = new ArrayList<TempSprite>();
private int[] bubbleValue = {0,1,2,3,4,5,6,7,8,9,10};
private long lastClick;
private SpriteObject timer;
private SpriteObject morebanner;
private SpriteObject formulaBox;
private SpriteObject levelbanner1;
private SurfaceHolder surfaceHolder;
public GameView(Context context) {
super(context);
gameLoopThread = new GameLoopThread(this);
timer = new SpriteObject (BitmapFactory.decodeResource(getResources(), R.drawable.hourglass), 1200, 100);
morebanner = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.morebanner), 650, 300);
formulaBox = new SpriteObject(BitmapFactory.decodeResource(getResources(), R.drawable.formulabox), 650, 600);
background = BitmapFactory.decodeResource(getResources(), R.drawable.background);
backgroundImage = BitmapFactory.decodeResource(getResources(), R.drawable.background);
pop = BitmapFactory.decodeResource(getResources(), R.drawable.pop);
final Toast toast1 = Toast.makeText(context, "LEVEL 1 start", Toast.LENGTH_LONG);
holder = getHolder();
holder.addCallback(new Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
//setSurfaceSize(getWidth(), getHeight());
toast1.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast1.show();
createSprites();
gameLoopThread.setRunning(true);
gameLoopThread.start();
//banner();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
}
private void createSprites() {
sprites.add(createSprite(R.drawable.bubble1));
sprites.add(createSprite(R.drawable.bubble2));
sprites.add(createSprite(R.drawable.bubble3));
sprites.add(createSprite(R.drawable.bubble4));
sprites.add(createSprite(R.drawable.bubble5));
sprites.add(createSprite(R.drawable.bubble6));
sprites.add(createSprite(R.drawable.bubble7));
sprites.add(createSprite(R.drawable.bubble8));
sprites.add(createSprite(R.drawable.bubble9));
sprites.add(createSprite(R.drawable.bubble10));
for (int i = 0; i <= 10; i++){
bubbleValue[i] = sprites.indexOf(i);
}
}
private Sprite createSprite(int resource) {
Bitmap bmp = BitmapFactory.decodeResource(getResources(), resource);
return new Sprite(this, bmp);
}
public void setSurfaceSize(int width, int height)
{
synchronized (surfaceHolder)
{
int canvasWidth = width;
int canvasHeight = height;
backgroundImage = Bitmap.createScaledBitmap(backgroundImage, width, height, true);
}
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
//levelbanner1.draw(canvas);//causes error when applied;for reference only
for (int i = temps.size() - 1; i >= 0; i--) {
temps.get(i).onDraw(canvas);
}
for (Sprite sprite : sprites) {
timer.draw(canvas);
//formulaBox.draw(canvas);
sprite.onDraw(canvas);
}
if (sprites.size() == 0){
morebanner.draw(canvas);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (System.currentTimeMillis() - lastClick > 300) {
lastClick = System.currentTimeMillis();
float x = event.getX();
float y = event.getY();
synchronized (getHolder()) {
for (int i = sprites.size() - 1; i >= 0; i--) {
Sprite sprite = sprites.get(i);
if (sprite.isCollition(x, y)) {
sprites.remove(sprite);
temps.add(new TempSprite(temps, this, x, y, pop));
break;
}
}
}
}
return true;
}
public void update(){
//for possible check of collision bet. sprites
//
}
}
I've tried assigning a Rect for the sprites here and checking collision on the bottom update() function but result gets awry and produces a runtime error. Probably would be better if its automated in the Sprite class update() function, just as it does for border collision.
If you want to have nice and proper collisions between your sprites, maybe looking at a physics engine like http://www.jbox2d.org/ would help.
It will handle a lot of the complex specific cases for you (tunnelling, time of impact, broadphase for early discard...)