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>
JavaScript小游戏实例:简单的键盘练习的更多相关文章
- JavaScript小游戏实例:统一着色
设计如下的简单小游戏. 在面板(画布)中放置10行10列共100个小方块,每个小方块随机在5种颜色中选一种颜色进行着色,在面板的下方,放置对应的5种颜色色块,如图1所示. 图1 “统一着色”游戏界面 ...
- 制作一个 JavaScript 小游戏
简评: 作者学习了编程两个月,边学边做了一个 JavaScript 小游戏,在文中总结了自己在这个过程中的一些体会,希望能给其他初学者一些帮助. 对于很多想学编程但一直没下定决心的同学来说,最大的问题 ...
- JavaScript小游戏--2048(PC端)
1.初始化棋局 $(document).ready(function() { prepare_for_mobile(); //适配移动端 new_game(); }); 2.开始新游戏 functio ...
- JavaScript 小游戏 贪吃蛇
贪吃蛇 代码: <!DOCTYPE html><html><head> <meta charset="UTF-8"> <met ...
- javascript小游戏--生命游戏
昨天参加Code Retreat的活动,"Code Retreat是一个一天的集中练习的活动,专注于软件开发和设计的基础". 要了解更多信息可前往 CodeRetreat官网 通过 ...
- JavaScript小游戏--翻牌记忆游戏
翻牌记忆游戏源码 1.有8张图片,每张图片要放两次,生成如下数组,长为16,[0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7] 其中两两相同的代表两张相同的图片,0对应文件夹image ...
- 《C++ Qt 设计模式》8|15拼图 小游戏的简单实现。拜托,别乱点!
第零章:介绍 看到这个游戏了,感觉蛮好玩的,实现了一下. 界面如下: 游戏玩法:在3×*3的矩阵中,每个按钮都可以点击,如果按钮四周有一个是空白,则点击此按钮则会移动到这个空白.按钮字母顺序变成“AB ...
- CSS技术实例1-使用CSS计数器实现数值计算小游戏实例页面
一 实例要达到的要求如图所示: 二 分析 1.7个圆角矩形标签(或按钮) 2. 点击触发并开始运算,最后一个标签显示结果 3.计算成功后弹出"万岁"字眼 三 代码实现 关键CSS代 ...
- JavaScript小游戏--2048(移动端)
HTML5中新添加了很多事件,但是由于他们的兼容问题不是很理想,应用实战性不是太强,所以在这里基本省略,咱们只分享应用广泛兼容不错的事件,日后随着兼容情况提升以后再陆续添加分享.今天为大家介绍的事件主 ...
随机推荐
- python 装饰器(五):装饰器实例(二)类装饰器(类装饰器装饰函数)
回到装饰器上的概念上来,装饰器要求接受一个callable对象,并返回一个callable对象(不太严谨,详见后文). 那么用类来实现也是也可以的.我们可以让类的构造函数__init__()接受一个函 ...
- MVC + EFCore 项目实战 - 数仓管理系统4 – 需求分解
上次课程我们完成了项目基本的UI风格配置. 现在就开始进入我们的需求开发,我们先捋一下需求. 一.总体需求说明 项目背景第一篇文章已有介绍,我们回顾一下. 这是一个数据管理"工具类" ...
- [apue] Linux / Windows 系统上只能建立不超过 PATH_MAX / MAX_PATH 长度的路径吗?
问题的提出 在处理文件系统路径的时候,我们一般会先开辟一块内存区,用来接收路径.或者拼接好路径传递给系统调用.这是因为路径在各个系统上都有最大长度限制,在 Windows 上这个值是 MAX_PATH ...
- Python2爬取学生名单
背景: 学校的网站可以根据学号查学生姓名和成绩(三年后的补充:借助sql注入漏洞跳过密码,但是该网站现在已经被弃用了),所以我希望通过Python的爬虫得到年级所有同学的学号与姓名对应表. 实现: 首 ...
- sql中in和exists的原理及使用场景。
在我们的工作中可能会遇到这样的情形: 我们需要查询a表里面的数据,但是要以b表作为约束. 举个例子,比如我们需要查询订单表中的数据,但是要以用户表为约束,也就是查询出来的订单的user_id要在用户表 ...
- Ethical Hacking - NETWORK PENETRATION TESTING(1)
Pre--Connection-Attacks that can be done before connecting to the network. Gaining Access - How to b ...
- Harbor打怪升级
目录 一.目标 二.V1.4升级至V1.6 三.V1.6升级至V1.9 四.V1.9升级至V2.0 五.写在最后 一.目标 Harbor V1.4版本升级至V2.0 注: Harbor升级需要注意的是 ...
- MSF查找提权exp
0x01:介绍 在拿到一个反弹shell后,下一步可以用metaspolit的内置模块Local Exploit SuggesterLocal-exploit-suggester的功能就如它的名字一样 ...
- day12:闭包函数&匿名函数
闭包函数 闭包函数的定义: 如果内函数使用了外函数的局部变量并且外函数把内函数返回出来的过程 叫做闭包里面的内函数是闭包函数 一个简单的闭包函数示例: def songyunjie_family(): ...
- PyCharm+PyQt5+Qt Designer配置
配置前提 因为本机已经配置完毕了,本次使用的是虚拟机中的Win7系统,Win10系统操作步骤完全一样,无任何区别 PyCharm (这个不多说,官网下载安装,我是用的是2019.3版本) Python ...