html游戏引擎,createJs框架

Phaser、CreateJS 、 Construct 3游戏框架 Phaser、CreateJS 和 Construct 3 都是用于创建网页游戏和互动应用程序的游戏开发框架。- Phaser 是一个开源的 HTML5 游戏框架,使用 JavaScript 编写。它提供了一个强大的 API 和工具集,用于创建各种类型的游戏,包括 2D 平台游戏、射击游戏、益智游戏等。- CreateJS 是一个 JavaScript 库和工具集,用于创建跨平台的互动内容,包括游戏、动画和可视化应用程序。 阅读详情

 声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢!

  楼主记忆力不好,最近刚好用了一下createJs框架,怕以后一段时间没用后会忘记,所以在此做个记录,或许以后用得着。

  createJs网上的中文教程挺少的,以前UC有个Xcanvas的论坛有createJs的详细教程,但是随着XCanvas团队的解散,那个网站也关闭了。。网上的大部分都是非常基础的教程,有点千遍一律的感觉。所以楼主就去把createJs下载下来,硬着头皮看英文文档了。凭着楼主这英语六级只考了三百多分的渣渣来说,看起来很费力啊,不过还是勉强摸索出了大概的用法。所以现在就是学了多少就记录多少,之后或许也会不定期更新一下该框架的新的学习心得。毕竟对自己以后还是有帮助的。

  希望本文能帮到那些想学createJs的新手。因为楼主也是刚学的,所以本文或许有不正确之处,因此本文仅当参考,若有不正之处欢迎斧正。

  闲话说到这,直接进入主题。

  楼主用createJs写了个简单的跑酷游戏DEMO,就拿它做例子吧。 看DEMO戳我。

  createJs的由来,基础什么的就不说了,就直接说createJs的用法吧。

  首先到createJs官网下载,createJs分成easelJs(图形动画)、preloadJs(文件加载)、soundJs(音频控制)以及tweenJs(补间动画)四部分,大家下载的时候,建议下载两个文件,一个是压缩版文件,用于项目中的引用,再下载个源码文件,用于查看用法、API、demo等。因为楼主目前只用了easelJs和preloadJs,所以暂时就只说这两个,其实就这两个已经非常够用了。

  接下来开始分析代码:

  首先引入js文件

1. <script src='easeljs-0.7.1.min.js'></script>
2. <script src='preloadjs-0.4.1.min.js'></script>

  然后进行舞台初始化操作:

01. function init(){
02. stage = new createjs.Stage('cas');
03. C_W = stage.canvas.width;
04. C_H = stage.canvas.height;
05.  
06. var manifest = [
07. {src:'image/man.png' , id:'man'},
08. {src:'image/ground.png' , id:'ground'},
09. {src:'image/bg.png' , id:'bg'},
10. {src:'image/high.jpg' , id:'high'},
11. {src:'image/coins.png' , id:'coin'}
12. ]
13.  
14. loader = new createjs.LoadQueue(false);
15. loader.addEventListener('complete' , handleComplete);
16. loader.loadManifest(manifest);
17.  
18. drawLoading();
19. }

上面就用到了preloadJs中的方法,实例化一个loader,把需要加载的图片文件放在manifest里面,进行加载,加载完成后调用回调handleCompelete函数:

01. function handleComplete(){        //当图片素材load完后执行该方法
02. var manImage = loader.getResult('man'),
03. lowground = loader.getResult('ground'),
04. highground = loader.getResult('high'),
05. bgImage = loader.getResult('bg'),
06. coins = loader.getResult('coin');
07.  
08. sky = new createjs.Shape();
09. sky.graphics.bf(bgImage).drawRect(0,0,C_W,C_H);
10. sky.setTransform(0, 0, 1 , C_H/bgImage.height);
11. stage.addChild(sky);
12.  
13. man = createMan(200,326,manImage);
14.  
15. //该框为判定角色的判定区域
16. kuang = new createjs.Shape();
17. kuang.graphics.beginStroke('rgba(255,0,0,0.5)').drawRect(0 , 0 , man.size().w , man.picsize().h*1.5);
18. // stage.addChild(kuang);
19.  
20. mapHandle(lowground , highground , coins);
21.  
22. createjs.Ticker.timingMode = createjs.Ticker.RAF;//设置循环方法,可以是requestAnimationFrame或者是setTimeout
23. createjs.Ticker.setFPS(30);//舞台帧率控制
24. createjs.Ticker.addEventListener('tick', tick);//绑定舞台每一帧的逻辑发生函数
25.  
26. window.addEventListener('keydown' , function(event){
27. event = event||window.event;
28. if(event.keyCode===32&&man.jumpNum<man.jumpMax){
29. man.jump();
30. }
31. })
32. }

获得加载完成后端的图片数据就直接用loader.getResult就可以获取了,跑酷游戏需要一个背景,所以,我们实例化一个sky,然后进行位图绘制,bf方法是beginBitmapFill的缩写,该方法就是开始绘制位图,后面的drawRect是位图的绘制区域,区域当然是整个画布啦,所以就是drawRect(0,0,C_W,C_H)。实例化出来sky后就直接添加到舞台stage里面就行了。接下来是实例化一个角色,createMan方法后面有说,是自己封装的。

  然后进行舞台循环设置,上面有注释了,就不说了。

  下面是人物模块的封装

