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

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代码如下。

  1. <html>
  2. <head>
  3. <title>刺破气泡小游戏</title>
  4. </head>
  5. <body>
  6. <canvas id="myCanvas"></canvas>
  7. <script>
  8. var canvas = document.getElementById('myCanvas');
  9. var ctx = canvas.getContext('2d');
  10. canvas.height = innerHeight;
  11. canvas.width = innerWidth;
  12. function rand(min, max)
  13. {
  14. return Math.floor(Math.random() * (max - min + 1) + min);
  15. }
  16. function Bubbles()
  17. {
  18. this.x = rand(30,canvas.width - 30);
  19. this.y = canvas.height;
  20. this.radius = rand(15, 30);
  21. this.color ='rgba(255, 255, 255, 0.75)';
  22. this.ySpeed= Math.random() * 2;
  23. this.gravity = 0.01;
  24. }
  25. Bubbles.prototype.draw = function ()
  26. {
  27. ctx.beginPath();
  28. ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
  29. ctx.fillStyle = this.color;
  30. ctx.fill();
  31. ctx.closePath();
  32. }
  33. Bubbles.prototype.update = function ()
  34. {
  35. this.y -= this.ySpeed;
  36. if (this.y - this.radius > 0)
  37. this.ySpeed += this.gravity;
  38. this.draw();
  39. }
  40. function miniBubbles(x,y,radius)
  41. {
  42. this.x = x;
  43. this.y = y;
  44. this.radius = radius;
  45. this.color = 'rgba(255, 255, 255, 0.5)';
  46. this.xSpeed=(Math.random() - 0.5) * 0.6;
  47. this.ySpeed=(Math.random() - 1) * 0.5;
  48. this.gravity = -0.03;
  49. this.timeToLive = 100;
  50. }
  51. miniBubbles.prototype.draw = function () {
  52. ctx.beginPath();
  53. ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
  54. ctx.fillStyle = this.color;
  55. ctx.fill();
  56. ctx.closePath();
  57. }
  58. miniBubbles.prototype.update = function () {
  59. if (this.y - this.radius > 0)
  60. this.ySpeed += this.gravity;
  61. this.x += this.xSpeed;
  62. this.y += this.ySpeed;
  63. this.timeToLive --;
  64. this.draw();
  65. }
  66. var backgroundGradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
  67. backgroundGradient.addColorStop(0, '#009cff')
  68. backgroundGradient.addColorStop(1, '#007bff')
  69. var bubbles = [];
  70. var minibubbles = [];
  71. var timer = 0;
  72. var spawnRate = 70;
  73. function animate()
  74. {
  75. requestAnimationFrame(animate);
  76. ctx.fillStyle = backgroundGradient;
  77. ctx.fillRect(0, 0, canvas.width, canvas.height);
  78. for (var i=bubbles.length-1;i>=0;i--)
  79. {
  80. bubbles[i].update();
  81. if (bubbles[i].y<0)
  82. {
  83. bubbles.splice(i, 1);
  84. }
  85. }
  86. for (var i=minibubbles.length-1;i>=0;i--)
  87. {
  88. minibubbles[i].update();
  89. if (minibubbles[i].timeToLive == 0)
  90. {
  91. minibubbles.splice(i, 1);
  92. }
  93. }
  94. timer++;
  95. if (timer==spawnRate)
  96. {
  97. bubbles.push(new Bubbles());
  98. timer=0;
  99. spawnRate = rand(50, 100);
  100. }
  101. }
  102. canvas.addEventListener('mousedown', function(){
  103. var x = event.pageX - canvas.getBoundingClientRect().left;
  104. var y = event.pageY - canvas.getBoundingClientRect().top;
  105. // 查找被单击的气泡
  106. for (var i=bubbles.length-1; i>=0; i--)
  107. {
  108. var bubble = bubbles[i];
  109. var dist = Math.sqrt(Math.pow(bubble.x-x,2)+ Math.pow(bubble.y- y,2));
  110. if (dist<= bubble.radius)
  111. {
  112. var mx = bubble.x;
  113. var my = bubble.y;
  114. var mr = rand(2,5);
  115. bubbles.splice(i, 1)
  116. for (var k = 0; k < bubble.radius/mr; k++)
  117. {
  118. minibubbles.push(new miniBubbles(mx,my, mr));
  119. }
  120. return;
  121. }
  122. }
  123. });
  124. animate();
  125. </script>
  126. </body>
  127. </html>

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

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

图2 键盘练习小游戏

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

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

