【CSON原创】基于HTML5的横版射击游戏发布

功能说明:

  基于HTML5的横版射击游戏,参考自flash游戏《双面特工》左右方向键控制移动,下方向键蹲下,上方向键跳跃,空格键射击。体验前请先关闭输入法。

  该游戏基于自己开发的HTML5游戏框架cnGameJS

效果预览:

  

 

实现分析:

  1.关于多层地图。  

  在上一个HTML5游戏《坦克后援队》中,所用的地图只为简单的单层地图,意思是地图中除了石头就是空地,仅仅只有一层的地图。但是这种单层地图具有比较大的局限性,如果需要实现场景类的游戏(例如超级玛丽和上面的游戏),只有一层的地图往往是不够的,因为我们除了游戏主角所站的障碍物外,还有游戏背景等元素(例如后面的墙壁等),因此我们需要为地图对象分层,从而达到多层展示的目的。

  新增的layer对象:

  每个layer对象维护该层的sprite,负责更新和绘制它们,并且可以获取指定坐标在该层的矩阵上的值。layer对象源码如下:

  

View Code
        /**
*层对象
*
*/
var layer = function(id,mapMatrix, options) {

if (!(this instanceof arguments.callee)) {
return new arguments.callee(id,mapMatrix, options);
}
this.init(id,mapMatrix, options);
}
layer.prototype={

/**
*初始化
*
*/
init: function(id,mapMatrix,options) {
/**
*默认对象
*
*/
var defaultObj = {
cellSize: [32, 32], //方格宽,高
x: 0, //layer起始x
y: 0 //layer起始y

};
options = options || {};
options = cg.core.extend(defaultObj, options);
this.id=options.id;
this.mapMatrix = mapMatrix;
this.cellSize = options.cellSize;
this.x = options.x;
this.y = options.y;
this.row = mapMatrix.length; //有多少行
this.width=this.cellSize[0]* mapMatrix[0].length;
this.height=this.cellSize[1]* this.row;
this.spriteList=new cg.SpriteList();//该层上的sprite列表
this.imgsReference=options.imgsReference;//图片引用字典:{"1":{src:"xxx.png",x:0,y:0},"2":{src:"xxx.png",x:1,y:1}}
this.zIindex=options.zIndex;
},
/**
*添加sprite
*
*/
addSprites:function(sprites){
if (cg.core.isArray(sprites)) {
for (var i = 0, len = sprites.length; i < len; i++) {
arguments.callee.call(this, sprites[i]);
}
}
else{
this.spriteList.add(sprites);
sprites.layer=this;
}

},
/**
*获取特定对象在layer中处于的方格的值
*
*/
getPosValue: function(x, y) {
if (cg.core.isObject(x)) {
y = x.y;
x = x.x;
}
var isUndefined = cg.core.isUndefined;
y = Math.floor(y / this.cellSize[1]);
x = Math.floor(x / this.cellSize[0]);
if (!isUndefined(this.mapMatrix[y]) && !isUndefined(this.mapMatrix[y][x])) {
return this.mapMatrix[y][x];
}
return undefined;
},
/**
*获取特定对象在layer中处于的方格索引
*
*/
getCurrentIndex: function(x, y) {
if (cg.core.isObject(x)) {
y = x.y;
x = x.x;
}
return [Math.floor(x / this.cellSize[0]), Math.floor(y / this.cellSize[1])];
},
/**
*获取特定对象是否刚好与格子重合
*
*/
isMatchCell: function(x, y) {
if (cg.core.isObject(x)) {
y = x.y;
x = x.x;
}
return (x % this.cellSize[0] == 0) && (y % this.cellSize[1] == 0);
},
/**
*设置layer对应位置的值
*
*/
setPosValue: function(x, y, value) {
this.mapMatrix[y][x] = value;
},
/**
*更新层上的sprite列表
*
*/
update:function(duration){
this.spriteList.update(duration);

},
/**
*根据layer的矩阵绘制layer和该layer上的所有sprite
*
*/
draw: function() {
var mapMatrix = this.mapMatrix;
var beginX = this.x;
var beginY = this.y;
var cellSize = this.cellSize;
var currentRow;
var currentCol
var currentObj;
var row = this.row;
var img;
var col;
for (var i = beginY, ylen = beginY + row * cellSize[1]; i < ylen; i += cellSize[1]) { //根据地图矩阵,绘制每个方格
currentRow = (i - beginY) / cellSize[1];
col=mapMatrix[currentRow].length;
for (var j = beginX, xlen = beginX + col * cellSize[0]; j < xlen; j += cellSize[0]) {
currentCol = (j - beginX) / cellSize[0];
currentObj = this.imgsReference[mapMatrix[currentRow][currentCol]];
if(currentObj){
currentObj.x = currentObj.x || 0;
currentObj.y = currentObj.y || 0;
img = cg.loader.loadedImgs[currentObj.src];
//绘制特定坐标的图像
cg.context.drawImage(img, currentObj.x, currentObj.y, cellSize[0], cellSize[1], j, i, cellSize[0], cellSize[1]);
}
}
}
//更新该layer上所有sprite
this.spriteList.draw();

}
}

  之后我们可以很方便地创建不同的层,并添加到地图中:

