前言
2014秋季开发者大会,微信报名页面上线后,大家一片惊呼声,都觉得Cocos2d-JS非常适合这种报名页和宣传页面的制作,可以以一个比较简单、快速的形式,构建出我们需要的漂亮页面。下面我们就来介绍一下,Cocos 2014秋季开发者大会的微信报名页面,是如何实现的。
在这篇教程里,我会教大家如何用Cocos2d-JS来实现一个微信宣传页面,最终结果如下几个页面。

 
需求分析
五个界面基本上就是整个宣传页的全部内容,通过滑动这几个页面可以看出,我们要实现这个页面,大致需要完成下面几项内容:

  • 实现上述五个页面的切换。
  • 实现5个页面的入场和出场动画。
  • 添加背景音乐
  • 屏幕适配
  • 添加微信分享的API

接下来,我们一项一项给大家介绍,完整的代码可以在这里进行[url=local://base_request.html/res/register.zip]下载[/url]。

开发环境与新建项目

  • 如果没用过cocos2d-JS的朋友们,可以到cocos官网上去下载,此处我们用的是3.0final,或者,我们可以下载Lite版本的Cocos2d-JS,lite版本可以很方便的根据需求去下载所需要的模块,可以很大的减少代码的体积,下载地址?此处,我们需要用到的模块有core?actions?menuprogress-timer,在该页面中选择Customized Version然后勾选上述几个模块,并点击下载。
  • 此处我们使用cocos 命令行来创建新的工程
复制代码

  1. $cd cocos2d-js/tools/cocos2d-console/bin
  2. $./cocos new weChat -l js --no-native
  3. $cd weChat/
  4. $../cocos run -p web

环境搭建并不是这篇文章的重点,更详细的信息可以参考:《搭建 Cocos2d-JS 开发环境》。
主界面及其页面切换框架的实现
程序的入口代码在main.js中,用编辑器打开并修改为下面的代码。

复制代码

  1. cc.game.onStart = function () {
  2. cc.view.adjustViewPort(true);
  3. cc.view.enableAutoFullScreen(false);
  4. var mode = cc.sys.isMobile && window.navigator.userAgent.indexOf("MicroMessenger") != -1 ? cc.ResolutionPolicy.FIXED_HEIGHT : cc.sys.isMobile ? cc.ResolutionPolicy.FIXED_WIDTH : cc.ResolutionPolicy.SHOW_ALL;
  5. cc.view.setDesignResolutionSize(640, 831, mode);
  6. //load resources
  7. cc.LoaderScene.preload(g_resources, function () {
  8. cc.director.runScene(new MainScene());
  9. }, this);};cc.game.run();

关键点解析如下:

  • 设置浏览器meta来适配屏幕,引擎内部会根据屏幕大小来设置meta的viewport值,会达到更好的屏幕适配效果。
  • 针对手机浏览器和PC浏览器启用不同的分辨率适配策略。
  • 预加载图片声音等资源。 cc.LoaderScene.preload会生成一个“加载中 x%”的界面,等待资源加载结束后,调用第二个参数传入的匿名函数。 对于基于html的游戏,页面是放在服务器端供浏览器下载的,为了获得流畅的用户体验,cc.LoaderScene.preload让浏览器先把远程服务器的资源缓存到本地。需要预加载的资源定义在src/Resources.js文件中。
  • 启动游戏的第一个场景。

主界面分为2个部分,第一个部分是不随着屏幕移动而移动的向上箭头和音乐按钮,第二个部分是根据用户滑动屏幕而改变的场景。
我们先根据需要,构建出需要的函数,并一一实现他,这里我们使用cc.Scene.extend()?来扩展出一个scene,并在这个scene中构建出我们需要功能,并一一实现他。
由引擎提供的cc.Scene.extend方法,让js能实现高级面向对象语言的继承特性。 onEnter方法是场景初始化完成即将展示的消息回调,在onEnter中必须调用this._super();来确保Scene被正确的初始化。

  • 用于初始化UI的函数 initUI()
  • 用于初始化touch事件的函数 initTouch()。
  • 用于切换页面的函数changePage()和记录当前页面的参数currentIndex
  • 用于控制箭头显示隐藏的函数toggleArrow()
  • 用于控制音乐按钮回调的函数
复制代码

  1. var MainScene = cc.Scene.extend({
  2. listener: null,
  3. accelListener: null,
  4. currentIndex: 0,
  5. sceneList: [],
  6. ctor: function () {
  7. this._super();
  8. cc.spriteFrameCache.addSpriteFrames(res.firstPage_plist);
  9. },
  10. onEnter: function () {
  11. this._super();
  12. this.initUI();
  13. this.addTouch();
  14. },
  15. initUI: function () {
  16. },
  17. toggleMusicCallback: function (sender) {
  18. },
  19. togleArrow: function (status) {
  20. },
  21. addTouch: function () {
  22. },
  23. changePage: function (index, next) {
  24. }
  25. });

接下来我们一一来实现他。

  • 首先,我们来实现音乐按钮与箭头,我们在initUI()中添加如下代码。
复制代码

  1. var bg = new cc.Sprite(res.background_png);
  2. bg.anchorX = 0;
  3. bg.anchorY = 0;
  4. bg.scaleX = cc.winSize.width / bg.width;
  5. bg.scaleY = cc.winSize.height / bg.height;
  6. this.addChild(bg, 0);
  7. this.arrow = new cc.Sprite("#arrow.png");
  8. this.arrow.setPosition(cc.pAdd(cc.visibleRect.bottom, cc.p(0, 50)));
  9. var posY = this.arrow.y;
  10. var arrowAction = cc.repeatForever(cc.sequence(cc.spawn(cc.moveTo(0.8, cc.p(this.arrow.x, posY + 30)).easing(cc.easeIn(0.5)), cc.fadeOut(1)), cc.delayTime(0.8), cc.callFunc(function () {
  11. this.arrow.y = this.arrow.y - 30;
  12. this.arrow.opacity = 255;
  13. }, this)));
  14. this.arrow.runAction(arrowAction);
  15. this.addChild(this.arrow, 1);
  16. this.menuItemToggle = new cc.MenuItemToggle(new cc.MenuItemImage("#music.png"), new cc.MenuItemImage("#music_sel.png"), this.toggleMusicCallback, this);
  17. this.menuItemToggle.setPosition(cc.pAdd(cc.visibleRect.right, cc.p(-this.menuItemToggle.width / 2 - 30, 140)));
  18. var togglemenu = new cc.Menu(this.menuItemToggle);
  19. togglemenu.anchorX = 0;
  20. togglemenu.anchorY = 0;
  21. togglemenu.x = 0;
  22. togglemenu.y = 0;
  23. this.addChild(togglemenu, 1);

我们在屏幕中,添加了一个背景的sprite,并且,将这个背景进行缩放,以让其在各种情况下都布满屏幕,并且我们为箭头设置了一系列动画,让其能够循环播放,Cocos2d-JS,为了方便广大开发者,提供了丰富多彩的动画(actions)。下面,我们先简单的介绍一下几个常用的action的API。

  • cc.repeatForever(action) 无限循环某个action
  • cc.sequence(action1,action2,...)顺序执行括号里面的action
  • cc.spawn(action1,action2,...)同时执行括号里面的action
  • cc.moveTo(duration,targetPoint)从当前位置在duration(秒)时间内移动到点targetPosition的action
  • cc.easeIn(rate) 以rate为ease参数执行easeIn的action,一般是这样使用的action.easing(cc.easeIn(rate))
  • fadeOut(duration) 在duration时间内从屏幕淡出的action
  • cc.delayTime(duration) 延时duration时间的action,通常用于等待一段时间后再播放某个action
  • cc.callFunc(function) 用于执行action的回调,通常在某个action结束后需要执行某段函数的话,可以使用它。

通过上述的简单介绍,是不是对action有了一个初步的了解了呢,我们实际来操作一下:

  • 我们需要一个箭头,往上走并慢慢减速和透明,最终消失,然后在原来的位置出现重复下去,所以我们可以归纳为,移动+淡出-->回到初始位置-->移动+淡出。这样我们很清晰就归纳出如何去写这个action了,我们使用cc.spawn(cc.moveTo(),cc.fadeOut())就构建出了移动+淡出这个效果,然后使用cc.callFunc()设置了这次action播放完毕要修改的位置回到初始位置,接着我们使用cc.sequence()来顺序执行这两个action,这样一来,一次action就编写完成了,最后我们只需要将这个action使用cc.repeatForever()就完成了我们需要的重复播放。

细心的读者可能会问了,代码中的位置设置,为什么是cc.pAdd(cc.visibleRect.right,cc.p())?这是cocos为了让大家更方便的做屏幕适配所定义的9个点,这9个点会根据不同屏幕大小来动态设定,例如cc.visibleRect.center,这个点的位置,无论在什么分辨率的屏幕下,都是在屏幕的正中央,这样我们就可以根据这个点的位置来做相对布局,已达到适配屏幕的目的,例如上面的代码this.arrow.setPosition(cc.pAdd(cc.visibleRect.bottom, cc.p(0, 50)));就是将arrow这个sprite,放在屏幕的底部的正中央,然后再在y轴上加50个像素,这样,无论屏幕的大小,都能保持在屏幕的底部的正中央向上50个像素。这也是我们做相对布局的基础。后续的布局,我们都会根据这些点的坐标来设置。

接下来,我们要开始思考,如何填充我们的主要功能——5个页面的框架。
在这里我们使用cc.Layer.extend定义出5个Layer,并在每个layer中,实现appear方法和disappear方法,分别用于控制页面的入场动画和出场动画,后面,我们会详细介绍每个layer的动画,现在我们设计出layer的框架后呢,我们就可以动手编写MainScene里面的initUI的剩余部分和nextPage函数的编写了,一下是完整的initUI()代码:

复制代码

  1. initUI: function () {
  2. var bg = new cc.Sprite(res.background_png);
  3. bg.anchorX = 0;
  4. bg.anchorY = 0;
  5. bg.scaleX = cc.winSize.width / bg.width;
  6. bg.scaleY = cc.winSize.height / bg.height;
  7. this.addChild(bg, 0);
  8. this.arrow = new cc.Sprite("#arrow.png");
  9. this.arrow.setPosition(cc.pAdd(cc.visibleRect.bottom, cc.p(0, 50)));
  10. var posY = this.arrow.y;
  11. var arrowAction = cc.repeatForever(cc.sequence(cc.spawn(cc.moveTo(0.8, cc.p(this.arrow.x, posY + 30)).easing(cc.easeIn(0.5)), cc.fadeOut(1)), cc.delayTime(0.8), cc.callFunc(function () {
  12. this.arrow.y = this.arrow.y - 30;
  13. this.arrow.opacity = 255;
  14. }, this)));
  15. this.arrow.runAction(arrowAction);
  16. this.addChild(this.arrow, 1);
  17. this.menuItemToggle = new cc.MenuItemToggle(new cc.MenuItemImage("#music.png"), new cc.MenuItemImage("#music_sel.png"), this.toggleMusicCallback, this);
  18. this.menuItemToggle.setPosition(cc.pAdd(cc.visibleRect.right, cc.p(-this.menuItemToggle.width / 2 - 30, 140)));
  19. var togglemenu = new cc.Menu(this.menuItemToggle);
  20. togglemenu.anchorX = 0;
  21. togglemenu.anchorY = 0;
  22. togglemenu.x = 0;
  23. togglemenu.y = 0;
  24. this.addChild(togglemenu, 1);
  25. this.animLayer = new cc.Layer();
  26. this.addChild(this.animLayer);
  27. this.sceneList.push(new Layer1());
  28. this.sceneList.push(new Layer2());
  29. this.sceneList.push(new Layer3());
  30. this.sceneList.push(new Layer4());
  31. this.sceneList.push(new Layer5());
  32. for (var i = 0; i < this.sceneList.length; i++) {
  33. var scene = this.sceneList;
  34. scene.anchorX = 0;
  35. scene.anchorY = 0;
  36. scene.x = 0;
  37. scene.y = 0;
  38. if (this.currentIndex != i) {
  39. scene.setVisible(false);
  40. }
  41. this.animLayer.addChild(scene, this.sceneList.length - i);
  42. }
  43. },

可以看到,首先,我们在MainScene中定义了一个animLayer,用来控制各个页面的动画层,然后我们定义了一个数组用来存储我们的需要的5个Layer,最后他们添加到animLayer里面,并将非当前显示页的Layer隐藏,这样引擎就不会去绘制他们了。

复制代码

  1. addTouch: function () {
  2. var self = this;
  3. self.listener = cc.EventListener.create({
  4. event: cc.EventListener.TOUCH_ONE_BY_ONE,
  5. swallowTouches: true,
  6. startPosY: 0,
  7. onTouchBegan: function (touch, event) {
  8. this.startPosY = touch.getLocation().y;
  9. return true;
  10. },
  11. onTouchMoved: function (touch, event) {
  12. },
  13. onTouchEnded: function (touch, event) {
  14. if (musicPlayStatus) {
  15. playMusic(true);
  16. }
  17. if (canChangePage) {
  18. var delta = touch.getLocation().y - this.startPosY;
  19. if (delta > 15 && self.currentIndex < self.sceneList.length - 1) {
  20. self.changePage(++self.currentIndex, true);
  21. } else if (delta < -15 && self.currentIndex > 0) {
  22. self.changePage(--self.currentIndex, false);
  23. }
  24. }
  25. },
  26. onTouchCancelled: function (touch, event) {
  27. }
  28. });
  29. cc.eventManager.addListener(self.listener, self);
  30. },
  31. changePage: function (index, next) {
  32. canChangePage = false;
  33. var scene = next ? this.sceneList[index - 1] : this.sceneList[index + 1];
  34. if (index == 4) {
  35. this.togleArrow(false);
  36. } else {
  37. this.togleArrow(true);
  38. }
  39. var nextPage = function () {
  40. scene.visible = false;
  41. this.sceneList[index].visible = true;
  42. this.sceneList[index].appear();
  43. };
  44. if (scene) {
  45. scene.disappear(nextPage, this);
  46. }
  47. }

我们想好如何去编写5个页面后,就可以开始编写addTouch()和changePage()了,在这里,我们设置了一个全局变量canChangePage来判断当前换页的操作是否可以执行,如果动画正在播放中,我们不能进行页面的切换操作。由于iOS和某些Android特定版本的限制,需要有实际的点击才能触发音频的播放,所以我们在onTouchEnded的时候,去触发音频播放。
说到音频播放,我们有2个选择,第一可以使用引擎自带的cc.audioEngine,其中集成了多种浏览器的兼容播放,可以很省时省力的进行音乐播放,不过这里,由于我们比较在意code的体积,所以直接使用简单粗暴的html标签<audio></audio>以下是我们简单实现的音乐播放,使用一个全局变量musicPlayStatus来控制音频的播放状态,其实现如下:

复制代码

  1. var initMusic = function () {
  2. var audio = getById("myAudio");
  3. audio.src = "res/bg.mp3";
  4. }
  5. var playMusic = function (status) {
  6. var audio = getById("myAudio");
  7. if (status) {
  8. if (audio.paused) {
  9. audio.play();
  10. musicPlayStatus = true;
  11. }
  12. } else {
  13. if (!audio.paused) {
  14. audio.pause();
  15. musicPlayStatus = false;
  16. }
  17. }
  18. }

由于我们不希望音乐在开始加载页面的时候就进行下载,所以我们使用initMusic()这个方法来初始化音乐,并使用playMusic()的方法来控制音乐的播放。
同时我们需要在MainScene加入一个方法,用来监听浏览器进入后台,和从后台进入前台的事件,用来控制音乐的播放状态,引擎已经封装好了对应的事件,我们可以非常方便的去监听这些事件,可以大大减少开发的周期。

复制代码

  1. initHideEvent: function () {
  2. cc.eventManager.addCustomListener(cc.game.EVENT_SHOW, function () {
  3. playMusic(true);
  4. });
  5. cc.eventManager.addCustomListener(cc.game.EVENT_HIDE, function () {
  6. playMusic(false);
  7. });
  8. }

第一个页面的实现
由于我们已经制定好了,页面的规则,所以每个页面我们要做的就以下几点

  • 实现UI的布局
  • 实现appear入场动画
  • 实现disappear出场动画
  • 控制能否滑动到下一个屏幕的状态
复制代码

  1. initUI: function () {
  2. canChangePage = false;
  3. this.accLayer = new cc.Layer();
  4. this.accLayer.anchorX = 0;
  5. this.accLayer.anchorY = 0;
  6. this.accLayer.x = 0;
  7. this.accLayer.y = 0;
  8. this.addChild(this.accLayer);
  9. this.logo = new cc.Sprite("#logo.png");
  10. this.logo.scale = 0;
  11. this.logo.setPosition(cc.pAdd(cc.visibleRect.center, cc.p(0, this.logo.height / 3 * 2)));
  12. this.addChild(this.logo);
  13. this.leftFont = new cc.Sprite("#font_left.png");
  14. this.leftFont.setPosition(cc.pAdd(cc.visibleRect.left, cc.p(-this.leftFont.width / 2, -this.leftFont.height / 2)));
  15. this.addChild(this.leftFont);
  16. this.rightFont = new cc.Sprite("#font_right.png");
  17. this.rightFont.setPosition(cc.pAdd(cc.visibleRect.right, cc.p(this.rightFont.width / 2, -this.rightFont.height / 2)));
  18. this.addChild(this.rightFont);
  19. this.leftUpPic = new cc.Sprite("#block_left up.png");
  20. this.leftUpPic.anchorX = 0, this.leftUpPic.anchorY = 1;
  21. this.leftUpPic.setPosition(cc.pAdd(cc.visibleRect.topLeft, cc.p(-this.leftUpPic.width, this.leftUpPic.height)));
  22. this.accLayer.addChild(this.leftUpPic);
  23. this.leftDownPic = new cc.Sprite("#block_left down.png");
  24. this.leftDownPic.anchorX = 0, this.leftDownPic.anchorY = 0;
  25. this.leftDownPic.setPosition(cc.pAdd(cc.visibleRect.bottomLeft, cc.p(-this.leftDownPic.width + 20, -this.leftDownPic.height)));
  26. this.accLayer.addChild(this.leftDownPic);
  27. this.rightUpPic = new cc.Sprite("#block_right up.png");
  28. this.rightUpPic.anchorX = 1, this.rightUpPic.anchorY = 1;
  29. this.rightUpPic.setPosition(cc.pAdd(cc.visibleRect.topRight, cc.p(this.rightUpPic.width, this.rightUpPic.height)));
  30. this.accLayer.addChild(this.rightUpPic);
  31. this.rightDownPic = new cc.Sprite("#block_right down.png");
  32. this.rightDownPic.anchorX = 1, this.rightDownPic.anchorY = 0;
  33. this.rightDownPic.setPosition(cc.pAdd(cc.visibleRect.bottomRight, cc.p(this.rightDownPic.width, -this.rightDownPic.height)));
  34. this.accLayer.addChild(this.rightDownPic);
  35. }

以上是对第一个页面的布局,从图上我们其实就可以看到,页面由logo、左上、左下、右上、右下、和左右两列文字组成,至于布局我们就不多说了,主要有以下几点。

  • 可以看到我们依然使用相对布局,让每个ui可以适应不同屏幕分辨率
  • 由于有入场动画,所以我们将这些UI都放到屏幕外面了
  • 我们对三角形的物体,放置在了一个独立的Layer?accLayer?为的是以后如果需要添加陀螺仪的监听,我们可以很方便的进行修改

接下来我们要实现的时入场动画

复制代码

  1. appear: function () {
  2. var logoAction = cc.sequence(cc.scaleTo(0.5, 1), cc.callFunc(function () {
  3. this.leftUpPic.leftUpAction = cc.moveTo(0.5, cc.p(this.leftUpPic.x + this.leftUpPic.width, this.leftUpPic.y - this.leftUpPic.height + 80));
  4. this.leftUpPic.runAction(this.leftUpPic.leftUpAction);
  5. this.leftDownPic.leftDownAction = cc.moveTo(0.5, cc.p(this.leftDownPic.x + this.leftDownPic.width, this.leftDownPic.y + this.leftDownPic.height));
  6. this.leftDownPic.runAction(this.leftDownPic.leftDownAction);
  7. this.rightUpPic.rightUpAction = cc.moveTo(0.5, cc.p(this.rightUpPic.x - this.rightUpPic.width - 30, this.rightUpPic.y - this.rightUpPic.height - 30));
  8. this.rightUpPic.runAction(this.rightUpPic.rightUpAction);
  9. this.rightDownPic.rightDownAction = cc.moveTo(0.5, cc.p(this.rightDownPic.x - this.rightDownPic.width, this.rightDownPic.y + this.rightDownPic.height));
  10. this.rightDownPic.runAction(this.rightDownPic.rightDownAction);
  11. this.leftFont.fontLeftAction = cc.sequence(cc.delayTime(0.3), cc.moveTo(0.5, cc.p(this.leftFont.x + this.leftFont.width, this.leftFont.y)));
  12. this.leftFont.runAction(this.leftFont.fontLeftAction);
  13. this.rightFont.fontRightAction = cc.sequence(cc.delayTime(0.4), cc.moveTo(0.4, cc.p(this.rightFont.x - this.rightFont.width, this.rightFont.y)));
  14. this.rightFont.runAction(this.rightFont.fontRightAction);
  15. }, this), cc.delayTime(1.3), cc.callFunc(function () {
  16. canChangePage = true;
  17. }, this));
  18. this.logo.runAction(logoAction);
  19. }

appear的实现方式非常简单,其实就是把几个我们上面写好的UI,移动到我们希望的位置。

  • logoAction,使用前面介绍过的函数cc.sequence()和cc.scaleTo(),最后在结束的时候调用cc.callFunc()
  • 在cc.callFunc()中呢,我们对其余的元素一一进行了入场动画,主要使用了cc.moveTo()这个方法,可以看到,我们从屏幕外面,移动到了屏幕里面。
  • 值得注意的是,我们在logoAction的最后,使用cc.delayTime()延时了一段时间,然后再执行canChangePage = true主要是为了在动画播放过程中,不然用户滑动改变页面。

接下来就是disappear方法的实现了:

复制代码

  1. disappear: function (callback, target) {
  2. var action = cc.sequence(cc.scaleTo(0.5, 0), cc.callFunc(function () {
  3. this.leftUpPic.runAction(this.leftUpPic.leftUpAction.reverse());
  4. this.leftDownPic.runAction(this.leftDownPic.leftDownAction.reverse());
  5. this.rightUpPic.runAction(this.rightUpPic.rightUpAction.reverse());
  6. this.rightDownPic.runAction(this.rightDownPic.rightDownAction.reverse());
  7. this.leftFont.runAction(this.leftFont.fontLeftAction.reverse());
  8. this.rightFont.runAction(this.rightFont.fontRightAction.reverse());
  9. }, this), cc.delayTime(0.9), cc.callFunc(function () {
  10. if (target && callback) {
  11. callback.call(target);
  12. }
  13. }, this));
  14. this.logo.runAction(action);
  15. }

很简单,我们也是让logo执行了一个action,然后再执行disappear传进来的回调方法就ok了。

  • 这里,我们使用了action.reverse()这个方法,可以很简便的实现大多数action的reverse
  • 动画播放完毕后,调用回调方法执行我们需要的回调操作

ok,此时我们第一个页面已经编写完了,赶紧运行下试试吧。接下来,由于第二第四第五个页面跟第一个页面都很类似,我们就不重复讲了,大家看看代码吧,也当做练练手。我们接着重点说说第三个页面的实现。

第三个页面的实现
第三个页面,是区别于其他页面的一个页面,主要原因是其余的页面,我们基本使用的是cc.moveTo()这个方法,配合上cc.delayTime()等,实现一系列的移动,只要多试验几次,我们就可以很清楚这些action的使用方法,各种混搭之后,可以实现出很复杂也很绚丽的效果。
不过接下来我们将介绍一个之前没有用过的接口cc.progressTimer()来快速实现我们的一条往下滑动的效果。
cc.progressTimer() 多数情况用于使用某个sprite进行计时,倒计时操作,如下图,我们可以很清楚的看到他的效果,我们使用这个效果,可以很容易的实现出那个功能。

我们需要准备一张图片,如下图,然后使用progressTimer,就可以很容易实现这个功能了。

复制代码

  1. initUI: function () {
  2. ...
  3. this.line = new cc.ProgressTimer(new cc.Sprite(res.line_png));
  4. this.line.type = cc.ProgressTimer.TYPE_BAR;
  5. this.line.midPoint = cc.p(0, 1);
  6. this.line.barChangeRate = cc.p(0, 1);
  7. this.line.percentage = 0;
  8. this.line.setPosition(cc.p(cc.winSize.width / 2 - 30, cc.winSize.height - this.line.height / 2));
  9. this.addChild(this.line);
  10. ...
  11. },
  12. appear: function () {//20,50,80,100
  13. this.leftUpPic.inAciton = cc.moveTo(0.2, cc.p(this.leftUpPic.x + this.leftUpPic.width + 20, this.leftUpPic.y - this.leftUpPic.height + 20));
  14. this.leftUpPic.runAction(this.leftUpPic.inAciton);
  15. this.leftDownPic.inAciton = cc.moveTo(0.2, cc.p(this.leftDownPic.x + this.leftDownPic.width + 20, this.leftDownPic.y + this.leftDownPic.height + 20));
  16. this.leftDownPic.runAction(this.leftDownPic.inAciton);
  17. this.rightUpPic.inAciton = cc.moveTo(0.2, cc.p(this.rightUpPic.x - this.rightUpPic.width - 30, this.rightUpPic.y - this.rightUpPic.height - 30));
  18. this.rightUpPic.runAction(this.rightUpPic.inAciton);
  19. this.rightDownPic.inAciton = cc.moveTo(0.2, cc.p(this.rightDownPic.x - this.rightDownPic.width - 20, this.rightDownPic.y + this.rightDownPic.height + 80));
  20. this.rightDownPic.runAction(this.rightDownPic.inAciton);
  21. var action = cc.sequence(cc.delayTime(0.2), cc.progressTo(0.3, 20), cc.callFunc(function () {
  22. this.firstPoint.inAction = cc.scaleTo(0.2, 1);
  23. this.firstPoint.runAction(this.firstPoint.inAction);
  24. this.firstText.inAction = cc.sequence(cc.delayTime(0.2), cc.spawn(cc.moveTo(0.2, cc.p(this.firstText.x - this.firstText.width / 2, this.firstText.y)), cc.fadeIn(0.5)));
  25. this.firstText.runAction(this.firstText.inAction);
  26. }, this), cc.delayTime(0.7), cc.progressTo(0.3, 50), cc.callFunc(function () {
  27. this.secondPoint.inAction = cc.scaleTo(0.2, 1);
  28. this.secondPoint.runAction(this.secondPoint.inAction);
  29. this.secondText.inAction = cc.sequence(cc.delayTime(0.2), cc.spawn(cc.moveTo(0.2, cc.p(this.secondText.x + this.secondText.width / 2, this.secondText.y)), cc.fadeIn(0.5)));
  30. this.secondText.runAction(this.secondText.inAction);
  31. }, this), cc.delayTime(0.7), cc.progressTo(0.3, 80), cc.callFunc(function () {
  32. this.thirdPoint.inAction = cc.scaleTo(0.2, 1);
  33. this.thirdPoint.runAction(this.thirdPoint.inAction);
  34. this.thirdText.inAction = cc.sequence(cc.delayTime(0.2), cc.spawn(cc.moveTo(0.2, cc.p(this.thirdText.x - this.thirdText.width / 2, this.thirdText.y)), cc.fadeIn(0.5)));
  35. this.thirdText.runAction(this.thirdText.inAction);
  36. }, this), cc.delayTime(0.7), cc.progressTo(0.3, 100), cc.callFunc(function () {
  37. this.forthPoint.inAction = cc.scaleTo(0.2, 1);
  38. this.forthPoint.runAction(this.forthPoint.inAction);
  39. canChangePage = true;
  40. }, this));
  41. this.line.runAction(action);
  42. }

上面的代码看似很多,不过,只要分清楚我们的目的,那就很清晰了(ps:initUI只贴出了一部分跟progressTimer相关的代码,具体代码请直接看源码吧)。
我们重点介绍一下cc.progressTimer()

  • 他跟所有Cocos2d-JS的API一样,使用new来创建对象
  • progressTimer的type参数用于设置类型,这里我们使用cc.ProgressTimer.TYPE_BAR也就是条状的progress
  • midPoint参数,用于设置开始progress的起始位置,有点类似于锚点传入一个cc.p()x y范围都是0到1
  • barchangeRate就是每次dt更新的百分比
  • 顺便介绍一下cc.progressTo(duration,percent),主要用于cc.progressTimer当中,从在duration的时间内,从当前的百分比增加到percent。

介绍了基础的用法之后呢,我们对cc.progressTimer()有了一定的了解,接下来我们主要使用cc.progressTimer里面的cc.progressTo()这个方法去实现第三个场景的动画,经过对图片的测量,我们选定了20%,50%,80%,100%进行分段的价值,所以我们通过cc.sequence(cc.progressTo(),cc.callFunc(),cc.delayTime(),.....)这样一组循环,去分段加载那个图片。
到这里为止,我们比较详细的介绍了Cocos2d-JS一些常用的action,并且用他,实现了一个比较美观的动画,大家有兴趣可以动手亲自去试试。
微信API的集成
本功能已经有大神提供了完整的库,地址?,以下我们做一个简单的使用分析。

复制代码

  1. // 微信分享的数据
  2. window.wxData = {
  3. "appId": "", // 服务号可以填写appId
  4. "imgUrl": "http://upyun.cocimg.com/cocoachina/cocos_logo.png",
  5. "link": "http://devcon.cocos.com/weixin/",
  6. "desc": "Cocos 2014 开发者大会(秋季)—Great or nothing",
  7. "title": "COCOS 2014 秋季开发者大会"
  8. };
  9. WeixinApi.ready(function (Api) {
  10. // 分享的回调
  11. var wxCallbacks = {
  12. ready: function () {
  13. },
  14. cancel: function (resp) {
  15. },
  16. fail: function (resp) {
  17. },
  18. confirm: function (resp) {
  19. },
  20. all: function (resp) {
  21. }
  22. };
  23. Api.shareToFriend(wxData, wxCallbacks);
  24. Api.shareToTimeline(wxData, wxCallbacks);
  25. Api.shareToWeibo(wxData, wxCallbacks);
  26. });
  • appId 就是服务号啦,有服务号的同志们可以直接填写上去。
  • imgUrl 就是分享出去的logo
  • link 分享后,别人点进来的链接
  • desc 分享后logo旁边的说明性文字
  • title 就是标题啦

如果有需要就可以对分享的回调进行监听了,针对分享过程中的每个状态,有需要的只需要在对应的函数回调里面进行编写对应代码就可以了。
混淆发布
如果使用cocos命令行,非常简单就可以进行打包发布了,在控制台输入命令:

复制代码

  1. cocos compile -p web -m release

程序会在当前的工程目录下,生成一个publish的文件夹,里面的html5文件就是我们的发布版本了,小伙伴们,赶紧也发布一个试试吧。

另外,如果需要更高得压缩比,只需要使用下面的指令:

复制代码

  1. cocos compile -p web -m release --advanced

添加--advanced标签会使用Closure Compiler混淆工具的高级压缩功能,将使JS代码所占的空间更加小,但是这个压缩模式有一定风险会导致错误,如果发现错误可以根据Google的官方文档来进行调试。

最后,记得哦,完整的代码可以在附件中下载。

最后附上微信效果地址:

[ 此帖被superdragon在2014-10-23 11:49重新编辑 ]

附件:  register.zip (1639 K) 下载次数:11

如何用Cocos2d-JS制作一个微信报名宣传页相关推荐

  1. 用JS制作一个信息管理平台完整版

      前  言 JRedu 在之前的文章中,介绍了如何用JS制作一个实用的信息管理平台. 但是那样的平台功能过于简陋了,我们今天来继续完善一下. 首先我们回顾一下之前的内容.   1.JSON的基础知识 ...

  2. 如何用原生JS制作图片时钟

    程序设计之道无远弗届,御晨风而返.---- 杰佛瑞 · 詹姆士 今天分享一个小demo,如何用原生JS制作图片时钟,话不多说上代码. html[外链图片转存失败(img-mD0n42FM-156223 ...

  3. 使用 ale.js 制作一个小而美的表格编辑器(2)

    今天来教大家如何使用 ale.js 制作一个小而美的表格编辑器,首先先上 gif: 是不是还是有一点非常 cool 的感觉的?那么我们现在开始吧! 这是我们这篇文章结束后完成的效果(如果想继续完成请访 ...

  4. 使用 ale.js 制作一个小而美的表格编辑器(3)

    今天来教大家如何使用 ale.js 制作一个小而美的表格编辑器,首先先上 gif: 是不是还是有一点非常 cool 的感觉的?那么我们现在开始吧! 这是我们这篇文章结束后完成的效果(如果想继续完成请访 ...

  5. (译)如何使用cocos2d来制作一个打地鼠的游戏:第一部分

    免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...

  6. 使用 ale.js 制作一个小而美的表格编辑器(1)

    今天来教大家如何使用 ale.js 制作一个小而美的表格编辑器,首先先上 gif: 是不是还是有一点非常 cool 的感觉的?那么我们现在开始吧! 这是我们这篇文章结束后完成的效果(如果想继续完成请访 ...

  7. 使用 ale.js 制作一个小而美的表格编辑器(4)

    今天来教大家如何使用 ale.js 制作一个小而美的表格编辑器,首先先上 gif: 是不是还是有一点非常 cool 的感觉的?那么我们现在开始吧! 这是我们这篇文章结束后完成的效果(如果想继续完成请访 ...

  8. jsp循环输出表格_使用 ale.js 制作一个小而美的表格编辑器(1)

    今天来教大家如何使用 ale.js 制作一个小而美的表格编辑器,首先先上 gif: 是不是还是有一点非常 cool 的感觉的?那么我们现在开始吧! 这是我们这篇文章结束后完成的效果(如果想继续完成请访 ...

  9. 如何用 Node.js 实现一个简单的 Websocket 服务?

    最近正在研究 Websocket 相关的知识,想着如何能自己实现 Websocket 协议.到网上搜罗了一番资料后用 Node.js 实现该协议,倒也没有想象中那么复杂,除去注释语句和 console ...

最新文章

  1. pycharm中R工具包的安装
  2. 架构之:微服务和单体服务之争
  3. 开源干货!.NET Core + Vue.js通用动态权限(RBAC)管理系统框架[DncZeus]开源
  4. 图解算法学习笔记(一): 算法简介
  5. 【DevCloud · 敏捷智库】两种你必须了解的常见敏捷估算方法
  6. cortex a7 a53_西昊人体工学椅A7开箱测评
  7. DataGridView 动态绑定列
  8. 387.字符串中的第一个唯一字符
  9. Louvain 算法原理 及设计实现
  10. pandas的认识与dataframe的认识 day04课件代码
  11. 图片(img)alt属性标签怎么写
  12. 华为android贡献度,米粉别不信,华为对安卓系统的贡献比小米更多
  13. 基音周期计算(pitch tracking)
  14. vue实现横向无限滚动
  15. input正则邮箱_常用正则表达式—邮箱(Email)
  16. 【我的OpenGL学习进阶之旅】介绍一下 绘制图元
  17. 音视频QoE核心指标
  18. 英语语法总结--倒装
  19. Silverlight游戏研发手记:(五)SLG动感增效之《幻影粒子》
  20. Python爬取高质量电脑壁纸,还是很好看的

热门文章

  1. C#|论文|毕业论文|毕业论文格式|毕业论文范文|毕业论文参考
  2. 最火的三亚自助游攻略
  3. asp.net 从服务器上下载文件
  4. jq插件的编写方法(自定义jq插件)
  5. iCAN使用faster r-cnn得到目标检测结果文件为空
  6. 不在路由器上做端口映射,如何访问局域网内网站
  7. 互联网企业蜂拥进入区块链,入局之前该思考什么?
  8. 婚恋交友app源码,你要了解数据结构
  9. 选择服务器租用托管机房的关键
  10. 没有卸载干净,全是泪啊!关于vs疑难杂症