坦克大战(一)

坦克大战(一)

相信大家对坦克大战都不陌生,并且网上也有很多用java实现的小程序,最近用了几天时间将其使用javaScript语言通过面向对象的方式实现,在实现的过程中吸收了很多新的知识,现在趁着程序即将完成之际将其记录下来。

废话不多说,先上程序源码:https://github.com/safemen/TankGame2.0.git

项目需求

  在写程序之前,我们需要先大体的了解一下项目的一些需求和注意事项,方便以后的开发。

  程序在运行之前会有从下到上的开场动画,然后鼠标点击选择游戏的人数,游戏在进入每一个关卡之前会有第几关的提示,进入游戏后,玩家通过键盘操纵坦克移动,转弯,射击,与敌人交战,直到消灭所有的敌人就算过关。

开发过程

HTML

  因为本程序的HTML结构比较简单,所以在此就不多加赘述,只是在引入js文件的时候,需要注意一下引入的顺序即可。

CSS

  在css中需要根据精灵图来分配每个小型单位的样式,需要注意的是因为有些图片的缺失使用了一部分css3做出了动画效果来表现为特殊坦克。

javaScript

  本程序以javaScript为主,下面我将以在本程序开发中javaScript的编写顺序来讲述一下大体的思路。

  在程序中我们会有一个游戏控制构造函数来进行游戏的总体控制,它在其中重要的是使用定时器来控制游戏的更新,也就是我们所做的所有活动都需要定时器来更新。

  我们需要define文件保存一些常用的数据,有兴趣的可以自己重新测量一遍,但我感觉没有必要,因为我感觉写一个或者学习一个程序还是以逻辑为主,很多无必要的工作能不做就不做。而mapData中则保存的是我们的地图数据,我们可以对其进行自由的拓展。在core中我们主要保存了一些常用的方法,方便在其他的js调用。

  根据我的设计思路是首先将地图构造函数即Map.class.js设计出来,再设计物体构造函数Object.class.js,而其他的所有的对象都会派生自物体构造函数,所以这就需要我们对其他的对象进行一下公有属性和公有方法的提取,再依次设计其他对象的具体构造函数,后面再依次介绍。

  首先我们们讲一下地图构造函数的大致思路:

function Map(oParent, oRight, level) {
   this.oParent = oParent;
   this.oRight = oRight;
   this.level = level;

   this.eMapLevel = [];     //地图数组
   this.eMapLength = 0;     //地图数组的长度
   this.mapEnemyType = [];  // 保存敌方坦克的出场顺序
   this.lairEnclosure = []; //保存老巢的围墙
   this.obstacle = [];      //保存所有障碍物
}

  因为我们需要对DOM进行操作,所以我们需要写一个创建节点的方法,如下

   Map.prototype.createElem = function (sElem, sClass, sId) {
        var oElem = document.createElement(sElem);
        if (sClass) {
        oElem.className = sClass;
        }
        if (sId) {
        oElem.id = sId;
        }
        return oElem;
    }

  当我们要对地图初始化时,需要调用initMap方法

    Map.prototype.initMap = function () {

       this.initLevel();
       this.initLeftMap();
    };

  它需要获取地图数据,并保存到相关的变量中,提前获取地图数组的长度,可以在遍历数组的时候不再重复的获取消耗时间。我只写了3关,如果有兴趣可自行在mapDate.js中添加

    Map.prototype.initLevel = function () {
        switch (this.level) {
            case 1:
                this.eMapLevel = eMap.level_1.obstacles;
                this.eMapLength = eMap.level_1.obstacles.length;
                this.mapEnemyType = eMap.level_1.enemyType;
                break;
            case 2:
                this.eMapLevel = eMap.level_2.obstacles;
                this.eMapLength = eMap.level_2.obstacles.length;
                this.mapEnemyType = eMap.level_2.enemyType;
                break;
            case 3:
                this.eMapLevel = eMap.level_3.obstacles;
                this.eMapLength = eMap.level_3.obstacles.length;
                this.mapEnemyType = eMap.level_3.enemyType;
                break;
            default :
                this.eMapLevel = eMap.level_1.obstacles;
                this.eMapLength = eMap.level_1.obstacles.length;
                this.mapEnemyType = eMap.level_1.enemyType;
                break;
        }
    };

  最后一步是我们需要对左侧的地图进行初始化,值得一提的是我们对其的做法,因为我们这个程序主要是侧重于对DOM的操作,所以我们首先对每一个节点div都不设置绝对定位,当我们将地图全部加载完毕后再,将它们转化为绝对定位,这样方便以后在我们的操作中修改和判断。

