日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

【CSON原创】HTML5游戏框架cnGameJS开发实录(精灵对象篇)

發布時間:2025/4/5 HTML 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【CSON原创】HTML5游戏框架cnGameJS开发实录(精灵对象篇) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

返回目錄

1.什么是精靈對象(sprite)?

  所謂的精靈對象,就是游戲中的一個具有行為的元素,以超級瑪麗為例,瑪麗,敵人都算是一個精靈對象。在cnGameJS框架中,精靈對象如下幾個特點:

  1.添加動畫:在之前的動畫篇中,我們介紹過cnGameJS如何實現幀動畫。而作為精靈對象,就是動畫的使用者。例如我們控制瑪麗向不同方向的行走,瑪麗會產生行走的動畫。

  2.包含圖像:對于另外一些精靈對象,它可能不需要運動動畫,這時我們就可以只讓它使用圖像。

  3.能進行不同類型的運動:可以讓精靈對象向不同方向,以不同加速度進行移動。

2.demo展現

  這里以一個簡單的demo進行展現,我們通過鼠標控制瑪麗的行動(勻加速運動),當瑪麗停止時,使用圖片。當瑪麗移動時,使用動畫,鍵盤左右方向鍵控制瑪麗的移動

  效果:

  代碼:

<body>
<div><canvas id="gameCanvas">請使用支持canvas的瀏覽器查看</canvas></div>
</body>
<script src="http://files.cnblogs.com/Cson/cnGame_v1.0.js"></script>
<script>
var Src="http://images.cnblogs.com/cnblogs_com/Cson/290336/o_player.png";

/* 初始化 */
cnGame.init(
'gameCanvas',{width:300,height:150});
var floorY=cnGame.height-40;
var gameObj=(function(){
/* 玩家對象 */
var player=function(options){
this.init(options);
this.speedX=0;
this.moveDir;
this.isJump=false;
}
cnGame.core.inherit(player,cnGame.Sprite);
player.prototype.initialize
=function(){
this.addAnimation(new cnGame.SpriteSheet("playerRight",Src,{frameSize:[50,60],loop:true,width:150,height:60}));
this.addAnimation(new cnGame.SpriteSheet("playerLeft",Src,{frameSize:[50,60],loop:true,width:150,height:120,beginY:60}));
}
player.prototype.moveRight
=function(){
if(cnGame.core.isUndefined(this.moveDir)||this.moveDir!="right"){
this.moveDir="right";
this.speedX<0&&(this.speedX=0);
this.setMovement({aX:10,maxSpeedX:15});
this.setCurrentAnimation("playerRight");
}
}
player.prototype.moveLeft
=function(){
if(cnGame.core.isUndefined(this.moveDir)||this.moveDir!="left"){
this.moveDir="left";
this.speedX>0&&(this.speedX=0);
this.setMovement({aX:-10,maxSpeedX:15});
this.setCurrentAnimation("playerLeft");
}
}
player.prototype.stopMove
=function(){

if(this.speedX<0){
this.setCurrentImage(Src,0,60);
}
else if(this.speedX>0){
this.setCurrentImage(Src);
}
this.moveDir=undefined;
this.resetMovement();

}
player.prototype.update
=function(){
player.prototype.parent.prototype.update.call(
this);//調用父類update
if(cnGame.input.isPressed("right")){
this.moveRight();
}
else if(cnGame.input.isPressed("left")){
this.moveLeft();
}
else{
this.stopMove();
}


}

return {
initialize:
function(){
cnGame.input.preventDefault([
"left","right","up","down"]);
this.player=new player({src:Src,width:50,height:60,x:0,y:floorY-60});
this.player.initialize();
},
update:
function(){
this.player.update();
},
draw:
function(){
this.player.draw();
}

};
})();
cnGame.loader.start([Src],gameObj);
</script> 復制代碼


3.實現

  和動畫篇spriteSheet對象一樣,sprite對象同樣劃分三個階段:初始化,更新,繪制

  首先看sprite的初始化函數:

