非html5实现js版弹球游戏示例代码


Posted in Javascript onSeptember 22, 2013

开始前的html页面
非html5实现js版弹球游戏示例代码 
开始后的html游戏界面
非html5实现js版弹球游戏示例代码 
html页面布局,即index.html文件源码如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
<title>弹球游戏</title> 
<link rel="stylesheet" type="text/css" href="css/index.css"/> </head> 
<body> 
<center> 
<div id="gamePanel" tabindex="0"> 
<div class="score">分数: 
<span id="score">0</span> 
</div> 
<div id="startBtn" onclick="Start()"></div> 
</div> 
</center> 
<script type="text/javascript" src="js/magic.js"></script> 
<script type="text/javascript" src="js/brick.js"></script> 
<script type="text/javascript" src="js/ball.js"></script> 
<script type="text/javascript" src="js/stick.js"></script> 
<script type="text/javascript" src="js/game.js"></script> 
</body> 
</html>

index.css文件源码如下:
#gamePanel{ width:504px; 
height:504px; 
background:Black; 
position:relative; 
} 
#gamePanel .score{ 
font-size:20px; 
color:White; 
position:absolute; 
left:0; 
top:0; 
z-index:9999; 
} 
#gamePanel .bullet{ 
width:5px; 
height:15px; 
position:absolute; 
background:url(../img/bullet.png); 
overflow:hidden; 
} 
#gamePanel .stick{ 
width:80px; 
height:18px; 
position:absolute; 
background:blue; 
} 
#gamePanel .ball{ 
width:15px; 
height:15px; 
position:absolute; 
background:url(../img/ball.gif); 
} 
#gamePanel .brick { 
width : 28px; 
height : 28px; 
position : relative; 
background : url(../img/brick.gif); 
float : left; 
} 
#gamePanel .hideBrick { 
width : 28px; 
height : 28px; 
position : relative; 
background : black; 
float : left; 
} 
#gamePanel .magic { 
width : 27px; 
height : 11px; 
position : absolute; 
background : green; 
} 
#gamePanel .shortMagic { 
width : 28px; 
height : 12px; 
position : absolute; 
background : yellow; 
} 
#gamePanel .bingo{ 
width:18px; 
height:18px; 
position:absolute; 
background:url(../img/bingo2.png); 
} 
#startBtn{ 
border-width:20px; 
border-style:solid; 
border-color:Black Black Black Green; 
position:absolute; 
left:240px; 
top:240px; 
cursor:pointer; 
width:0px; 
height:0px; 
overflow:hidden; 
}

JavaScript部分分为5个源文件,即ball.js(球类)、brick.js(砖类)、game.js(游戏类)、magic.js(魔法棒类)、stick.js(挡板类)

球类代码实现如下:

