JavaScript小游戏实例:简单的键盘练习

键盘是一种常用的输入设备,灵活熟练地使用键盘进行输入是计算机用户需掌握的一门基本功。下面我们编写一个简单的键盘练习游戏

1.刺破气泡交互式小动画

在编写简单的键盘练习游戏之前,先设计一个简单地刺破气泡交互式小动画。

在面板底部逐个上升一些气泡,用鼠标在某个气泡上单击,该气泡被刺破,刺破后的小气泡逐渐消散在面板中。交互式效果如图1所示。

图1  刺破气泡交互式动画

一个气泡可分为两个状态:(1)气泡从面板底部上升;(2)气泡被鼠标单击刺破成小气泡或气泡上升越过了面板顶部消散了。

为此抽象出两个对象类:Bubbles和miniBubbles。其中,Bubbles用于表示一个未被刺破的气泡,miniBubbles用于表示一个气泡刺破后得到的逐渐消散的小气泡。

Bubbles对象类定义6个属性:表示气泡圆心的坐标(x,y)、气泡的半径radius、上升时垂直方向的位移改变量ySpeed、气泡上升加速度gravity和气泡颜色color。

坐标属性值y的初始值取画布的高度,表示气泡从游戏面板底部开始上升,其余各属性的初始值采用随机数确定或直接指定。具体定义如下:

function Bubbles()

{

this.x = rand(30,canvas.width - 30);

this.y = canvas.height;

this.radius = rand(15, 30);

this.color ='rgba(255, 255, 255, 0.75)';

this.ySpeed= Math.random() * 2;

this.gravity = 0.01;

}

Bubbles对象类定义2个方法:绘制气泡的方法draw()、气泡上升时坐标改变方法update()。

miniBubbles对象类定义8个属性:表示小气泡圆心的坐标(x,y)、小气泡半径radius、散开时水平和垂直方向的位移改变量xSpeed和ySpeed、小气泡的填充color、小气泡的减速度gravity、小气泡的存活时间timeToLive。具体定义如下:

function miniBubbles(x,y,radius)

{

this.x = x;

this.y = y;

this.radius = radius;

this.color = 'rgba(255, 255, 255, 0.5)';

this.xSpeed=(Math.random() - 0.5) * 0.6;

this.ySpeed=(Math.random() - 1) * 0.5;

this.gravity = -0.03;

this.timeToLive = 100;

}

miniBubbles对象类定义2个方法:绘制小气泡的方法draw()、小气泡位置改变改变方法update()。小气泡每次改变位置后,timeToLive减1,当timeToLive值等于0时,从小气泡数组中删除该小气泡,表示该小气泡已消亡。

定义两个数组var bubbles = [];和 var minibubbles = [];分别存储未刺破的大气泡对象和大气泡刺破后散开的小气泡。

为画布添加鼠标按下事件监控canvas.addEventListener('mousedown', function(){ });,在事件处理函数中查找鼠标单击的气泡,然后将该气泡从bubbles数组中删除,向minibubbles数组中添加若干个散开的小气泡。

完整的HTML代码如下。

<html>
<head>
<title>刺破气泡小游戏</title>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script>
   var canvas = document.getElementById('myCanvas');
   var ctx = canvas.getContext('2d');
   canvas.height = innerHeight;
   canvas.width = innerWidth;
   function rand(min, max)
   {
      return Math.floor(Math.random() * (max - min + 1) + min);
   }
   function Bubbles()
   {
      this.x = rand(30,canvas.width - 30);
      this.y = canvas.height;
      this.radius = rand(15, 30);
      this.color ='rgba(255, 255, 255, 0.75)';
      this.ySpeed= Math.random() * 2;
      this.gravity = 0.01;
   }
   Bubbles.prototype.draw = function ()
   {
      ctx.beginPath();
      ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
      ctx.fillStyle = this.color;
      ctx.fill();
      ctx.closePath();
   }
   Bubbles.prototype.update = function ()
   {
      this.y -= this.ySpeed;
      if (this.y - this.radius > 0)
         this.ySpeed += this.gravity;
      this.draw();
   }
   function miniBubbles(x,y,radius)
   {
      this.x = x;
      this.y = y;
      this.radius = radius;
      this.color = 'rgba(255, 255, 255, 0.5)';
      this.xSpeed=(Math.random() - 0.5) * 0.6;
      this.ySpeed=(Math.random() - 1) * 0.5;
      this.gravity = -0.03;
      this.timeToLive = 100;
   }
   miniBubbles.prototype.draw = function () {
      ctx.beginPath();
      ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
      ctx.fillStyle = this.color;
      ctx.fill();
      ctx.closePath();
   }
   miniBubbles.prototype.update = function () {
      if (this.y - this.radius > 0)
         this.ySpeed += this.gravity;
      this.x += this.xSpeed;
      this.y += this.ySpeed;
      this.timeToLive --;
      this.draw();
   }
   var backgroundGradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
   backgroundGradient.addColorStop(0, '#009cff')
   backgroundGradient.addColorStop(1, '#007bff')
   var bubbles = [];
   var minibubbles = [];
   var timer = 0;
   var spawnRate = 70;
   function animate()
   {
      requestAnimationFrame(animate);
      ctx.fillStyle = backgroundGradient;
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      for (var i=bubbles.length-1;i>=0;i--)
      {
          bubbles[i].update();
       if (bubbles[i].y<0)
          {
             bubbles.splice(i, 1);
          }
      }
      for (var i=minibubbles.length-1;i>=0;i--)
      {
         minibubbles[i].update();
     if (minibubbles[i].timeToLive == 0)
         {
            minibubbles.splice(i, 1);
         }
      }
      timer++;
      if (timer==spawnRate)
      {
     bubbles.push(new Bubbles());
         timer=0;
     spawnRate = rand(50, 100);
      }
    }
    canvas.addEventListener('mousedown', function(){
        var x = event.pageX - canvas.getBoundingClientRect().left;
        var y = event.pageY - canvas.getBoundingClientRect().top;
        // 查找被单击的气泡
        for (var i=bubbles.length-1; i>=0; i--)
        {
            var bubble = bubbles[i];
            var dist = Math.sqrt(Math.pow(bubble.x-x,2)+ Math.pow(bubble.y- y,2));
            if (dist<= bubble.radius)
            {
                 var mx = bubble.x;
         var my = bubble.y;
                 var mr = rand(2,5);
         bubbles.splice(i, 1)
         for (var k = 0; k < bubble.radius/mr; k++)
                 {
                    minibubbles.push(new miniBubbles(mx,my, mr));
         }
                 return;
            }
        }
    });
   animate();
