首页 web前端 js教程 javascript制作坦克大战全纪录(1)_javascript技巧

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

May 16, 2016 pm 04:30 PM
javascript 面向对象

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

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

1.1    如何在地图中绘制画布

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

1.2    代码实现

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

1.2.1    创建顶级对象

html代码:

复制代码 代码如下:

 
 
 
     坦克大战
    
    
    
    
    
    
     <script><br /> window.onload = function () {<br /> // 调用游戏装载对象<br /> var loader = new GameLoader();<br /> loader.Begin();<br /> }<br /> </script>
 
 
 
    
    

    

    

    

 
 

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方法移动坦克。

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

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

探索Go语言中的面向对象编程 探索Go语言中的面向对象编程 Apr 04, 2024 am 10:39 AM

Go语言支持面向对象编程,通过类型定义和方法关联实现。它不支持传统继承,而是通过组合实现。接口提供了类型间的一致性,允许定义抽象方法。实战案例展示了如何使用OOP管理客户信息,包括创建、获取、更新和删除客户操作。

PHP高级特性:面向对象编程的最佳实践 PHP高级特性:面向对象编程的最佳实践 Jun 05, 2024 pm 09:39 PM

PHP中OOP最佳实践包括命名约定、接口与抽象类、继承与多态、依赖注入。实战案例包括:使用仓库模式管理数据,使用策略模式实现排序。

Golang中有类似类的面向对象特性吗? Golang中有类似类的面向对象特性吗? Mar 19, 2024 pm 02:51 PM

在Golang(Go语言)中并没有传统意义上的类的概念,但它提供了一种称为结构体的数据类型,通过结构体可以实现类似类的面向对象特性。在本文中,我们将介绍如何使用结构体实现面向对象的特性,并提供具体的代码示例。结构体的定义和使用首先,让我们看一下结构体的定义和使用方式。在Golang中,结构体可以通过type关键字定义,然后在需要的地方使用。结构体中可以包含属

Go语言的面向对象特性解析 Go语言的面向对象特性解析 Apr 04, 2024 am 11:18 AM

Go语言支持面向对象编程,通过struct定义对象,使用指针接收器定义方法,并通过接口实现多态。面向对象特性在Go语言中提供了代码重用、可维护性和封装,但也存在缺乏传统类和继承的概念以及方法签名强制类型转换的局限性。

如何在JavaScript中获取HTTP状态码的简单方法 如何在JavaScript中获取HTTP状态码的简单方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP状态码获取方法简介:在进行前端开发中,我们常常需要处理与后端接口的交互,而HTTP状态码就是其中非常重要的一部分。了解和获取HTTP状态码有助于我们更好地处理接口返回的数据。本文将介绍使用JavaScript获取HTTP状态码的方法,并提供具体代码示例。一、什么是HTTP状态码HTTP状态码是指当浏览器向服务器发起请求时,服务

PHP面向对象编程的深入理解:面向对象编程的调试技巧 PHP面向对象编程的深入理解:面向对象编程的调试技巧 Jun 05, 2024 pm 08:50 PM

通过掌握追踪对象状态、设置断点、追踪异常和利用xdebug扩展,可以有效调试PHP面向对象编程代码。1.追踪对象状态:使用var_dump()和print_r()查看对象属性和方法值。2.设置断点:在开发环境中设置断点,调试器将在执行到达断点时暂停,便于检查对象状态。3.追踪异常:使用try-catch块和getTraceAsString()获取异常发生时的堆栈跟踪和消息。4.利用调试器:xdebug_var_dump()函数可在代码执行过程中检查变量的内容。

JavaScript和WebSocket:打造高效的实时搜索引擎 JavaScript和WebSocket:打造高效的实时搜索引擎 Dec 17, 2023 pm 10:13 PM

JavaScript和WebSocket:打造高效的实时搜索引擎引言:随着互联网的发展,用户对实时搜索引擎的要求也越来越高。传统的搜索引擎在进行搜索时,用户需要点击搜索按钮后才能得到结果,这种方式无法满足用户对于实时搜索结果的需求。因此,采用JavaScript和WebSocket技术来实现实时搜索引擎成为了一个热门的话题。本文将详细介绍使用JavaScri

See all articles