001. (function(w){
002. var FRAME_RATE = 13,    //精灵表播放速度
003. SCALE_X = 1.5,    //X轴缩放
004. SCALE_Y = 1.5,    //Y轴缩放
005. GRAVITY = 3,    //重力加速度
006. JUMP_SPEED = 2.6,        //垂直速度
007. WIDTH = 40,
008. HEIGHT = 96,
009. PICWIDTH = 64,
010. PICHEIGHT = 64,
011. PROPORTION = 150/1;  //游戏与实际的距离比例
012.  
013. var Man = function(x , y , img){
014. this.x = x;
015. this.y = y;
016. this.endy = y;
017. this.vx = 0.5;
018. this.vy = 0;
019. this.ground = [];
020. this.state = 'run';
021. this.jumpNum = 0;
022. this.jumpMax = 1;
023. this.init(img);
024. }
025.  
026. Man.prototype = {
027. constructors:Man,
028.  
029. init:function(img){
030. var manSpriteSheet = new createjs.SpriteSheet({  //实例化精灵表绘制器
031. 'images':[img],
032. 'frames':{'regX':0,'height':PICWIDTH,'count':45,'regY':1,'width':PICHEIGHT},
033. 'animations':{
034. 'run':{
035. frames:[21,20,19,18,17,16,15,14,13,12],    //精灵表每一帧的位置
036. next:'run',                    //当精灵表循环完后的下一步动作
037. speed:1,                      //精灵表播放速度
038. },
039. 'jump':{
040. frames:[34,35,36,37,38,39,40,41,42,43],
041. next:'run',
042. speed:1,
043. },
044. 'die':{
045. frames:[8,7,6,5,4,3,2,1,0],
046. next:'die',
047. speed:1,
048. }
049. }
050. });
051. this.sprite = new createjs.Sprite(manSpriteSheet , this.state);  //实例化精灵
052. this.sprite.framerate = FRAME_RATE;      //精灵表绘制速率
053. this.sprite.setTransform(this.x, this.y, SCALE_X, SCALE_Y);  //设置精灵的位置
054. stage.addChild(this.sprite);    //添加到舞台
055. },
056.  
057. update:function(){
058. var sprite = this.sprite;
059. var time = createjs.Ticker.getInterval()/1000;    //获取当前帧与上一帧的时间间隔
060.  
061. if(this.state==='run'){          
062. if(sprite.x<this.x){
063. sprite.x +=this.vx;
064. }else {
065. sprite.x = this.x
066. }
067. }
068. if(this.endy>sprite.y||this.state==='jump'){  //角色的动作处理
069. var nexty = sprite.y+time*this.vy*PROPORTION;
070. this.vy += time*GRAVITY;
071. sprite.y += time*this.vy*PROPORTION;
072. if(Math.abs(sprite.y-this.endy)<10&&this.vy>0){
073. this.state = 'run';
074. sprite.y=this.endy;
075. this.vy = 0;
076. }
077. }
078.  
079. if(sprite.x+(PICWIDTH*SCALE_X-WIDTH)/2<0||sprite.y>C_H+200){
080. this.die();
081. createjs.Ticker.reset();
082. alert('you are Die!');
083. }
084.  
085. switch(this.state){
086. case 'run':
087. this.jumpNum = 0;
088. break;
089. case 'die':
090. if(sprite.currentFrame===0){
091. sprite.paused = true;
092. }
093. break;
094. }
095. },
096.  
097. run:function(){
098. this.sprite.gotoAndPlay('run')
099. },
100.  
101. jump:function(){
102. this.vy = -JUMP_SPEED;
103. this.state = 'jump';
104. this.sprite.gotoAndPlay('jump');  //让精灵表播放特定的动画
105. this.jumpNum++;
106. },
107.  
108. die:function(){
109. this.state = 'die';
110. this.sprite.gotoAndPlay('die')
111. },
112.  
113. size:function(){
114. return {
115. w:WIDTH,
116. h:HEIGHT
117. }
118. },
119.  
120. picsize:function(){
121. return {
122. w:PICWIDTH,
123. h:PICHEIGHT
124. }
125. }
126. }
127.  
128. w.createMan = function(x , y , img){
129. return new Man(x , y , img)
130. };
131. })(window)

人物模块封装就是简单的在createJs的封装之上进行进一步的封装,封装很简单,就是用createJs实例化一个精灵类,再绑定精灵表,因为本文讲createJs的大概用法,所以游戏的逻辑处理就不具体解释了。

下面贴出封装的石头以及金币模块,简单说下背景的循环,预先实例化一堆石头和金币,然后移动响应的石头,当石头移动到超出舞台区域时,把他的visible属性置为false,再重新添加一个石头在最后的位置进行新的一次移动。

