Хитбоксы в игре Java без прямоугольников - PullRequest
0 голосов
/ 30 марта 2020

Я новичок в создании игр на Java, но я сделал некоторые игры, используя метод paintComponent, однако я чувствовал, что что-то упустил. Поэтому я хотел увидеть различные варианты рендеринга графики и т. Д. c. Поэтому я погуглил и застрял на рисовании отдельных пикселей. Я думал, что это было действительно круто. Однако у меня есть некоторые проблемы с этим.

Основная проблема заключается в том, что система столкновений работает не очень хорошо. В моем случае я сейчас использую изображение блока в качестве игрока. Этот блок иногда перекрывается изображением уровня.

Вот изображение проблемы:

enter image description here

Как вы видите изображение уровня перекрывает изображение игрока в углу. Я читал некоторые посты об исправлении, они упоминали, что я должен установить положение блока прямо перед столкновением. Однако это сделало еще хуже, поскольку игрок просто телепортировался туда-сюда.

Я думал, что создание GIF этого вопроса не повредит, поэтому здесь вы go!

enter image description here

Кажется мне что углы установлены неправильно?

Вот код:

Метод Render в GameManager (обрабатывает код столкновения) :

    @Override
public void render(GameContainer gc, Renderer renderer) {

    for(GameObject obj : list) {    //Draw objects
        obj.setGoRight(true);
        obj.setGoLeft(true);
        obj.setGoUp(true);
        obj.setGoDown(true);
        obj.render(gc, renderer);


        //Collision     

        for(int y = 2; y < obj.getHeight() - 2; y++) {


//TODO CORNERS DON'T HAVE COLLISION, FIX 

            if(collision[(obj.getxCord()) + ((obj.getyCord() + y) * gc.getWidth())] ) { //GLITCHES INTO BLOCK

                    obj.setxCord(obj.getxCord());
                    obj.setGoLeft(false);       //MOVEMENT LEFT



                }


            if(collision[obj.getxCord() + obj.getWidth() + ((obj.getyCord() + y) * gc.getWidth())] ) {
                //MOVEMENT RIGHT
                obj.setxCord(obj.getxCord());
                obj.setGoRight(false);

            }

        }




        for(int x = 3; x < obj.getWidth() - 3; x++) {   //SKJUTER SÅ DE INTE SKANNAR KANTERNA, DVS SÅ ATT X OCH Y AXELN HAR SAMMA HITBOX

        if(collision[(obj.getxCord() + x) + ((obj.getyCord() + obj.getHeight()) * gc.getWidth())] ) {

            //MOVEMENT DOWN
            obj.setyCord(obj.getyCord());
            obj.setGoDown(false);

        }
        if(collision[(obj.getxCord() + x) + (obj.getyCord()  * gc.getWidth())] ) {

            //MOVEMENT UP
            obj.setGoUp(false);
            obj.setyCord(obj.getyCord());

        }

      }


    }






    renderer.drawImage(backgroundImg, 0, 0);
}

Класс игрока

public class Player extends GameObject{
private Image image;
private int speed = 2;
String imagePath = "/picture.png";


public Player() {
    this.xCord = 160;
    this.yCord = 120;
    image = new Image(imagePath);
    tag = "player";
    this.width = image.getWidth();
    this.height = image.getHeight();

    this.hitBox = new Rectangle(this.xCord,this.yCord,this.width,this.height);


}
@Override
public void update(GameContainer gc, float updatetime) {

    if(goLeft) {

        if(gc.getInput().isKeyPressed(KeyEvent.VK_A)) {

            this.xCord -= speed;
        }

    }
    if(goRight ) {

        if(gc.getInput().isKeyPressed(KeyEvent.VK_D)) {

            xCord += speed;

        }

    }
    if(goUp) {

         if(gc.getInput().isKeyPressed(KeyEvent.VK_W)) {

                yCord -= speed;
            }

    }
    if(goDown) {

         if(gc.getInput().isKeyPressed(KeyEvent.VK_S)) {

                yCord += speed;
                System.out.println(yCord);
            }

    }




     if(gc.getInput().isKeyPressed(KeyEvent.VK_K)) {

        this.setDead(true);
    }
     this.setHitBox(hitBox);
}

@Override
public void render(GameContainer gc, Renderer renderer) {
    renderer.drawImage(image,xCord,yCord);  

}
public Image getImage() {
    return image;
} 

}

Метод загрузки уровней в GameManager :

    public void loadLevel(String levelPath) {

    backgroundImg= new Image(levelPath);

    levelWidth = backgroundImg.getWidth();
    levelHeight = backgroundImg.getHeight();

    collision = new boolean[levelHeight * levelWidth];
    for(int y = 0; y < levelHeight; y++) {

        for(int x = 0; x < levelWidth; x++) {

            if(backgroundImg.getPixels()[x + (y * levelWidth)] == new Color(0,0,0).getRGB()) {  

                collision[x + (y * levelWidth)] = true;
                if(collision[x+(y * levelWidth)]) {

                    backgroundImg.getPixels()[x + (y * levelWidth)] = 56;
                }

            }
            else collision[x + (y * levelWidth)] = false;
        }
    }

}






}

Так что я пытаюсь это сделать?

Когда игрок сталкивается с любым из пикселей, которые я установил как сталкивающиеся пиксели в методе loadLevel (), я хочу, чтобы он прекратил движение. Простая идея, но она оказалась сложной.

У меня есть два цикла for в части столкновения render () для изменения хитбокса.

Если я не использую эти петли, я не могу двигаться вверх или вниз, когда я ударяюсь о стену с левой или правой стороны. И если я попаду на крышу, я не смогу двигаться влево и вправо и т.д. c.

Следовательно, циклы for меняются в зависимости от места попадания игрока. Это заставляет угол игрока казаться, что это не существует. Если я нарисую изображение прямо у меня в голове, оно должно выглядеть так:

enter image description here

Любые советы относительно того, как я могу изменить код для решения проблемы, приветствуются ! Я смотрел много постов, касающихся этого ранее, но они использовали прямоугольники, которые на самом деле не совпадают с проверкой значений x и y плеера с отдельными пикселями?

Люди могут также спросить, почему я использую систему пикселей. Какой честный вопрос. Мой единственный ответ - я хочу нарисовать уровень в краске, а затем импортировать это изображение вместо того, чтобы кодировать, где вещи должны быть размещены? Я только что обнаружил, что это может быть более разумным решением! Поэтому я делаю карту пикселей, затем создаю отдельное изображение, куда я помещаю черные пиксели, где блоки столкновений и т. Д. c. Я надеюсь, что вы поняли мою точку зрения!

Однако я думаю, что эта система немного сложна, но я не нашел хорошего способа сделать это.

Заранее спасибо!

...