碰撞检测后显示精灵

时间:2013-06-05 17:22:36

标签: javascript html5 canvas

因此,当我射击敌人时,他们会从屏幕上擦掉,这样可行。

然而,我想要发生的事情是我要发生爆炸(一个接一个4个) 基本上是敌人所在的地方。爆炸的代码本身就可以工作,但我试图将它与我的代码集成。

这是爆炸类,你可以看到我在间隔方面有些麻烦,因为我对它们没有任何经验。我认为错误或错误的逻辑存在于这个对象中。

由于某种原因,它会擦除​​其他画布层:/ 在这里试试:http://www.taffatech.com/DarkOrbit.html

function Explosion()
{
this.srcX = 0;
this.srcY = 1250;
this.drawX = 0;
this.drawY = 0;
this.width = 70;
this.height = 70;
this.currentFrame =0;
this.totalFrames =5;
this.hasHit = false;
}

Explosion.prototype.draw = function() //makes it last 10 frames using total frames
{

if(this.currentFrame <= this.totalFrames)
{

   this.currentFrame++;
  Exploder(this.drawX,this.drawY);
}

else
{
   this.hasHit = false;
   currentFrame =0;

}

}


function Exploder(srcX,srcY)
{
  whereX = this.srcX;
   whereY = this.srcY;
 intervalT = setInterval(BulletExplosionAnimate, 80);
}

var bulletExplosionStart = 0;
var whereX =0;
var whereY =0;

function BulletExplosionAnimate(intervalT)
{


var wide = 70;
var high = 70;

if (bulletExplosionStart > 308)
{
  bulletExplosionStart = 0;
 clearInterval(intervalT);
}
else
{
ctxExplosion.clearRect(0,0,canvasWidth,canvasHeight)
ctxExplosion.drawImage(spriteImage,bulletExplosionStart,1250,wide,high,whereX,whereY,wide,high);
bulletExplosionStart += 77;
}


}

我的子弹对象:

function Bullet() //space weapon uses this
{
this.srcX = 0;
this.srcY = 1240;
this.drawX = -20;
this.drawY = 0;
this.width = 11;
this.height = 4;
this.bulletSpeed = 10;
this.bulletReset = -20;

this.explosion = new Explosion();
}

Bullet.prototype.draw = function()
{

this.drawX += this.bulletSpeed;
ctxPlayer.drawImage(spriteImage,this.srcX,this.srcY,this.width,this.height,this.drawX,this.drawY,this.width,this.height);
this.checkHitEnemy();

if (this.drawX > canvasWidth)
  {
  this.recycle();

  }

}

Bullet.prototype.fire = function(startX, startY)
{

   this.drawX = startX;
   this.drawY = startY;

}

Bullet.prototype.checkHitEnemy = function()
{

    for(var i = 0; i < enemies.length; i++)
    {
       if( this.drawX >= enemies[i].drawX && this.drawX <= enemies[i].drawX + enemies[i].enemyWidth && this.drawY >= enemies[i].drawY && this.drawY <= enemies[i].drawY + enemies[i].enemyHeight)
        {

        this.explosion.drawX = enemies[i].drawX - (this.explosion.width/2);
        this.explosion.drawY = enemies[i].drawY;

        this.explosion.hasHit = true;
        this.recycle(); //bullet resets after hit enemy
        enemies[i].recycleEnemy(); //change this soon to have if loop if health is down 
        }


    }

}


Bullet.prototype.recycle = function()
{

    this.drawX = this.bulletReset;

}

在我的玩家对象中,我有一个功能,可以检查它是否击中了敌人,它有效:

Player.prototype.drawAllBullets = function()
{

  for(var i = 0; i < this.bullets.length; i++)
   {
     if(this.bullets[i].drawX >= 0)
     {

       this.bullets[i].draw();

     }

     if(this.bullets[i].explosion.hasHit)
     {
     this.bullets[i].explosion.draw();
     }

   }
}

目前当我射击敌人他们消失但没有发生爆炸时,我知道我的间隔不是很好的编码,所以我需要一些帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

在画布中播放spritesheet