001. (function(w){
002. var SPEED = 4,
003. COIN_STAY_X = 20,
004. COIN_STAY_Y = 20,
005. COIN_STAY_WIDTH = 30,
006. COIN_STAY_HEIGHT = 30,
007. COIN_SCALE_X = 0.08,
008. COIN_SCALE_Y = 0.08;
009.  
010. //地上的石头类
011.  
012. var Stone = function(x,kind,allImage){
013. this.x = x;
014. this.kind = kind;
015. this.allImage = allImage;
016. this.init();
017. }
018.  
019. var sp = Stone.prototype;
020.  
021. sp.init=function(){
022. this.shape = new createjs.Shape();
023. if(this.kind!=='C'){
024. this.h = this.allImage[this.kind].height;
025. this.w = this.allImage[this.kind].width*2;
026. this.y = C_H - this.h;
027. this.shape.graphics.beginBitmapFill(this.allImage[this.kind]).drawRect(0, 0, this.w, this.h);
028. this.shape.setTransform(this.x, this.y, 1, 1);
029. }else {
030. this.h = -1000;
031. this.w = 170;
032. this.y = C_H - this.h;
033. this.shape.graphics.beginFill('#000').drawRect(0, 0, this.w, this.h);
034. this.shape.setTransform(this.x, this.y, 1, 1);
035. }
036. this.shape.visible = false;
037. this.shape.cache(0 , 0 , this.w , this.h);
038. stage.addChild(this.shape);
039. }
040.  
041. sp.update=function(){
042. this.shape.x -= SPEED;
043. }
044.  
045. //金币类
046. var Coin = function(image){
047. this.sizeX = COIN_SCALE_X;
048. this.sizeY = COIN_SCALE_Y;
049.  
050. this.isget = false;
051. this.init = function(){
052. this.shape = new createjs.Shape();
053. this.shape.graphics.beginBitmapFill(image).drawRect(0, 0, image.width, image.height);
054. this.shape.setTransform(0, 0, COIN_SCALE_X, COIN_SCALE_Y);
055. this.shape.visible = false;
056. stage.addChild(this.shape);
057. }
058. this.init();
059.  
060. this.update = function(){
061. if(this.isget){
062. this.sizeX = this.sizeX + ((COIN_STAY_WIDTH/image.width) - this.sizeX)*0.1;
063. this.sizeY = this.sizeY + ((COIN_STAY_HEIGHT/image.height) - this.sizeY)*0.1;
064. this.shape.setTransform(
065. this.shape.x + (COIN_STAY_X - this.shape.x)*0.1,
066. this.shape.y + (COIN_STAY_Y - this.shape.y)*0.1,
067. this.sizeX,
068. this.sizeY
069. );
070.  
071. if(Math.abs(this.shape.x-COIN_STAY_X)<0.5&&Math.abs(this.shape.y-COIN_STAY_Y)<0.5){
072. this.shape.visible = false;
073. this.isget = false;
074. this.sizeX = COIN_SCALE_X;
075. this.sizeY = COIN_SCALE_Y;
076. this.shape.setTransform(0,0,this.sizeX,this.sizeY);
077. }
078. } else{
079. this.shape.x -= SPEED;
080. if(this.shape.x<-image.width*COIN_SCALE_X){
081. this.shape.visible = false;
082. }
083. }
084. }
085.  
086. this.size = function(){
087. return {
088. w:image.width*COIN_SCALE_X,
089. h:image.height*COIN_SCALE_Y
090. }
091. }
092. }
093.  
094. w.createCoin = function(image){
095. return new Coin(image)
096. }
097.  
098. w.createStone = function(x,kind,allImage){
099. return new Stone(x,kind,allImage);
100. }
101. })(window)

封装方法跟上面的人物模块封装差不多,不过人物是用精灵类,石头金币则是用形状类了。就是通过位图的绘制,来绘制位图的图片,原理都一样。

最后是舞台逐帧处理的tick方法:

01. function tick(event){        //舞台逐帧逻辑处理函数
02. man.update();
03.  
04. kuang.x = man.sprite.x+(man.picsize().w*1.5-man.size().w)/2;    //参考框
05. kuang.y = man.sprite.y;
06.  
07. man.ground.length=0;
08. var cg = stoneHandle();
09.  
10. if(man.ground[0]&&!cg) {
11. man.ground.sort(function(a,b){return b.h-a.h});
12. man.endy = man.ground[0].y-man.picsize().h*1.5;
13. }
14.  
15. allCoins.forEach(function(cc , index){
16. if(cc.shape.visible){
17. if(
18. Math.abs((kuang.x+man.size().w/2) - (cc.shape.x+cc.size().w/2)) <= (man.size().w+cc.size().w)/2&&
19. Math.abs((kuang.y+man.size().h/2) - (cc.shape.y+cc.size().h/2)) <= (man.size().h+cc.size().h)/2&&
20. !cc.isget
21. ){
22. cc.isget = true;
23. countCoin.innerHTML = parseInt(countCoin.innerHTML)+1
24. }
25. cc.update();
26. }
27. })
28.  
29. document.getElementById('showFPS').innerHTML = man.endy
30. stage.update(event)
31. }

在每一帧的处理,就像自己写游戏一样啦,就是把舞台里的所有对象逐个进行逻辑运算,进行相应处理。 

基本上createJs的用法还是相对比较简单并且强大的。比自己去造轮子能省很多功夫。下面贴出所有代码:

主页面:


