html游戏引擎,createJs框架
声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢!
createJs网上的中文教程挺少的,以前UC有个Xcanvas的论坛有createJs的详细教程,但是随着XCanvas团队的解散,那个网 站也关闭了。。网上的大部分都是非常基础的教程,有点千遍一律的感觉。所以楼主就去把createJs下载下来,硬着头皮看英文文档了。凭着楼主这英语六 级只考了三百多分的渣渣来说,看起来很费力啊,不过还是勉强摸索出了大概的用法。所以现在就是学了多少就记录多少,之后或许也会不定期更新一下该框架的新 的学习心得。毕竟对自己以后还是有帮助的。
闲话说到这,直接进入主题。
楼主用createJs写了个简单的跑酷游戏DEMO,就拿它做例子吧。 看DEMO戳我。
createJs的由来,基础什么的就不说了,就直接说createJs的用法吧。
接下来开始分析代码:
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.
}
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.
}
然后进行舞台循环设置,上面有注释了,就不说了。
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)
下面贴出封装的石头以及金币模块,简单说下背景的循环,预先实例化一堆石头和金币,然后移动响应的石头,当石头移动到超出舞台区域时,把他的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.
}
在每一帧的处理,就像自己写游戏一样啦,就是把舞台里的所有对象逐个进行逻辑运算,进行相应处理。
主页面:
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)
html游戏引擎,createJs框架的更多相关文章
- 排名前10的H5、Js 3D游戏引擎和框架
由于很多人都在用JavaScript.HTML5和WebGL技术创建基于浏览器的3D游戏,所有JavaScript 3D游戏引擎是一个人们主题.基于浏览器的游戏最棒的地方是平台独立,它们能在iOS.A ...
- 转:高层游戏引擎——基于OGRE所实现的高层游戏引擎框架
高层游戏引擎——基于OGRE所实现的高层游戏引擎框架 这是意念自己的毕业论文,在一个具体的实践之中,意念主要负责的是物件和GUI之外的其他游戏系统.意念才学疏陋,望众位前辈不吝赐教.由于代码质量不高. ...
- 游戏引擎网络开发者的 64 做与不做 | Part 1 | 客户端方面
摘要:纵观过去 10 年的游戏领域,单机向网络发展已成为一个非常大的趋势.然而,为游戏添加网络支持的过程中往往存在着大量挑战,这里将为大家揭示游戏引擎网络开发者的 64 个做与不做. [编者按]时下, ...
- 开源战棋 SLG 游戏框架设计思考(一)简介和游戏引擎
战棋 SLG 游戏 SLG(Simulation Game)游戏是模拟游戏的简称.战棋类的SLG有两种:一种是 War Game 中的兵棋推演分支,常见的游戏有战争艺术3(TOAW3 — The Op ...
- 20款最受欢迎的HTML5游戏引擎收集
在“最火HTML5 JavaScript游戏引擎”系列文章国外篇(一)中,我们盘点了当下备受开发者推崇的非国产HTML5和JavaScript游戏引擎.在各种2D小游戏逆袭的今天,用HTML5和Jav ...
- QQ空间玩吧HTML5游戏引擎使用比例分析
GameLook报道/“Cocos 2015开发者大会(春季)”于4月2日在国家会议中心圆满落下帷幕.在会上全新的3D编辑器,Cocos Runtime等产品重磅公布,给业界带来了Cocos这款国产引 ...
- HTML5游戏引擎深度测评
https://zhuanlan.zhihu.com/p/20768495 最近看到网上一篇文章,标题叫做<2016年 最火的 15 款 HTML5 游戏引擎>.目前针对HTML5游戏的解 ...
- UWP简单示例(三):快速开发2D游戏引擎
准备 IDE:VisualStudio 2015 Language:VB.NET/C# 图形API:Win2D MSDN教程:UWP游戏开发 游戏开发涉及哪些技术? 游戏开发是一门复杂的艺术,编码方面 ...
- 八款常见的Android游戏引擎
原文地址:http://bbs.csdn.net/topics/380203732 1.Angle Angle是一款专为Android平台设计的,敏捷且适合快速开发的2D游戏引擎,基于OpenGL ...
- 控制台游戏引擎CGE——贪吃蛇
今天我也来发一个控制台游戏.先看图: 缘起 LZ是一个有严重拖延症的人,表现的形式就是隔一段时间就要刷一刷博客园. 这不前几天,看到了魏大师<使用Lua脚本语言开发出高扩展性的系统...> ...
随机推荐
- 武汉科技大学ACM :1005: 零起点学算法101——手机短号
Problem Description 大家都知道,手机号是一个11位长的数字串,同时,作为学生,还可以申请加入校园网,如果加入成功,你将另外拥有一个短号.假设所有的短号都是是 6+手机号的后5位,比 ...
- Go语言之异常处理
在编写Go语言代码的时候,我们应该习惯使用error类型值来表明非正常的状态.作为惯用法,在Go语言标准库代码包中的很多函数和方法也会以返回error类型值来表明错误状态及其详细信息. error是一 ...
- Asp.Net页面生命周期--转发(学海无涯)
一.什么是Asp.Net页面生命周期 当我们在浏览器地址栏中输入网址,回车查看页面时,这时会向服务器端(IIS)发送一个request请求,服务器就会判断发送过来的请求页面, 完全识别 HTTP 页 ...
- js定时跳转
在项目中有时会用到定时跳转,自己收藏了一个比较好用的 js写的,不依赖jQuery <script type="text/javascript"> function c ...
- discuz 使模板中的函数不解析 正常使用
<!--{if $_GET['zcdw']=="baxi"}--><!--{eval $duiwuxinxi = "巴西队";}-->& ...
- (翻译玩)SQLALchemy backref章节文档
Linking Relationships with Backref 自从在Object Relational Tutorial中第一次提到backref参数后,许多案例中也用到了backref,那么 ...
- (转载)Python装饰器学习
转载出处:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方 ...
- Python 番外 消息队列设计精要
消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一.当今市面上有很多主流的消息中间件,如老牌的Active ...
- iOS应用崩溃日志分析-备用
作为一名应用开发者,你是否有过如下经历? 为确保你的应用正确无误,在将其提交到应用商店之前,你必定进行了大量的测试工作.它在你的设备上也运行得很好,但是,上了应用商店后,还是有用户抱怨会闪退 ! ...
- windows mongodb 安装
window平台一下所有命令 务必以管理员身份运行 且在window系统命令行下,如git bash不可以 具体以管理员身份运行的快捷键是 1. win+x 2. shift + a 设置文件存储目录 ...