代码之家  ›  专栏  ›  技术社区  ›  Red

Java命中检测/对象之间的碰撞

  •  0
  • Red  · 技术社区  · 7 年前

    由于不熟悉编码,我看了一段关于如何制作乒乓球的视频。这进行得很顺利,因此我想尝试使用一些用于Pong的编码技术重新创建Brick Breaker。到目前为止,我有球,桨和比赛的基础。然而,球没有与桨叶正确碰撞,而是在通过时反弹。

    基本游戏代码:

    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();
    
    }
    

    我还没有完全理解点击检测,所以我只是把用于乒乓球的东西弄乱了,然而,这不起作用(我相信它可能看起来很奇怪)。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Kalkran    7 年前

    有时,碰撞检测可能很难让你全神贯注。真正帮助我的是在一张纸上画出我需要检查的东西,并在代码中逐个编写检查。记住你的轴也是个好主意,很容易混淆 x y ,但它们将对游戏性产生重要影响。

    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(通常是顶部和左侧边界),哪些等于 width height 在画布上。