Map.prototype.initLeftMap = function () {
    var oFrag = document.createDocumentFragment();

    for (var i = 0; i < this.eMapLength; i++) {
        for (var j = 0; j < this.eMapLevel[i].length; j++) {

            switch (this.eMapLevel[i][j]) {
                case 0://道路
                    var oBare = this.createElem(DIV, BARE);
                    oBare.material = 0;//用以分辨类型
                    oFrag.appendChild(oBare);
                    break;

                case 1://墙
                    var oWall = this.createElem(DIV, WALL);
                    oWall.material = 1;//用以分辨类型
                    oFrag.appendChild(oWall);
                    break;

                case 2://铁(石头)
                    var oIron = this.createElem(DIV, IRON);
                    oIron.material = 2;//用以分辨类型
                    oFrag.appendChild(oIron);
                    break;

                case 3://花
                    var oFlower = this.createElem(DIV, FLOWER);
                    oFlower.material = 3;//用以分辨类型
                    oFrag.appendChild(oFlower);
                    break;

                case 7://墙(老巢周围的墙)
                    var oWall = this.createElem(DIV, WALL);
                    oWall.material = 7;//用以分辨类型
                    oFrag.appendChild(oWall);
                    break;

                case 9://老巢
                    var oBare = this.createElem(DIV, BARE);
                    oBare.material = 0;
                    oFrag.appendChild(oBare);

                    var oLair = this.createElem(DIV, LAIR, LAIR);
                    //这个时候设置老巢为绝对定位,使其不在原来的位置不影响div的排列
                    oLair.style.position = POSITION;
                    oLair.material = 9;
                    oFrag.appendChild(oLair);
                    break;

                default :
                    break;
            }
        }
    }

    this.oParent.appendChild(oFrag);

    var oElem = this.oParent.getElementsByTagName(DIV);
    var iElemLen = oElem.length;
    var index = 0;

    //需要对每一个方块进行绝对定位,
    // 所以要计算每一个相对于左上角的偏移量就是每一个div的offsetLeft
    for (var i = 0; i < iElemLen; i++) {
        if (oElem[i].id !== LAIR) {//不是老巢
            oElem[i].style.left = oElem[i].offsetLeft + PX;
            oElem[i].style.top = oElem[i].offsetTop + PX;
        }
    }

    //给每一个元素进行绝对定位
    for (var i = 0; i < iElemLen; i++) {
        if (oElem[i].id != LAIR) {//不是老巢
            oElem[i].style.position = POSITION;
            if (oElem[i].material == 7) {  //老巢周围的墙
                oElem[i].id = index++;
                this.lairEnclosure.push(oElem[i]);
                this.obstacle.push(oElem[i]);
            } else if (oElem[i].material == 1 || oElem[i].material == 2) {
                //如果是墙或者是铁(石头),保存到障碍物数组中
                this.obstacle.push(oElem[i]);
            }
        }
    }

    //获取老巢节点
    var oLair = $(LAIR);
    //设置老巢节点的偏移量与和它上一个同级的的位置相同
    oLair.style.top = oLair.previousSibling.offsetTop + PX;
    oLair.style.left = oLair.previousSibling.offsetLeft + PX;
    oLair.style.zIndex = 6;
};

  好了,今天先暂且写到这里吧,下一次将把物体的构造思路和坦克的构造思路写一下,感觉还是比较有新意的。小弟初识javaScript面向对象设计,如有错误之处,望批评指正。

*:first-child {
margin-top: 0 !important;
}

body>*:last-child {
margin-bottom: 0 !important;
}

/* BLOCKS
=============================================================================*/

p, blockquote, ul, ol, dl, table, pre {
margin: 15px 0;
}

/* HEADERS
=============================================================================*/

h1, h2, h3, h4, h5, h6 {
margin: 20px 0 10px;
padding: 0;
font-weight: bold;
-webkit-font-smoothing: antialiased;
}

h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
font-size: inherit;
}

