粘性碰撞

时间:2015-06-19 01:08:40

标签: java collision

我正在使用瓷砖地图碰撞制作快速瓷砖地图游戏。问题是,当我碰到一堵墙时,它会粘住。我可以摆脱它,但我的目标是,当你撞到墙壁时,你仍然会摔倒,而不是留在墙上。我试图分别检测碰撞,但它不起作用。这是代码的碰撞部分:

//31 is the amount of blocked tiles.
for(int counter = 0; counter < 31; counter++) {

        if(spriteX + 40 + velX >= collisionX[counter] && collisionX[counter] + 100 >= spriteX + velX &&spriteY + 40 + velY >= collisionY[counter] && collisionY[counter] + 100 >= spriteY + velY) {

            velX = 0;
            velY = 0;

            collisions = counter;

        } else {

            if(counter == collisions && jumping == false) {

                fall();

            }

        }

我知道阵列很笨重,我正在解决这个问题。 这是全班同学:

package Main;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

public class Panel extends JPanel implements Runnable, KeyListener {

// dimensions

public static final int width = 800;
public static final int height = 800;
public static final int scale = 1;

// main loop

private Thread thread;
private boolean running = false;
private int FPS = 60;
private int targetTime = 1000 / FPS;

// drawing

private Graphics2D g;
private BufferedImage image;

int x;
int y;

boolean makeCollision = false;

// sprite

int spriteX = 210;
int spriteY = 200;
int velX = 0;
int velY = 10;

public boolean notOnGround = true;

int counter;
int collisionsCounter;
int jumps = 0;

public int row;
public int column;

public boolean collision;
public boolean jumping = false;

public String side = null;

// tilemap

int[][] map = {

        {1, 1, 1, 1, 1, 1, 1, 1},
        {1, 0, 0, 1, 0, 0, 1, 1},
        {1, 0, 0, 0, 0, 1, 1, 1},
        {1, 0, 0, 0, 1, 1, 0, 1},
        {1, 0, 0, 1, 1, 0, 0, 1},
        {1, 0, 0, 1, 0, 0, 0, 1},
        {1, 0, 0, 0, 0, 0, 0, 1},
        {1, 1, 1, 1, 1, 1, 1, 1}

};

int[] collisionX = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
int[] collisionY = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
int[] jump = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
int collisions;

public Panel() {

    setPreferredSize(new Dimension(width * scale, height * scale));
    setFocusable(true);
    requestFocus();

}

public void addNotify() {
    super.addNotify();

    if(thread == null) {

        running = true;
        addKeyListener(this);
        thread = new Thread(this);
        thread.start();

    }

}

public void init() {

    image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    g = (Graphics2D) image.getGraphics();

}

public void update() {

    if(spriteY < jump[0]) {

        System.out.println(jump[0]);

        jumping = false;

        fall();

    }

}

public void draw() {

    g.clearRect(0, 0, WIDTH, HEIGHT);

    x = 0;
    y = 0;

    for(column = 0; column <= 7; column++) {

        x = 0;

        for(row = 0; row <= 7; row++) {

            changeColor(row, column, g);

            g.fillRect(x, y, 100, 100);

            x = x + 100;

        }

        y = y + 100;

    }

    g.setColor(Color.YELLOW);
    g.fillRect(spriteX, spriteY, 40, 40);

    spriteX += velX;
    spriteY += velY;

    for(int counter = 0; counter < 31; counter++) {

        if(spriteX + 40 + velX >= collisionX[counter] && collisionX[counter] + 100 >= spriteX + velX &&spriteY + 40 + velY >= collisionY[counter] && collisionY[counter] + 100 >= spriteY + velY) {

            velX = 0;
            velY = 0;

            collisions = counter;

        } else {

            if(counter == collisions && jumping == false) {

                fall();

            }

        }

    }

}

public void changeColor(int rowGive, int columnGive, Graphics g) {

    if(map[rowGive][columnGive] == 1) {

        g.setColor(Color.BLACK);

        if(counter < 30) {

            collisionX[counter] = x;
            collisionY[counter] = y;

        }

        counter++;

    } else {

        g.setColor(Color.WHITE);

    }

}

public void fall() {

    velY = 5;

}

public void drawToScreen() {

    Graphics g2 = getGraphics();
    g2.drawImage(image, 0, 0, width * scale, height * scale, null);
    g2.dispose();

}

public void run() {

    init();

    long wait;
    long elapsed;
    long start;

    while(running) {

        start = System.nanoTime();
        update();
        draw();
        drawToScreen();

        elapsed = System.nanoTime() - start;

        wait = targetTime - elapsed / 1000000;

        if(wait < 0) wait = 5;

        try {

            thread.sleep(wait);

        } catch(Exception e) {

            e.printStackTrace();

        }

    }

}

public void keyPressed(KeyEvent e) {

    int code = e.getKeyCode();

    if(code == KeyEvent.VK_RIGHT) {

        velX = 5;

    }
    if(code == KeyEvent.VK_LEFT) {
        velX = -5;

    }
    if(code == KeyEvent.VK_SPACE && jumping == false) {

        jumping = true;

        velY = -5;
        jump[0] = spriteY - 100;

    }

}
public void keyReleased(KeyEvent e) {



}
public void keyTyped(KeyEvent e) {


}

}

1 个答案:

答案 0 :(得分:0)

为了让精灵停止坚持并继续摔倒,你的程序需要区分不同类型的碰撞:与底部瓷砖碰撞,地面,与上方或旁边的瓷砖相撞没有重力的精灵。目前,您的碰撞部分通过停止所有精灵运动来处理所有类型的碰撞。

一个简单的解决方案就是制作所有的底部瓷砖&#39;矩阵中的数字不同。例如:

{1, 2, 2, 1, 1, 1, 1, 1},
{1, 0, 0, 2, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 2, 1},
{1, 0, 0, 0, 1, 2, 0, 1},
{1, 0, 0, 1, 2, 0, 0, 1},
{1, 0, 0, 2, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1}

复杂的解决方案是让您的程序区分“底部磁贴”。通过检查它上面的瓷砖是否是白色瓷砖(非碰撞瓷砖)。如果是这样,那么这个瓷砖可以从上面被击中并且可以阻止精灵掉落。

在这两种情况下,你都会改变你的碰撞部分,只有当它与底部瓷砖碰撞时才能阻止精灵掉落。如果它与侧面或上方的瓷砖碰撞,您可以使精灵以相反的方向反弹。