// 球类 
var Ball = function() { // 弹球dom元素 
this.dom = null; 
// 是否激活 
this.isFirst = true; 
// 弹球移动方向 
this.direction = null; 
this.init(); 
} 
Ball.prototype = { 
// 弹球横向移动速度 
movepx : 3, 
// 弹球纵向移动速度 
movepy : 2, 
// 弹球移动频率 
movesp : 20, 
// 弹球移动频率映射 
movespMap : { 
1 : 75, 
2 : 65, 
3 : 50, 
4 : 40 
}, 
// 初始化 
init : function() { 
this.dom = document.createElement("div"); 
this.dom.className = "ball"; 
}, 
// 设置弹球的初始化位置,x与y坐标 
setPosition : function(x, y) { 
this.dom.style.left = x + "px"; 
this.dom.style.top = y + "px"; 
}, 
// 弹球动画,就是移动,传入参数为游戏背景的宽与高 
animation : function(gameWidth, gameHeight, stick) { 
var _this = this; 
// 实际的横向移动速度,左或者右 
var _movepx = this.dom.offsetLeft > gameWidth/2 ? -1*this.movepx : this.movepx; 
var _movepy = this.dom.offsetTop > gameHeight/2 ? this.movepy : -1*this.movepy; 
// 处理移动函数 
var process = function() { 
// 弹球的x,y坐标 
var left = _this.dom.offsetLeft; 
var top = _this.dom.offsetTop; 
// 是否要调转方向 
if (left <= 0 || left >= gameWidth - _this.dom.clientWidth) { 
_movepx *= -1; 
} 
var isCrashStick = _this.OnCheckCrashStick(); 
var isCrashBall = _this.OnCheckCrashBrick(); 
// 判断是否想上调转方向 
if (top < 0 || isCrashStick || isCrashBall) { 
_movepy *= -1; 
} 
// 向下移动 
top = top + _movepy; 
left = left + _movepx; 
// 设置弹球位置 
_this.dom.style.top = top + "px"; 
_this.dom.style.left = left + "px"; 
if(top > gameHeight) { 
_this.onend(); 
alert("You Lose"); 
} else { 
setTimeout(process, _this.movesp); 
} 
// 判断弹球移动方向 
if (_movepx > 0 && _movepy < 0) { 
_this.direction = "RightUp"; 
return; 
} 
if (_movepx > 0 && _movepy > 0) { 
_this.direction = "RightDown"; 
return; 
} 
if (_movepx < 0 && _movepy < 0) { 
_this.direction = "LeftUp"; 
return; 
} 
if (_movepx < 0 && _movepy > 0) { 
_this.direction = "LeftDown"; 
return; 
} 
}; 
// 开始移动 
process(); 
}, 
// 外部接口,检测是否撞到魔法棒 
OnCheckCrashStick : function() {}, 
// 外部接口,检测是否撞到砖块 
OnCheckCrashBrick : function() {}, 
// 弹球结束事件 
onend : function() {}, 
// 游戏结束 
gameover : function() {} 
}

砖类代码如下brick.js源文件:
// 砖类 
var Brick = function(gamePanel) { // 砖的dom元素 
this.dom = null; 
// 砖块所在的画布 
this.gamePanel = gamePanel; 
// 是否激活 
this.isLive = true; 
// 是否带有魔法棒 
this.magic = null; 
this.width = 28; 
this.height = 28; 
this.left = 0; 
this.top = 0; 
this.init(); 
} 
Brick.prototype = { 
// 初始化 
init : function() { 
this.dom = document.createElement("div"); 
this.dom.className = "brick"; 
}, 
// 为position: relative的Brick初始化位置 
setPosition : function(x, y) { 
this.left = x; 
this.top = y; 
}, 
// 为positon : relative的Brick初始化尺寸 
setSize : function(width, height) { 
this.width = width; 
this.height = height; 
}, 
// 初始化生成魔法棒 
initMagic : function() { 
var _this = this; 
// 随机数 
var random = parseInt(Math.random()*1000 + 1, 10); 
var type = random % 5 == 0 ? "good" : random % 4 == 0 ? "bad" : "none"; 
// 新建一个魔法棒对象 
var magic = new Magic(type); 
this.magic = magic; 
magic.initPosition(this); 
// 将魔法棒添加进砖块中 
this.gamePanel.appendChild(magic.dom); 
magic.onEnd = function() { 
_this.gamePanel.removeChild(magic.dom); 
}; 
magic.animation(this.gamePanel.clientHeight); 
}, 
// 击中后的动作 
onEnd : function() { 
this.isLive = false; 
this.dom.className = "hideBrick"; 
this.initMagic(); 
} 
}

