Cocos2d-x-html5 之 HelloWorld 深入分析与调试

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6


Cocos2d-x-html5之HelloWorld深入分析与调试

 另:本章所用Cocos2d-x版本为:

​Cocos2d-html5-v2.1.1​

​http://cn.cocos2d-x.org/download​


 

         html5的时代正在来临,其可以方便的运行在多平台上并调用OPENGL 进行图形渲染,大量使用html5开发的2D和3D游戏正在涌现,Cocos2d-x也顺应形势推出了相应的版本,今天我们来学习一下Cocos2d-x在Html5上怎么运行和开发及调试。

 

         打开HelloHTML5World,可以看到以下文件和目录:


res:资源图片目录:

Cocos2d-x-html5 之 HelloWorld 深入分析与调试_2d

​src:当前程序的js文件目录:​

Cocos2d-x-html5 之 HelloWorld 深入分析与调试_加载_02



main.js:主逻辑js代码文件

index.html:html5网页文件

cocos2d.js:加载Cocos2d-x库的文件

build.xml:编译cocos2d-x的html5平台版本生成的文件清单报告。

.DS_Store:系统目录显示属性存储文件,可以删除。

我们用浏览器直接打开index.html,可以看到:


Cocos2d-x-html5 之 HelloWorld 深入分析与调试_Cocos2d-x_03


     其源码为:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cocos2d-html5 Hello World test</title>
<link rel="icon" type="image/GIF" href="res/favicon.ico"/>
</head>
<body style="padding:0; margin: 0; background: #000;">
<div style="text-align: center; font-size: 0">
<canvas id="gameCanvas" width="800" height="450"></canvas>
</div>
</body>
</html>
<script src="cocos2d.js"></script>


可以看到,这里面关键的要点是两个地方:

1.  <canvas id="gameCanvas"width="800" height="450"></canvas>

在html5中创建了一个画布(canvas),设定了名称和大小

2.  <scriptsrc="cocos2d.js"></script>

在网页中加载了cocos2d.js

打开cocos2d.js后,可以看到下面的代码:

(function () {
//定义变量d为当前网页的文档对象
var d = document;
//定义变量c为一个结构,存储了一些配置属性和值。
var c = {
COCOS2D_DEBUG:2, //0 to turn debug off, 1 for basic debug, and 2 for full debug
box2d:false,//不使用box2d
chipmunk:false,//不使用chipmunk
showFPS:true,//显示FPS
frameRate:60,//设定每秒60帧
loadExtension:false,不载入扩展库
tag:'gameCanvas', //运行cocos2d-x的画布
engineDir:'../cocos2d/',//引擎的目录,这里指定为当前上级目录下的cocos2d目录中
//SingleEngineFile:'',//这里注释掉了。
appFiles:[//应用程序要使用到的两个js文件。
'src/resource.js',//资源定义文件
'src/myApp.js'//逻辑处理文件
]
};
//当前窗口加载一个事件响应处理,在DOM被加载时调用。
window.addEventListener('DOMContentLoaded', function () {
//当前文档创建一个脚本
var s = d.createElement('script');
//如果c结构中有SingleEngineFile变量并肯engineDir为空,则s中的脚本引用为SingleEngineFile指示的文件,当然,本例中这个变量注释掉了,这一段不成立。
if (c.SingleEngineFile && !c.engineDir) {
s.src = c.SingleEngineFile;
}
//如果engineDir有效,则s中的脚本引用为engineDir指定目录下的相应文件,本例中为“../cocos2d/platform/jsloader.js”。
else if (c.engineDir && !c.SingleEngineFile) {
s.src = c.engineDir + 'platform/jsloader.js';
}
else {
//如果都不是,弹出对话框提示c结构成员变量设置错误。
alert('You must specify either the single engine file OR the engine directory in "cocos2d.js"');
}
//将结构c做为一个成员变量存入到当前文档。
document.ccConfig = c;
//上面创建的‘script’的id设置为’cocos2d-html5’.
s.id = 'cocos2d-html5';
//将这个script加入到当前HTML文档的结尾。
d.body.appendChild(s);
//else if single file specified, load singlefile
});
})();


本页代码的作用是在html页面尾部中加入:


“<scriptsrc = ’../cocos2d/platform/jsloader.js’ id=’cocos2d-html5’></script>

下面我们来打开cocos2d目录下的’platform/jsloader.js’:

