热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

javascript制作坦克大战全纪录(1)

本文写作的目的是巩固一下自己最近学习的js知识,这个教程适合熟悉js基本语法和面向对象语法的小伙伴学习。由于自己也是刚学js不久,所以难免出现错误。如果发现希望给予指正。

PS:这个坦克大战是在网上下的一段源码之后,自己进行的重写。本身没有太难的东西,这个案例将js面向对象用的比较好,可以作为js面向对象的入门教程。

1.   创建基本对象,实现坦克简单的移动

1.1    如何在地图中绘制画布

    考虑到浏览器兼容的问题,我们用操作dom的方式来实现游戏对象的绘制和刷新。我们如何存储我们的地图呢? 我们应该把地图用一个二维数组来保存, js中没有二维数组,但是可以通过在一维数组从存储数组来实现。

1.2    代码实现

    我们将画布设计为 13 * 13 的一个二维数组,每个元素在地图中对应的长和宽均为40px,可以把整个地图看成由 40px*40p x大小的单元格组成的一个表格,那么我们整个画布的大小为 520px  *  520px ;
 
   上代码前先给大家来一张对象关系图:

1.2.1    创建顶级对象

html代码:

代码如下:

 
 
 
    
    
    
    
    
    
    
    
 
 
 
    
    

    

    

    

 
 

TankObject.js文件:
 

代码如下:

 // 顶级对象
 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";
     }
 }

 
    这里​我们用X,Y坐标表示对象在地图上的位置。后面我们会将地图中的每个对象都放入二维数组中,这时可以通过X,Y坐标来取得对应的对象。
    然后用css中的left和top来控制我们对象在窗体中的位置。(可以移动的对象:坦克,子弹)
 

1.2.2   创建公用对象

    我们还需要创建一个公共的对象,来写入我们常用的一些方法。
 
Common.js:
 

代码如下:

// 坦克移动的四个方向
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.js
 

代码如下:

 // 移动对象,继承自顶层对象
 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);
 }

 
    这里的移动对象继承自我们的顶级对象 ,这里this就代表调用Move方法的对象。
    Move对象的功能根据对象的方向和速度进行移动,每次移动5px总共移动40px一个单元格。后面这个对象还会进行扩展,会加入碰撞检测等功能。

1.2.4    创建坦克对象
 
Tank.js 文件:

代码如下:

//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();
         }
     }
 };

   游戏装载对象代码看起来很多,其实就做了两件事情:
        1、创建玩家坦克对象。
        2、添加按键监听事件,当玩家按下移动键调用坦克Move方法移动坦克。

总结:到这里我们的坦克可以通过按键自由的移动了。下一步我们需要完善地图和碰撞检测。


推荐阅读
  • 本文详细介绍了W3C标准盒模型和IE传统盒模型的区别,探讨了CSS3中box-sizing属性的使用方法及其在布局中的重要性。通过实例分析,帮助读者更好地理解和应用这一关键概念。 ... [详细]
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文详细介绍了如何使用Python编写爬虫程序,从豆瓣电影Top250页面抓取电影信息。文章涵盖了从基础的网页请求到处理反爬虫机制,再到多页数据抓取的全过程,并提供了完整的代码示例。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 在Linux系统中配置并启动ActiveMQ
    本文详细介绍了如何在Linux环境中安装和配置ActiveMQ,包括端口开放及防火墙设置。通过本文,您可以掌握完整的ActiveMQ部署流程,确保其在网络环境中正常运行。 ... [详细]
  • 如何在WPS Office for Mac中调整Word文档的文字排列方向
    本文将详细介绍如何使用最新版WPS Office for Mac调整Word文档中的文字排列方向。通过这些步骤,用户可以轻松更改文本的水平或垂直排列方式,以满足不同的排版需求。 ... [详细]
  • 几何画板展示电场线与等势面的交互关系
    几何画板是一款功能强大的物理教学软件,具备丰富的绘图和度量工具。它不仅能够模拟物理实验过程,还能通过定量分析揭示物理现象背后的规律,尤其适用于难以在实际实验中展示的内容。本文将介绍如何使用几何画板演示电场线与等势面之间的关系。 ... [详细]
  • 本文介绍如何通过Windows批处理脚本定期检查并重启Java应用程序,确保其持续稳定运行。脚本每30分钟检查一次,并在需要时重启Java程序。同时,它会将任务结果发送到Redis。 ... [详细]
  • MySQL中枚举类型的所有可能值获取方法
    本文介绍了一种在MySQL数据库中查询枚举(ENUM)类型字段所有可能取值的方法,帮助开发者更好地理解和利用这一数据类型。 ... [详细]
  • 本文介绍如何在应用程序中使用文本输入框创建密码输入框,并通过设置掩码来隐藏用户输入的内容。我们将详细解释代码实现,并提供专业的补充说明。 ... [详细]
  • 本文介绍如何通过SQL查询从JDE(JD Edwards)系统中提取所有字典数据,涵盖关键表的关联和字段选择。具体包括F0004和F0005系列表的数据提取方法。 ... [详细]
  • 如何高效创建和使用字体图标
    在Web和移动开发中,为什么选择字体图标?主要原因是其卓越的性能,可以显著减少HTTP请求并优化页面加载速度。本文详细介绍了从设计到应用的字体图标制作流程,并提供了专业建议。 ... [详细]
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
author-avatar
芙蓉花
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有