Javascript 游戏命中检测仅适用于第一个对象

标签 javascript

我已经潜伏了很长时间,但只是在这里注册。该站点对涉及 VBA、PHP、MySQL 和 CSS 的工作和个人项目提供了极大的帮助。
我正处于学习 Javascript 的早期阶段,我通过处理实际项目学得最好,所以我正在开发一款名为 Coronaga 的以冠状病毒为主题的 Galaga 风格游戏。我跟着 w3schools 上的 HTML/JS 游戏教程学习,所以一般框架就像他们的示例游戏一样开始。我希望能够使用对象数组来制作实际冗长且具有挑战性的游戏玩法,而无需大量重复代码,但这是另一场战斗。
我有五个“坏人”显示并朝主 Angular 向下移动,但尽管对命中检测代码进行了很多摆弄,但我只能让它在最左边的“坏人”上工作。我以前让它在其他“坏人”上工作,但你必须先打左边,所以没用。
我正在为对象使用 SVG 图像,因此 CodePen 并不是一个真正有效的演示,但它可以在以下链接中使用:http://hwmp.hopto.org:100/coronaga/coronaga.html
我还将所有代码和资源都放在了 GitHub 上:
https://github.com/jonbuder/coronaga
这是游戏区域更新,包括命中检测代码:

function updateGameArea() {
    
    myGameArea.clear();
    //myScore.text = "SCORE: ";
    //myScore.update();
    
    ctx = myGameArea.context;
    ctx.font = '20px Consolas';
    ctx.fillStyle = '#FFFFFF';
    ctx.fillText(("Coronavirus: " + score +"   Humanity: " + peoplePoint), 80, 20);
    

    myGamePiece.speedX = 0;
    myGamePiece.speedY = 0;    
    if (myGameArea.key && myGameArea.key == 37) {myGamePiece.speedX = -4; }
    if (myGameArea.key && myGameArea.key == 39) {myGamePiece.speedX = 4; }
    if (myGameArea.key && myGameArea.key == 38) {myGamePiece.speedY = -4; }
    if (myGameArea.key && myGameArea.key == 40) {myGamePiece.speedY = 4; }
    myGamePiece.newPos();    
    myGamePiece.update();
    myBaddie1.newPos();
    myBaddie1.update();
    myBaddie2.newPos();
    myBaddie2.update();
    myBaddie3.newPos();
    myBaddie3.update();
    myBaddie4.newPos();
    myBaddie4.update();
    myBaddie5.newPos();
    myBaddie5.update();
    //myVirus.newPos();
   if (myGameArea.key && myGameArea.key == 32) {myVirus.launch(); }
    myVirus.reloadVirus();
    myVirus.newPos();
    myVirus.update();
    
    
    if  (score < 5) {
    if (myVirus.crashWith(myBaddie1) == 1) { myBaddie1.hit(); score++; myVirus.reloadVirus(); }
    else { myVirus.reloadVirus(); }
    if (myVirus.crashWith(myBaddie2) == 1) { myBaddie2.hit(); score++; myVirus.reloadVirus(); }
    else { myVirus.reloadVirus(); }
    if (myVirus.crashWith(myBaddie3) == 1) { myBaddie3.hit(); score++; myVirus.reloadVirus(); }
    else { myVirus.reloadVirus(); }
    if (myVirus.crashWith(myBaddie4) == 1) { myBaddie4.hit(); score++; myVirus.reloadVirus(); }
    else { myVirus.reloadVirus(); }
    if (myVirus.crashWith(myBaddie5) == 1) { myBaddie5.hit(); score++; myVirus.reloadVirus(); }
    
    }

    //else { myVirus.reloadVirus(); }
    /*else { hit = 0;}
     if (myVirus.crashWith(wave1[1]) == 1) { 
        baddieVar = "myBaddie";
        wave1[1].hit();
        score++;
    }*/
    if (myBaddie1.y >= 640) {
            peoplePoint++;
        }

       

    
    //myBaddie = new baddie(30, 70, "baddie.svg", 200, 100, "image");
    //myBaddie2 = new baddie2(30, 70, "baddie.svg", 240, 180, "image");
    
    
    
}
这是坏人对象的创作:
myBaddie1 = new baddie(30, 70, "baddie.svg", 20, 100, "image", "1");
    myBaddie2 = new baddie(30, 70, "baddie.svg", 80, 100, "image", "1");
    myBaddie3 = new baddie(30, 70, "baddie.svg", 140, 100, "image", "1");
    myBaddie4 = new baddie(30, 70, "baddie.svg", 200, 100, "image", "1");
    myBaddie5 = new baddie(30, 70, "baddie.svg", 260, 100, "image", "1");
