虽然目前几乎所有的webgame动画都使用Flash来实现,但是使用用JS来实现一场RPG的战斗动画,一直以来都不是什么难题。
去年我通过JS方式实现战斗引擎播放,效果也可以做的很绚丽,所有浏览器下,都测试通过,尚未发现卡的问题,但是,由于IE6下面,需要使用了VML(
由于将完成的一个游戏,是关卡玩法的游戏,PVE部分,比较适合放到手机平台上当做手机单机游戏来玩,所以我考虑,是否使用HTML5来完成战斗引擎,针对Webkit内核的等等支持HTML5的浏览器,我们可以使用HTML5来完成战斗动画播放,则可以直接使用在Andriod、iOS、WP7等手机平台上。
由于我从05年开始,我使用JavaScript越来越多,其中大部分是使用Prototype,所以下面这个例子,是基于了Prototype JS的。
注:如Internet Explorer的一些浏览器,不支持canvas标签或本演示。的Chrome、Firefox、Safari、Opera浏览器的最新版本正常工作。
不使用HTML5来完成动画的时候,通过css改变背景图片的偏移量可以做出战斗动画。使用HTML5来完成,只需要在Canvas上面循环画出图片上面不同帧即可。
最好的说明是实例:
配置动画参数:
var attack = {
name: 'attack',
totalFrames: 10,
loop: true,
step: 4,
width: 150,
height: 150,
sY: 0,
sX: 0
}; //set initial animation set
角色动画:
/**
* Sprite 系统,雏形
*
* @file_name Sprite.js
* @version 1.0
* @author 黄新泽
* @date 2011/1/14
*/
var Sprite = Class.create({
initialize : function(x, y, width, height, img, animation)//initialize sprite
{
this.canvas = document.createElement('canvas'); //动画canvas
this.canvas.setAttribute('width', width);
this.canvas.setAttribute('height', height);
this.ctx = this.canvas.getContext('2d'); //get canvas drawing context
this.x = x; // X position of this sprite
this.y = y; //Y position of this sprite
this.animation = 0; //current animation for this sprite
this.currentFrame = 0; //current animation frame for this sprite
this.width = width;
this.height = height;
this.image = img; //image that is being drawn to the canvas
this.currentStep = 0; //number of frames since this sprite's animation was updated
this.isReady = true; //sprite has finished loading and can be used
this.animation = animation;
},
drawImage: function()
{
//draw image into sprite canvas
this.ctx.clearRect(0, 0, this.width, this.height); //clear previous frame
if(this.isReady)
{
//do not draw if sprite is not ready
//calculate values for sprite based on animation
var srcX = this.animation.sX + (this.currentFrame * this.animation.width);
var srcY = this.animation.sY ;
var srcWidth = this.animation.width;
var srcHeight = this.animation.height;
this.ctx.drawImage(this.image, srcX, srcY, srcWidth, srcHeight, 0, 0, srcWidth, srcHeight); //draw image
this.stepSprite(); //advance animation
}
},
stepSprite: function()
{
//advance animation based on animation speed (step value)
if(this.currentStep >= this.animation.step)
{
this.currentStep = 0;
this.currentFrame++;
if(this.currentFrame >= this.animation.totalFrames)
{
if(this.animation.loop)
{
this.currentFrame = 0; //loop animation back to start
}
else
{
this.currentFrame = this.animation.totalFrames -1; //if loop not set, hold on final frame
}
}
}
else
{
this.currentStep++; //advance step counter if step limit not reached
}
}
});
播放战斗动画:
var FightAnimation = Class.create({
canvas: 0, //main canvas object
ctx: 0, //main canvas drawing context
sprite: 0, //sprite object
width: 900,
height: 450,
timer: 0, //hold reference to game loop timer
background: 0, //background image - for now is drawn right onto main canvas which is not ideal
foreground: 0, //foreground object
initialize: function(img)
{
//initialize FightAnimation
this.canvas = document.getElementById('main'); //get canvas element from html
this.ctx = this.canvas.getContext('2d'); //create main drawing canvas
this.canvas.setAttribute('width', FightAnimation.width); //set attributes of canvas
this.canvas.setAttribute('height', FightAnimation.height);
this.sprite = new Sprite(0, 0, 150, 150, img, attack); //init sprite //create new Sprite object
//document.body.insert(FightAnimation.sprite.canvas);
this.timer = setInterval(this.drawFrame.bind(this), 40);
},
drawFrame: function()
{
//main drawing function
this.ctx.clearRect(0, 0, this.width, this.height); //clear main canvas
//FightAnimation.ctx.drawImage(FightAnimation.background, 0, 0); // draw canvas background
if(this.sprite)
{
this.sprite.drawImage(); //cause sprite to draw itself on its internal canvas
this.ctx.drawImage(this.sprite.canvas, this.sprite.x, this.sprite.y);//draw sprite canvas onto main canvas
}
}
});
初始化战斗:
function startCanvas(e)
{
new FightAnimation(img_res.successList['129_1_1'].img); //initialize main Expermient object
}
document.on('img:oneloaded', startCanvas); //处理进度条,........
var img_res = ImgManage.getInstance();
img_res.addResourcesBag([["129_1_1", "/Images/actionicon/56/1/2.png"]]);
Related posts:
- 去掉JW Player水印及右键官方菜单 之前为葱哥修改编译了去掉JW Player水印及右键官方菜单JW Player, 今天想弄个视频,就又去下载了修改了下: 修改方法: 去掉Logo水印; 在文件“/com/longtailvideo/jwplayer/view/View.as ”中找到“_logoLayer.addChild(_logo);”将其注释掉即可。 去掉右键about官网地址链接。 在文件“/com/longtailvideo/jwplayer/view/RightclickMenu.as...
- Android and HTML5 开发手机应用 作为一个WEB开发者,HTML5让我兴奋,因为它可以将桌面应用程序功能带入浏览器中。但在国内,看着到处横行的IE8版本以下的浏览器,觉得到能大规模使用HTML5技术的那天,还遥遥无期。但面对iOS及Android等平台的手机用户越来越多,基于Webkit内核的移动浏览器一定能让HTML5先大规模应用起来。这将对对移动 Web 应用程序开发具有重大影响。 作为非常看好未来手机网络的我,也在一直研究Android平台的应用的开发,也许是因为自己更熟悉HTML及CSS、JS,并受到之前使用HTML和VC开发程序的影响,我也更愿意使用HTML来做Android程序的UI…. 09年,在开发《华夏风云》游戏的时候,使用了基于Google Gear插件来做了很多离线应用,可惜Gear已经不在更新开发,被HTML5取代。下面介绍基于HTML 5 的Web 应用程序的本地存储,不再废话,例子说明一切。 ...
呵呵,挺棒的,为什么不放个demo呢。wp有运行代码的插件。runcode
我安装个试试。
把这个的演示版完整代码放出来看看吧