加载中...
001. <!doctype html>
002. <html lang='en'>
003. <head>
004. <meta charset='UTF-8'>
005. <style>
006. /*#cas{margin:auto;display: block;}*/
007. .view{width: 700px;height:500px;position: relative;}
008. #coins{width:90px;height: 70px;line-height: 70px;position:absolute;left:0px;top:0;padding-left: 60px;background:url(image/coins.png) no-repeat;background-size:30px 30px;background-position:20px 20px;font-size: 34px;color: #FFF;}
009. </style>
010. <title>跑酷游戏</title>
011. <script src='easeljs-0.7.1.min.js'></script>
012. <script src='preloadjs-0.4.1.min.js'></script>
013. <script src='person.js'></script>
014. <script src='otherThings.js'></script>
015. </head>
016. <body>
017. <div class='view'>
018. <canvas id='cas' width='700' height='500'>您的<a href="http://www.it165.net/edu/ewl/" target="_blank" class="keylink">浏览器</a>不支持canvas</canvas>
019. <div id='coins'>0</div>
020. </div>
021. <div id='showFPS' style='display: none;'></div>
022. <script>
023. var fps = document.getElementById('showFPS'),
024. countCoin = document.getElementById('coins');
025. var stage , C_W , C_H , loader;
026. var man , ground , sky;
027.  
028. function init(){
029. stage = new createjs.Stage('cas');
030. C_W = stage.canvas.width;
031. C_H = stage.canvas.height;
032.  
033. var manifest = [
034. {src:'image/man.png' , id:'man'},
035. {src:'image/ground.png' , id:'ground'},
036. {src:'image/bg.png' , id:'bg'},
037. {src:'image/high.jpg' , id:'high'},
038. {src:'image/coins.png' , id:'coin'}
039. ]
040.  
041. loader = new createjs.LoadQueue(false);
042. loader.addEventListener('complete' , handleComplete);
043. loader.loadManifest(manifest);
044.  
045. drawLoading();
046. }
047.  
048. function drawLoading(){
049. var ctx = stage.canvas.getContext('2d');
050. ctx.textAlign = 'center';
051. ctx.textBaseline = 'middle';
052. ctx.fillStyle = '#000';
053. ctx.fillRect(0,0,C_W,C_H);
054. ctx.fillStyle = '#FFF';
055. ctx.font = '25px 微软雅黑';
056. ctx.fillText('Loading...',C_W/2,C_H/2)
057. }
058.  
059. //地图数据,mapData为石头数据,coinCode为金币数据
060. var mapData = [
061. 'AAAACBBAAACABBAAACAABBBAAAABAAAAAACABCABCABCAAAABBBBBBAAAAACAAAAAAAAAAAABBBBBBAAAAAACACACACACAAAABBBBAAAAACAAAAAAAAAAAABBBBBBAAAAAACACACACACAABBAAAAAAABBA',
062. 'AAAAAAAACAABAAAAAAAAAAAAAAABBBBBBCBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAACACACACACACACACACACBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBCBCBCBCAAAAAAAAAAAAAAAAAA',
063. 'AAAAAAAACAABAAAAAAAAAAAACACACACACACACACABAABABABABABABABACBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCABABACBCBCACACACACACACACACACACACACACACACACACACACACACAAAAAAAAAAAAAAAA'
064. ],
065. coinCode = [
066. '--------##########----------------############-#--#---##############-----------------##########-#-#-#-#-#-#-#-##-------################-------------###',
067. '--#--#-------####----------##----###-----####-#--#---####-#-#-#-######------####------#####-#-#-#-#-#-#-#-##-------################---############--###',
068. '-------#--#-------####----------##----##--##############---------######------####------#####-#-#-#-#-#-#-#-##----------################-------------###'
069. ]
070.  
071. function handleComplete(){        //当图片素材load完后执行该方法
072. var manImage = loader.getResult('man'),
073. lowground = loader.getResult('ground'),
074. highground = loader.getResult('high'),
075. bgImage = loader.getResult('bg'),
076. coins = loader.getResult('coin');
077.  
078. sky = new createjs.Shape();
079. sky.graphics.bf(bgImage).drawRect(0,0,C_W,C_H);
080. sky.setTransform(0, 0, 1 , C_H/bgImage.height);
081. stage.addChild(sky);
082.  
083. man = createMan(200,326,manImage);
084.  
085. //该框为判定角色的判定区域
086. kuang = new createjs.Shape();
087. kuang.graphics.beginStroke('rgba(255,0,0,0.5)').drawRect(0 , 0 , man.size().w , man.picsize().h*1.5);
088. // stage.addChild(kuang);
089.  
090. mapHandle(lowground , highground , coins);
091.  
092. createjs.Ticker.timingMode = createjs.Ticker.RAF;
093. createjs.Ticker.setFPS(30);
094. createjs.Ticker.addEventListener('tick', tick);
095.  
096. window.addEventListener('keydown' , function(event){
097. event = event||window.event;
098. if(event.keyCode===32&&man.jumpNum<man.jumpMax){
099. man.jump();
100. }
101. })
102. }
103.  
104.  
105. var mapIndex = 0,        //地图序列
106. Mix = 0,            //地图数组的索引
107. allStones = [],        //存放所有的石头
108. allCoins = [],        //所有金币
109. showSt = [];        //存放显示出来的石头
110.  
111. function mapHandle(lowground , highground , coins){        //初始化地图
112. allStones.length = 0;
113. var stoneImage = {'A':lowground , 'B':highground},kind = null;
114. for(var i=0;i<30;i++){            //把需要用到的石头预先放入容器中准备好
115. switch(i){
116. case 0:kind='A';break;
117. case 10:kind='B';break;
118. case 20:kind='C';break;
119. }
120. var st = createStone(C_W , kind , stoneImage);
121. allStones.push(st)
122. }
123.  
124. for(var i=0;i<10;i++){            //把需要用到的金币预先放入容器中
125. var coin = createCoin(coins);
126. allCoins.push(coin);
127. }
128.  
129. Mix = Math.floor(Math.random()*mapData.length);            //随机地图序列
130. for(var i=0;i<8;i++){
131. setStone(false)
132. }
133. }
134.  
135. function setStone(remove){        //添加陆地的石头
136. var arg = mapData[Mix].charAt(mapIndex),
137. coarg = coinCode[Mix].charAt(mapIndex),
138. cc = null;
139.  
140. if(coarg==='#'){
141. for(var i=0;i<allCoins.length;i++){
142. if(!allCoins[i].shape.visible){
143. cc = allCoins[i];
144. cc.shape.visible = true;
145. break;
146. }
147. }
148. }
149.  
150. for(var z=0;z<allStones.length;z++){
151. if(!allStones[z].shape.visible&&allStones[z].kind===arg){
152. var st = allStones[z];
153. st.shape.visible = true;
154. st.shape.x = showSt.length===0?0:showSt[showSt.length-1].shape.x+showSt[showSt.length-1].w;
155.  
156. if(cc){
157. cc.shape.x = showSt.length===0?allStones[z].w/2-cc.size().w/2:showSt[showSt.length-1].shape.x+showSt[showSt.length-1].w+allStones[z].w/2-cc.size().w/2;
158. cc.shape.y = arg==='C'? C_H-loader.getResult('high').height-50 : allStones[z].shape.y-cc.size().h/2-50;
159. }
160.  
161. if(remove) showSt.shift();
162. showSt.push(st);
163. break;
164. }
165. }
166.  
167. mapIndex++;
168. if(mapIndex>=mapData[Mix].length){
169. Mix = Math.floor(Math.random()*mapData.length)
170. mapIndex=0;
171. }
172. }
173.  
174. function tick(event){        //舞台逐帧逻辑处理函数
175. man.update();
176.  
177. kuang.x = man.sprite.x+(man.picsize().w*1.5-man.size().w)/2;    //参考框
178. kuang.y = man.sprite.y;
179.  
180. man.ground.length=0;
181. var cg = stoneHandle();
182.  
183. if(man.ground[0]&&!cg) {
184. man.ground.sort(function(a,b){return b.h-a.h});
185. man.endy = man.ground[0].y-man.picsize().h*1.5;
186. }
187.  
188. allCoins.forEach(function(cc , index){
189. if(cc.shape.visible){
190. if(
191. Math.abs((kuang.x+man.size().w/2) - (cc.shape.x+cc.size().w/2)) <= (man.size().w+cc.size().w)/2&&
192. Math.abs((kuang.y+man.size().h/2) - (cc.shape.y+cc.size().h/2)) <= (man.size().h+cc.size().h)/2&&
193. !cc.isget
194. ){
195. cc.isget = true;
196. countCoin.innerHTML = parseInt(countCoin.innerHTML)+1
197. }
198. cc.update();
199. }
200. })
201.  
202. document.getElementById('showFPS').innerHTML = man.endy
203. stage.update(event)
204. }
205.  
206.  
207. function stoneHandle(){        //石头的逐帧处理  cg为判断当前角色的位置是否被阻挡,overStone是保存离开stage的石头块
208. var cg = false , overStone = null;
209. allStones.forEach(function(s){   //遍历石头,确定玩家落点
210. if(s.shape.visible){
211. s.update();
212.  
213. if(s.shape.visible&&s.shape.x<=-s.w){
214. overStone = s;
215. }
216.  
217. var juli = Math.abs((kuang.x+man.size().w/2)-(s.shape.x+s.w/2));
218. if(juli<=(man.size().w+s.w)/2 && man.ground.indexOf(s)===-1){
219. man.ground.push(s);
220.  
221. if((s.shape.x+s.w/2)>(kuang.x+man.size().w/2)&&s.y<(kuang.y+man.size().h-10)){
222. man.sprite.x = s.shape.x-man.picsize().w-8;
223. cg = true;
224. }
225. }
226. }
227. });
228. if(overStone) {
229. setStone(true);
230. overStone.shape.visible = false;
231. }
232.  
233. return cg;
234. }
235.  
236. init();
237. </script>
238. </body>
239. </html>

