java - Breakout ball collision in libgdx -


i'm trying make breakout clone using java , libgdx. i'm experiencing trouble getting ball bounce off of blocks @ appropriate angle. in short problem i'm having ball moves 12 pixels every frame , doesn't line edge of brick. if has suggestions on better way move ball or different way check collision appreciated!

main game class

    package com.kyleparker.breakout;  import com.badlogic.gdx.applicationlistener; import com.badlogic.gdx.gdx; import com.badlogic.gdx.audio.music; import com.badlogic.gdx.audio.sound; import com.badlogic.gdx.graphics.gl10; import com.badlogic.gdx.graphics.orthographiccamera; import com.badlogic.gdx.graphics.texture; import com.badlogic.gdx.graphics.g2d.spritebatch; import com.badlogic.gdx.math.rectangle; import com.badlogic.gdx.utils.array;  public class breakoutgamescreen implements applicationlistener {    texture dropimage;    sound dropsound;    music rainmusic;    spritebatch batch;    orthographiccamera camera;    rectangle bucket;    paddle paddle;    //brick bricks[];    array<brick> bricks;    ball ball;     @override    public void create() {       // load images droplet, 64x64 pixels       dropimage = new texture(gdx.files.internal("droplet.png"));        // load drop sound effect , rain background "music"       dropsound = gdx.audio.newsound(gdx.files.internal("drop.wav"));       rainmusic = gdx.audio.newmusic(gdx.files.internal("rain.mp3"));        // start playback of background music       rainmusic.setlooping(true);       rainmusic.play();        // create camera , spritebatch       camera = new orthographiccamera();       camera.settoortho(false, 1280, 720);       batch = new spritebatch();        paddle = new paddle(new texture(gdx.files.internal("bucket.png")));        bricks = new array<brick>();       populatebricks();        ball = new ball(new texture(gdx.files.internal("bucket.png")), paddle, bricks);    }     private void populatebricks() {        bricks.add(new brick(200,100));        (int = 0; < 5; i++) {            (int j = 0; j <= 7; j++) {                bricks.add(new brick (j * 144 + 76, * 80 + 300)); //offsets each new brick            }        }    }     @override    public void render() {        // clear screen dark blue color.        // arguments glclearcolor red, green        // blue , alpha component in range [0,1]        // of color used clear screen.        gdx.gl.glclearcolor(0, 0, 0.2f, 1);        gdx.gl.glclear(gl10.gl_color_buffer_bit);         // tell camera update matrices.        camera.update();         // tell spritebatch render in        // coordinate system specified camera.        batch.setprojectionmatrix(camera.combined);         // begin new batch , draw bucket ,        // drops        batch.begin();         paddle.render(batch, camera);         ball.move();        ball.render(batch, camera);         (int x = bricks.size - 1; x > 0; x--) {            bricks.get(x).render(batch,camera);        }         batch.end();         }     @override    public void dispose() {       // dispose of native resources       dropimage.dispose();       dropsound.dispose();       rainmusic.dispose();       batch.dispose();       paddle.dispose();    }     @override    public void resize(int width, int height) {    }     @override    public void pause() {    }     @override    public void resume() {    } } 

ball class

    package com.kyleparker.breakout;  import com.badlogic.gdx.graphics.orthographiccamera; import com.badlogic.gdx.graphics.texture; import com.badlogic.gdx.graphics.g2d.spritebatch; import com.badlogic.gdx.math.rectangle; import com.badlogic.gdx.utils.array;  public class ball{    texture ballimage;    rectangle ball;    private int xdir;    private int ydir;    paddle paddle;    array<brick> bricks;    final int ball_speed = 12;     public ball(texture ballimage, paddle paddle, array<brick> bricks) {       // load ball image       this.ballimage = ballimage;       xdir = 1;       ydir = -1;        // create rectangle balls collision       ball = new rectangle();       ball.x = 1280 / 2 - 64 / 2; // center ball       ball.y = 100; // put ball 200px away bottom of screen       ball.width = 64;       ball.height = 64;        this.paddle = paddle;       this.bricks = bricks;    }     public void render(spritebatch batch, orthographiccamera camera) {        // draw paddle onto batch of level        batch.draw(ballimage, ball.x, ball.y);    }     public void move() {        ball.x += xdir * ball_speed;        ball.y += ydir * ball_speed;         if (ball.x <= 0) {            setxdir(1);        }         if (ball.x >= 1280 - 64) {            setxdir(-1);        }         if (ball.y <= 0) {            setydir(1);        }         if (ball.y >= 720 - 64) {            setydir(-1);        }         if (ball.overlaps(paddle.getrect())) {                   setydir(1);        }         (int = 0; < bricks.size; i++) {            if (ball.overlaps(bricks.get(i).getrect())) {                if ((ball.x == (bricks.get(i).getrect().x + 128)))                 {                     setxdir(1);                    bricks.get(i).setdestroyed(true);                    system.out.println("collision right");                }                if (((ball.x + 64) == bricks.get(i).getrect().x))                 {                     setxdir(-1);                    bricks.get(i).setdestroyed(true);                    system.out.println("collision left");                }                if ((ball.y == (bricks.get(i).getrect().y + 64)))                 {                     setydir(1);                    bricks.get(i).setdestroyed(true);                    system.out.println("collision top");                }                if (((ball.y + 64) == bricks.get(i).getrect().y))                 {                                      setydir(-1);                    bricks.get(i).setdestroyed(true);                    system.out.println("collision bottom");                }            }        }// end of    }     public void setxdir(int x) {        xdir = x;    }     public void setydir(int y) {        ydir = y;    }     public int getydir() {        return ydir;    }     public int getxdir() {        return xdir;    }     public rectangle getrect() {        // return collision rectangle checking overlaps        return ball;    }     public void dispose() {       // dispose of native resources       ballimage.dispose();    } }// end of class 

brick code in case

package com.kyleparker.breakout;  import com.badlogic.gdx.gdx; import com.badlogic.gdx.graphics.orthographiccamera; import com.badlogic.gdx.graphics.texture; import com.badlogic.gdx.graphics.g2d.spritebatch; import com.badlogic.gdx.math.rectangle;  public class brick{    texture brickimage;    rectangle brick;    boolean destroyed;     public brick(int x, int y) {        brickimage = new texture(gdx.files.internal("brick.png"));            // create rectangle bricks collision        brick = new rectangle();        brick.x = x;        brick.y = y;        brick.width = 128;        brick.height = 64;         destroyed = false;    }     public void render(spritebatch batch, orthographiccamera camera) {        // draw brick onto batch of level        batch.draw(brickimage, brick.x, brick.y);    }     public boolean isdestroyed() {        // return collision rectangle checking overlaps        return destroyed;    }     public void setdestroyed(boolean destroyed)    {      this.destroyed = destroyed;       if (this.destroyed == true) {          dispose();          brick.x = -1000;          brick.y = -1000;      }    }     public rectangle getrect() {        return brick;    }     public void dispose() {       // dispose of native resources       brickimage.dispose();    } } 

don't worry fact ball doesn't line object collision needs handled -- that's not relevant. can (and should) handle collisions less 'precisely.' is, ball's path fixed, can calculate position @ future point. check position, calculate position in next frame (which have draw anyway), , add code handle collision going happen, rather trying detect , handle collision has happened. can slow down ball if want clean reflection, or can speed framerate, or can let ball partially 'absorbed' object before reflects:

public class ball { . . .     public void move() {     . . .         if (collisionobject.overlaps(new rectangle(ball.x + xdir, ball.y + ydir, ball.width, ball.height))) {             //a collision have occurred in next frame             //handle collision please         }     } } 

i note ball_speed field inaccurately named. presently coded, ball moves @ 45° angle, speed of 17 pixels per frame (in direction). you've coded x- , y-offset 12 pixels, if (when?) change ball's direction, you'll find speed fluctuates wildly depending on values placed in xdir , ydir fields. example, if (somewhat) randomize these, keep rest of code as-is, might find xdir = 2 , ydir = 4 on 1 instance, , xdir = 6 , ydir = 12 on another. note these describe same direction, second version move 3 times fast.

to handle ball's direction , speed, assign angle, , calculate xdir , ydir values through appropriate trigonometric functions (xdir = ball_speed * math.cos(ballangle) , ydir = ball_speed * math.sin(ballangle)).


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -