2017-08-25 30 views
0

コーディングに新しいので、Pongの作成方法に関するビデオを見ました。それはうまく行きました。その結果、私はPongに使用されていたコーディングテクニックのいくつかを使ってBrick Breakerを再現しようとしたかったのです。これまでのところ、私はボール、パドル、そしてゲームのベースを持っています。しかし、パドルが跳ね返るのではなく、パドルとボールが適切に衝突することはありません。Javaヒットの検出/オブジェクト間の衝突

ベースのゲームのためのコード:

import java.applet.Applet; 
import java.awt.Color; 
import java.awt.Image; 
import java.awt.Graphics; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

public class Breaker extends Applet implements Runnable, KeyListener{ 
final int WIDTH = 600, HEIGHT= 400; 
Thread thread; 
Graphics gfx; 
Image img; 
Ball b1; 
Player p1; 

public void init() { 
    this.resize(WIDTH, HEIGHT); 
    this.addKeyListener(this); 
    b1 = new Ball(); 
    p1 = new Player(1); 
    img = createImage(WIDTH,HEIGHT); 
    gfx = img.getGraphics(); 
    thread = new Thread(this); 
    thread.start(); 
} 

public void paint(Graphics g) { 
    gfx.setColor(Color.black); 
    gfx.fillRect(0, 0, WIDTH, HEIGHT); 
    b1.draw(gfx); 
    p1.draw(gfx); 
    g.drawImage(img, 0, 0, this); 
} 

public void update (Graphics g) { 
    paint(g); 
} 

@Override 
public void keyPressed(KeyEvent e) { 
    if(e.getKeyCode() == KeyEvent.VK_LEFT){ 
     p1.setLeftAccel(true); 
    } 
    else if(e.getKeyCode() == KeyEvent.VK_RIGHT){ 
     p1.setRightAccel(true); 
    } 

} 

@Override 
public void keyReleased(KeyEvent e) { 
    if(e.getKeyCode() == KeyEvent.VK_LEFT){ 
     p1.setLeftAccel(false); 
    } 
    else if(e.getKeyCode() == KeyEvent.VK_RIGHT){ 
     p1.setRightAccel(false); 
    } 
} 

@Override 
public void run() { 
    for(;;) { 

     p1.move(); 
     b1.move(); 
     b1.checkPlayerCollision(p1); 

     repaint(); 
     getToolkit().sync(); 
     try { 
      Thread.sleep(10); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

@Override 
public void keyTyped(KeyEvent arg0) { 
} 
} 

ボール:

import java.awt.Graphics; 
import java.awt.Color; 

public class Ball { 
int score; 
double xVel, yVel, x, y; 

public Ball() { 
    x= 350; 
    y = 250; 
    xVel= 0; 
    yVel = 1; 
} 

public void draw(Graphics g) { 
    g.setColor(Color.white); 
    g.fillOval((int)x - 10, (int)y - 10, 20, 20); 
} 

public void checkPlayerCollision(Player p1) { 
    if (x <= 50) { 
     if(x >= p1.getX() && x <= p1.getX() + 10) 
      xVel = -xVel; 
    } 
    else if (x >= 680) { 
     xVel = -xVel; 
    } 
} 

public void move() { 
    x += xVel; 
    y += yVel; 

    if (y < 10) //Bounce at top side of screen 
     yVel = -yVel; 
    if (x < 10) // Bounce at left side of screen 
     xVel = -xVel; 
} 

public int getX() { 
    return (int)x; 
} 

public int getY() { 
    return (int)y; 
} 


} 

プレーヤー:

import java.awt.Color; 
import java.awt.Graphics; 

public class Player implements Paddle { 
double x, xVel; 
boolean leftAccel, rightAccel; 
int player, y; 

public Player(int player) { 
    leftAccel = false; rightAccel = false; 
    x=260; xVel=0; 
} 

@Override 
public void draw(Graphics g) { 
    g.setColor(Color.white); 
    g.fillRect((int)x, 380, 80, 10); 

} 

@Override 
public void move() { 
    if(leftAccel){ 
     xVel -= 2; 
    } 
    else if (rightAccel) { 
     xVel += 2; 
    } 
    else if (!leftAccel && !rightAccel) { 
     xVel = 0; 
    } 
    if(xVel >= 5) { 
     xVel = 5; 
    } 
    else if (xVel <= -5) { 
     xVel = -5; 
    } 
    x += xVel; 

    if(x < 0) 
     x=0; //Collision with left wall 
    if(x > 520) 
     x = 520; //Collision with right wall 

} 

public void setLeftAccel(boolean input) { 
    leftAccel = input; 
} 

public void setRightAccel(boolean input) { 
    rightAccel = input; 
} 

@Override 
public int getX() { 
    return (int)x; 

} 
} 

パドル:

import java.awt.Graphics; 

public interface Paddle { 
public void draw(Graphics g); 
public void move(); 
public int getX(); 

} 

まだヒット検知を完全には理解していないので、ポンに使われていたものをちょっと混乱させてしまいましたが、それはうまくいかない(と私は奇妙に見えるかもしれません)。

+0

あなたの 'Ball.checkPlayerCollision()'関数でX座標だけをチェックしているようです。 Xは(通常)横軸です。最初のチェック( 'if(x <= 50)')を 'if(y <= 50)'に置き換えてみてください。編集:また、 'xVel'の代わりに' yVel'を反転させます。 – Kalkran

+0

また、楕円の半径を衝突検出に含めることもできます。あなたが質問している姿勢はボールの真ん中ですが、実際にボールの境界が何かに衝突したかどうか疑問に思っています。 –

答えて

1

時々衝突検知が頭を包むのが難しい場合があります。私が本当に助けてくれるのは、チェックしてチェックをコードごとに書く必要があることを紙に描くことです。軸を覚えておくことも良い考えです。xyを混ぜるのは本当に簡単ですが、ゲームプレイに重要な影響を与えます。 私の目はあなたのcheckPlayerCollision関数に描画されました。ちょっと見えなくなったので、いくつかのチェックを変更して、各チェック/関数が何をしているのかをコメントしました。

public void checkPlayerCollision(Player p1) { 
    if (
     // Is the ball at or below paddle height? 
     y <= 50 
     // AND Is the ball right of the left side of the paddle? 
     && x >= p1.getX() 
     // AND Is the ball left of the right side of the paddle? 
     && x <= p1.getX() + 10 
    ) { 
     // Collision with the paddle! 
     // (Ball is lower than y=50 and between left and right side of the paddle!) 
     // As we want the ball to go back up, we will be changing its velocity 
     // along the Y-axis. 
     yVel -= yVel; 
    } else if (x >= 680) { 
     // This checks whether the ball went too far to the right..? 
     xVel -= xVel; 
    } 
} 

私はあなたを与えることができる最高のヒント:一枚の紙をつかむと、単純なグリッドまたはグラフを描画し、あなたがチェックする必要が異なるものを引き出すためにそれを使用。さまざまな罫線を扱うときは、(0,0)点にラベルを付けるようにしてください。どの辺が0(通常は左上隅)で、どの辺がキャンバスのwidthheightに等しいかわかります。