人物模块:


加载中...
001. (function(w){
002. var FRAME_RATE = 13,    //精灵表播放速度
003. SCALE_X = 1.5,    //X轴缩放
004. SCALE_Y = 1.5,    //Y轴缩放
005. GRAVITY = 3,    //重力加速度
006. JUMP_SPEED = 2.6,        //垂直速度
007. WIDTH = 40,
008. HEIGHT = 96,
009. PICWIDTH = 64,
010. PICHEIGHT = 64,
011. PROPORTION = 150/1;  //游戏与实际的距离比例
012.  
013. var Man = function(x , y , img){
014. this.x = x;
015. this.y = y;
016. this.endy = y;
017. this.vx = 0.5;
018. this.vy = 0;
019. this.ground = [];
020. this.state = 'run';
021. this.jumpNum = 0;
022. this.jumpMax = 1;
023. this.init(img);
024. }
025.  
026. Man.prototype = {
027. constructors:Man,
028.  
029. init:function(img){
030. var manSpriteSheet = new createjs.SpriteSheet({
031. 'images':[img],
032. 'frames':{'regX':0,'height':PICWIDTH,'count':45,'regY':1,'width':PICHEIGHT},
033. 'animations':{
034. 'run':{
035. frames:[21,20,19,18,17,16,15,14,13,12],
036. next:'run',
037. speed:1,
038. },
039. 'jump':{
040. frames:[34,35,36,37,38,39,40,41,42,43],
041. next:'run',
042. speed:1,
043. },
044. 'die':{
045. frames:[8,7,6,5,4,3,2,1,0],
046. next:'die',
047. speed:1,
048. }
049. }
050. });
051. this.sprite = new createjs.Sprite(manSpriteSheet , this.state);
052. this.sprite.framerate = FRAME_RATE;
053. this.sprite.setTransform(this.x, this.y, SCALE_X, SCALE_Y);
054. stage.addChild(this.sprite);
055. },
056.  
057. update:function(){
058. var sprite = this.sprite;
059. var time = createjs.Ticker.getInterval()/1000;
060.  
061. if(this.state==='run'){
062. if(sprite.x<this.x){
063. sprite.x +=this.vx;
064. }else {
065. sprite.x = this.x
066. }
067. }
068. if(this.endy>sprite.y||this.state==='jump'){
069. var nexty = sprite.y+time*this.vy*PROPORTION;
070. this.vy += time*GRAVITY;
071. sprite.y += time*this.vy*PROPORTION;
072. if(Math.abs(sprite.y-this.endy)<10&&this.vy>0){
073. this.state = 'run';
074. sprite.y=this.endy;
075. this.vy = 0;
076. }
077. }
078.  
079. if(sprite.x+(PICWIDTH*SCALE_X-WIDTH)/2<0||sprite.y>C_H+200){
080. this.die();
081. createjs.Ticker.reset();
082. alert('you are Die!');
083. }
084.  
085. switch(this.state){
086. case 'run':
087. this.jumpNum = 0;
088. break;
089. case 'die':
090. if(sprite.currentFrame===0){
091. sprite.paused = true;
092. }
093. break;
094. }
095. },
096.  
097. run:function(){
098. this.sprite.gotoAndPlay('run')
099. },
100.  
101. jump:function(){
102. this.vy = -JUMP_SPEED;
103. this.state = 'jump';
104. this.sprite.gotoAndPlay('jump');
105. this.jumpNum++;
106. },
107.  
108. die:function(){
109. this.state = 'die';
110. this.sprite.gotoAndPlay('die')
111. },
112.  
113. size:function(){
114. return {
115. w:WIDTH,
116. h:HEIGHT
117. }
118. },
119.  
120. picsize:function(){
121. return {
122. w:PICWIDTH,
123. h:PICHEIGHT
124. }
125. }
126. }
127.  
128. w.createMan = function(x , y , img){
129. return new Man(x , y , img)
130. };
131. })(window)

