Проблема с обнаружением столкновений - JS Canvas. - PullRequest
0 голосов
/ 16 сентября 2018

Я пытаюсь создать небольшую игру, похожую на Chicken Invaders , но я столкнулся с проблемой обнаружения столкновений. Когда игрок делает выстрел, если он поражает врага, этот враг должен исчезнуть. Но я не могу заставить его работать. Вот ручка:

https://codepen.io/Undefined_Variable/pen/bxxqBo

Вот код:

//Drawing & Animating: Classes & Variables Definitions
let canvas = document.body.querySelector("#gameCanvas");
let ctx = canvas.getContext("2d");
canvas.width =  window.innerWidth;
canvas.height = 0.9 * window.innerHeight;
let CW = canvas.width;
let CH = canvas.height;
let easyPlaneArr = [];
let hotShotsArr = [];
let easyPlaneCounter = 0;
class plane {
    constructor(x, y, size, color) {
        this.x = x;
        this.y = y;
        this.size = size;
        this.color = color;
    }
    drawPlane() {
        ctx.save();
        ctx.translate(this.x, this.y);
        ctx.scale(this.size, this.size)
        ctx.strokeStyle = this.color;
        ctx.fillStyle = this.color;
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(10, -30);
        ctx.lineTo(10, -100);
        ctx.lineTo(40, -100);
        ctx.lineTo(40, -120);
        ctx.lineTo(-10, -100);
        ctx.lineTo(-40, -100);
        ctx.lineTo(-40, -120);
        ctx.lineTo(10, -100);
        ctx.lineTo(-10, -100);
        ctx.lineTo(-10, -75);
        ctx.lineTo(-70, -75);
        ctx.lineTo(-60, -60);
        ctx.lineTo(-10, -60);
        ctx.lineTo(10, -60);
        ctx.lineTo(60, -60);
        ctx.lineTo(70, -75);
        ctx.lineTo(10, -75);
        ctx.lineTo(-10, -60);
        ctx.lineTo(-10, -30);
        ctx.stroke();
        ctx.fill();
        ctx.closePath();
        ctx.clearRect(-140, 0, 0, -120)
        ctx.restore();
    }
    animatePlane() {
        this.y += 5;
    }
}
class hotShot {
    constructor(x) {
        this.x = x;
        this.y = 0.95 * CH;
    }
}
let player = {
    x: CW / 2,
    y: 0.95 * CH
}
//Drawing & Animating: Functions Definitions
function drawPlayer() {
    ctx.save();
    ctx.translate(player.x, player.y);
    ctx.clearRect(-20, -40, 20, 0);
    ctx.beginPath();
    ctx.moveTo(0, -40);
    ctx.lineTo(-20, 0);
    ctx.lineTo(0, -10);
    ctx.lineTo(20, 0);
    ctx.closePath();
    ctx.stroke();
    ctx.fill()
    ctx.restore();
}
function drawHotShots() {
    for (let shot of hotShotsArr) {
        ctx.save()
        ctx.translate(shot.x, shot.y)
        ctx.fillRect(-10,0,20,20)
        ctx.restore()
        shot.y -= 10
    }
}
function detectHits() {
    for (let shot in hotShotsArr) {
        easyPlaneCounter = 0;
        for (let plane in easyPlaneArr) {
            if (shot.y > 0) {
                easyPlaneArr.splice(easyPlaneCounter, 1)
            }
            easyPlaneCounter++;
        }
    }
}
function mainLoop() {
    canvas.width = window.innerWidth;
    canvas.height = 0.9 * window.innerHeight;
    CW = canvas.width;
    CH = canvas.height;
    player.y = 0.95 * CH;

    for (let plane of easyPlaneArr) {
        plane.drawPlane();
        plane.animatePlane();
    }

    drawHotShots();
    drawPlayer();
    detectHits()
    requestAnimationFrame(mainLoop);
}
//Drawing & Animating: Program Flow
let easyPlanes = setInterval(function () {
    easyPlaneArr.push(new plane(Math.random() * ((CW - 150) - 150) + 150, -100, 1, "green"));
}, 1000)
canvas.addEventListener("mousemove", function (e) {
    player.x = e.clientX;
})
canvas.addEventListener("click", function (e) {
    hotShotsArr.push(new hotShot(player.x))
})
mainLoop();
body{
    margin: 0px auto;
    overflow:hidden;
}
#levelDiv {
    height:10vh;
    width:100vw;
    border-bottom: 1px solid black;
    background:linear-gradient(90deg, yellow 40%, red)
}
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Attack On Ship!</title>
</head>
<body>
    <div id="levelDiv"></div>
    <canvas id="gameCanvas"></canvas>
    <script src="AttackOnShip.js"></script>
</body>
</html>

Я пробовал это с обнаружением столкновений, но это не сработало:

function detectHits() {
    for (let shot in hotShotsArr) {
        easyPlaneCounter = 0;
        for (let plane in easyPlaneArr) {
            if ((shot.x - 10) > (plane.x - 70) && (shot.x + 10) < (plane.x + 70)) {
                easyPlaneArr.splice(easyPlaneCounter, 1)
            }
            easyPlaneCounter++;
        }
    }
}

1 Ответ

0 голосов
/ 16 сентября 2018

Ваша detectHits функция - хотя это не совсем правильное обнаружение столкновений - не работает, потому что она использует for..in вместо for..of петель.Попробуйте реализовать это следующим образом:

function detectHits() {
    for (let shot of hotShotsArr) {
        easyPlaneCounter = 0;
        for (let plane of easyPlaneArr) {
            if (shot.y > 0) {
                easyPlaneArr.splice(easyPlaneCounter, 1)
            }
            easyPlaneCounter++;
        }
    }
}

Несколько лучшее обнаружение столкновения может проверить, находятся ли выстрел X и Y внутри ограничительной рамки самолета, например:

const PlaneWidth = 100.0;
const PlaneHeight = 100.0;
function detectHits() {
    for (let shot of hotShotsArr) {
        easyPlaneCounter = 0;
        for (let plane of easyPlaneArr) {
            if (Math.abs(shot.x - plane.x) < 0.5 * PlaneWidth && Math.abs(shot.y - plane.y) < 0.5 * PlaneHeight) {
                easyPlaneArr.splice(easyPlaneCounter, 1)
            }
            easyPlaneCounter++;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...