魔法棒类代码即magic.js源文件实现如下:
// 魔法棒类 
var Magic = function(type) { // Magic的dom元素 
this.dom = null; 
// Magic的dom信息 
this.left = 0; 
this.top = 0; 
this.width = 0; 
this.height = 0; 
this.type = type; 
this.init(); 
} 
Magic.prototype = { 
// 魔法棒类型 
magicType : { 
"good" : "magic", 
"bad" : "shortMagic", 
"none" : "" 
}, 
// 每次移动位移 
movepy : 3, 
// 移动速度 
movespeed : 20, 
// 初始化魔法棒 
init : function() { 
this.dom = document.createElement("div"); 
this.dom.className = this.magicType[this.type]; 
//this.dom.style.display = "none"; 
this.width = parseInt(this.dom.style.width, 10); 
this.height = parseInt(this.dom.style.height, 10); 
}, 
// 魔法棒初始化位置 
initPosition : function(brick) { 
this.left = brick.left; 
this.top = brick.top; 
this.dom.style.left = this.left + "px"; 
this.dom.style.top = this.top + "px"; 
}, 
// 更新位置 
update : function() { 
this.dom.style.left = this.left + "px"; 
this.dom.style.top = this.top + "px"; 
}, 
// 魔法棒动画,height为游戏背景高度 
animation : function(height) { 
if (this.type == "none") { 
return; 
} 
var _this = this; 
// 向下移动函数 
var downMove = function() { 
_this.top = _this.top + _this.movepy; 
_this.update(); 
// 判断魔法棒下移是否越界,是否击中stick 
if (_this.top < height && !_this.isBeatStick()) { 
setTimeout(downMove, _this.movespeed); 
} else { 
// 动画结束触发事件 
_this.onEnd(); 
} 
}; 
downMove(); 
}, 
// 动画结束触发事件,外部覆盖 
onEnd : function() {}, 
// 魔法棒是否击中挡板以及击中后处理事件,外部覆盖 
isBeatStick : function() {} 
}

挡板类代码即stick.js源文件如下:
// 新建棒类 
var Stick = function() { // 飞机对应的dom元素 
this.dom = null; 
// 是否移动中 
this.isMove = false; 
// 移动的ID 
this.moveId = null; 
// 是否弹球中 
this.isSend = false; 
// 变大标记 
this.bigCount = 0; 
// 变小标记 
this.smallCount = 0; 
// 接棒的宽度变大变小时做存储 
this.width = 0; 
this.init(); 
} 
Stick.prototype = { 
// 游戏背景Dom 
gamePanel : null, 
// 游戏背景宽度 
gameWidth : 0, 
// 游戏背景高度 
gameHeight : 0, 
// 魔法棒移动速度 
movepx : 10, 
// 魔法棒移动频率 
movesp : 30, 
// 方向键值对应 
keyCodeAndDirection : { 
37 : "left", 
39 : "right" 
}, 
// 初始化 
init : function() { 
this.dom = document.createElement("div"); 
this.dom.className = "stick"; 
}, 
// 设置位置 
setPosition : function(gamePanel, width, height) { 
// 将魔法棒添加进游戏背景中 
this.gamePanel = gamePanel; 
this.gamePanel.appendChild(this.dom); 
// 设置飞机的初始位置 
this.dom.style.left = (width - this.dom.clientWidth)/2 + "px"; 
this.dom.style.top = height - this.dom.clientHeight + "px"; 
// 获取到游戏背景的宽和高 
this.gameWidth = width; 
this.gameHeight = height; 
}, 
// 键盘按下事件 
keydown : function(e) { 
var keyCode = e.keyCode; 
if (!this.isMove) { 
this.move(keyCode); 
} 
}, 
// 键盘释放事件 
keyup : function(e) { 
// 判断是否为键盘释放 
if (this.keyCodeAndDirection[e.keyCode]) { 
// 停止移动 
this.stopMove(); 
} else if (e.keyCode == 32) { 
// 设置为非发弹中 
this.isSend = false; 
} 
}, 
// 移动 
move : function(keyCode) { 
// 设置为移动中 
this.isMove = true; 
var _this = this; 
// 判断移动方向 
switch(this.keyCodeAndDirection[keyCode]) { 
case "left" : { 
this.moveId = setInterval(function() {_this.moveLeft();}, _this.movesp); 
break; 
} 
case "right" : { 
this.moveId = setInterval(function() {_this.moveRight();}, _this.movesp); 
break; 
} 
default : break; 
} 
}, 
// 向左移动 
moveLeft : function() { 
var left = this.dom["offsetLeft"]; 
left = left - this.movepx >= 0 ? left - this.movepx : 0; 
this.dom.style["left"] = left + "px"; 
if (left == 0) { 
this.stopMove(); 
} 
}, 
// 向右移动 
moveRight : function() { 
var left = this.dom["offsetLeft"]; 
var maxDistance = this.gameWidth - this.dom.clientWidth; 
left = left + this.movepx <= maxDistance ? left + this.movepx: maxDistance; 
this.dom.style["left"] = left + "px"; 
if (left == maxDistance) { 
this.stopMove(); 
} 
}, 
// 变小 
changeSmall : function() { 
if (this.smallCount >= 1) { 
return; 
} else { 
this.dom.style.width = 80 + "px"; 
this.smallCount ++; 
this.bigCount >= 1 ? this.bigCount -- : this.bigCount + 0; 
} 
this.dom.style.left = parseInt(this.dom.style.left, 10) + 20 + "px"; 
this.dom.style.width = 40 + "px"; 
}, 
// 变大 
changeBig : function() { 
if (this.bigCount >= 1) { 
return; 
} else { 
this.dom.style.width = 80 + "px"; 
this.bigCount ++; 
this.smallCount >= 1 ? this.smallCount -- : this.smallCount + 0; 
} 
if (parseInt(this.dom.style.left, 10) <= 75 ) { 
this.dom.style.width = parseInt(this.dom.style.width, 10) + 75 + parseInt(this.dom.style.left, 10)+ "px"; 
this.dom.style.left = 0 + "px"; 
return; 
} else if (this.dom.style.width + 150 + parseInt(this.dom.style.left, 10) >= this.gamePanel.clientWidth) { 
this.dom.style.left = parseInt(this.dom.style.left, 10) - 150 + "px"; 
this.dom.style.width = this.dom.style.width + 150 + "px"; 
return; 
} else { 
this.dom.style.left = parseInt(this.dom.style.left, 10) - 75 + "px"; 
this.dom.style.width = 150 + "px"; 
} 
}, 
// 停止移动 
stopMove : function() { 
this.isMove = false; 
clearInterval(this.moveId); 
}, 
// 发射弹球,外部接口, 
onSendBall : function() {}, 

// 改分数外部接口 
onChangeScore : function() {} 
}