//脚本执行函数。
(function () {
//定义变量engine为一个字符串数组,元素为运行当前版本cocos2d-x要加载的所有代码文件。
var engine = [
'platform/CCClass.js',
'platform/miniFramework.js',
'platform/CCCommon.js',
'platform/ZipUtils.js',
'platform/base64.js',
'platform/gzip.js',
'platform/CCMacro.js',
'platform/CCFileUtils.js',
'platform/CCTypes.js',
'platform/zlib.min.js',
'cocoa/CCGeometry.js',
'platform/Sys.js',
'platform/CCConfig.js',
'cocoa/CCSet.js',
'cocoa/CCNS.js',
'cocoa/CCAffineTransform.js',
'support/CCPointExtension.js',
'support/CCUserDefault.js',
'base_nodes/CCNode.js',
'base_nodes/CCAtlasNode.js',
'textures/CCTexture2D.js',
'textures/CCTextureCache.js',
'textures/CCTextureAtlas.js',
'misc_nodes/CCRenderTexture.js',
'misc_nodes/CCProgressTimer.js',
'effects/CCGrid.js',
'effects/CCGrabber.js',
'actions/CCAction.js',
'actions/CCActionInterval.js',
'actions/CCActionInstant.js',
'actions/CCActionManager.js',
'actions/CCActionProgressTimer.js',
'actions/CCActionCamera.js',
'actions/CCActionEase.js',
'actions/CCActionGrid.js',
'actions/CCActionTiledGrid.js',
'actions/CCActionCatmullRom.js',
'layers_scenes_transitions_nodes/CCScene.js',
'layers_scenes_transitions_nodes/CCLayer.js',
'layers_scenes_transitions_nodes/CCTransition.js',
'layers_scenes_transitions_nodes/CCTransitionProgress.js',
'layers_scenes_transitions_nodes/CCTransitionPageTurn.js',
'sprite_nodes/CCSprite.js',
'sprite_nodes/CCAnimation.js',
'sprite_nodes/CCAnimationCache.js',
'sprite_nodes/CCSpriteFrame.js',
'sprite_nodes/CCSpriteFrameCache.js',
'sprite_nodes/CCSpriteBatchNode.js',
'label_nodes/CCLabelAtlas.js',
'label_nodes/CCLabelTTF.js',
'label_nodes/CCLabelBMFont.js',
'particle_nodes/CCParticleSystem.js',
'particle_nodes/CCParticleSystemQuad.js',
'particle_nodes/CCParticleExamples.js',
'particle_nodes/CCParticleBatchNode.js',
'touch_dispatcher/CCTouchDelegateProtocol.js',
'touch_dispatcher/CCTouchHandler.js',
'touch_dispatcher/CCTouchDispatcher.js',
'touch_dispatcher/CCMouseDispatcher.js',
'keyboard_dispatcher/CCKeyboardDelegate.js',
'keyboard_dispatcher/CCKeyboardDispatcher.js',
'text_input_node/CCIMEDispatcher.js',
'text_input_node/CCTextFieldTTF.js',
'CCDirector.js',
'CCCamera.js',
'CCScheduler.js',
'CCLoader.js',
'CCDrawingPrimitives.js',
'platform/CCApplication.js',
'platform/CCSAXParser.js',
'platform/AppControl.js',
'menu_nodes/CCMenuItem.js',
'menu_nodes/CCMenu.js',
'tileMap_parallax_nodes/CCTMXTiledMap.js',
'tileMap_parallax_nodes/CCTMXXMLParser.js',
'tileMap_parallax_nodes/CCTMXObjectGroup.js',
'tileMap_parallax_nodes/CCTMXLayer.js',
'tileMap_parallax_nodes/CCParallaxNode.js',
'menu_nodes/CCMenuItem.js',
'menu_nodes/CCMenu.js',
'base_nodes/CCdomNode.js',
'../CocosDenshion/SimpleAudioEngine.js'

];
//取得当前文档存入d,取得上一节中创建的当前d的成员变量ccCofing存入c.
var d = document;
var c = d.ccConfig;
//如果c的结构变量loadExtension有效,即当前程序需要加载扩展库,则在上面的变量engine所对应的字符串数组尾部添加cocos2d-x扩展库所涉及的代码文件。
if (c.loadExtension != null && c.loadExtension == true) {
engine = engine.concat([
'../extensions/GUI/CCControlExtension/CCControl.js',
'../extensions/GUI/CCControlExtension/CCControlButton.js',
'../extensions/GUI/CCControlExtension/CCControlUtils.js',
'../extensions/GUI/CCControlExtension/CCInvocation.js',
'../extensions/GUI/CCControlExtension/CCScale9Sprite.js',
'../extensions/GUI/CCControlExtension/CCMenuPassive.js',
'../extensions/GUI/CCControlExtension/CCControlSaturationBrightnessPicker.js',
'../extensions/GUI/CCControlExtension/CCControlHuePicker.js',
'../extensions/GUI/CCControlExtension/CCControlColourPicker.js',
'../extensions/GUI/CCControlExtension/CCControlSlider.js',
'../extensions/GUI/CCControlExtension/CCControlSwitch.js',
'../extensions/GUI/CCScrollView/CCScrollView.js',
'../extensions/GUI/CCScrollView/CCSorting.js',
'../extensions/GUI/CCScrollView/CCTableView.js',
'../extensions/CCBReader/CCNodeLoader.js',
'../extensions/CCBReader/CCBReaderUtil.js',
'../extensions/CCBReader/CCControlLoader.js',
'../extensions/CCBReader/CCSpriteLoader.js',
'../extensions/CCBReader/CCNodeLoaderLibrary.js',
'../extensions/CCBReader/CCBReader.js',
'../extensions/CCBReader/CCBValue.js',
'../extensions/CCBReader/CCBKeyframe.js',
'../extensions/CCBReader/CCBSequence.js',
'../extensions/CCBReader/CCBRelativePositioning.js',
'../extensions/CCBReader/CCBAnimationManager.js',
'../extensions/CCControlEditBox.js'
]);
}

//如果c中的engineDir设置无效,清空engine。
if (!c.engineDir) {
engine = [];
}
else {
//如果c中的engineDir设置有效
//如果c的结构中有结构变量box2d和chipmunk,则在变量engine所对应的字符串数组尾部添加cocos2d-x物理引擎库所涉及的代码文件。
if(c.box2d || c.chipmunk){
engine.push('Draw_Nodes/CCDrawNode.js');
engine.push('physics_nodes/CCPhysicsSprite.js');
engine.push('physics_nodes/CCPhysicsDebugNode.js');
if (c.box2d)
engine.push('../box2d/box2d.js');
if (c.chipmunk)
engine.push('../chipmunk/chipmunk.js');
}
//遍历engine中的所有元素,将各元素的文件相对目录转变为绝对目录。
engine.forEach(function (e, i) {
engine[i] = c.engineDir + e;
});
}
//定义量时变量
var loaded = 0;
//在engine最尾部加上c的结构变量appFiles (即当前程序资源和逻辑所对应的js),将新数组保存到que。
var que = engine.concat(c.appFiles);
//再加上当前程序的主逻辑js文件。
que.push('main.js');
//判断浏览器是否是IE9
if (navigator.userAgent.indexOf("Trident/5") > -1) {
//如果是IE9
//创建一个局部变量serial,存值-1
this.serial = -1;
//定义一个函数loadNext
var loadNext = function () {
//定义临时变量s为serial+1
var s = this.serial + 1;
//如果s所指定的索引小于que的数组数量.
if (s < que.length) {
//当前文档创建一个脚本标记,保存为变量f
var f = d.createElement('script');
//设置script的src为索引s指定的que数组元素。
f.src = que[s];
//将索引s存入f成员变量serial。
f.serial = s;
//设定scrip在被加载时调用函数loadNext。
f.onload = loadNext;
//将scrip放入到当前HTML文档的结尾.
d.body.appendChild(f);
//将数组的加载进度保存到临时变量p,在当前位置你可以处理你的加载进度条。
p = s / (que.length - 1);
}
};
//调用一下刚创建的函数,执行第一次后,就会不断的在html文档结尾加入:‘<script src = ‘这里为que[新索引]’ serial=’索引’ οnlοad=’loadNext’></script>’。

loadNext();
}
else {
//如果不是IE9,则遍历que数组的每个元素。
que.forEach(function (f, i) {
//当前文档创建一个脚本标记,保存为变量s
var s = d.createElement('script');
//设置scrip的async变量为false. 目前firefox和chrome都是实现了script标签的async属性.这个新的属性能让我们以一种更 简单的方式防止浏览器阻塞
s.async = false;
//设置script的src变量值为遍历元素。
s.src = f;
//设定加载时调用函数更新进度计算。
s.onload = function () {
loaded++;
p = loaded / que.length;
//TODO: code for updating progress bar
};
//将scrip放入到当前HTML文档的结尾.
d.body.appendChild(s);
//将s保存到que数组的第i个数组元素中。
que[i] = s;

});
}
})();//最后的()代表当前函数被调用。


        可见jsloader.js的作用是加载cocos2d-x所要用到的所有js文件以及‘resource.js’,‘myApp.js’,‘main.js’。

        打开’resource.js’:

//定义一些资源文件字符串变量。
var s_HelloWorld = "res/HelloWorld.png";
var s_CloseNormal = "res/CloseNormal.png";
var s_CloseSelected = "res/CloseSelected.png";
//创建一个结构数组,标记文件类型和对应的文件名称字符串。
var g_ressources = [
//image
{type:"image", src:s_HelloWorld},
{type:"image", src:s_CloseNormal},
{type:"image", src:s_CloseSelected}

//plist

//fnt

//tmx

//bgm

//effect
];


上面的文件主要是就是定义程序所要用到的资源信息。

打开myApp.js:

//创建一个cocos2d-x精灵的派生类存入CircleSprite用于计时.初始化成员变量_radians为0,即不旋转。
var CircleSprite = cc.Sprite.extend({
_radians:0,
//重载父类(精灵) 构造函数ctor,调用其父类的相应函数。
ctor:function () {
this._super();
},
//重载父类(精灵)成员函数draw。增加绘制代码。
draw:function () {
//设置要绘制时的设置信息
//填充色为白色
cc.renderContext.fillStyle = "rgba(255,255,255,1)";
//画笔色为白色
cc.renderContext.strokeStyle = "rgba(255,255,255,1)";
//如果当前精灵的_radians小于0,则重置为360。
if (this._radians < 0)
this._radians = 360;
//调用cocos2d-x的绘制圆的函数,这个函数是在CCDrawingPrimitives.js中定义的,drawCircle:function (center, radius, angle, segments, drawLineToCenter),参一为中心位置,参二为半径,参三为绘制的起始角度当然也是中心连线的起始角度,参四为圆的段数,参五为是否与中心连线。
cc.drawingUtil.drawCircle(cc.PointZero(), 30, cc.DEGREES_TO_RADIANS(this._radians), 60, true);
},
//定义成员函数myUpdate,用于每次调用时成员变量_raduans自减6。等于每次调用顺时针旋转6度,因为设定FPS为60,所以一秒转一圈正好360度嘛。
myUpdate:function (dt) {
this._radians -= 6;
//this._addDirtyRegionToDirector(this.getBoundingBoxToWorld());
}
});