h1 {
font-size: 28px;
color: #000;
}

h2 {
font-size: 24px;
border-bottom: 1px solid #ccc;
color: #000;
}

h3 {
font-size: 18px;
}

h4 {
font-size: 16px;
}

h5 {
font-size: 14px;
}

h6 {
color: #777;
font-size: 14px;
}

body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
margin-top: 0;
padding-top: 0;
}

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
margin-top: 0;
padding-top: 0;
}

h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
margin-top: 10px;
}

/* LINKS
=============================================================================*/

a {
color: #4183C4;
text-decoration: none;
}

a:hover {
text-decoration: underline;
}

/* LISTS
=============================================================================*/

ul, ol {
padding-left: 30px;
}

ul li > :first-child,
ol li > :first-child,
ul li ul:first-of-type,
ol li ol:first-of-type,
ul li ol:first-of-type,
ol li ul:first-of-type {
margin-top: 0px;
}

ul ul, ul ol, ol ol, ol ul {
margin-bottom: 0;
}

dl {
padding: 0;
}

dl dt {
font-size: 14px;
font-weight: bold;
font-style: italic;
padding: 0;
margin: 15px 0 5px;
}

dl dt:first-child {
padding: 0;
}

dl dt>:first-child {
margin-top: 0px;
}

dl dt>:last-child {
margin-bottom: 0px;
}

dl dd {
margin: 0 0 15px;
padding: 0 15px;
}

dl dd>:first-child {
margin-top: 0px;
}

dl dd>:last-child {
margin-bottom: 0px;
}

/* CODE
=============================================================================*/

pre, code, tt {
font-size: 12px;
font-family: Consolas, "Liberation Mono", Courier, monospace;
}

code, tt {
margin: 0 0px;
padding: 0px 0px;
white-space: nowrap;
border: 1px solid #eaeaea;
background-color: #f8f8f8;
border-radius: 3px;
}

pre>code {
margin: 0;
padding: 0;
white-space: pre;
border: none;
background: transparent;
}

pre {
background-color: #f8f8f8;
border: 1px solid #ccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px;
}

pre code, pre tt {
background-color: transparent;
border: none;
}

kbd {
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
background-color: #DDDDDD;
background-image: linear-gradient(#F1F1F1, #DDDDDD);
background-repeat: repeat-x;
border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
border-image: none;
border-radius: 2px 2px 2px 2px;
border-style: solid;
border-width: 1px;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
line-height: 10px;
padding: 1px 4px;
}

/* QUOTES
=============================================================================*/

blockquote {
border-left: 4px solid #DDD;
padding: 0 15px;
color: #777;
}

blockquote>:first-child {
margin-top: 0px;
}

blockquote>:last-child {
margin-bottom: 0px;
}

/* HORIZONTAL RULES
=============================================================================*/

hr {
clear: both;
margin: 15px 0;
height: 0px;
overflow: hidden;
border: none;
background: transparent;
border-bottom: 4px solid #ddd;
padding: 0;
}

/* TABLES
=============================================================================*/

table th {
font-weight: bold;
}

table th, table td {
border: 1px solid #ccc;
padding: 6px 13px;
}

table tr {
border-top: 1px solid #ccc;
background-color: #fff;
}

table tr:nth-child(2n) {
background-color: #f8f8f8;
}

/* IMAGES
=============================================================================*/

img {
max-width: 100%
}
-->

时间: 2024-10-10 10:31:48

坦克大战(一)的相关文章

坦克大战系列(3.0版)

无论头上是怎样的天空,我准备承受任何风暴.--拜伦 本讲内容:坦克3.0版(面向对象的思想) 要求:画出我方坦克会动并且会发射子弹.画出敌人坦克 一.同一个包下建二个文件分别为:MyTankGame.Members(负责其它成员譬如:制造坦克.子弹等) MyTankGame类 /** * 功能:坦克游戏的3.0版本 * 1:画出坦克 * 2:实现我方坦克移动并且會發子彈,并 画出敌人的坦克 */ package a; import javax.swing.*; import java.awt.*

C++代码训练之坦克大战(2)

这一篇中,我们继续继续进行我们的坦克大战. 位置信息数据结构 在游戏设计过程中,需要记录大量的位置信息,如果仅仅使用(x,y)坐标很容易出错.这一篇中,我们先定义两个简单的数据结构用来保存点和矩形的信息. 在项目中新建Model目录,创建下面四个文件: 代码如下: Point.h #ifndef __POINT_H__ #define __POINT_H__ class Point { public: Point(int x = 0, int y = 0) : m_x(x), m_y(y){};

坦克大战(版本2.5-版本2.9)

版本2.5 功能:添加“血块”步骤:        1)添加blood类        2)添加必要的方法:eat方法等        3)让blood对象固定轨迹运动, 并在一定时间后消失 具体代码实现: 新增的blood类: 1 import java.awt.Color; 2 import java.awt.Graphics; 3 import java.awt.Rectangle; 4 5 //模拟血块,坦克吃了可以补血 6 public class Blood { 7 int x, y

