当我碰到障碍物时如何添加一个事件使其重新开始

3
我目前正在开发一个小游戏,并尝试在撞到障碍物时实现“游戏结束”功能。但每次添加完整的代码以实现该功能后,它都会破坏一切。如果有人能帮助我,我会非常感激。我不确定问题出在哪里。
这是全部代码(仅 JS 部分):

var myGamePiece;
var myObstacle;

function startGame() {
    myGamePiece = new component(30, 30, "red", 225, 225);
    myObstacle = new component(40, 40, "green", 300, 120);
    myGameArea.start();
}

var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 1000;
        this.canvas.height = 890;
        this.context = this.canvas.getContext("2d");
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.frameNo = 0;
        this.interval = setInterval(updateGameArea, 20);
        window.addEventListener('keydown', function (e) {
            e.preventDefault();
            myGameArea.keys = (myGameArea.keys || []);
            myGameArea.keys[e.keyCode] = (e.type == "keydown");
        })
        window.addEventListener('keyup', function (e) {
            myGameArea.keys[e.keyCode] = (e.type == "keydown");
        })
    },
    stop : function() {
        clearInterval(this.interval);
    },    
    clear : function() {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    }
}

function component(width, height, color, x, y, type) {

    this.type = type;
    this.width = width;
    this.height = height;
    this.speed = 0;
    this.angle = 0;
    this.moveAngle = 0;
    this.x = x;
    this.y = y;    
    this.update = function() {
        ctx = myGameArea.context;
        ctx.save();
        ctx.translate(this.x, this.y);
        ctx.rotate(this.angle);
        ctx.fillStyle = color;
        ctx.fillRect(this.width / -2, this.height / -2, this.width, this.height);
        ctx.restore();    
    }
    this.newPos = function() {
        this.angle += this.moveAngle * Math.PI / 180;
        this.x += this.speed * Math.sin(this.angle);
        this.y -= this.speed * Math.cos(this.angle);
    }

}

function updateGameArea() {

    myGameArea.clear();
    myGamePiece.moveAngle = 0;
    myGamePiece.speed = 0;
    myObstacle.update();
    if (myGameArea.keys && myGameArea.keys[37]) {myGamePiece.moveAngle = -2; }
    if (myGameArea.keys && myGameArea.keys[39]) {myGamePiece.moveAngle = 2; }
    if (myGameArea.keys && myGameArea.keys[38]) {myGamePiece.speed= 2; }
    if (myGameArea.keys && myGameArea.keys[40]) {myGamePiece.speed= -2; }
    myGamePiece.newPos();
    myGamePiece.update();
}

startGame();


1
你正在寻找多边形与多边形的碰撞检测。这是我在谷歌上找到的一篇文章:https://www.gamedevelopment.blog/collision-detection-circles-rectangles-and-polygons/ - user5734311
1
看起来像是w3schools.com的游戏之一。如果您继续跟随他们的教程,您会找到有关命中检测的信息。请尝试从此处实现一个函数 https://www.w3schools.com/graphics/game_obstacles.asp - cb64
我正在使用w3schools。我按照每个步骤进行操作,但每次添加命中检测部分时,整个画布都会消失。 - Frantic Bomb
2个回答

0
你所要求的是2D碰撞检测。如果你要使用正方形,那么它就相当简单。基本上,可以通过以下方式比较两个正方形:
if (rect1.x < rect2.x + rect2.width &&
   rect1.x + rect1.width > rect2.x &&
   rect1.y < rect2.y + rect2.height &&
   rect1.y + rect1.height > rect2.y) {
    // collision detected!
}

摘自:https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection

此代码仅适用于没有旋转的正方形。对于旋转,您需要根据旋转角度使用三角函数sin/cos/tan。

有多种解决2D碰撞的方法。其中一种方法是基于我个人在地理围栏中使用的方法,即将Object 1的每个点与Object 2的每条边进行比较。如果一个点在某个方向上(例如,向右)有奇数条边,则表示该点在对象内部。您应该为每个点迭代此过程,并且如果任何点返回奇数,则return true。然后,您应该使用Object 2点重复此过程。

这被称为点在多边形中的方法:

https://en.wikipedia.org/wiki/Point_in_polygon

这适用于多边形,但一旦使用曲线,就会变得更加困难。但是,通常游戏使用“命中框”,因为它们的简单性。

编辑:请注意,如果命中框大小相同,则此点在多边形内的方法有效,但如果您可以将两个矩形重叠在一起,则必须将Object1的每条边与Object2中的边的交点进行比较。


0
尝试修复这个问题: 你在第14行和第17行缺少了分号 让我们看看...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接