/**
*初始化
*
*/
init:function(options){

/**
*默認對象
*
*/
var defaultObj={
x:0,
y:0,
imgX:0,
imgY:0,
width:32,
height:32,
angle:0,
speedX:0,
speedY:0,
aX:0,
aY:0,
maxSpeedX:postive_infinity,
maxSpeedY:postive_infinity,
maxX:postive_infinity,
maxY:postive_infinity,
minX:-postive_infinity,
minY:-postive_infinity
};
options=options||{};
options=cg.core.extend(defaultObj,options);
this.x=options.x;
this.y=options.y;
this.angle=options.angle;
this.width=options.width;
this.height=options.height;
this.angle=options.angle;
this.speedX=options.speedX;
this.speedY=options.speedY;
this.aX=options.aX;
this.aY=options.aY;
this.maxSpeedX=options.maxSpeedX;
this.maxSpeedY=options.maxSpeedY;
this.maxX=options.maxX;
this.maxY=options.maxY;
this.minX=options.minX;
this.minY=options.minY;


this.spriteSheetList={};
if(options.src){ //傳入圖片路徑
this.setCurrentImage(options.src,options.imgX,options.imgY);
}
else if(options.spriteSheet){//傳入spriteSheet對象
this.addAnimation(options.spriteSheet);
setCurrentAnimation(options.spriteSheet);
}

} 復制代碼

  參數很多,主要包括:對象位置,旋轉角度,尺寸,xy方向的速度,xy方向的加速度,xy方向的最大速度。另外如果用戶傳入圖片地址,則設置當前sprite對象使用圖片,否則使用spriteSheet動畫。

  先看看sprite對象如何使用圖像:

/**
*設置當前顯示圖像
*
*/
setCurrentImage:function(src,imgX,imgY){
if(!this.isCurrentImage(src,imgX,imgY)){
imgX=imgX||0;
imgY=imgY||0;
this.image=cg.loader.loadedImgs[src];
this.imgX=imgX;
this.imgY=imgY;
this.spriteSheet=undefined;
}
}, 復制代碼

  首先檢測現在是否正在使用該圖像,如果不是,則從loader里獲取下載好的image對象(所有圖像資源在游戲開始時已下載好,詳情請看:HTML5游戲框架cnGameJS開發實錄(資源加載模塊篇)),并且設置spriteSheet為undefined(表示不使用spriteSheet動畫),這樣sprite對象就可以使用圖像了。

  再看看如何使用動畫:

/**
*設置當前顯示動畫
*
*/
setCurrentAnimation:function(id){//可傳入id或spriteSheet
if(!this.isCurrentAnimation(id)){
if(cg.core.isString(id)){
this.spriteSheet=this.spriteSheetList[id];
this.image=this.imgX=this.imgY=undefined;
}
else if(cg.core.isObject(id)){
this.spriteSheet=id;
this.addAnimation(id);
this.image=this.imgX=this.imgY=undefined;
}
}

}, 復制代碼

  首先根據傳入的spriteSheet或spriteSheet的id判斷是否正在使用該動畫,如果不是,則設置sprite使用spriteSheet動畫。

  設置好sprite對象使用動畫后,核心函數update就負責調用spriteSheet的update,更新sprite使用的動畫,需要注意的是使spriteSheet的xy為sprite的xy:


if(this.spriteSheet){//更新spriteSheet動畫
this.spriteSheet.x=this.x
this.spriteSheet.y=this.y;
this.spriteSheet.update();
} 復制代碼

  這樣就完成的sprite對象動畫的展示。

  最后看看如何實現最后一個特點:使sprite能進行變速的運動。

  要進行變速運動,我們需要確立如下幾個變量:初始速度,經過的時間,以及加速度。現在看cnGameJS負責變速運動的部分:

/**
*設置移動參數
*
*/
setMovement:function(options){
isUndefined=cg.core.isUndefined;
isUndefined(options.speedX)?this.speedX=this.speedX:this.speedX=options.speedX;
isUndefined(options.speedY)?this.speedY=this.speedY:this.speedY=options.speedY;

isUndefined(options.aX)?this.aX=this.aX:this.aX=options.aX;
isUndefined(options.aY)?this.aY=this.aY:this.aY=options.aY;
isUndefined(options.maxX)?this.maxX=this.maxX:this.maxX=options.maxX;
isUndefined(options.maxY)?this.maxY=this.maxY:this.maxY=options.maxY;
isUndefined(options.minX)?this.minX=this.minX:this.minX=options.minX;
isUndefined(options.minY)?this.minY=this.minY:this.minY=options.minY;


if(this.aX!=0){
this.startTimeX=new Date().getTime();
this.oriSpeedX=this.speedX;
isUndefined(options.maxSpeedX)?this.maxSpeedX=this.maxSpeedX:this.maxSpeedX=options.maxSpeedX;
}
if(this.aY!=0){
this.startTimeY=new Date().getTime();
this.oriSpeedY=this.speedY;
isUndefined(options.maxSpeedY)?this.maxSpeedY=this.maxSpeedY:this.maxSpeedY=options.maxSpeedY;
}

} 復制代碼

  每次用戶調用setMovement,就保留sprite的初速度,和運動開始的時間。這樣在每次update的時候,就可以根據前面兩個變量,獲取到sprite現時的速度,并計算現時的XY方向上的位移:

 

