2013-05-14 47 views
0

我正在嘗試使用java和libgdx製作突破克隆。我目前遇到了麻煩,讓球以適當的角度跳出積木。總之,我遇到的問題是,球每幀移動12個像素,並不總是與磚的邊緣對齊。如果任何人有任何建議更好的方式來移動球或不同的方式來檢查碰撞它將不勝感激!libgdx中的突圍球碰撞

主要遊戲類

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 the images for the droplet, 64x64 pixels 
     dropImage = new Texture(Gdx.files.internal("droplet.png")); 

     // load the drop sound effect and the rain background "music" 
     dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav")); 
     rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3")); 

     // start the playback of the background music immediately 
     rainMusic.setLooping(true); 
     rainMusic.play(); 

     // create the camera and the 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)); 
     for (int i = 0; i < 5; i++) { 
      for (int j = 0; j <= 7; j++) { 
       bricks.add(new Brick (j * 144 + 76, i * 80 + 300)); //Offsets each new brick 
      } 
     } 
    } 

    @Override 
    public void render() { 
     // clear the screen with a dark blue color. The 
     // arguments to glClearColor are the red, green 
     // blue and alpha component in the range [0,1] 
     // of the color to be used to clear the screen. 
     Gdx.gl.glClearColor(0, 0, 0.2f, 1); 
     Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 

     // tell the camera to update its matrices. 
     camera.update(); 

     // tell the SpriteBatch to render in the 
     // coordinate system specified by the camera. 
     batch.setProjectionMatrix(camera.combined); 

     // begin a new batch and draw the bucket and 
     // all drops 
     batch.begin(); 

     paddle.render(batch, camera); 

     ball.move(); 
     ball.render(batch, camera); 

     for (int x = bricks.size - 1; x > 0; x--) { 
      bricks.get(x).render(batch,camera); 
     } 

     batch.end();  
    } 

    @Override 
    public void dispose() { 
     // dispose of all the 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類

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 the ball image 
     this.ballImage = ballImage; 
     xdir = 1; 
     ydir = -1; 

     // create a Rectangle for the balls collision 
     ball = new Rectangle(); 
     ball.x = 1280/2 - 64/2; // center the ball 
     ball.y = 100; // put the ball 200px away from the bottom of the screen 
     ball.width = 64; 
     ball.height = 64; 

     this.paddle = paddle; 
     this.bricks = bricks; 
    } 

    public void render(SpriteBatch batch, OrthographicCamera camera) { 
     // draw the paddle onto the batch of the 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); 
     } 

     for (int i = 0; i < 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 for 
    } 

    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 the collision rectangle for checking overlaps 
     return ball; 
    } 

    public void dispose() { 
     // dispose of all the native resources 
     ballImage.dispose(); 
    } 
}// end of class 

磚碼,以防萬一

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 a Rectangle for the 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 the brick onto the batch of the level 
     batch.draw(brickImage, brick.x, brick.y); 
    } 

    public boolean isDestroyed() { 
     // return the collision rectangle for 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 all the native resources 
     brickImage.dispose(); 
    } 
} 
+0

請將您的粘貼代碼縮短到下一個問題的輸入和行。 – BennX

回答

-1

我會使用的Box2D整個事情。你還沒有使用box2d可能意味着你沒有經驗,所以這將是一個小障礙,但我相信你可以快速將你的頭圍繞在它周圍。這裏有一個鏈接:http://code.google.com/p/libgdx/wiki/PhysicsBox2D

+0

使用完整的物理引擎來處理軸對齊的彈跳看起來對我來說過分。他的問題在於球在碰撞點之外移動。他所需要做的就是檢查下一幀是否會發生碰撞並相應處理。 – Madmenyo

2

不要擔心這樣的事實,即球並不總是與碰撞需要處理的物體對齊 - 這實際上並不相關。你可以(也應該)更精確地處理你的碰撞。也就是說,球的路徑是固定的,所以你可以計算它在任何未來點的位置。檢查它的位置,計算它在下一幀的位置(無論如何你都必須這樣做),並添加一些代碼來處理碰撞,即要發生而不是嘗試檢測並處理碰撞,其中已發生。您可以減慢球,如果你真的想要一個乾淨的反映,也可以加快你的幀率,或者你可以讓球是部分「吸收」的對象反映前:

public class Ball { 
. . . 
    public void move() { 
    . . . 
     if (collisionObject.overlaps(new Rectangle(ball.x + xdir, ball.y + ydir, ball.width, ball.height))) { 
      //a collision will have occurred in the next frame 
      //handle the collision however you please 
     } 
    } 
} 

我也注意到您的BALL_SPEED字段的名稱不正確。按照目前編碼,球始終以45°角移動,每幀速度約爲17個像素(在該方向上)。您已將其x和y偏移量編碼爲12像素,但如果(當?)更改球的方向,則會發現速度波動很大,具體取決於xdirydir字段的值。例如,如果您要(稍微)隨機化這些代碼,但保留代碼的其餘部分,則可能在一個實例上發現了xdir = 2ydir = 4,並且在另一個實例上發現了xdir = 6ydir = 12。注意這些描述了相同的方向,但第二個版本將移動速度的三倍。

爲了正確地處理球的方向和速度,分配的角度,並且通過適當的三角函數(xdir = BALL_SPEED * Math.cos(ballAngle)ydir = BALL_SPEED * Math.sin(ballAngle))計算xdirydir值。