使用requestAnimationFrame进行动画变为最佳做法。它做了一些不错的事件分组和性能增强。这是requestAnimationFrame上的一篇好文章:http://creativejs.com/resources/requestanimationframe/

这是你可以使用requestAnimationFrame来播放spritesheet的方法:

在这种情况下,它是一个4x4 spritesheet,将播放超过1秒:

var fps = 16;
function explode() {

    // are we done? ... if so, we're outta here
    if(spriteIndex>15){return;}

    // It's good practice to use requestAnimation frame
    // We wrap it in setTimeout because we want timed frames
    setTimeout(function() {

        // queue up the next frame
        requestAnimFrame(explode);

        // Draw the current frame
        var x=spriteIndex%(cols-1)*width;
        var y=parseInt(spriteIndex/(rows-1))*height;
        ctx.clearRect(0,0,canvas.width,canvas.height);
        ctx.drawImage(sheet,x,y,width,height,0,0,width,height);

        // increment the sprite counter
        spriteIndex++;
    }, 1000 / fps);

}

这是代码和小提琴:http://jsfiddle.net/m1erickson/nSGyx/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
    $(function(){

        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");

        // This is Paul Irish's great cross browser shim for requestAnimationFrame
        window.requestAnimFrame = (function(callback) {
          return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
          function(callback) {
            window.setTimeout(callback, 1000 / 60);
          };
        })();

        // define the spritesheet
        var spriteIndex=0;
        var width=64;
        var height=64;
        var rows=4;
        var cols=4;

        // load the sheet image
        var sheet=document.createElement("img");
        sheet.onload=function(){
            canvas.width=width;
            canvas.height=height;
            // call the animation
            explode();
        }
        sheet.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/explodeSprite.png";


        var fps = 16;
        function explode() {

            // are we done? ... if so, we're outta here
            if(spriteIndex>15){return;}

            // It's good practice to use requestAnimation frame
            // We wrap it in setTimeout because we want timed frames
            setTimeout(function() {

                // queue up the next frame
                requestAnimFrame(explode);

                // Draw the current frame
                var x=spriteIndex%(cols-1)*width;
                var y=parseInt(spriteIndex/(rows-1))*height;
                ctx.clearRect(0,0,canvas.width,canvas.height);
                ctx.drawImage(sheet,x,y,width,height,0,0,width,height);

                // increment the sprite counter
                spriteIndex++;
            }, 1000 / fps);

        }

        $("#explode").click(function(){ spriteIndex=0; explode(); });

    }); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=64 height=64></canvas><br>
    <button id="explode">Explode</button>
</body>
</html>

。 。

[已编辑以显示动画如何适合您的代码的详细信息]

这是对爆炸功能的重新编码。

在函数之外声明爆炸相关变量:

var bulletExplosionStart;
var whereX =0;
var whereY =0;
var wide = 70;
var high = 70;

接下来,在Exploder()中,设置爆炸发生的位置并将精灵索引(bulletExplosionStart)重置为0

可能的错误:检查您的Exploder功能:您提供srcX,srcY但是然后执行whereX = this.srcX,其中Y = this.srcY。我假设您打算使用srcX,srcY作为Exploder()的参数而不是this.srcX,this.srcY。

function Exploder(srcX,srcY)
{
    whereX = srcX;
    whereY = srcY;
    bulletExplosionStart=0;
    BulletExplosionAnimate();
}

这是重新编码的bulletExplosionAnimate函数,可以播放spritesheet的4帧。

4帧后,此动画会自动停止。

var fps = 2;
function bulletExplosionAnimate() {

    // are we done? ... if so, we're outta here
    if(bulletExplosionStart>308){return;}

    // It's good practice to use requestAnimation frame
    // We wrap it in setTimeout because we want timed frames
    setTimeout(function() {

        // queue up the next frame
        requestAnimFrame(bulletExplosionAnimate);

        // Draw the current frame
        ctxExplosion.clearRect(0,0,canvasWidth,canvasHeight)
        ctxExplosion.drawImage(spriteImage,
            bulletExplosionStart,1250,wide,high,
            whereX,whereY,wide,high);

        // increment the sprite position
        bulletExplosionStart += 77;
    }, 1000 / fps);

}