前言:
  勿忘初心, 本系列的目标是实现一款类似QQ"火拼系列"人机对战版俄罗斯方块. 在完成了基本游戏框架和AI的算法探索后, 让我们来尝试一下人机大战雏形编写.
  本系列的文章链接如下:
  1). 需求分析和目标创新 
  2). 游戏的基本框架和实现
  3). 游戏的AI算法 
  这些博文和代码基本是同步的, 并不确定需求是否会改变, 进度是否搁置, 但期翼自己能坚持和实现.

演示&下载:

  在线版本, 点击试玩(求点击, 求轻拍, ^_^).
  该版本界面依旧简陋, 效果如图所示:
   
  注: 左边为玩家, 右边为机器人, 使用键盘方向键(上下左右)控制.

  代码下载地址: http://pan.baidu.com/s/1gd2Hl6b
  下载解压目录结构如下所示:
  
  点击tetris.html, 在浏览器上运行(由于HTML5程序, 最好在Chrome/Firefox上运行).

游戏策划:
  游戏采用人机对战的方式, 是为了让玩家有个参照物. 这样在游戏过程中, 始终处于之中激烈的竞技状态中, 同时又有明确的目标(打败对方).
  当前整个游戏还不是很完全, 只是简单做了改造.
  1). 引入准备界面
  
  犹如短跑的发枪令一样, 让玩家有短暂时间去准备.
  2). 限定游戏时间
  
  由于AI机器人的强大(跑一天也不会挂), 因此无时间限定的挑战, 用户玩家必然会崩溃. 由此引入一个合适的时间限定. 在这个时间窗口中, 谁得分高, 谁就是最后的赢家.
  引入了这两个之后, 感觉游戏的可玩性强了很多, ^_^.

源码解读:
  代码文件结构如图所示:
  
  • game_engine.js: 定义了游戏引擎了一些基本类.
  • tetris_player.js: 封装了玩家和机器人的agent类.
  • tetris_game.js: 实现了具体的scene和layer类, 并用状态模式串联.
  游戏编程中, 状态模式(state pattern)以及状态机(state machine)尤被推崇. 程序中并没有完全按照该模式来实现, 不过多少有些影子.
  场景(Scene)和画板层(Layer)的类结构如下所示:
  
  BaseScene的类定义如下:

    function BaseScene() {
this.currentLayer = null;
} BaseScene.prototype.switchLayer = function(baseLayer) {
// *) 上一个画板层执行 exitLayer的操作
if ( this.currentLayer != null ) {
this.currentLayer.exitLayer();
}
this.currentLayer = baseLayer;
// *) 下一个画板层执行 entryLayer的操作
if ( this.currentLayer != null ) {
this.currentLayer.entryLayer();
}
} BaseScene.prototype.update = function(interval) {
if ( this.currentLayer != null ) {
this.currentLayer.update(interval);
}
} BaseScene.prototype.render = function(ctx) {
if ( this.currentLayer != null ) {
this.currentLayer.render(ctx);
}
}

  BaseLayer的类定义如下:

    function BaseLayer() {
} BaseLayer.prototype.entryLayer = function() {
} BaseLayer.prototype.exitLayer = function() {
} BaseLayer.prototype.update = function(interval) {
} BaseLayer.prototype.render = function(ctx) {
}

  角色之间的交互, 往往采用消息通知的机制来实现. 不过该程序并没有实现. 对于玩家和机器人, 其通过BasePlayer来进行了抽象. 其类结构如下所示:
  
  对于其他部分的代码, 这边不再具体展开, 请详细见该系列的前面几篇文章.

总结:
  人机对战的实现进展还是比较顺利的, 一方面游戏本身比较简单, 另一方面之前做了很多铺垫的工作. 但越写到后面, 越发觉得一个好的游戏引擎对一个游戏编写的重要性. 犹如IDE对于代码编写的重要性. 后续想借助cocos2d-js来实现, 站在巨人的肩膀上, 看得更远.
  希望自己能坚持, 完成最初的目标和设想. 也期待你的关注.

写在最后:
  
如果你觉得这篇文章对你有帮助, 请小小打赏下. 其实我想试试, 看看写博客能否给自己带来一点小小的收益. 无论多少, 都是对楼主一种由衷的肯定.

  

最新文章

  1. tp5 model 中的查询范围(scope)
  2. 【hbase】——bulk load导入数据时value=\x00\x00\x00\x01问题解析
  3. 【MySQL】锁入门
  4. [杂题]URAL2047. Maths
  5. Chrome&FF&Opera&下DIV不设置高度显示背景颜色和边框的办法
  6. [wikioi]没有上司的舞会
  7. 基于visual Studio2013解决C语言竞赛题之0803报数
  8. HashMap源码解读(转)
  9. Python IDLE快捷键一览
  10. 小白学爬虫-在无GUI的CentOS上使用Selenium+Chrome
  11. 2017 ES GZ Meetup分享:Data Warehouse with ElasticSearch in Datastory
  12. MySQL delete语句的问题
  13. 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象
  14. [基础知识]在PeopleSoft中SMTP设置不生效如何查找问题
  15. Go语言Windows 10开发环境搭建:Eclipse+GoClipse
  16. Hibernate 中 联合主键映射 组合关系映射 大对象映射(或者说文本大对象,二进制数据大对象)
  17. BZOJ 1211[HNOI2004]树的计数 - prufer数列
  18. POJ 1046
  19. Java:HttpClient篇,HttpClient4.2在Java中的几则应用:Get、Post参数、Session(会话)保持、Proxy(代理服务器)设置,多线程设置...
  20. Arrays.sort和Collections.sort实现原理解析

热门文章

  1. [Python爬虫]cnblogs博客备份工具(可扩展成并行)
  2. php : 工厂类演示
  3. Windows Internals学习笔记(六)Windows关键系统组件
  4. odoo定时任务
  5. springMVC的两种下载方式
  6. windows服务相关
  7. A:石头剪刀布
  8. Java—接口与抽象类
  9. 如何做出header,footer固定定位后让main主体部分可以滑动,在微信浏览器中滑动到最后不出现黑边的情况
  10. iOS开发UI篇—实现UItableview控件数据刷新