【问题标题】:JavaScript does not detect collisions (game)JavaScript 不检测碰撞(游戏)
【发布时间】:2022-01-02 18:02:53
【问题描述】:

我正在关注来自德国 YouTuber 的 JavaScript 教程。我有和他一样的代码,但由于某种原因,程序没有打印“碰撞!!!”进入控制台。我和他有相同的代码,但我的代码不起作用。他的代码有效。我不知道如何解决这个问题。请帮忙!

如果有人想比较我和他的代码,这里是视频的 URL(它已经在正确的时间戳上):https://youtu.be/eWLDAAMsD-c?t=5041


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Space Fight</title>
    <style>
        canvas {
            background-color:rgba(0, 0, 0, 0.8);
        }
    </style>

    <script>
        let KEY_SPACE = false; // 32
        let KEY_UP = false; // 38
        let KEY_DOWN = false; // 40
        let canvas;
        let ctx;
        let backgroundImage = new Image();
        let divisor = 4


        let rocket = {
            x: 100,
            y: 200,
            width: 640 / divisor,
            height: 366 / divisor,
            src: "assets/img/rocket.png"
        };
        let ufos = []

        document.onkeydown = function(e) {
            if (e.keyCode == 32) { // SPACE KEY WAS PRESSED
                KEY_SPACE = true;
            }
            if (e.keyCode == 38) { // UP-ARROW KEY WAS PRESSED
                KEY_UP = true;
            }
            if (e.keyCode == 40) { // DOWN-ARROW KEY WAS PRESSED
                KEY_DOWN = true;
            }
        }

        document.onkeyup = function(e) {
            if (e.keyCode == 32) { // SPACE KEY WAS RELEASED
                KEY_SPACE = false;
            }
            if (e.keyCode == 38) { // UP-ARROW KEY WAS RELEASED
                KEY_UP = false;
            }
            if (e.keyCode == 40) { // DOWN-ARROW KEY WAS RELEASED
                KEY_DOWN = false;
            }
        }

        function startGame() {
            canvas = document.getElementById("canvas");
            ctx = canvas.getContext('2d');
            loadImages();
            setInterval(update, 1000 / 60);
            setInterval(createUfos, 5000);
            setInterval(checkForCollision, 1000 / 60);
            draw();
            //calculate
        }

        function checkForCollision() {
            ufos.forEach(function(ufo) {
                if (
                    rocket.x + rocket.width > ufo.x && 
                    rocket.y + rocket.height > ufo.y && 
                    rocket.x < ufo.x && 
                    rocket.y < ufo.y
                    ) {
                    console.log('Collision!!!');
                }
            });
        }

        function createUfos() {
            let ufo = {
            x: 800,
            y: 200,
            width: 640 / divisor,
            height: 324 / divisor,
            src: "assets/img/ufo.png",
            img: new Image()
        };
            ufo.img.src = ufo.src;
            ufos.push(ufo);
        }

        function update() {
            if (KEY_UP) {
                rocket.y -= 2;
            }
            if (KEY_DOWN) {
                rocket.y += 2;
            }

            ufos.forEach(function(ufo){
                ufo.x -= 4
            });
        }

        function loadImages() {
            backgroundImage.src = 'assets/img/background.jpg';
            rocket.img = new Image();
            rocket.img.src = rocket.src;


        }

        function draw() {
            ctx.drawImage(backgroundImage, 0, 0);
            ctx.drawImage(rocket.img, rocket.x, rocket.y, rocket.width, rocket.height);
            ufos.forEach(function(ufo) {
                ctx.drawImage(ufo.img, ufo.x, ufo.y, ufo.width, ufo.height);
            })

            requestAnimationFrame(draw);
        }
    </script>
</head>
<body onload="startGame()">
    <canvas id="canvas" width="720" height="480"></canvas>
</body>
</html>

这是文件结构:https://i.stack.imgur.com/iTl9E.png

【问题讨论】:

  • 我试过了,它有效吗? jsfiddle.net/gqdzn3mr
  • 有时有效;有时它不起作用
  • 火箭下部接触UFO但不接触火箭上部时有效
  • 看起来你应该在碰撞函数中的 if 语句中添加高度,将 rocket.y &lt; ufo.y 更改为 rocket.y &lt; ufo.y + ufo.height,就像作者在他的文章中所做的那样

标签: javascript html json


【解决方案1】:

您的碰撞检查条件不正确。更新如下。

(rocket.x + rocket.width > ufo.x && 
rocket.x < ufo.x) ||
(rocket.y + rocket.height > ufo.y && 
rocket.y < ufo.y)

你的代码是这样的。

rocket.x + rocket.width > ufo.x && 
rocket.y + rocket.height > ufo.y && 
rocket.x < ufo.x &&
rocket.y < ufo.y

【讨论】:

    【解决方案2】:

    你可以像这样检查碰撞:

    function dotInBox (dotX, dotY, box) {
        const {x, y, w, h} = box
        return x <= dotX && dotX <= x + w && y <= dotY && dotY <= y + h
    }
    
    if (dotInBox(b.x, b.y, a) ||
        dotInBox(b.x + b.w, b.y, a) ||
        dotInBox(b.x, b.y + b.h, a) ||
        dotInBox(b.x + b.w, b.y + b.h, a)) {
        // Collision
    }
    

    函数dotInBox 检查您的正方形中是否有任何由坐标和尺寸给出的点。通过检查其他正方形的每个点,我们可以说发生了碰撞。

    【讨论】:

      猜你喜欢
      • 2016-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-17
      • 1970-01-01
      相关资源
      最近更新 更多