• Html5游戏框架createJs的简单用法


    声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢!http://www.it165.net/pro/html/201403/11105.html

      楼主记忆力不好,最近刚好用了一下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{ 700px;height:500px;position: relative;}
    008.#coins{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的文档还是挺全面的,如果看不懂英文,就跟楼主一样下载个有道词典吧。哈哈哈。

  • 相关阅读:
    FireDAC的数据库的FDConnect
    Readers and Writers JSON Framework(2)
    JSON Objects Framework(1)
    SQLServer 临时表的使用
    客户重复需要检查CRM客户
    采购订单下推付款申请单获取组织业务关系
    采购订单跨组织生成销售订单,没得选组织的问题
    销售合同缓存问题
    BOS中给基础资料赋值
    辅助属性值列表功能的缺点
  • 原文地址:https://www.cnblogs.com/kt520/p/4434913.html
Copyright © 2020-2023  润新知