//由Cocos2d-x的层派生出一个类HelloWorld.
var Helloworld = cc.Layer.extend({
//初始化其成员变量
isMouseDown:false,
helloImg:null,
helloLabel:null,
circle:null,
sprite:null,
//初始化函数。
init:function () {
//定义临时变量保存当前实例指针。
var selfPointer = this;
//首先调用父类精灵的初始化函数。
this._super();

//取得窗口的大小
var size = cc.Director.getInstance().getWinSize();

//增加一个菜单按钮,设置点击后响应函数退回前一步。
var closeItem = cc.MenuItemImage.create(
"res/CloseNormal.png",
"res/CloseSelected.png",
function () {
history.go(-1);
},this);
//设置菜单按钮精灵的锚点。
closeItem.setAnchorPoint(cc.p(0.5, 0.5));
//由菜单按钮创建一个菜单,设置菜单位置并放入当前层下。
var menu = cc.Menu.create(closeItem);
menu.setPosition(cc.PointZero());
this.addChild(menu, 1);
//设置菜单按钮的位置。
closeItem.setPosition(cc.p(size.width - 20, 20));

//创建一个文字标签,显示字符串“HelloWorld”。
this.helloLabel = cc.LabelTTF.create("Hello World", "Arial", 38);
//设置横向居中显示。
this.helloLabel.setPosition(cc.p(size.width / 2, 0));
//将文字标签加入到当前层下。
this.addChild(this.helloLabel, 5);
//创建一个新层lazyLayer并放入当前层
var lazyLayer = new cc.LazyLayer();
this.addChild(lazyLayer);

// 创建当前类成员精灵,设置位置,缩放,旋转。
this.sprite = cc.Sprite.create("res/HelloWorld.png");
this.sprite.setPosition(cc.p(size.width / 2, size.height / 2));
this.sprite.setScale(0.5);
this.sprite.setRotation(180);
//将新建的精灵放入到层lazyLayer.
lazyLayer.addChild(this.sprite, 0);

//创建两个动画。
var rotateToA = cc.RotateTo.create(2, 0);
var scaleToA = cc.ScaleTo.create(2, 1, 1);
//让精灵运行一个动画序列,动画序列为这两个新建的动画。
this.sprite.runAction(cc.Sequence.create(rotateToA, scaleToA));
//创建一个计时精灵类,设置位置并放入到当前层中。
this.circle = new CircleSprite();
this.circle.setPosition(cc.p(40, size.height - 60));
this.addChild(this.circle, 2);
//这句很重要,每1/60秒响应一次它的MyUpdate函数更新。
this.circle.schedule(this.circle.myUpdate, 1 / 60);
//当前文字标签到运行一个移动动画。
this.helloLabel.runAction(cc.MoveBy.create(2.5, cc.p(0, size.height - 40)));
//开启当前视窗的触屏响应处理。
this.setTouchEnabled(true);
//这一句调用是让屏幕的分辩率按窗口大小来自适应避免拉伸。
this.adjustSizeForWindow();
//lazyLayer层的分辩率按所在画布的大小来自适应避免拉伸。
lazyLayer.adjustSizeForCanvas();
//设置当前窗口在改变大小时要调用函数adjustSizeForWindow
window.addEventListener("resize", function (event) {
selfPointer.adjustSizeForWindow();
});
return true;
},
//如果窗口在改变大小时要调用的函数,现实等比调整Cocos2d-x画布大小以适应填充网页客户区。
adjustSizeForWindow:function () {
//窗口客户端宽度减去body区域宽度,得到一个差值保存到新创建变量margin。
var margin = document.documentElement.clientWidth - document.body.clientWidth;
//如果客户端宽度小于html5中画布宽度800,设置cocos2d-x画布的宽度按照html5中画布宽度800设置,这里是限制了显示cocos2d-x画面的最小宽度。
if (document.documentElement.clientWidth < cc.originalCanvasSize.width) {
cc.canvas.width = cc.originalCanvasSize.width;
} else {
//否则,设置cocos2d-x画布的宽度按照html5中body宽度设置。
cc.canvas.width = document.documentElement.clientWidth - margin;
}
//如果可见区域高度小于html5中画布高度450,设置cocos2d-x画布的高度按照html5中画布高度450设置。
if (document.documentElement.clientHeight < cc.originalCanvasSize.height) {
cc.canvas.height = cc.originalCanvasSize.height;
} else {
//否则,设置cocos2d-x画布的高度按照html5中body高度设置。
cc.canvas.height = document.documentElement.clientHeight - margin;
}
//计算出cocos2d-x的画布与HTML5上的画布的缩放比例
var xScale = cc.canvas.width / cc.originalCanvasSize.width;
var yScale = cc.canvas.height / cc.originalCanvasSize.height;
//因为一般窗口都是宽大于高,所以这里做个处理,使画面保持等比缩放。
if (xScale > yScale) {
xScale = yScale;
}
//根据等比缩放重新计算出Cocos2d-x中画布的宽高。
cc.canvas.width = cc.originalCanvasSize.width * xScale;
cc.canvas.height = cc.originalCanvasSize.height * xScale;
//取得网页中id为Cocos2dGameContainer的文档div元素。
var parentDiv = document.getElementById("Cocos2dGameContainer");
if (parentDiv) {
//如果找到了设置其style中的宽和高按画布的像素大小
parentDiv.style.width = cc.canvas.width + "px";
parentDiv.style.height = cc.canvas.height + "px";
}
//设置cocos2d-x中渲染区域向上移动相应距离及设置相应缩放。
cc.renderContext.translate(0, cc.canvas.height);
cc.renderContext.scale(xScale, xScale);
//设置cocos2d-x的像素与点的缩放比例。
cc.Director.getInstance().setContentScaleFactor(xScale);
},
// 菜单按扭(关闭按钮)按下时的响应处理。
menuCloseCallback:function (sender) {
//终止cocos2d-x设备运行。
cc.Director.getInstance().end();
},
//当触屏按下事件被响应时的处理。
onTouchesBegan:function (touches, event) {
//设置当前层的成员变量isMouseDown为ture
this.isMouseDown = true;
},
//当触屏按下并移动事件被响应时的处理。
onTouchesMoved:function (touches, event) {
//判断如果isMouseDown为ture。
if (this.isMouseDown) {
//如果触点有效.
if (touches) {
//这里本来是显示触点的,但屏蔽了。
//this.circle.setPosition(cc.p(touches[0].getLocation().x, touches[0].getLocation().y));
}
}
},
//当触屏松开事件响应时的处理
onTouchesEnded:function (touches, event) {
//设置当前层的成员变量isMouseDown为false
this.isMouseDown = false;
},
//当触摸被取消(比如触摸过程中被来电打断),就会调用touchesCancelled方法。
onTouchesCancelled:function (touches, event) {
//控制台输出日志
console.log("onTouchesCancelled");
}
});
//创建一个cocos2d-x的场景的派生类HelloWorldScene。
var HelloWorldScene = cc.Scene.extend({
//重载onEnter函数指定在场景被加载时要做的处理。
onEnter:function () {
//先调用基类cc.Scene的相应处理。
this._super();
//创建一个Helloworld层的实例并初始化。
var layer = new Helloworld();
layer.init();
//将这个层加入到当前场景。
this.addChild(layer);
}
});


 

