javascript 面向对象制作坦克大战 (一)
PS:这个坦克大战是在网上下的一段源码之后,自己进行的重写。 写这个的目的是为了巩固自己这段时间对js的学习。整理到博客上,算是对自己近端时间学习js的一个整理。 同时也希望可以帮助到学习js的园友。由于自己也是刚学js不久,所以难免出现错误。如果发现希望给予指正。 这个教程适合熟悉js基本语法和面向对象语法的园友学习。 本身没有太难的东西,这个案例将js面向对象用的比较好,可以作为js面向对象的入门教程。
1. 创建基本对象,实现坦克简单的移动。
1.1 如何在地图中绘制画布?
1.2 代码实现

1.2.1 创建顶级对象
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>坦克大战</title>
<link rel=stylesheet href="css/main.css" />
<script src="js/Common.js"></script>
<script src="js/TankObject.js"></script>
<script src="js/Mover.js"></script>
<script src="js/Tank.js"></script>
<script src="js/Frame.js"></script>
<script>
window.onload = function () {
// 调用游戏装载对象
var loader = new GameLoader();
loader.Begin();
}
</script>
</head> <body>
<!--地图容器-->
<div id="divMap">
</div>
<div id="debugInfo">
</div>
</body>
</html>
// 顶级对象
TankObject = function () {
this.XPosition = 0; // 对象在地图(13*13)中的X的位置
this.YPosition = 0;
this.UI = null; // dom元素
}
// 更改UI静态方法
TankObject.prototype.UpdateUI = function (battlFiled) { }
// 设置位置,参数是这样:1*40,6*40
TankObject.prototype.SetPosition = function (leftPosition, topPosition) {
// 在地图的位置 Math.round四舍五入
this.XPosition = Math.round(leftPosition / 40);
this.YPosition = Math.round(topPosition / 40);
// 设置在窗体上的位置
if (this.UI != null && this.UI.style != null) {
this.UI.style.left = leftPosition + "px";
this.UI.style.top = topPosition + "px";
}
}
1.2.2 创建公用对象
// 坦克移动的四个方向
var EnumDirection = {
Up: "0",
Right: "1",
Down: "2",
Left: "3"
}; // 通用方法对象
var UtilityClass = {
// 创建dom元素到parentNode中,可指定id,className
CreateE: function (type, id, className, parentNode) {
var J = document.createElement(type);
if (id) { J.id = id };
if (className) { J.className = className };
return parentNode.appendChild(J);
}, // 移除元素
RemoveE: function (obj, parentNode) {
parentNode.removeChild(obj);
},
GetFunctionName: function (context, argumentCallee) {
for (var i in context) {
if (context[i] == argumentCallee) { return i };
}
return "";
}, // 绑定事件,返回func方法,this为传入的obj
BindFunction: function (obj,func) {
return function () {
func.apply(obj, arguments);
};
}
};
1.2.3 创建移动对象
// 移动对象,继承自顶层对象
Mover = function () {
this.Direction = EnumDirection.Up;
this.Speed = 1;
}
Mover.prototype = new TankObject();
Mover.prototype.Move = function () {
if (this.lock) {
return;/* 停用或者尚在步进中,操作无效 */
}
// 根据方向设置坦克的背景图片
this.UI.style.backgroundPosition = "0 -" + this.Direction * 40 + "px";
// 如果方向是上和下,vp就是top;如果方向是上和左,val就是-1
var vp = ["top", "left"][((this.Direction == EnumDirection.Up) || (this.Direction == EnumDirection.Down)) ? 0 : 1];
var val = ((this.Direction == EnumDirection.Up) || (this.Direction == EnumDirection.Left)) ? -1 : 1;
this.lock = true;/* 加锁 */
// 把当前对象保存到This
var This = this;
// 记录对象移动起始位置
var startmoveP = parseInt(This.UI.style[vp]);
var xp = This.XPosition, yp = This.YPosition;
var subMove = setInterval(function () {
// 开始移动,每次移动5px
This.UI.style[vp] = parseInt(This.UI.style[vp]) + 5 * val + "px";
// 每次移动一个单元格 40px
if (Math.abs((parseInt(This.UI.style[vp]) - startmoveP)) >= 40) {
clearInterval(subMove);
This.lock = false;/* 解锁,允许再次步进 */
// 记录对象移动后在表格中的位置
This.XPosition = Math.round(This.UI.offsetLeft / 40);
This.YPosition = Math.round(This.UI.offsetTop / 40); }
}, 80 - this.Speed * 10); }
1.2.4 创建坦克对象
//tank对象 继承自Mover
Tank=function(){} Tank.prototype = new Mover(); // 创建玩家坦克,继承自tank对象
SelfTank = function () {
this.UI = UtilityClass.CreateE("div", "", "itank", document.getElementById("divMap"));
this.MovingState = false;
this.Speed = 4;
}
SelfTank.prototype = new Tank();
// 设置坦克的位置
SelfTank.prototype.UpdateUI = function () {
this.UI.className = "itank";
// 顶级对象方法,设置坦克的位置
this.SetPosition(this.XPosition * 40, this.YPosition * 40);
}
1.2.5 创建游戏装载对象(核心)
// 游戏载入对象 整个游戏的核心对象
GameLoader = function () {
this.mapContainer = document.getElementById("divMap"); // 存放游戏地图的div
this._selfTank = null; // 玩家坦克
this._gameListener = null; // 游戏主循环计时器id
}
GameLoader.prototype = {
Begin: function () {
// 初始化玩家坦克
var selfT = new SelfTank();
selfT.XPosition = 4;
selfT.YPosition = 12;
selfT.UpdateUI();
this._selfTank = selfT; // 添加按键事件
var warpper = UtilityClass.BindFunction(this, this.OnKeyDown);
window.onkeydown = document.body.onkeydown = warpper;
warpper = UtilityClass.BindFunction(this, this.OnKeyUp);
window.onkeyup = document.body.onkeyup = warpper;
// 游戏主循环
warpper = UtilityClass.BindFunction(this, this.Run);
/*长定时器监听控制键*/
this._gameListener = setInterval(warpper, 20); }
// 键盘按下玩家坦克开始移动
, OnKeyDown: function (e) {
switch ((window.event || e).keyCode) {
case 37:
this._selfTank.Direction = EnumDirection.Left;
this._selfTank.MovingState = true;
break; //左
case 38:
this._selfTank.Direction = EnumDirection.Up;
this._selfTank.MovingState = true;
break; //上
case 39:
this._selfTank.Direction = EnumDirection.Right;
this._selfTank.MovingState = true;
break; //右
case 40:
this._selfTank.Direction = EnumDirection.Down;
this._selfTank.MovingState = true;
break; //下
} }
// 按键弹起停止移动
, OnKeyUp: function (e) {
switch ((window.event || e).keyCode) {
case 37:
case 38:
case 39:
case 40:
this._selfTank.MovingState = false;
break;
}
}
/*游戏主循环运行函数,游戏的心脏,枢纽*/
, Run: function () {
if (this._selfTank.MovingState) {
this._selfTank.Move();
}
} };
javascript 面向对象制作坦克大战 (一)的更多相关文章
- 用javascript 面向对象制作坦克大战(四)
我们现在还差一个重要的功能,没错,敌人坦克的创建以及子弹击中敌人坦克时的碰撞检测功能. 5. 创建敌人坦克完成炮弹碰撞检测 5.1 创建敌人坦克对象 敌人坦克和玩家坦克一样,同样继承自我们的坦克 ...
- 用javascript 面向对象制作坦克大战(三)
之前,我们完成了坦克的移动和地图的绘制,这次我们来完成碰撞检测和炮弹的发射. 上代码前来张最新的类图: 3. 碰撞检测 前面我们已经完成了坦克的移动和地图的绘制,下面我们开始写碰撞检测. 3. ...
- 用javascript 面向对象制作坦克大战(二)
2. 完善地图 我们的地图中有空地,墙,钢,草丛,水,总部等障碍物. 我们可以把这些全部设计为对象. 2.1 创建障碍物对象群 对象群保存各种地图上的对象,我们通过对象的属性来判断对 ...
- html5制作坦克大战
全部html5都采用绘图技术完成.坦克是画出来的.(坦克,子弹,墙,水,草坪) 首先我们画出坦克. 坦克是两边两个矩形,中间一个大矩形,矩形了有一个圆,还有一根线. 画出坦克的思路是以坦克的左上角为参 ...
- 【blade04】用面向对象的方法写javascript坦克大战
前言 javascript与程序的语言比如C#或者java不一样,他并没有“类”的概念,虽然最新的ECMAScript提出了Class的概念,我们却没有怎么用 就单以C#与Java来说,要到真正理解面 ...
- 汉顺平html5课程分享:6小时制作经典的坦克大战!
记起自己去年參加的一次面试,在做过Java多年的面试官面前发挥的并不好,但他一听说我会html5,立刻眼睛发亮.无论不顾的想要和我签约.. .所以.如今为工作犯愁的朋友们,学好html5,绝对会为你找 ...
- java制作简单的坦克大战
坦克大战是我们小时候玩红白机时代的经典游戏,看到有不少小伙伴都使用各种语言实现了一下,手痒痒,也使用java做的一个比较简单的坦克大战,主要面向于学过Java的人群,与学了一段时间的人,有利于面向对象 ...
- [置顶] 小强的HTML5移动开发之路(9)——坦克大战游戏3
上一篇我们创建了敌人的坦克和自己的坦克,接下来就应该让坦克发子弹了,我们下面来看一下如何让我们的坦克发出子弹. 前面我们用面向对象的思想对Tank进行了封装,又利用对象冒充实现了我们的坦克和敌人的坦克 ...
- 例子:web版坦克大战1.0
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
随机推荐
- lintcode:最大子数组差
题目 最大子数组差 给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大. 返回这个最大的差值. 样例 给出数组[1, 2, -3, 1], ...
- [cocoapods]cocoapods问题解决
错误1. While executing gem no such name 错误原因:gem 网址被挡住了. 解决办法:设置https://ruby.taobao.org/ 详情参考 http://w ...
- Java API —— BigDecimal类
1.BigDecimal类概述 由于在运算的时候,float类型和double很容易丢失精度,演示案例.所以,为了能精确的表示.计算浮点数,Java提供了BigDecimal 不可变的.任意精度的有 ...
- HDU 4351 Digital root 线段树区间合并
依然不是十分理解……待考虑…… #include <cstdio> #include <cstring> #include <cstdlib> #include & ...
- Vim的tagbar插件
1.tagbar针对当前文件,调用ctags来生成结果,并抓取其结果,像下边这样的 ctags -f - --format=2 --excmd=pattern --extra= --fields=nk ...
- 20-语言入门-20-Financial Management
题目地址: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=72 描述Larry graduated this year and fina ...
- C结构体之位域(位段)
C结构体之位域(位段) 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C ...
- 【笨嘴拙舌WINDOWS】伟大的变革
"改革"."革命"."变革" 这几个词语毫无疑问是每一个时代必须被呼吁的词语,当一个国家没有人求变时,那是一个时代的悲剧.无论是文景之治,贞 ...
- UVa 11427 (期望 DP) Expect the Expected
设d(i, j)表示前i局每局获胜的比例均不超过p,且前i局共获胜j局的概率. d(i, j) = d(i-1, j) * (1-p) + d(i-1, j-1) * p 则只玩一天就就不再玩的概率Q ...
- UVa 10253 (组合数 递推) Series-Parallel Networks
<训练之南>上的例题难度真心不小,勉强能看懂解析,其思路实在是意想不到. 题目虽然说得千奇百怪,但最终还是要转化成我们熟悉的东西. 经过书上的神分析,最终将所求变为: 共n个叶子,每个非叶 ...