还有坏人功能:
function baddie(width, height, color, x, y, type) {
        this.type = type;
        if (type == "image") {
            this.image = new Image();
            this.image.src = color;
        }
        this.width = width;
        this.height = height;
        this.speed = 1;
        this.angle = 0;
        this.moveAngle = 1;
        this.x = x;
        this.y = y;
        this.hit = function()
        {
            hitCode = 1;
            //this.baddienum = num;
            //var whichBaddie = "MyBaddie" + baddienum;
            this.x = -666;
            this.y = -666;          
        }


        this.update = function() {
            
            
            ctx = myGameArea.context;
            if (type == "image") {
                ctx.drawImage(this.image,
                    this.x,
                    this.y,
                    this.width, this.height);
            } else {
                ctx.fillStyle = '#000000';
                ctx.fillRect(this.x, this.y, this.width, this.height);
            }
        } 
        
    
        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);
            this.y += 0.2;
        }
        if (this.y >= 640) { peoplePoint++; }

        

        
    }
先感谢您!
这将是一个开源项目,我希望人们能从中获得乐趣,并希望参与进来,做得更好。
-乔恩
编辑以添加 myVirus.CrashWith 代码
this.crashWith = function(otherobject) {
      var tip = myAimVirusY;
      var leftedge = myAimVirusX;
      var rightedge = (myAimVirusX + 30);
      var otherbottom = otherobject.y + (otherobject.height);
      var otherleft = otherobject.x;
      var otherright = (otherobject.x + 30);
      if (hit == 0) {
      if(tip <= otherbottom) { 
            if(leftedge <= otherright) {
                
                hit = 1;
                //return hit;
                myAimVirusX = -999;
                myAimVirusY = -999;
                
            }
            else { hit = 0; delete myVirus;}
            if(rightedge >= otherleft) {
                
                hit = 1;
                //return hit;
                myAimVirusX = -999;
                myAimVirusY = -999;
                
            }
            else { hit = 0;}
                             } 
      return hit;
      hit = 0;
      tip = 0;
      //leftedge = 0;
      //rightedge = 0;
      otherbottom = 0;
      otherleft = 0;
      otherright = 0;

    }

最佳答案

OK 所以如果你不介意的话,我会尽量笼统的回答这个问题,制作这个游戏的具体代码可以试着去适应。
基本上,假设您要进行边界框碰撞(框到框),您需要检查每个的 x 和 y,以及每个的宽度和高度。
意思是,假设我有两个对象,每个对象都有 x、y、width 和 height 属性,x 和 y 在左上角,然后检查它们是否发生碰撞,创建一个函数:

function areBoxesColliding(box1, box2) {
    return (
        box1.x < box2.x + box2.width &&
        box1.x + box1.width > box2.x &&
        box1.y < box2.y + box2.height &&
        box1.y + box1.height > box2.y
    )
}
现在,每当您想检查两个对象是否正在击中(无论是子弹还是 Angular 色本身),首先要确保每个对象都具有与其实际位置相匹配的 x、y、宽度和高度属性和大小,然后在循环中(或无论何时检查),只需检查
if(areBoxesColliding(someObjectLikePlayerOrBullet, someObjectLikeAnEnemy)) doIt();
只需将此基本方法调整为您当前的代码,我不知道 myVirus.crashWith看起来像你的代码,但只要确保它基本上是这样的,以及检查你的子弹是否击中敌人的代码。
顺便说一句,您再次提到将您的 Angular 色放入数组中,但这真的很简单,只需为每个敌人创建一个类构造函数,在渲染时循环遍历该列表,并在检查碰撞时循环遍历它,以及当您想添加一个新敌人,调用.push到数组

关于Javascript 游戏命中检测仅适用于第一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62748083/

相关文章:

javascript - ASP.NET WebForms 无法使用 ajax 从 javascript 调用 webmethod

javascript - 未捕获的语法错误 : missing ) after argument list3

javascript - NodeJS 服务器无法处理多个用户

javascript - 单击另一个 div 时删除一个 div 上的类

javascript - 停止链接重定向jquery

javascript - 智能表格无法正确排序

javascript - 一个优秀的文本转语音 JavaScript 库

javascript - 使用外部更新 angular-ui-grid 中的totalItems

javascript - 如何禁用可排序容器中的垂直拖动?

javascript - 如何在 HTML 中使用外部 Javascript 文件中的函数?