adjustSizeForWindow



     

好,现在开始动刀:


在Helloworld层中加入变量

sizeLabel:null,

然后我们在HelloWorld文字标签之后加入:

//显示大小

this.sizeLabel =cc.LabelTTF.create("ClientSize:CanvasSize","Arial",16);

this.sizeLabel.setPosition(cc.p(size.width / 2, 100));

this.addChild(this.sizeLabel, 4);

 

最后我们在adjustSizeForWindow函数尾部加入:

//字符串变量

                  var sizeString= "ClientSize:[Width:"+document.documentElement.clientWidth+",Height:"+document.documentElement.clientHeight+"]- bodySize:[Width:" +document.body.clientWidth+",Height:"+document.body.clientHeight+"]-CanvasSize:[Width:"+cc.canvas.width+",Height:"+cc.canvas.height+"]";

                  this.sizeLabel.setString(sizeString);


运行一下:

Cocos2d-x-html5 之 HelloWorld 深入分析与调试_2d_04



这样就可以很方便的观察各个大小了。

然后我们来继续修改代码。首先将创建lazyLayer代码屏蔽  :  

// var lazyLayer =new cc.LazyLayer();

 // this.addChild(lazyLayer);

 

并将lazyLayer加入当前层的代码

//lazyLayer.addChild(this.sprite, 0);

