Как бы я справился с боковыми столкновениями в двух измерениях? - PullRequest
0 голосов
/ 31 января 2019

Я экспериментировал с элементом html.Я пытаюсь создать 2-мерную игру с боковым скроллером, и у меня возникают проблемы со столкновениями по сторонам объектов.

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

Вот код

<html>
<canvas id="canvas" width="200" height="200" style="border-style:solid; border-width:1px"></canvas>
<script>if (typeof module === 'object') { window.module = module; module = undefined; }</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>if (window.module) module = window.module;</script>

<span id="x"></span>
<span id="y"></span>
<br>
<br>
<span id="test"></span>

<script>
    let canvas = document.getElementById("canvas");
    let ctx = canvas.getContext("2d");

    function clear() {
        ctx.fillStyle = "#FFFFFF"
        ctx.fillRect(0, 0, 200, 200);
        ctx.fillStyle = "#000000"
    }
    let keys = {};
    $(document).keydown(function (e) { //Records keystrokes
        keys[e.which] = true;
    })
    $(document).keyup(function (e) {
        delete keys[e.which];
    });

    let worldx = 10;
    const x = 90;
    let y = 0;

    let yVel = 0;

    let grounded = false;

    let objects = { //I'm representing the game world as an array of boxes
        "boxes": [
            { "width": 50, "height": 10, "x": 45, "y": 100 },
            { "width": 75, "height": 20, "x": 60, "y": 150 },
            { "width": 10, "height": 100, "x": 125, "y": 40 }
        ]
    }

    let id = window.setInterval(function () { //Lock it at ~60fps
        clear();
        $("span").empty();
        ctx.fillRect(x, y, 10, 20) //Player character
        yVel += 9.8 * 0.016 // force of gravity
        y += yVel

        for (let check = 0; check != objects.boxes.length; check++) { //Loop through objects
            if (y >= objects.boxes[check].y - 20 && y <= objects.boxes[check].y + objects.boxes[check].height && x < objects.boxes[check].x + worldx + objects.boxes[check].width && x >= objects.boxes[check].x - 10 + worldx) { //Check if there is a collision.
                yVel = 0;

                //TODO add something here that will handle side-on collisions

                if (y <= objects.boxes[check].y + objects.boxes[check].height / 2) {
                    y = objects.boxes[check].y - 20
                    grounded = true
                }
                else {
                    y = objects.boxes[check].y + objects.boxes[check].height
                }
            }
            ctx.fillRect(objects.boxes[check].x + worldx, objects.boxes[check].y, objects.boxes[check].width, objects.boxes[check].height) // draw object

        }


        $("#x").append(Math.floor(x - worldx) + ", ")
        $("#y").append(Math.floor(y))

        for (i in keys) {
            if (!keys.hasOwnProperty(i)) { continue; }
            if (i == 32 && grounded) { //Space bar
                yVel -= 5;
                grounded = false;
            }

            if (i == 65) { //A
                worldx += 3;
            }
            if (i == 68) { //D
                worldx -= 3;
            }
        }
    }, 16)
</script>

</html>

В комментарии TODO я проверяю наличие коллизий.

1 Ответ

0 голосов
/ 31 января 2019

Вот хорошее начало для вас (этот код с нуля, ваш немного сложен для понимания):

var px = 0;//player's x and y
var py = 0;
var velX = 0;
var velY = 0;
var grounded = false;
var pw = 20;//player's width
var ph = 20;//player's height

var block = function(x, y, w, h) {
    if (px + pw > x && px < x + w && py + ph > y && py + ph < y + 5 && velY > 0) {//Top
    velY = 0;
    grounded = true;
    py = y - ph;
    }
    if (px + pw > x && px < x + w && py < y + h && py > y + h - 5 && velY < 0) {//bottom
    velY = 2;//bonk
    py = y + h;
    }
    if (px + pw > x && px < x + 5 && py + ph > y && py < y + h && velX > 0) {//left
    velX = 0;
    px = x - pw;
    }
    if (px > x + w - 5 && px < x + w && py + ph > y && py < y + h && velX < 0) {//right
    velX = 0;
    px = x + w;
    }
};
...