【问题标题】:Sticky Collisions粘性碰撞
【发布时间】:2015-06-19 13:05:36
【问题描述】:

我正在制作一个快速的 tilemap 游戏,其中包含 tilemap 碰撞。问题是当我撞到墙上时它会粘住。我可以摆脱它,但我的目标是当你撞到墙上时,你仍然会摔倒,而不是留在墙上。我试图单独检测碰撞,但它不起作用。这是代码的碰撞部分:

//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) {


}

}

【问题讨论】:

  • 我正在尝试了解您的问题。我执行了您的代码并得到相反的结果..您的怨恨不断下降并且从不坚持。您能否详细说明/并确保我们正在查看您的代码的相同版本。
  • @Haloboy 天哪,对不起。我给你发错了代码。我会改变它(在碰撞中应该有 2 个其他语句。

标签: java collision


【解决方案1】:

为了让精灵停止粘住并继续下落,您的程序需要区分不同类型的碰撞:与“底部瓷砖”(地面)的碰撞,与精灵上方或旁边的瓷砖碰撞停止重力。目前,您的碰撞部分通过停止所有精灵移动来处理所有类型的碰撞。

一个简单的解决方案是在矩阵中将所有“底部瓷砖”设为不同的数字。例如:

{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}

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

在这两种情况下,您都可以更改碰撞部分,以仅在精灵与“底部瓷砖”碰撞时才停止下落。如果它与侧面或上方的瓷砖碰撞,您可以使精灵向相反的方向反弹。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    相关资源
    最近更新 更多