换成:

this.addChild(this.sprite);

 

lazyLayer设置大小自适应代码屏蔽:

//lazyLayer.adjustSizeForCanvas();

 

 

之后修改adjustSizeForWindow:

adjustSizeForWindow:function () {
/*屏蔽原来的代码。
var margin = document.documentElement.clientWidth - document.body.clientWidth;
if (document.documentElement.clientWidth < cc.originalCanvasSize.width) {
cc.canvas.width = cc.originalCanvasSize.width;
} else {
cc.canvas.width = document.documentElement.clientWidth - margin;
}
if (document.documentElement.clientHeight < cc.originalCanvasSize.height) {
cc.canvas.height = cc.originalCanvasSize.height;
} else {
cc.canvas.height = document.documentElement.clientHeight - margin;
}
*/
//直接将画布大小设为窗口页面大小
cc.canvas.width = document.documentElement.clientWidth;
cc.canvas.height = document.documentElement.clientHeight;
//计算X方向和Y方向的缩放
var xScale = cc.canvas.width / cc.originalCanvasSize.width;
var yScale = cc.canvas.height / cc.originalCanvasSize.height;
/*
if (xScale > yScale) {
// xScale = yScale;
}
cc.canvas.width = cc.originalCanvasSize.width * xScale;
cc.canvas.height = cc.originalCanvasSize.height * yScale;
*/
var parentDiv = document.getElementById("Cocos2dGameContainer");
if (parentDiv) {
parentDiv.style.width = cc.canvas.width + "px";
parentDiv.style.height = cc.canvas.height + "px";
}
//设置渲染缓冲区位置和缩放。
cc.renderContext.translate(0, cc.canvas.height);
cc.renderContext.scale(xScale, yScale);
cc.Director.getInstance().setContentScaleFactor(xScale);

//字符串变量
var size = cc.Director.getInstance().getWinSize()
var sizeString = "ClientSize:[Width:"+document.documentElement.clientWidth+",Height:"+document.documentElement.clientHeight+"] - bodySize:[Width:" + document.body.clientWidth+",Height:"+document.body.clientHeight+"]- CanvasSize:[Width:"+cc.canvas.width+",Height:"+cc.canvas.height+"]";
this.sizeLabel.setString(sizeString);

},