脚本游戏之四: 坦克大战源码注释(待续。。。)

要点: 1.echo的高级用法,主要包括:颜色.位置定位输出等 2.trap 信号捕捉, kill 发送信号 3.捕捉用户输入,控制后台进程 参考:坦克大战 文章结尾的几段代码 总体: 多个进程后台并行运行, 前端一个段接受用户输入的代码,根据用户输入通过发送信号控制后台进程. 几乎每一个组件都是一个后台运行的函数. #!/bin/bash # BY: LingYi # DATE: 2016.02.23 #place temporary files tmpdir='/tmp' #u:up d:d

NYOJ 284 坦克大战 【BFS】+【优先队列】

坦克大战 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it on computer now. What we are discussing is a simple edition of this game. Given a map that co

Java__线程---基础知识全面实战---坦克大战系列为例

今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自己的java进行一下实战. 每个程序版本代码中,都附有相关注释,看完注释大家就可以对本程序设计有个很明显的思路.真的很有趣,想对java重新温习的同学完全不必再对厚厚的java基础书籍进行阅读了,在跟着本次代码练习并分析后,大家一定会对java各方面基础知识 尤其是线程的知识有更深一步的了解!!! 本次坦克大

【Cocos2D-x 3.5实战】坦克大战(1)环境配置

前言: 最近课比较少,空闲时间比较多,一有时间就东想西想,想着想着就突然想到做手机游戏(android)了,学习下CoCos2d.看了一些CoCos2D的相关文档和教程,觉得是时候实战了,但是苦于没有什么新奇的游戏点子,只有写下被儿时玩过的坦克大战了(主要素材好找).而这个系列的文章来记录下我的开发过程. 开发环境: Win7(x64) VS2012  下载地址: http://www.itellyou.cn/ Eclipse  下载地址:http://www.eclipse.org/downl

坦克大战系列(8.0版)

人生在勤,不索何获.--张衡 本讲内容:坦克大战8.0版(面向对象的思想) 一.解决:防止敌人坦克重叠运动 1.定义一个Vector容器,装所有敌人的坦克(为了得到所有坦克坐标) 2.定义一个方法getEts()可以得到敌人的坦克(为了得到所有坦克坐标) 3.在我的我的面板的构造方法调用getEts() 4.定义一个判断是否碰到了别的敌人的坦克的方法isTouchOtherEnemy() 5.在设置敌人坦克随机走动那调用isTouchOtherEnemy() 二.解决:我方坦克死亡(即隐身)后,

【跟我一起学Unity3D】做一个2D的90坦克大战之地图编辑器

从10月20号到现在,Unity3D也学了10天了,对于Unity3D也有了一个大致的了解,有必要做一个小游戏来检测一下自己的学习成果了.经过两天的努力,终于总算是做出来了一个可以玩的坦克大战了.首先讲讲我的设计目标: 1.地图编辑器 2.道具系统 3.简单AI系统 4.计分器 其中,最重要的就是地图编辑器了,其次到AI系统,其他几个都挺简单的. ---------------------------------------------------------------------------

Java坦克大战游戏源代码

转载自: http://blog.csdn.net/java_cxrs/article/details/3860870 经过几天的练习和研究终于自己能写出坦克大战游戏了,写完这个程序后感觉收获了很多东西,对JAVA的知识又有了一定的增长,接下来还准备继续写几个小项目来练习J2SE 由于代码太长就不发在博客里了,我上传到了资源下载里,有需要的朋友大家可以去下载 下载地址:http://download.csdn.net/source/988654