部分难点技术实现

通过键盘左右方向键移动挡板的代码实现:

// 键盘按下事件 
keydown : function(e) { var keyCode = e.keyCode; 
if (!this.isMove) { 
this.move(keyCode); 
} 
}, 
// 键盘释放事件 
keyup : function(e) { 
// 判断是否为键盘释放 
if (this.keyCodeAndDirection[e.keyCode]) { 
// 停止移动 
this.stopMove(); 
} else if (e.keyCode == 32) { 
// 设置为非发弹中 
this.isSend = false; 
} 
}, 
// 移动 
move : function(keyCode) { 
// 设置为移动中 
this.isMove = true; 
var _this = this; 
// 判断移动方向 
switch(this.keyCodeAndDirection[keyCode]) { 
case "left" : { 
this.moveId = setInterval(function() {_this.moveLeft();}, _this.movesp); 
break; 
} 
case "right" : { 
this.moveId = setInterval(function() {_this.moveRight();}, _this.movesp); 
break; 
} 
default : break; 
} 
}, 
// 向左移动 
moveLeft : function() { 
var left = this.dom["offsetLeft"]; 
left = left - this.movepx >= 0 ? left - this.movepx : 0; 
this.dom.style["left"] = left + "px"; 
if (left == 0) { 
this.stopMove(); 
} 
}, 
// 向右移动 
moveRight : function() { 
var left = this.dom["offsetLeft"]; 
var maxDistance = this.gameWidth - this.dom.clientWidth; 
left = left + this.movepx <= maxDistance ? left + this.movepx: maxDistance; 
this.dom.style["left"] = left + "px"; 
if (left == maxDistance) { 
this.stopMove(); 
} 
},
Javascript 相关文章推荐
JS限制Textarea文本域字符个数的具体实现
Aug 02 Javascript
js控制不同的时间段显示不同的css样式的实例代码
Nov 04 Javascript
jQuery实现图片预加载效果
Nov 27 Javascript
JS获取地址栏参数的两种方法(简单实用)
Jun 14 Javascript
Bootstrap简单表单显示学习笔记
Nov 15 Javascript
简单实现js选项卡切换效果
Feb 09 Javascript
jQuery实现jQuery-form.js实现异步上传文件
Apr 28 jQuery
vue-cli3.0实现一个多页面应用的历奇经历记录总结
Mar 16 Javascript
Vue切换组件实现返回后不重置数据,保留历史设置操作
Jul 21 Javascript
Vue表单提交点击事件只允许点击一次的实例
Oct 23 Javascript
Vue实现菜单切换功能
Nov 08 Javascript
vue 封装面包屑组件教程
Nov 16 Javascript
多种方法判断Javascript对象是否存在
Sep 22 #Javascript
利用毫秒减值计算时长的js代码
Sep 22 #Javascript
js获取多个tagname的节点数组
Sep 22 #Javascript
jQuery中校验时间格式的正则表达式小结
Sep 22 #Javascript
jquery中获取id值方法小结
Sep 22 #Javascript
document.getElementBy(&quot;id&quot;)与$(&quot;#id&quot;)有什么区别
Sep 22 #Javascript
浏览器页面区域大小的js获取方法
Sep 21 #Javascript
You might like
用文本作数据处理
2006/10/09 PHP
PHP Squid中可缓存的动态网页设计
2008/09/17 PHP
CI框架集成Smarty的方法分析
2016/05/17 PHP
PHP获取当前文件的父目录方法汇总
2016/07/21 PHP
PHP设计模式(九)外观模式Facade实例详解【结构型】
2020/05/02 PHP
Jquery Ajax学习实例3 向WebService发出请求,调用方法返回数据
2010/03/16 Javascript
PHP abstract与interface之间的区别
2013/11/11 Javascript
JavaScript实现微信号随机切换代码
2018/03/09 Javascript
vue中rem的配置的方法示例
2018/08/30 Javascript
Nodejs中获取当前函数被调用的行数及文件名详解
2018/12/12 NodeJs
JSX在render函数中的应用详解
2019/09/04 Javascript
vue.js自定义组件实现v-model双向数据绑定的示例代码
2020/01/08 Javascript
[02:33]DOTA2亚洲邀请赛趣味视频之吐真话筒
2018/03/31 DOTA
Python实现HTTP协议下的文件下载方法总结
2016/04/20 Python
python之文件的读写和文件目录以及文件夹的操作实现代码
2016/08/28 Python
python中requests小技巧
2017/05/10 Python
Python数据结构与算法之完全树与最小堆实例
2017/12/13 Python
Python requests发送post请求的一些疑点
2018/05/20 Python
一篇文章搞懂Python的类与对象名称空间
2018/12/10 Python
Keras 切换后端方式(Theano和TensorFlow)
2020/06/19 Python
python 安装移动复制第三方库操作
2020/07/13 Python
Python实现画图软件功能方法详解
2020/07/28 Python
解决tensorflow模型压缩的问题_踩坑无数,总算搞定
2021/03/02 Python
什么是规则表达式
2012/05/03 面试题
印刷工程专业应届生求职信
2013/09/29 职场文书
自荐信范文
2013/12/10 职场文书
销售主管的自我评价分享
2014/01/03 职场文书
经销商培训邀请函
2014/01/21 职场文书
教师党员公开承诺书
2014/03/25 职场文书
副处级干部考察材料
2014/05/17 职场文书
环卫工人先进事迹材料
2014/06/02 职场文书
商务英语专业大学生职业生涯规划书
2014/09/14 职场文书
2014乡党委副书记党建工作汇报材料
2014/11/02 职场文书
读完《骆驼祥子》的观后感!
2019/07/05 职场文书
Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件
2021/04/17 Vue.js
分享node.js实现简单登录注册的具体代码
2022/04/26 NodeJs