这样当我们拖放窗口时,画布大小就按窗口大小了。


Cocos2d-x-html5 之 HelloWorld 深入分析与调试_2d_05

最后我们看main.js:代码,打开main.js:


//由cc.Application派生出本程序所用的cocos2d-x的程序类。
var cocos2dApp = cc.Application.extend({
//创建一个变量config,初始化其值为之前创建的网页文档的成员结构变量ccConfig.
config:document['ccConfig'],
//重载构造函数ctor。
ctor:function (scene) {
//调用父类的相应函数。
this._super();
//将参数场景scene保存到成员变量startScene做为要启动的场景。
this.startScene = scene;
//设置Cocos2d-x的一些配置。
//使用DEBUG标记
cc.COCOS2D_DEBUG = this.config['COCOS2D_DEBUG'];
//初始化Debug的一些设置。
cc.initDebugSetting();
//取得config中tag结构变量值,即字符串’gameCanvas'做为参数调用cc.setup函数。
cc.setup(this.config['tag']);
//在Cocos2d-x正被加载时的响应函数。
cc.Loader.getInstance().onloading = function () {
//设置调用程序加载场景的draw函数,这里是为了显示进度条。
cc.LoaderScene.getInstance().draw();
};
//在Cocos2d-x被加载完时的响应函数。
cc.Loader.getInstance().onload = function () {
//加载完调用程序控制管理器的didFinishLaunchingWithOptions函数。
cc.AppController.shareAppController().didFinishLaunchingWithOptions();
};
//设置是否要预加载一些相关文件。
cc.Loader.getInstance().preload(g_ressources);
},
//重载程序的applicationDidFinishLaunching函数。
applicationDidFinishLaunching:function () {
// 初始化Cocos2d-x的设备。
var director = cc.Director.getInstance();

// 设置使用高清屏显示模式
// director->enableRetinaDisplay(true);

// 从config中的showFPS变量取得设置是否显示FPS
director.setDisplayStats(this.config['showFPS']);

// 设置FPS
director.setAnimationInterval(1.0 / this.config['frameRate']);

//运行当前要启动的场景。
director.runWithScene(new this.startScene());

return true;
}
});
//这里创建一个程序的实例,运行场景HelloWorldScene。
var myApp = new cocos2dApp(HelloWorldScene);


            main.js还是很容易理解的,创建场景运行场景。但这里有一个重要的函数cc.setup。它必须讲一下:

            打开coco2d/platform下的CCApplication.js我们来看一下:

//定义cc.setup函数,参数有三个,
cc.setup = function (el, width, height) {
//取得cc中id为el的值或者id为 ’#’+el的值。
var element = cc.$(el) || cc.$('#' + el);
//如果元素的tgaName变量值为’CANVAS’,判断参数有效,保存宽度和高度。
if (element.tagName == "CANVAS") {
width = width || element.width;
height = height || element.height;
//新建一个HTML5中的DIV标记给cc.container做为存放画布的区域层。
cc.container = cc.$new("DIV");
//保存画布
cc.canvas = element;
//将画布放入到DIV中。
cc.canvas.parentNode.insertBefore(cc.container, cc.canvas);
cc.canvas.appendTo(cc.container);
//判断参数有效,如果有效,取参数宽高,如果无效,取480,320。
cc.container.style.width = (width || 480) + "px";
cc.container.style.height = (height || 320) + "px";
//设置DIV的id为’Cocos2dGameContainer’,在myApp.js中有取得网页中id为Cocos2dGameContainer的文档div元素,自然就是指这个DIV了。
cc.container.setAttribute('id', 'Cocos2dGameContainer');
//设置DIV的画布的大小与DIV一致。
cc.canvas.setAttribute("width", width || 480);
cc.canvas.setAttribute("height", height || 320);
} else {//如果元素的tgaName变量值为’DIV’。
if (element.tagName != "DIV") {
cc.log("Warning: target element is not a DIV or CANVAS");
}
//判断参数有效,如果有效,取参数宽高,如果无效,取DIV的宽高。
width = width || parseInt(element.style.width);
height = height || parseInt(element.style.height);
//新建一个HTML5中的Canvas标记返回给cc.canvas
cc.canvas = cc.$new("CANVAS");
//在cc.canvas下增加一个子类名称为gameCanvas
cc.canvas.addClass("gameCanvas");
//设置DIV的画布的大小与DIV一致。
cc.canvas.setAttribute("width", width || 480);
cc.canvas.setAttribute("height", height || 320);
//保存DIV到cc.container并将画布放入到这个DIV之中。
cc.container = element;
element.appendChild(cc.canvas);
//判断参数有效,如果有效,取参数宽高,如果无效,取480,320。
cc.container.style.width = (width || 480) + "px";
cc.container.style.height = (height || 320) + "px";
}
//设置DIV使用相对布局方式和style属性。
cc.container.style.position = 'relative';
cc.container.style.overflow = 'hidden';
cc.container.top = '100%';
//这里取出cc.canvas的Context给cc.renderContext,即设置渲染目标缓冲区为上面创建的DIV的显示设备上下文。
cc.renderContext = cc.canvas.getContext("2d");
//这里设置渲染目标缓冲区类型为画布类型
cc.renderContextType = cc.CANVAS;
//如果渲染目标缓冲区类型为画布类型
if (cc.renderContextType == cc.CANVAS) {
//因为cocos2d-x的坐标系是左下角为0,0点,而html的坐标系为左上角0,0点,为了在html上显示正确的图像,将渲染目标缓冲区设置到画布的左下角位置。
cc.renderContext.translate(0, cc.canvas.height);
//创建一个可以绘制到标缓冲区的cc.drawingUtil实例对象。
cc.drawingUtil = new cc.DrawingPrimitiveCanvas(cc.renderContext);
}
//设置Cocos2dx中的画布大小。
cc.originalCanvasSize = cc.size(cc.canvas.width, cc.canvas.height);
//设置DIV。
cc.gameDiv = cc.container;
//输出引擎版本到日志
cc.log(cc.ENGINE_VERSION);
//设置关闭响应菜单
cc.setContextMenuEnable(false);
//是否是移动游览器,如果是,增加对于用户输入控制的处理。
if(cc.Browser.isMobile)
cc._addUserSelectStatus();
//下面是一些显示属性的设置和响应。
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") {
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.mozHidden !== "undefined") {
hidden = "mozHidden";
visibilityChange = "mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}

function handleVisibilityChange() {
if (!document[hidden])
cc.Director.getInstance()._resetLastUpdate();
}

if (typeof document.addEventListener === "undefined" ||
typeof hidden === "undefined") {
cc.isAddedHiddenEvent = false;
} else {
cc.isAddedHiddenEvent = true;
document.addEventListener(visibilityChange, handleVisibilityChange, false);
}
};


 

         好了,所有的js代码基本讲完了,现在为了更好的显示整个程序的流程,现在我们用安装FireBug的Firefox浏览器来进行调试。请先安装一下Firefox,然后在组件管理器里安装FireBug.



Cocos2d-x-html5 之 HelloWorld 深入分析与调试_加载_06



         FireBug可以很方便的调试js并监控变量和堆栈。


         用Firefox打开index.html。之后我们在画布上右键“使用FireBug查看元素”:


Cocos2d-x-html5 之 HelloWorld 深入分析与调试_Cocos2d-x_07


 

         可以看到相应语句对应的元素在网页上反蓝显示。

        我们在FireBug里开启脚本进入cocos2d.js,我们在其中的尾部加入断点后重新载入页面,我们会看到中断的代码以及右边的监控:


Cocos2d-x-html5 之 HelloWorld 深入分析与调试_加载_08



         我们可以看到d.body.appendChild的参数s的属性表为

src=”../cocos2d/platform/jsloader.js”,id=”cocos2d-html5”.

         所以执行完这一句之后会调用执行jsloader.js,我们在其增加本实例所用的js处加入断点。




         可以看到.在右边que的数组元素尾部增加了“resource.js”,”myApp.js”,”main.js”。


我们在main.js里可以增加断点看一下cc.setup的函数执行情况:


Cocos2d-x-html5 之 HelloWorld 深入分析与调试_2d_09


:

Cocos2d-x-html5 之 HelloWorld 深入分析与调试_Cocos2d-x_10


进入函数内部我们可以在右边看到参数值并跟踪执行:


              通过FireBug的跟踪,我们可以深入的理解js脚本的整个执行情况。在main.js中我们可以加断点观察当前网页上的显示状态,如果没有断点,你是否有看到过这个进度显示的页面呢?好了,下课!

Cocos2d-x-html5 之 HelloWorld 深入分析与调试_html5_11

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: HTML5

“Cocos2d-x-html5 之 HelloWorld 深入分析与调试” 的相关文章