/*    背景矩阵    */
var bgMatrix = [
[1,1,1],
[1,1,1],
[1,1,1]
];

this.map = new cnGame.Map({width:3000,height:3000});
var newLayer=new cnGame.Layer("bg",bgMatrix, { cellSize: [1000, 1000], width: this.map.width, height: this.map.height });
newLayer.imgsReference={ "1": { src: srcObj.bg }};
this.map.addLayer(newLayer);

 

  2.关于移动场景。 

  在上一次的HTML5《游戏超级玛丽游戏demo》中,我们通过使游戏玩家的移动转换为游戏场景的移动来实现玩家固定,场景移动的效果,但是这种实现方法有比较大的问题,因为它干涉了地图和玩家的xy值的变化,因此会带来很多不便。更好的实现方法是,保持玩家和地图的xy值不变,只改变绘制它们时原点的坐标。

  view对象新增的方法:applyInView:

  applyInView方法的作用是在不改变地图和玩家实际坐标的前提下,在绘制时使view固定,其他游戏元素相对于view移动,实现移动背景的效果。例如,我们需要使玩家相对于view中点固定,该map上的其他所有游戏元素相对于view移动,我们只需要在初始化时:

        this.view=new cnGame.View({map:this.map,x:0,y:0,width:cnGame.width,height:cnGame.height});
this.view.centerElem(this.player,true);

  在绘制时:

        this.view.applyInView(function(){
map.draw();
});

  这样map内所有元素都会相对于view而移动。

  而applyInView的实现原理也非常简单,它只是不断使绘制的原点和view的坐标等长且相反:

            /**
*使坐标相对于view
*
*/
applyInView:function(func){
cg.context.save();
cg.context.translate(-this.x, -this.y);
func();
cg.context.restore();
},

  这样无论view的坐标如何变化,view在视觉上始终固定在canvas,其他元素的坐标在视觉上始终相对于view。

 

  该游戏所有源码下载地址:点击下载

  欢迎转载,请标明出处:http://www.cnblogs.com/Cson/archive/2012/03/15/2398129.html



转载于:https://www.cnblogs.com/Cson/archive/2012/03/15/2398129.html