if(this.aX!=0){
var now=new Date().getTime();
var durationX=now-this.startTimeX;
var speedX=this.oriSpeedX+this.aX*durationX/1000;
if(this.maxSpeedX<0){
this.maxSpeedX*=-1;
}
if(speedX<0){
this.speedX=Math.max(speedX,this.maxSpeedX*-1) ;
}
else{
this.speedX=Math.min(speedX,this.maxSpeedX);
}
}
if(this.aY!=0){
var now=new Date().getTime();
var durationY=now-this.startTimeY;
this.speedY=this.oriSpeedY+this.aY*durationY/1000;
}
this.move(this.speedX,this.speedY); 復制代碼

  當update更新了sprite的位移,就可以通過第三個階段draw方法,把sprite繪制出來。

/**
*繪制出sprite
*
*/
draw:function(){
var context=cg.context;
if(this.spriteSheet){
this.spriteSheet.x=this.x
this.spriteSheet.y=this.y;
this.spriteSheet.draw();
}
else if(this.image){
context.save()
context.translate(this.x, this.y);
context.rotate(this.angle * Math.PI / 180);
context.drawImage(this.image,this.imgX,this.imgY,this.width,this.height,0,0,this.width,this.height);
context.restore();
}

}, 復制代碼

  注意sprite在使用spriteSheet動畫或在使用圖像,draw方法執行都不相同。當使用sprieSheet動畫時,draw方法實質上是調用了spriteSheet的draw方法繪制幀圖像,而當sprite使用圖像,我們還可以讓圖像旋轉之后再繪制。

  sprite對象還提供一個getRect方法,返回包含該sprite對象的矩形。該方法為檢測sprite對象和其他對象的碰撞帶來方便。有關碰撞檢測請看:HTML5游戲框架cnGameJS開發實錄(碰撞檢測篇)

  另外sprite對象同樣具有move,moveTo,resize,resizeTo等功能,方便對該對象的位置和尺寸進行操控。

?

  sprite對象所有源碼:

/**
*
*sprite對象
*
*
*/
cnGame.register("cnGame",function(cg){

var postive_infinity=Number.POSITIVE_INFINITY;

var sprite=function(id,options){
if(!(this instanceof arguments.callee)){
return new arguments.callee(id,options);
}
this.init(id,options);
}
sprite.prototype={
/**
*初始化
*
*/
init:function(options){

/**
*默認對象
*
*/
var defaultObj={
x:0,
y:0,
imgX:0,
imgY:0,
width:32,
height:32,
angle:0,
speedX:0,
speedY:0,
aX:0,
aY:0,
maxSpeedX:postive_infinity,
maxSpeedY:postive_infinity,
maxX:postive_infinity,
maxY:postive_infinity,
minX:-postive_infinity,
minY:-postive_infinity
};
options=options||{};
options=cg.core.extend(defaultObj,options);
this.x=options.x;
this.y=options.y;
this.angle=options.angle;
this.width=options.width;
this.height=options.height;
this.angle=options.angle;
this.speedX=options.speedX;
this.speedY=options.speedY;
this.aX=options.aX;
this.aY=options.aY;
this.maxSpeedX=options.maxSpeedX;
this.maxSpeedY=options.maxSpeedY;
this.maxX=options.maxX;
this.maxY=options.maxY;
this.minX=options.minX;
this.minY=options.minY;

this.spriteSheetList={};
if(options.src){ //傳入圖片路徑
this.setCurrentImage(options.src,options.imgX,options.imgY);
}
else if(options.spriteSheet){//傳入spriteSheet對象
this.addAnimation(options.spriteSheet);
setCurrentAnimation(options.spriteSheet);
}

},
/**
*返回包含該sprite的矩形對象
*
*/
getRect:function(){
return new cg.shape.Rect({x:this.x,y:this.y,width:this.width,height:this.height});

},
/**
*添加動畫
*
*/
addAnimation:function(spriteSheet){
this.spriteSheetList[spriteSheet.id]=spriteSheet;
},
/**
*設置當前顯示動畫
*
*/
setCurrentAnimation:function(id){//可傳入id或spriteSheet
if(!this.isCurrentAnimation(id)){
if(cg.core.isString(id)){
this.spriteSheet=this.spriteSheetList[id];
this.image=this.imgX=this.imgY=undefined;
}
else if(cg.core.isObject(id)){
this.spriteSheet=id;
this.addAnimation(id);
this.image=this.imgX=this.imgY=undefined;
}
}

},
/**
*判斷當前動畫是否為該id的動畫
*
*/
isCurrentAnimation:function(id){
if(cg.core.isString(id)){
return (this.spriteSheet&&this.spriteSheet.id===id);
}
else if(cg.core.isObject(id)){
return this.spriteSheet===id;
}
},
/**
*設置當前顯示圖像
*
*/
setCurrentImage:function(src,imgX,imgY){
if(!this.isCurrentImage(src,imgX,imgY)){
imgX=imgX||0;
imgY=imgY||0;
this.image=cg.loader.loadedImgs[src];
this.imgX=imgX;
this.imgY=imgY;
this.spriteSheet=undefined;
}
},
/**
*判斷當前圖像是否為該src的圖像
*
*/
isCurrentImage:function(src,imgX,imgY){
imgX=imgX||0;
imgY=imgY||0;
var image=this.image;
if(cg.core.isString(src)){
return (image&&image.srcPath===src&&this.imgX===imgX&&this.imgY===imgY);
}
},
/**
*設置移動參數
*
*/
setMovement:function(options){
isUndefined=cg.core.isUndefined;
isUndefined(options.speedX)?this.speedX=this.speedX:this.speedX=options.speedX;
isUndefined(options.speedY)?this.speedY=this.speedY:this.speedY=options.speedY;

isUndefined(options.aX)?this.aX=this.aX:this.aX=options.aX;
isUndefined(options.aY)?this.aY=this.aY:this.aY=options.aY;
isUndefined(options.maxX)?this.maxX=this.maxX:this.maxX=options.maxX;
isUndefined(options.maxY)?this.maxY=this.maxY:this.maxY=options.maxY;
isUndefined(options.minX)?this.minX=this.minX:this.minX=options.minX;
isUndefined(options.minY)?this.minY=this.minY:this.minY=options.minY;


if(this.aX!=0){
this.startTimeX=new Date().getTime();
this.oriSpeedX=this.speedX;
isUndefined(options.maxSpeedX)?this.maxSpeedX=this.maxSpeedX:this.maxSpeedX=options.maxSpeedX;
}
if(this.aY!=0){
this.startTimeY=new Date().getTime();
this.oriSpeedY=this.speedY;
isUndefined(options.maxSpeedY)?this.maxSpeedY=this.maxSpeedY:this.maxSpeedY=options.maxSpeedY;
}

},
/**
*重置移動參數回到初始值
*
*/
resetMovement:function(){
this.speedX=0;
this.speedY=0;
this.aX=0;
this.aY=0;
this.maxSpeedX=postive_infinity;
this.maxSpeedY=postive_infinity;
this.maxX=postive_infinity;
this.minX=-postive_infinity;
this.maxY=postive_infinity;
this.minY=-postive_infinity;
},
/**
*更新位置和幀動畫
*
*/
update:function(){
if(this.aX!=0){
var now=new Date().getTime();
var durationX=now-this.startTimeX;
var speedX=this.oriSpeedX+this.aX*durationX/1000;
if(this.maxSpeedX<0){
this.maxSpeedX*=-1;
}
if(speedX<0){
this.speedX=Math.max(speedX,this.maxSpeedX*-1) ;
}
else{
this.speedX=Math.min(speedX,this.maxSpeedX);
}
}
if(this.aY!=0){
var now=new Date().getTime();
var durationY=now-this.startTimeY;
this.speedY=this.oriSpeedY+this.aY*durationY/1000;
}
this.move(this.speedX,this.speedY);


if(this.spriteSheet){//更新spriteSheet動畫
this.spriteSheet.x=this.x
this.spriteSheet.y=this.y;
this.spriteSheet.update();
}
},
/**
*繪制出sprite
*
*/
draw:function(){
var context=cg.context;
if(this.spriteSheet){
this.spriteSheet.x=this.x
this.spriteSheet.y=this.y;
this.spriteSheet.draw();
}
else if(this.image){
context.save()
context.translate(this.x, this.y);
context.rotate(this.angle * Math.PI / 180);
context.drawImage(this.image,this.imgX,this.imgY,this.width,this.height,0,0,this.width,this.height);
context.restore();
}

},
/**
*移動一定距離
*
*/
move:function(dx,dy){
dx=dx||0;
dy=dy||0;
var x=this.x+dx;
var y=this.y+dy;
this.x=Math.min(Math.max(this.minX,x),this.maxX);
this.y=Math.min(Math.max(this.minY,y),this.maxY);
return this;

},
/**
*移動到某處
*
*/
moveTo:function(x,y){
this.x=Math.min(Math.max(this.minX,x),this.maxX);
this.y=Math.min(Math.max(this.minY,y),this.maxY);
return this;
},
/**
*旋轉一定角度
*
*/
rotate:function(da){
this.angle+=da;
return this;
},
/**
*旋轉到一定角度
*
*/
rotateTo:function(){
this.angle=da;
return this;

},
/**
*改變一定尺寸
*
*/
resize:function(dw,dh){
this.width+=dw;
this.height+=dh;
return this;
},
/**
*改變到一定尺寸
*
*/
resizeTo:function(width,height){
this.width=width;
this.height=height;
return this;
}

}
this.Sprite=sprite;

}); 復制代碼