完整的HTML代码如下。

  1. <html>
  2. <head>
  3. <title>简单键盘练习</title>
  4. </head>
  5. <body>
  6. <canvas id="myCanvas"></canvas>
  7. <script>
  8. var canvas = document.getElementById('myCanvas');
  9. var ctx = canvas.getContext('2d');
  10. canvas.height = innerHeight;
  11. canvas.width = innerWidth;
  12. var str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  13. var cnt1=0;
  14. var cnt2=0;
  15. var cnt3=0;
  16. function rand(min, max)
  17. {
  18. return Math.floor(Math.random() * (max - min + 1) + min);
  19. }
  20. function Bubbles()
  21. {
  22. this.x = rand(30,canvas.width - 30);
  23. this.y = canvas.height;
  24. this.radius = 20;
  25. this.color ='rgba(255, 255, 255, 0.75)';
  26. this.ySpeed= Math.random() * 2;
  27. this.gravity = 0.01;
  28. this.letter=str.charAt(rand(0,str.length-1));
  29. }
  30. Bubbles.prototype.draw = function ()
  31. {
  32. ctx.beginPath();
  33. ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
  34. ctx.fillStyle = this.color;
  35. ctx.fill();
  36. ctx.closePath();
  37. ctx.font = "Bold 20px Georgia";
  38. ctx.fillStyle = "Black";
  39. ctx.textAlign = 'center';
  40. ctx.baseline = 'middle';
  41. ctx.fillText(this.letter,this.x, this.y);
  42. }
  43. Bubbles.prototype.update = function ()
  44. {
  45. this.y -= this.ySpeed;
  46. if (this.y - this.radius > 0)
  47. this.ySpeed += this.gravity;
  48. this.draw();
  49. }
  50. function miniBubbles(x,y,radius)
  51. {
  52. this.x = x;
  53. this.y = y;
  54. this.radius = radius;
  55. this.color = 'rgba(255, 255, 255, 0.5)';
  56. this.xSpeed=(Math.random() - 0.5) * 0.6;
  57. this.ySpeed=(Math.random() - 1) * 0.5;
  58. this.gravity = -0.03;
  59. this.timeToLive = 100;
  60. }
  61. miniBubbles.prototype.draw = function () {
  62. ctx.beginPath();
  63. ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
  64. ctx.fillStyle = this.color;
  65. ctx.fill();
  66. ctx.closePath();
  67. }
  68. miniBubbles.prototype.update = function () {
  69. if (this.y - this.radius > 0)
  70. this.ySpeed += this.gravity;
  71. this.x += this.xSpeed;
  72. this.y += this.ySpeed;
  73. this.timeToLive --;
  74. this.draw();
  75. }
  76. var backgroundGradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
  77. backgroundGradient.addColorStop(0, '#009cff')
  78. backgroundGradient.addColorStop(1, '#007bff')
  79. var bubbles = [];
  80. var minibubbles = [];
  81. var timer = 0;
  82. var spawnRate = 70;
  83. function animate()
  84. {
  85. requestAnimationFrame(animate);
  86. ctx.fillStyle = backgroundGradient;
  87. ctx.fillRect(0, 0, canvas.width, canvas.height);
  88. ctx.font = "Bold 30px Georgia";
  89. ctx.fillStyle = "Black";
  90. ctx.textAlign = 'center';
  91. ctx.baseline = 'middle';
  92. var mess="正确按键次数:"+cnt1+" 无效按键次数:"+cnt2+" 丢失字母个数:"+cnt3;
  93. ctx.fillText(mess,canvas.width/2,35);
  94.  
  95. for (var i=bubbles.length-1;i>=0;i--)
  96. {
  97. bubbles[i].update();
  98. if (bubbles[i].y<30)
  99. {
  100. cnt3++;
  101. bubbles.splice(i, 1);
  102. }
  103. }
  104. for (var i=minibubbles.length-1;i>=0;i--)
  105. {
  106. minibubbles[i].update();
  107. if (minibubbles[i].timeToLive == 0)
  108. {
  109. minibubbles.splice(i, 1);
  110. }
  111. }
  112. timer++;
  113. if (timer==spawnRate)
  114. {
  115. bubbles.push(new Bubbles());
  116. timer=0;
  117. spawnRate = rand(50, 100);
  118. }
  119. }
  120. window.addEventListener('keypress', function(e){
  121. var keyID = e.keyCode ? e.keyCode :e.which;
  122. for (var i=0;i<bubbles.length-1;i++)
  123. {
  124. var bubble = bubbles[i];
  125. if (keyID== bubble.letter.charCodeAt(0))
  126. {
  127. var mx = bubble.x;
  128. var my = bubble.y;
  129. var mr = rand(2,5);
  130. bubbles.splice(i, 1)
  131. cnt1++;
  132. for (var k = 0; k < bubble.radius/mr; k++)
  133. {
  134. minibubbles.push(new miniBubbles(mx,my, mr));
  135. }
  136. return;
  137. }
  138. }
  139. cnt2++;
  140. },true);
  141. animate();
  142. </script>
  143. </body>
  144. </html>