物品模块:


加载中...
001. (function(w){
002. var SPEED = 4,
003. COIN_STAY_X = 20,
004. COIN_STAY_Y = 20,
005. COIN_STAY_WIDTH = 30,
006. COIN_STAY_HEIGHT = 30,
007. COIN_SCALE_X = 0.08,
008. COIN_SCALE_Y = 0.08;
009.  
010. //地上的石头类
011.  
012. var Stone = function(x,kind,allImage){
013. this.x = x;
014. this.kind = kind;
015. this.allImage = allImage;
016. this.init();
017. }
018.  
019. var sp = Stone.prototype;
020.  
021. sp.init=function(){
022. this.shape = new createjs.Shape();
023. if(this.kind!=='C'){
024. this.h = this.allImage[this.kind].height;
025. this.w = this.allImage[this.kind].width*2;
026. this.y = C_H - this.h;
027. this.shape.graphics.beginBitmapFill(this.allImage[this.kind]).drawRect(0, 0, this.w, this.h);
028. this.shape.setTransform(this.x, this.y, 1, 1);
029. }else {
030. this.h = -1000;
031. this.w = 170;
032. this.y = C_H - this.h;
033. this.shape.graphics.beginFill('#000').drawRect(0, 0, this.w, this.h);
034. this.shape.setTransform(this.x, this.y, 1, 1);
035. }
036. this.shape.visible = false;
037. this.shape.cache(0 , 0 , this.w , this.h);
038. stage.addChild(this.shape);
039. }
040.  
041. sp.update=function(){
042. this.shape.x -= SPEED;
043. }
044.  
045. //金币类
046. var Coin = function(image){
047. this.sizeX = COIN_SCALE_X;
048. this.sizeY = COIN_SCALE_Y;
049.  
050. this.isget = false;
051. this.init = function(){
052. this.shape = new createjs.Shape();
053. this.shape.graphics.beginBitmapFill(image).drawRect(0, 0, image.width, image.height);
054. this.shape.setTransform(0, 0, COIN_SCALE_X, COIN_SCALE_Y);
055. this.shape.visible = false;
056. stage.addChild(this.shape);
057. }
058. this.init();
059.  
060. this.update = function(){
061. if(this.isget){
062. this.sizeX = this.sizeX + ((COIN_STAY_WIDTH/image.width) - this.sizeX)*0.1;
063. this.sizeY = this.sizeY + ((COIN_STAY_HEIGHT/image.height) - this.sizeY)*0.1;
064. this.shape.setTransform(
065. this.shape.x + (COIN_STAY_X - this.shape.x)*0.1,
066. this.shape.y + (COIN_STAY_Y - this.shape.y)*0.1,
067. this.sizeX,
068. this.sizeY
069. );
070.  
071. if(Math.abs(this.shape.x-COIN_STAY_X)<0.5&&Math.abs(this.shape.y-COIN_STAY_Y)<0.5){
072. this.shape.visible = false;
073. this.isget = false;
074. this.sizeX = COIN_SCALE_X;
075. this.sizeY = COIN_SCALE_Y;
076. this.shape.setTransform(0,0,this.sizeX,this.sizeY);
077. }
078. } else{
079. this.shape.x -= SPEED;
080. if(this.shape.x<-image.width*COIN_SCALE_X){
081. this.shape.visible = false;
082. }
083. }
084. }
085.  
086. this.size = function(){
087. return {
088. w:image.width*COIN_SCALE_X,
089. h:image.height*COIN_SCALE_Y
090. }
091. }
092. }
093.  
094. w.createCoin = function(image){
095. return new Coin(image)
096. }
097.  
098. w.createStone = function(x,kind,allImage){
099. return new Stone(x,kind,allImage);
100. }
101. })(window)

简单的记录,如果有疑问请在评论提出,楼主看到会尽量解答。。。。自己用createJs的时候,最好多查查API文档哈,createJs的文档还是挺全面的,如果看不懂英文,就跟楼主一样下载个有道词典吧。哈哈哈。