轉載于:https://www.cnblogs.com/Cson/archive/2012/02/14/2349661.html

總結

以上是生活随笔為你收集整理的【CSON原创】HTML5游戏框架cnGameJS开发实录(精灵对象篇)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩色av | 婷婷综合在线 | 未满十八岁勿进 | 成人h动漫精品一区二区 | 天天谢天天干 | japanese中文字幕 | www.555国产精品免费 | 强侵犯の奶水授乳羞羞漫虐 | 中文字幕在线免费 | 免费黄色国产 | 欧美视频一区二区在线 | 国产午夜精品一区 | 成人激情文学 | 亚洲乱码国产乱码精品 | 黑帮大佬和我的365日第二部 | 亚洲女人在线 | 亚洲高清av在线 | 性欧美在线视频 | 中文字幕第一页在线视频 | 亚洲区视频在线观看 | 成人亚洲免费 | 亚洲人一区二区三区 | av在线最新 | 中文字幕色图 | 天堂网成人 | 天天撸夜夜操 | 亚洲天堂系列 | 美女91网站| 午夜精品久久久久久久第一页按摩 | 免费黄色小视频在线观看 | 人妻在线一区二区 | 国产麻豆一精品一av一免费 | 日韩国产一区二区三区 | 日韩国产欧美一区 | 大陆极品少妇内射aaaaaa | 亚洲欧美激情小说另类 | 国产日产亚洲精品 | 香蕉视频传媒 | 欧美三日本三级少妇三 | 四虎在线免费视频 | 青青草免费在线视频 | 国产精品一区二区三区四区在线观看 | 亚洲欧美另类在线 | 亚洲一二三av | 不卡影院 | 国产免费叼嘿网站免费 | 欧美群妇大交群 | 国产日韩欧美亚洲 | 亚洲精品xxxxx | 国产成人一区二区三区影院在线 | 亚洲偷偷 | 超碰在线观看免费版 | 特级淫片aaaaaaa级附近的 | 久久久久久91香蕉国产 | 三级在线观看 | 超碰在线免费公开 | 饥渴的少妇和男按摩师 | 真人一及毛片 | 亚洲丝袜天堂 | 五月婷婷开心中文字幕 | 欧美精品综合 | 中文字幕日韩高清 | 青青操久久 | 人人爽av | 男生插女生视频在线观看 | 中文字幕一区二区免费 | 日本少妇性高潮 | 亚洲xxxxxx| 在线视频日本 | 欧美精品久久久久性色 | 日本少妇18p| 日本美女毛片 | 一本色道久久综合亚洲精品按摩 | 久久久久久久久久久久久久国产 | 台湾av在线 | 麻豆网站入口 | 国产激情视频一区二区三区 | av优选在线观看 | 精品久久久久久久无码 | 18av视频| 一本一道久久a久久 | 久久人妻少妇嫩草av无码专区 | 激情宗合 | 美女视频免费在线观看 | 久久人 | 国产免费一区二区三区在线播放 | 亚洲一区二区三区麻豆 | 女人高潮娇喘1分47秒 | 欧美国产一级 | 九九热精品视频 | 手机看片国产日韩 | 毛片大全在线观看 | av黄| 激情瑟瑟 | 成人羞羞网站 | 日韩欧美亚洲综合 | 国产精品成人免费一区久久羞羞 | 涩涩免费网站 | 欧美在线中文 |