【blade04】用面向对象的方法写javascript坦克大战

时间:2022-09-15 00:00:18

前言

javascript与程序的语言比如C#或者java不一样,他并没有“类”的概念,虽然最新的ECMAScript提出了Class的概念,我们却没有怎么用

就单以C#与Java来说,要到真正理解面向对象的程度也是要花一点功夫的,特别是初学的同学往往意识不到面向对象的好处,因为我们编码的流程是这样的

① 面向过程

这个时候,我们要思想一个东西,往往就用一个大代码段完成了

② 方法重用

我们有时候再也受不了重复的代码在一个地方存在了,于是这个时候我们会将相同的逻辑抽象为一个方法

③ 当代码达到一定量的时候,我们发现另一个模块似乎实现了相似的功能,当前这种情况越来越多的发生时,我们会将之变成一个“类”

④ 类的出现又带来了继承等特性,这个就是我们所谓面向对象了

面向过程VS面向对象

面向过程的代码效率高,代码清晰,甚至本身不会发生耦合的现象,但这个只是适用于代码量较小或者说复杂度低的系统

系统稍微变大,面向过程的代码将变得难以维护并且难以扩展

面向对象的代码自然效率要稍低,至少代码复杂度要上升,对初学者来说不太好理解,加上模块划分后方法东一个西一个

如果没有好的设计,出来的代码会互相影响,系统层次混乱,但是好的面向对象的设计会让系统代码变得优雅并且有所依据

比如没有面向对象的类,什么观察者、工厂模式是玩不转的

所以面向过程与面向对象的设计没有明显的好坏之分,要看使用场景,系统比较复杂的话就不要去搞面向过程了,因为多人维护一个文件比上面所以问题都要复杂

此文以一个小型的坦克大战游戏来介绍“面向对象”的在前端javascript中的一些使用场景,希望对各位理解面向对象编程有所帮助

由于本人水平有限,文中想法有误,请您提出

游戏简介

游戏源码

https://github.com/yexiaochai/blade/tree/master(请看其中的tank文件夹)

http://yexiaochai.github.io/blade/tank/index.html(demo地址)

俗话说得好,没图你说个JB,我这里当然是有图的!

游戏说明

做这个游戏的目的其实主要是验证Blade框架ui.abstract.view的设计是否合理,因为我准备将他用到实际工作中了,于是这里便花了周末两天做这个游戏

PS:游戏中的图片全部是“偷”的,到现在连偷的谁的都不知道了,代码完全自己写的,这里没有抄袭

这里说是坦克大战,其实不然,因为小时候红白机的坦克大战实现起来还是要复杂的多,要实现那种程度的话两天时间怕是妄想了

于是这里实现的便是简版了,说是简版,其实他的原型是我们小时候玩的手柄游戏机中的坦克大战,不知各位还记不记得

功能玩法

游戏玩法便是与NPC坦克不停的厮杀,厮杀过程中英雄坦克会不停的升级,升级后整体性能会提升,但是随着级数增加NPC坦克的数量会不停增加

所以一般20多级我就挂了,挂了后也未做什么处理,主要原因是这两天写得太累了!!!

游戏扩展

事实上这个游戏是可以扩展的,虽然我这里未做扩展

首先子弹可做扩展,比如英雄的子弹可以变成激光或者散弹

其次NPC是可扩展的,扩展时候NPC可以设定为跟着英雄跑

以上都未实现:),这里这样说是因为游戏本身是以面向对象的方式实现,所以就算我要实现以上功能可以十分方便

代码缺陷

最初的想法很好,写面向对象的程序,但是真正代码过程中仍然有一些不够“面向对象”的写法,如果后面有时间对他进行重构,这是主要要做的事情

另外,代码写了后只经过了简单测试,有BUG就不要见外了,可以留言嘛

代码实现

其实游戏的实现,首先要有一个全局的控制器,我这里全局的控制器为app