atitit ui引擎之道 游戏引擎之道.docx 1. 概念 2 1.1. (cocos,createjs,dom) 2 2. 游戏引擎的构成(图形引擎(渲染系统),控件部件系统,事件系统 ,布局 atitit ui引擎之道 游戏引擎之道.docx   1. 概念 2 1.1. (cocos,createjs,dom) 2 2. 游戏引擎的构成(图形引擎(渲染系统),控件部件系统,事件系统 ,布局系统 ,动画系统,粒子系统(烟雾),物理系统(重力,碰撞) 2 3. 游戏引擎与gui引擎的区别(主要在重力,粒子系统) 2 4. Ui界面与游戏常用sdk api 3 4.1 阅读详情

相关推荐

HTML5游戏开发:选择适合的引擎和编程语言

Phaser引擎适用于2D游戏开发,CreateJS框架提供了强大的2D绘图功能,而Three.js库则适用于创建复杂的3D场景。以上示例代码可以帮助你入门HTML5游戏开发,并为你的游戏项目提供一个良好的起点。HTML5游戏开发是一种流行的方式,它允许开发者使用HTML、CSS和JavaScript创建跨平台的游戏。在进行HTML5游戏开发时,选择适合的游戏引擎和编程语言是至关重要的。它是一个基于WebGL的JavaScript库,可以用于创建复杂的3D场景和效果。

CyberLynxX的博客 387

createjs入门

createjs是一个轻量级的框架,稍微有点时间和耐心,就可以把全部源代码都看一遍,毕竟只有三十几个js文件。地址:http://www.createjs.com/ 开发createjs的动画或游戏,没有重型的IDE或什么工具支持,我们只能从零开始写js。一方面,这样对于jser来说,足够灵活;另外一方面,createjs因此足够精简足够小。 createjs由几个库组成: l easeljs,这个是核心,包括了显示列表、事件机制; l preloadjs,用于预加载图片等; l tweenjs,

細水、長流√的专栏 2866

vasimr:游戏引擎基于CreateJS套件构建

瓦西姆 游戏引擎基于CreateJS套件构建。

CreateJS入门 -- 注释详细到爆炸(My Style)

写在前面首先,还是谢谢大家的支持,谢谢!记得在之前的文章中我说过自己算是一个半文艺程序员,也一直想着写一写技术性和其他偏文学性的文章。虽然自己的底子没有多么优秀,但总是觉得这个过程中可以督促自己去思考,督促自己去学习和交流。毕竟每天忙忙碌碌之余,还是要活出自己不一样的生活。其次,我开通了个人的 GitHub主页,里面有自己的技术文章,还会有个人的随想、思考和日志。以后所有的文章都会第一时间更新到这...

weixin_34167819的博客 1356

window下安装并使用nvm(含卸载node、卸载nvm、全局安装npm)

文章目录一、卸载node二、安装nvm三、配置路径和下载源四、使用nvm安装node五、nvm常用命令六、卸载nvm七、遇到的问题 nvm 全名 node.js version management,顾名思义是一个nodejs的版本管理工具。通过它可以安装和切换不同版本的nodejs。 一、卸载node 如果你已经安装了node,那么你需要先卸载node,如果你没有安装那直接跳过这一步到下一步。 打开控制面板 -> 打开程序和功能 -> 右上角搜索输入node -> 右键卸载 为了确保彻底

HuangsTing的博客 41万+

Cox构建预测模型(5):如何用R语言绘制校准曲线(附全套代码)

这篇文献通过绘制两个模型的DCA曲线来评估模型的临床决策实际需求,一个是列线图模型,包括纳入列线图的全部变量,一个是TNM模型,只纳入TNM分期3个变量。A图是训练集1年、3年、5年患者的总生存期的DCA曲线;B图是训练集1年、3年、5年患者的总生存期的DCA曲线,红色线条代表列线图模型(包括构建模型的10个变量),黄色线条代表TNM模型(仅纳入TNM分期3个变量),两个模型对比,在绘制校准图之前,必须要完成数据的导入、拆分数据集的工作、预测因子的筛选,校准图的绘制是分别在训练集与验证集独立进行的。

qq_37610365的博客 1360

createjs新手教程-前端向(一)

createjs新手教程-前端向(一)

曾大强博客 816

速腾R128雷达+海康全景相机ROS数据采集避坑实录:从‘雷达不转’到MATLAB标定的完整流程

本文详细记录了速腾R128激光雷达与海康威视全景相机在ROS环境下的数据采集与MATLAB标定全流程。从硬件配置的常见陷阱(如雷达旋转参数设置)、驱动编译的依赖管理,到多传感器同步的实战技巧和MATLAB标定方法,提供了完整的避坑指南和技术方案。特别针对RoboSense R128雷达和海康相机的特殊需求给出了具体解决方案。

weixin_28717807的博客 1219

一篇文章带你快速入门createjs

开始用createjs这个框架的时候,发现网上的相关教程还是挺少的,所以写一篇文章,方便日后查看。 createjs简介 官网:http://www.createjs.cc/ createjs中包含以下四个部分: EaselJS:用于 Sprites、动画、向量和位图的绘制,创建 HTML5 Canvas 上的交互体验(包含多点触控) TweenJS:用于做动画效果 SoundJ...

weixin_34308389的博客 336

华硕三频万兆分布式路由组网实战:从AiMesh 2.0到全屋Wi-Fi 6覆盖

Mesh组网是解决大户型Wi-Fi覆盖难题的主流方案,其核心原理是通过多个节点构建网状网络,实现设备间的无缝漫游。在技术层面,Wi-Fi 6标准、三频设计(包括专属回程频段)和有线回程等技术,共同提升了网络的带宽、稳定性和抗干扰能力。这些技术的工程价值在于,能够为多设备并发、高带宽应用(如4K/8K流媒体、在线游戏、内网文件高速传输)提供可靠支撑。具体到应用场景,例如利用华硕AiMesh 2.0系统,配合三频万兆分布式路由器,可以实现智能的设备连接与负载均衡。通过合理规划节点位置、优先采用有线回程,并进行Q

weixin_34054866的博客 431

从AXI到CHI:深入解析基于Credit的流量控制如何优化NoC设计

本文深入解析了从AXI握手式流控到CHI基于Credit的流量控制机制的演进。通过对比传统流控的瓶颈,详细阐述了Credit机制如何通过信用预分配和记账系统,有效解决FIFO气泡、时序收敛等难题,从而优化NoC设计的带宽利用率、降低延迟并提升系统可扩展性。

weixin_29227585的博客 522

流行的前端游戏引擎/框架

PixiJS,Phaser,CreateJS,Three.js,Egret

编程架构三分天下:分层、分治、分时序。 1449

【PyGIS】ERA5降雨蒸散发数据预处理

ERA5-LAND降雨蒸散发数据预处理

```On Earth, Be Water, By Coding``` 3144

java clickheat_整理一份程序员常用的各类工具、技术站点

GRUNT: js task runnerSea.js: js模块化knockout.js:MVVM开发前台,绑定技术Angular.js: 使用超动感HTML & JS开发WEB应用!Highcharts.js,Flot:常用的Web图表插件Raw:非常不错的一款高级数据可视化工具Rickshaw:时序图标库,可用于构建实时图表JavaScript InfoVis Toolkit:另一款...

weixin_34543731的博客 146

【AI大模型:架构实战】31、工业级AI大模型系统全景解析:从架构设计到提示语引擎实践

本文系统解析了工业级AI大模型的核心架构与技术体系。整体采用分层解耦设计,包含数据工程、模型训练、模型部署、应用集成和监控运维五大核心模块,以及分布式计算、高速网络、异构硬件三大支撑体系。数据工程构建高质量数据处理流水线;模型训练实现从预训练到业务适配的全流程;模型部署优化服务性能与可用性;应用集成连接业务场景;监控运维保障系统持续优化。三大支撑能力专注于千亿参数管理、高并发低延迟处理和持续学习进化。该架构设计既满足当前需求,又为技术演进预留空间,为企业在数字化转型中提供AI工业化落地的完整解决方案。

2025博客之星Top81。专注AI工程化与架构实战。从分布式思维到模型部署,用工程化视角为你厘清AI落地的真实路径。 1989

学习笔记:TF卡启动荔枝派Nano(全志F1C200S)

荔枝派Nano编译Kernel报错报错内容如下编译烧录 报错内容如下 No controllers found No ethernet found. 从这些报错我真没看从出啥问题,也是在网上找,说是没有找到flash,是因为淘宝买的板子更换了flash,需要在u-boot里面重新适配型号: 板子的型号为xt25f128,但是实际u-boot的配置里面不是需要重新更改: u-boot/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts &spi0 { pin

热爱科技,物联,程序开发等 2133

主流HTML5游戏框架的分析和对比

本文主要选取了Construct2、ImactJS、LimeJS、GameMaker、CreateJS、lycheeJS、Crafty、three.js、melonJS、Turbulenz、Quintus、Cocos2d-html5等进行了简要介绍和对比,主要是根据网上的资料整理而成。 主流框架对比   Construct2 Construct 2是一个运行于Windows平台的游戏制作工...

weixin_34413357的博客 187

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

主流HTML5游戏框架的分析和对比(Construct2、ImpactJS、CreateJS、Cocos2d-html5……)

本文主要选取了Construct2、ImactJS、LimeJS、GameMaker、CreateJS、lycheeJS、Crafty、three.js、melonJS、Turbulenz、Quintus、Cocos2d-html5等进行了简要介绍和对比,主要是根据网上的资料整理而成。

心砚THU的专栏 2万+

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

[转]前端游戏引擎CreateJS与PixiJS之比较

经过数年的发展演化,HTML 5 为基础的游戏引擎很多,本文将就其中两个国外的著名的引擎CreateJS和PixiJS进行比较分析。鉴于CreateJS有工具帮忙又集成了声音引擎,所以如果对性能和兼容性要求不高,希望进行短期快速简单的开发,可以选择CreateJS。但由于性能问题和无法期望其进行延续行的开发和支持,如果项目希望有更好的品质,而且资源,时间充足,Pixi则是更好的选择。作者:时间1812来源:优快云。

Admans的专栏 949

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

前端游戏引擎CreateJS与PixiJS之比较

经过数年的发展演化,HTML 5 为基础的游戏引擎很多,本文将就其中两个著名的引擎CreateJS和PixiJS进行比较分析。对比了他们的API设计,功能,性能,工具支持,维护和开发几个方面。

time1812的专栏 2万+

HTML5各引擎显示效率比较

现在越来越多的人开始尝试使用HTML5开发,HTML5的引擎也逐渐增多,开发者到底应该选择一款什么样的引擎呢?这一次我来对比一下几个我个人认为还不错的引擎的效率。 本次参加对比的引擎: 1. createJS,2. cocos2d-HTML5,3. enchant.js,4. lufylegend.js

lufy小屋 3万+

如何使用Createjs来编写HTML5游戏(六)完成一个简单的打飞机游戏(上)

打飞机游戏雷电是一款经典的空战游戏,利用已知的CreateJS知识就可以很容易的做出一款类似的打飞机游戏。 首先,弄一些游戏需要的资源,做这样的一个小游戏,首先需要一架玩家操控的飞机图片,然后是可以击落的敌机图片,连续的爆炸图片来组成一个爆炸的动画Sprite,开枪的声音,爆炸的声音,星空的背景,然后使用TexturePacker把这些图片合并成一张图片,并获得一个json文件,其中的数据可以用

失业矿工的博客 7837

HTML5游戏引擎宝典:开启你的游戏开发之旅

HTML5游戏引擎宝典:开启你的游戏开发之旅 项目介绍 《HTML5游戏引擎宝典》是由CRC Press出版的一本专注于HTML5游戏开发的权威书籍。本书不仅提供了丰富的理论知识,还通过实际的示例代码,帮助开发者深入理解并掌握多种流行的HTML5游戏引擎。本书的示例代码和相关资源均已开源,方便开发者学习和使用。 项目技术分析 本书涵盖了多种主流的HTML5游戏引擎,包括: CraftyJS:一个...

gitblog_00684的博客 671

createJs游戏引擎

从昨天开始学习createJs,学习到的心得会陆续的记录到此处,做个笔记

o470780348的博客 439
上一篇: Oracle中NVARCHAR2与VARCHAR2的区别
下一篇: XAMPP 的安装配置(Linux 版)
zljjava
博客等级 码龄15年 155粉丝 15原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值