### 回答1: protobuf是一种语言无关的数据序列化格式,可以将结构化数据以二进制形式进行存储、传输和解析。相比其他序列化格式(如JSON和XML),protobuf具有更高的效率和更小的存储空间,特别适用于性能要求较高的场景。 CSON是一种基于文本的数据交换格式,它的语法和JSON类似,但更加简洁易读。CSON可以直接嵌入到许多编程语言中,而无需额外的解析器或库。相比JSON,CSON有更好的人机可读性,可以更快地编写和解析。在一些开发工具中,如Atom编辑器,CSON被广泛用于配置文件。 当我们使用protobuf和CSON时,两者的作用是不同的。protobuf主要用于高效的数据存储和传输,主要用于网络通信和持久化存储。它定义了用于描述结构化数据的消息格式,并生成相应的编解码代码。protobuf允许我们使用预定义的消息结构定义数据模型,并将其序列化为二进制数据进行传输或存储。在接收端,我们可以将二进制数据反序列化为原始的消息结构,以进行后续处理。 CSON则更适用于配置文件和简单数据的存储和交换。与JSON相比,CSON的语法更简洁易读,可以更方便地进行人工编辑和修改。在开发过程中,我们可以使用CSON格式的配置文件来定义应用程序的设置和参数,以及其他需要在运行时进行调整的数据。CSON可以与各种编程语言一起使用,通过相应的解析库来读取和写入CSON数据。 综上所述,protobuf和CSON都是用于数据交换和存储的格式,但其使用场景和特点有所不同。protobuf适合高效的网络通信和持久化存储,而CSON则适用于配置文件和简单数据的存储和交换。 ### 回答2: protobuf cson 是 Google 开发的一种数据序列化格式,可以用于不同编程语言之间的数据交换。cson 是 CSN(CoffeeScript Object Notation)的缩写,它是一种类似于 JSON 的数据格式,但具有更简洁和易读的语法。 protobuf cson 结合了 Protocol Buffers(一种用于结构化数据的语言无关、平台无关、可扩展的序列化格式)和 cson 的优势,既可以确定数据结构,又可以通过人类可读的方式来表示数据。相比于 JSON,protobuf cson 使用更少的字符来表示相同的数据结构,因此也更加紧凑和高效。 使用 protobuf cson,开发者可以根据预先定义好的消息结构来序列化和反序列化数据。通过定义消息类型和字段,我们可以精确控制所要传输的数据结构,在不同语言中实现数据的互相转换。同时,protobuf cson 还支持扩展和向后兼容性,可以轻松地向已有的消息类型添加新的字段。 protobuf cson 在分布式系统、微服务架构以及网络通信中广泛应用。它的高效和灵活性使得数据的传输和解析更加方便和高效。此外,由于具备易读的特性,一些配置文件和参数文件也可以使用 protobuf cson 进行存储和传输。 总而言之,protobuf cson 是一种强大的数据序列化格式,它兼具 Protocol Buffers 和 cson 的优势。通过结构化和紧凑的表示,protobuf cson 提供了高效的数据传输和解析方式,广泛应用于不同领域和语言环境中。 ### 回答3: protobuf是一种数据序列化格式,用于将结构化数据转化为可传输和存储的二进制格式。而CSON则是一种用于存储和表示数据的文本格式,类似于JSON,但更接近于CoffeeScript语法。 protobuf和CSON在功能和用途上有一些差异。protobuf适合用于高效地序列化和反序列化数据,并且可以在多种编程语言之间进行数据交换。它使用二进制格式,因此在数据传输和存储方面更高效,尤其是对于大量数据和复杂结构的数据。protobuf还提供了强大的扩展和版本控制机制,使得在不同版本之间进行数据兼容性处理更加方便。 CSON则更加适用于人类可读和可编辑的数据表示。它使用文本格式并支持类似于CoffeeScript的语法,因此更加容易阅读和理解。与JSON相比,CSON提供了一些额外的功能,比如支持注释和多行字符串。但是,CSON相对于protobuf而言在性能上差一些,因为它需要将文本转换为内部数据结构,并且在解析和生成过程中需要进行额外的处理。 总的来说,如果需要高效的数据传输和存储,或者需要跨多种编程语言进行数据交换,protobuf是更好的选择。而如果需要人类可读和可编辑的数据表示,或者对数据格式有更高的灵活性要求,使用CSON可能更合适。但是,具体使用哪种格式还是要根据具体的应用场景和需求来决定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值