this.app = {
//英雄升级参数
levelParameter: [
{ speed: 1, bulletSpeed: 4, maxBulletSize: 1, init: 0 },
{ speed: 1, bulletSpeed: 4, maxBulletSize: 1, init: 0 },
{ speed: 2, bulletSpeed: 6, maxBulletSize: 1, init: 0 },
{ speed: 2, bulletSpeed: 6, maxBulletSize: 2, init: 32 },
{ speed: 2, bulletSpeed: 6, maxBulletSize: 2, init: 32 },
{ speed: 2, bulletSpeed: 6, maxBulletSize: 3, init: 64 },
{ speed: 2, bulletSpeed: 6, maxBulletSize: 4, init: 64 },
{ speed: 2, bulletSpeed: 6, maxBulletSize: 4, init: 96 },
{ speed: 2, bulletSpeed: 7, maxBulletSize: 5, init: 96 }
],
npcObj: {
NO1: {
dirObj: {
init: 32 * 4
}
},
NO2: {
dirObj: {
init: 32 * (4 + 2)
},
datamodel: {
speed: 2
}
},
NO3: {
dirObj: {
init: 32 * (4 + 4)
},
datamodel: {
bulletSpeed: 6
}
},
NO4: {
dirObj: {
init: 32 * (4 + 6)
},
HP: 4
}
},
maxNpcSize: 2,
npcSize: 0,
gameStatus: false,
GAMEOBJ: {
hero: [], //暂时只有一个hero,这里先不予关注
npc: [],
heroBullet: [],
npcBullet: [],
boom: []
},
tick: $.proxy(function () {
if (this.me.status == 'destroy') {
this.app.gameStatus = false;
} $.each(this.app.GAMEOBJ, $.proxy(function (k, v) {
//首先做筛选
this.app.GAMEOBJ[k] = _.filter(this.app.GAMEOBJ[k], function (item) {
return item.status !== 'destroy';
});
for (var i = 0, len = this.app.GAMEOBJ[k].length; i < len; i++) {
this.app.GAMEOBJ[k][i].move();
}
}, this)); this.createNPC();
this.dataChange();
this.levelUp(); if (this.app.gameStatus) {
rAF($.proxy(this.app.tick, this));
} }, this),
//创建NPC坦克
createNPC: $.proxy(function (opts) {
opts = $.extend({
gameRule: 'npc',
wrapper: this.$el.find('#map'),
app: this.app
}, opts, true);
var flag = parseInt(Math.random() * 4);
if (parseInt(Math.random() * 5) == 4) {
opts.speciality = 'hp';
}
opts = $.extend(opts, this.app.npcObj['NO' + (flag + 1)], true);
console.log(opts) var npc = new NPCTank(opts);
var i, len, bullet; npc.show(); /*这里英雄每一步移动会对NPC产生影响,同样NPC会对影响造成影响
npc只需要关注英雄和英雄发出的子弹即可,英雄处理要复杂的对多
*/
this.me.registerObserver(npc);
npc.registerObserver(this.me); //缺陷,npc暂时不关注npc,可互相穿透
// $.each(this.app.GAMEOBJ.npc, function (i, item) {
// npc.registerObserver(item);
// }); //记录最后一个npc以便测试
this.npc = npc; this.app.GAMEOBJ.npc.push(npc); }, this),
//创建我方英雄坦克
createHero: $.proxy(function () {
this.me = new Tank({
datamodel: {
x: 192,
y: 192
},
gameRule: 'hero',
wrapper: this.$el.find('#map'),
app: this.app
});
this.me.show();
window.me = this.me;
this.app.GAMEOBJ.hero.push(this.me); }, this),
createBullet: $.proxy(function (opts) {
//子弹的创建要区分是hero还是npc
opts = $.extend({
wrapper: this.$el.find('#map'),
app: this.app
}, opts, true);
var gameRule = opts.gameRule;
var bullet = new Bullet(opts);
bullet.show(); //这里根据子弹角色不同,会有不同的观察对象,npc子弹对应英雄,英雄子弹对象npc! //英雄子弹需要被npc坦克以及子弹观察
if (gameRule == 'heroBullet') {
$.each(this.app.GAMEOBJ.npc, function (i, item) {
bullet.registerObserver(item);
}); $.each(this.app.GAMEOBJ.npcBullet, function (i, item) {
bullet.registerObserver(item);
});
} else if (gameRule == 'npcBullet') {
//npc子弹来了,英雄就要小心了
$.each(this.app.GAMEOBJ.hero, function (i, item) {
bullet.registerObserver(item);
}); $.each(this.app.GAMEOBJ.heroBullet, function (i, item) {
bullet.registerObserver(item);
});
} this.app.GAMEOBJ[gameRule].push(bullet); return bullet;
}, this),
createBoom: $.proxy(function (opts) {
opts = $.extend({
wrapper: this.$el.find('#map'),
app: this.app
}, opts, true);
var boom = new Boom(opts);
boom.show();
this.app.GAMEOBJ.boom.push(boom);
return boom; }, this) };

这个全局控制器扮演着“游戏时钟”的角色

 tick: $.proxy(function () {
if (this.me.status == 'destroy') {
this.app.gameStatus = false;
} $.each(this.app.GAMEOBJ, $.proxy(function (k, v) {
//首先做筛选
this.app.GAMEOBJ[k] = _.filter(this.app.GAMEOBJ[k], function (item) {
return item.status !== 'destroy';
});
for (var i = 0, len = this.app.GAMEOBJ[k].length; i < len; i++) {
this.app.GAMEOBJ[k][i].move();
}
}, this)); this.createNPC();
this.dataChange();
this.levelUp(); if (this.app.gameStatus) {
rAF($.proxy(this.app.tick, this));
} }, this),

他每过一段时间便会通知游戏对象运动一下,再根据彼此的运动引发游戏事件,这个是一个典型的发布订阅模型

游戏时钟变化,然后通知到其它所有对象运动,并且需要做对象销毁工作

而游戏对象完全继承自一个对象“moveOBJ”运动对象,继承关系为:

【blade04】用面向对象的方法写javascript坦克大战

结语

本来是想多说几句的,但是最近两天编码有点累,各位自己去看源码吧,我这里扛不住了。。。。。。

【blade04】用面向对象的方法写javascript坦克大战的更多相关文章

  1. C&num;面向对象的方法写数组的功能

    上一篇文章用Java方法写出了可以对数组执行的功能,然后在用实例化后的对象调用这些方法来实现这些功能: 这篇随笔改用C#语言实现同样的功能 方法类:Array using System; using ...

  2. 用 Python 写个坦克大战

    坦克大战是一款策略类的平面射击游戏,于 1985 年由 Namco 游戏公司发布,尽管时至今日已经有了很多衍生类的游戏,但这款游戏仍然受到了相当一部分人的欢迎,本文我们看一下如何使用 Python 来 ...

  3. 分享一下Java写的坦克大战游戏,相信很多人小时候玩过

    写在前面 程序是五六年前读书的时候写的,里面会有一些不规范的,我已经将代码传到github上了,有时间会优化修改. 程序运行机制 定义了一个JPanel,然后每隔一小段时间重绘一遍. 重绘的内容如下: ...

  4. javascript 面向对象制作坦克大战 (一)

    PS:这个坦克大战是在网上下的一段源码之后,自己进行的重写.   写这个的目的是为了巩固自己这段时间对js的学习.整理到博客上,算是对自己近端时间学习js的一个整理. 同时也希望可以帮助到学习js的园 ...

  5. javaScript面向对象继承方法经典实现

    转自原文javaScript面向对象继承方法经典实现 JavaScript的出现已经将近20多年了,但是对这个预言的褒贬还是众说纷纭.很多人都说JavaScript不能算是面向对象的变成语言.但是Ja ...

  6. 面向对象,更适合JavaScript

    面向对象程序设计是软件开发中一个很庞大很复杂的话题,它并不是仅仅学会类.继承.封装.多态这些面向对象编程语法元素就表示掌握的,这些语法元素只是实现面向对象程序的工具, 就像砖块.水泥能搭建小屋,也能造 ...

  7. js面向过程改写成面向对象--通用方法

    响亮的标题:一个万能的,保底的.面向过程改写成面向对象的方法 前提朗读:很多刚接触js面向对象的时候都不知道如何能快速的写出一个面向对象的程序,这个是必然的现象,不是每一位学js的一上来就会写面向对象 ...

  8. CoffeeScript飞一样的写javascript

    之前看到同事在使用coffeescript写js,当我看到那简介的coffee文件,就深深的被coffescript吸引了,简洁的语法,熟练之后会大大提升javascript的开发速度,写脚本也能像飞 ...

  9. js面向对象&plus;一般方法的选项卡

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

随机推荐

  1. DOM概述

    <!-- DOM:Document Object Model 文档对象模型 用来将标记型文档封装成对象,并将标记型文档中的所有内容(标签,文本,属性等)都封装成对象 封装成对象的目的是为了更为方 ...

  2. Java线程生命模型

    一. 线程状态类型1. 新建状态(New):新创建了一个线程对象.2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运 ...

  3. Thrift项目Server端开发流程

    Thrift项目Server端开发流程 首先,先了解工程中所有包的功能(见下图) 该图为用户中心项目的目录结构,以下依次介绍. 1.     src/main/java com.framework:该 ...

  4. Android中使用ContentProvider进行跨进程方法调用

    原文同一时候发表在我的博客 点我进入还能看到很多其它 需求背景 近期接到这样一个需求,须要和别的 App 进行联动交互,比方下载器 App 和桌面 App 进行联动.桌面的 App 能直接显示下载器 ...

  5. c&num;泛型约束 &lpar;where T&colon;class&rpar;

    .NET支持的类型参数约束有以下五种:where T : struct                               | T必须是一个结构类型where T : class       ...

  6. WebApi 全局使用filter

    先上代码: public static class WebApiConfig { public static void Register(HttpConfiguration config) { // ...

  7. cetus系列~ 继续分析

    一 简介:我们来继续探讨cetus的细节问题 二 命令 1 select help 查看帮助  2 select * from backends 查看后端列表  3 select conn_detai ...

  8. 2019&period;01&period;17 bzoj2333&colon; &lbrack;SCOI2011&rsqb;棘手的操作(启发式合并)

    传送门 启发式合并菜题. 题意:支持与连通块有关的几种操作. 要求支持连边,单点修改,连通块修改,全局修改和单点查值,连通块查最大值和全局最大值. 我们对每个连通块和答案用可删堆维护最大值,然后用启发 ...

  9. 【本地服务器】用nodejs搭建最简单、轻量化的http server

    1. 引言 前端程序猿主要关注的是页面,你可能根本就用不到.net,java,php等后台语言. 但是你制作出来的网页总要运行.总要测试吧?——那就免不了用到http server.我先前都是用vis ...

  10. 【洛谷】P1063 能量项链【区间DP】

    P1063 能量项链 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子, ...