JavaScript小游戏实例:简单的键盘练习的更多相关文章

  1. JavaScript小游戏实例:统一着色

    设计如下的简单小游戏. 在面板(画布)中放置10行10列共100个小方块,每个小方块随机在5种颜色中选一种颜色进行着色,在面板的下方,放置对应的5种颜色色块,如图1所示. 图1  “统一着色”游戏界面 ...

  2. 制作一个 JavaScript 小游戏

    简评: 作者学习了编程两个月,边学边做了一个 JavaScript 小游戏,在文中总结了自己在这个过程中的一些体会,希望能给其他初学者一些帮助. 对于很多想学编程但一直没下定决心的同学来说,最大的问题 ...

  3. JavaScript小游戏--2048(PC端)

    1.初始化棋局 $(document).ready(function() { prepare_for_mobile(); //适配移动端 new_game(); }); 2.开始新游戏 functio ...

  4. JavaScript 小游戏 贪吃蛇

    贪吃蛇 代码: <!DOCTYPE html><html><head> <meta charset="UTF-8"> <met ...

  5. javascript小游戏--生命游戏

    昨天参加Code Retreat的活动,"Code Retreat是一个一天的集中练习的活动,专注于软件开发和设计的基础". 要了解更多信息可前往 CodeRetreat官网 通过 ...

  6. JavaScript小游戏--翻牌记忆游戏

    翻牌记忆游戏源码 1.有8张图片,每张图片要放两次,生成如下数组,长为16,[0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7] 其中两两相同的代表两张相同的图片,0对应文件夹image ...

  7. 《C++ Qt 设计模式》8|15拼图 小游戏的简单实现。拜托,别乱点!

    第零章:介绍 看到这个游戏了,感觉蛮好玩的,实现了一下. 界面如下: 游戏玩法:在3×*3的矩阵中,每个按钮都可以点击,如果按钮四周有一个是空白,则点击此按钮则会移动到这个空白.按钮字母顺序变成“AB ...

  8. CSS技术实例1-使用CSS计数器实现数值计算小游戏实例页面

    一 实例要达到的要求如图所示: 二 分析 1.7个圆角矩形标签(或按钮) 2. 点击触发并开始运算,最后一个标签显示结果 3.计算成功后弹出"万岁"字眼 三 代码实现 关键CSS代 ...

  9. JavaScript小游戏--2048(移动端)

    HTML5中新添加了很多事件,但是由于他们的兼容问题不是很理想,应用实战性不是太强,所以在这里基本省略,咱们只分享应用广泛兼容不错的事件,日后随着兼容情况提升以后再陆续添加分享.今天为大家介绍的事件主 ...

随机推荐

  1. MySQL数据库使用报错ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

    今天MySQL数据库,在使用的过程中一直报错ERROR 1820 (HY000): You must reset your password using ALTER USER statement be ...

  2. angular浏览器兼容性问题解决方案

    问题:edge浏览器下,固定列的边框消失 原因:ng-zorro-antd表格组件使用nzLeft和nzRight指令固定的表格列,这两个指令的实现css3中的标签: position: -webki ...

  3. Flink之对时间的处理

    window+trigger+watermark处理全局乱序数据,指定窗口上的allowedLateness可以处理特定窗口操作的局部事件时间乱序数据 1.流处理系统中的微批 Flink内部也使用了某 ...

  4. Python 爬取 42 年高考数据,告诉你高考为什么这么难?

    作者 | 徐麟 历年录取率 可能很多经历过高考的人都不知道高考的全称,高考实际上是普通高等学校招生全国统一考试的简称.从1977年国家恢复高考制度至今,高考经历了许多的改革,其中最为显著的变化就是录取 ...

  5. Python Ethical Hacking - Intercepting and Modifying Packets

    INTERCEPTING & MODIFYING PACKETS Scapy can be used to: Create packets. Analyze packets. Send/rec ...

  6. 【软件安装】在 CentOS 7(Linux)上部署流媒体服务(Tengine、ffmpeg、Centos 7、nginx-http-flv-module、OBS)

    Centos7+Tengine+Nginx-http-flv-module+ffmpeg+OBS搭建流媒体服务器 一.需求和背景 视频直播是基于领先的内容接入.分发网络和大规模分布式实时转码技术打造的 ...

  7. 浅谈服务治理、微服务与Service Mesh(三) Service Mesh与Serverless

    作为本系列文章的第三篇(前两篇<浅谈服务治理.微服务与Service Mesh(一)Dubbo的前世今生>,<浅谈服务治理.微服务与Service Mesh(二) Spring Cl ...

  8. MapReduce之自定义InputFormat

    在企业开发中,Hadoop框架自带的InputFormat类型不能满足所有应用场景,需要自定义InputFormat来解决实际问题. 自定义InputFormat步骤如下: (1)自定义一个类继承Fi ...

  9. Bootstrap 3 -> 4 : 居中布局的变化

    我们知道,Bootstrap布局的核心是栅格系统,一行有12个栅格. 比如,我想让两个宽度400px左右的div居中显示. 这个时候,我们可以利用栅格的列偏移功能. <div class=&qu ...

  10. k8s教程:Kubernetes集群使用网络存储NFS

    NFS存储 NFS即网络文件系统Network File System,它是一种分布式文件系统协议,最初是由Sun MicroSystems公司开发的类Unix操作系统之上的一款经典网络存储方案,其功 ...