</script>
</body>
</html>

2.简单的键盘练习小游戏

有了上面的基础,我们可以编写一个简单的键盘练习小游戏,大小写字母出现在游戏面板中,按键盘某个字母键后,对应的字母消失。游戏过程如图2所示。

图2 键盘练习小游戏

在Bubbles对象类中增加一个属性letter,表示气泡中显示的字母。

为Windows添加键盘按下keypress事件监听,处理键盘按键。

完整的HTML代码如下。

<html>
<head>
<title>简单键盘练习</title>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script>
   var canvas = document.getElementById('myCanvas');
   var ctx = canvas.getContext('2d');
   canvas.height = innerHeight;
   canvas.width = innerWidth;
   var str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
   var cnt1=0;
   var cnt2=0;
   var cnt3=0;
   function rand(min, max)
   {
      return Math.floor(Math.random() * (max - min + 1) + min);
   }
   function Bubbles()
   {
      this.x = rand(30,canvas.width - 30);
      this.y = canvas.height;
      this.radius = 20;
      this.color ='rgba(255, 255, 255, 0.75)';
      this.ySpeed= Math.random() * 2;
      this.gravity = 0.01;
      this.letter=str.charAt(rand(0,str.length-1));
   }
   Bubbles.prototype.draw = function ()
   {
      ctx.beginPath();
      ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
      ctx.fillStyle = this.color;
      ctx.fill();
      ctx.closePath();
      ctx.font = "Bold 20px Georgia";
      ctx.fillStyle = "Black";
      ctx.textAlign = 'center';
      ctx.baseline = 'middle';
      ctx.fillText(this.letter,this.x, this.y);
   }
   Bubbles.prototype.update = function ()
   {
      this.y -= this.ySpeed;
      if (this.y - this.radius > 0)
         this.ySpeed += this.gravity;
      this.draw();
   }
   function miniBubbles(x,y,radius)
   {
      this.x = x;
      this.y = y;
      this.radius = radius;
      this.color = 'rgba(255, 255, 255, 0.5)';
      this.xSpeed=(Math.random() - 0.5) * 0.6;
      this.ySpeed=(Math.random() - 1) * 0.5;
      this.gravity = -0.03;
      this.timeToLive = 100;
   }
   miniBubbles.prototype.draw = function () {
      ctx.beginPath();
      ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
      ctx.fillStyle = this.color;
      ctx.fill();
      ctx.closePath();
   }
   miniBubbles.prototype.update = function () {
      if (this.y - this.radius > 0)
         this.ySpeed += this.gravity;
      this.x += this.xSpeed;
      this.y += this.ySpeed;
      this.timeToLive --;
      this.draw();
   }
   var backgroundGradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
   backgroundGradient.addColorStop(0, '#009cff')
   backgroundGradient.addColorStop(1, '#007bff')
   var bubbles = [];
   var minibubbles = [];
   var timer = 0;
   var spawnRate = 70;
   function animate()
   {
      requestAnimationFrame(animate);
      ctx.fillStyle = backgroundGradient;
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.font = "Bold 30px Georgia";
      ctx.fillStyle = "Black";
      ctx.textAlign = 'center';
      ctx.baseline = 'middle';
      var mess="正确按键次数:"+cnt1+" 无效按键次数:"+cnt2+"  丢失字母个数:"+cnt3;
      ctx.fillText(mess,canvas.width/2,35);

      for (var i=bubbles.length-1;i>=0;i--)
      {
          bubbles[i].update();
       if (bubbles[i].y<30)
          {
             cnt3++;
             bubbles.splice(i, 1);
          }
      }
      for (var i=minibubbles.length-1;i>=0;i--)
      {
         minibubbles[i].update();
     if (minibubbles[i].timeToLive == 0)
         {
            minibubbles.splice(i, 1);
         }
      }
      timer++;
      if (timer==spawnRate)
      {
     bubbles.push(new Bubbles());
         timer=0;
     spawnRate = rand(50, 100);
      }
    }
    window.addEventListener('keypress', function(e){
        var keyID = e.keyCode ? e.keyCode :e.which;
        for (var i=0;i<bubbles.length-1;i++)
        {
            var bubble = bubbles[i];
            if (keyID== bubble.letter.charCodeAt(0))
            {
                 var mx = bubble.x;
         var my = bubble.y;
                 var mr = rand(2,5);
         bubbles.splice(i, 1)
                 cnt1++;
         for (var k = 0; k < bubble.radius/mr; k++)
                 {
                    minibubbles.push(new miniBubbles(mx,my, mr));
         }
                 return;
            }
        }
        cnt2++;
    },true);
   animate();
</script>
</body>
</html>

View Code

(0)

相关推荐