本帖最后由 bulangnisi 于 2016-4-3 16:51 编辑
这次来了解一下 精灵(Sprite)元素
对于做游戏的大神都知道精灵(Sprite)对于游戏的重要性(ps:我不是大神,我是初心者。。。)
这里我仅用自己的思路大致来描述一下,有偏差的地方请同学们指正一下。
拿这个rpgmaker来说,里面大大小小的东西都可以算作是精灵,首页显示的背景算是,地图的每个单元算是,更不用说我们操作的角色了,你游戏中几乎所有看到的东西动起来,仅仅是精灵单元改变自己的图片而已,由于游戏的fps(帧)刷新得比较快,所以我们看到的就是一个连贯动作的精灵(就像我小时候在课本每页的右下角画小人,然后每一页画一个动作,然后把书翻起来的话,就会看到一个连贯的动作,就是这个意思)。
在rpgmaker中大多数对象都具有update的方法,这就像是我们在翻书的动作,然后里面的图片素材就是我们画的小人。
所以这次我们来做个自己想要的标题页,可以动起来的,主要操作的东西,就是精灵(Sprite)。
在rpg_scene.js的233行找到创建标题页的代码
其中createBackground方法就给了我们很好的示例,他在里面创建了2个精灵(说白了你甚至可以把精灵直接理解为一个图片都行- -),
Scene_Title.prototype.createBackground = function() { this._backSprite1 = new Sprite(ImageManager.loadTitle1($dataSystem.title1Name)); this._backSprite2 = new Sprite(ImageManager.loadTitle2($dataSystem.title2Name)); this.addChild(this._backSprite1); this.addChild(this._backSprite2); };
Scene_Title.prototype.createBackground = function() {
this._backSprite1 = new Sprite(ImageManager.loadTitle1($dataSystem.title1Name));
this._backSprite2 = new Sprite(ImageManager.loadTitle2($dataSystem.title2Name));
this.addChild(this._backSprite1);
this.addChild(this._backSprite2);
};
这里就是我们在System里面选择的图片
$dataSystem.title1Name 背景图片名称 左一列表所选择的
$dataSystem.title2Name 前景图片名称 左二列表所选择的
然后通过ImageManager中的loadTitle1方法,传入名称去获取到图片
稍微描述一下这个ImageManager,他里面的每个loadxxxx的方法都直接对应到的是项目文件下img文件里的每个文件夹
而且他每个load方法的实现也是很容易看懂的
创建了精灵之后,还需要把这个精灵加入到我们的屏幕(Scene)中去
就像这句的写法就行了, this.addChild(this._backSprite1);
具体精灵有哪些参数和方法,大家可以去官方文档查看,这里不做介绍了
现在开始做我们的标题页,这里为想做一个背景在移动,中间再放个人物,然后人物背后一遍遍的扩散自己本身,效果如下
首先我们把背景换成 SeaofClouds 这个图片,这里不是要你直接在System里面去改,因为那样的话图片是不会动的,而我们需要一个水平移动的背景
老样子,复制源码过来改改改
var _myScene_Title_create = Scene_Title.prototype.create; Scene_Title.prototype.create = function() { _myScene_Title_create.call(this);//原本官方执行的方法不去动它的,他该怎么创建就怎么创建 //创建我们自己的背景; this.create_myTitleSprite(); };
var _myScene_Title_create = Scene_Title.prototype.create;
Scene_Title.prototype.create = function() {
_myScene_Title_create.call(this);//原本官方执行的方法不去动它的,他该怎么创建就怎么创建
//创建我们自己的背景;
this.create_myTitleSprite();
};
然后实现我们自己创建背景的方法
Scene_Title.prototype.create_myTitleSprite = function(){ this._myBackSprite = new Sprite(ImageManager.loadParallax('SeaofClouds')); this.addChild(this._myBackSprite); };
Scene_Title.prototype.create_myTitleSprite = function(){
this._myBackSprite = new Sprite(ImageManager.loadParallax('SeaofClouds'));
this.addChild(this._myBackSprite);
};
这里的效果跟官方设置背景的效果是一模一样的,如果仅是这样做的话,就等于用我们的方式再画了一个精灵贴上去而已,也就是然并卵,我们要让这个背景水平动起来
var _myScene_Title_update = Scene_Title.prototype.update; Scene_Title.prototype.update = function() { _myScene_Title_update.call(this); this._myBackSprite.x += 1 ; }
var _myScene_Title_update = Scene_Title.prototype.update;
Scene_Title.prototype.update = function() {
_myScene_Title_update.call(this);
this._myBackSprite.x += 1 ;
}
这里是让标题页的每一帧刷新的时候,让我们的背景精灵 x 坐标 +1 ,先运行看看效果吧
是不是看到问题出来了,这我们的背景精灵向左移动的同时,把他覆盖的下面的官方设置的背景元素露出来了。也许你有些编程的思路的话,你会考虑放两张图片上去,两张图片水平放置,一张图片移动的时候另一张也跟着移动出来吧啦吧啦吧啦吧啦...... 太麻烦了,rpgmaker提供了另一种精灵对象就能轻松完成这个任务,就是平铺精灵(TilingSprite)。我们先把创建的普通精灵改成平铺精灵
Scene_Title.prototype.create_myTitleSprite = function(){ //this._myBackSprite = new Sprite(ImageManager.loadParallax('SeaofClouds'));//普通精灵 this._myBackSprite = new TilingSprite(ImageManager.loadParallax('SeaofClouds'));//平铺精灵 //平铺精灵需要设置他默认的位置,否则是看不到的 //通过平铺精灵的move函数设置他的位置 //参数1 TilingSprite(平铺精灵) 的 X 坐标 //参数2 TilingSprite(平铺精灵) 的 Y 坐标 //参数3 TilingSprite(平铺精灵) 的宽度 //参数4 TilingSprite(平铺精灵) 的高度 //这里的Graphics的width和height是游戏窗口显示的宽度和高度,我们这样设置就会让这个平铺精灵全部占满屏幕 this._myBackSprite.move(0,0,Graphics.width,Graphics.height); //将我们的精灵添加到标题页 this.addChild(this._myBackSprite); };
Scene_Title.prototype.create_myTitleSprite = function(){
//this._myBackSprite = new Sprite(ImageManager.loadParallax('SeaofClouds'));//普通精灵
this._myBackSprite = new TilingSprite(ImageManager.loadParallax('SeaofClouds'));//平铺精灵
//平铺精灵需要设置他默认的位置,否则是看不到的
//通过平铺精灵的move函数设置他的位置
//参数1 TilingSprite(平铺精灵) 的 X 坐标
//参数2 TilingSprite(平铺精灵) 的 Y 坐标
//参数3 TilingSprite(平铺精灵) 的宽度
//参数4 TilingSprite(平铺精灵) 的高度
//这里的Graphics的width和height是游戏窗口显示的宽度和高度,我们这样设置就会让这个平铺精灵全部占满屏幕
this._myBackSprite.move(0,0,Graphics.width,Graphics.height);
//将我们的精灵添加到标题页
this.addChild(this._myBackSprite);
};
接下来让他动起来,但是平铺精灵跟普通精灵不同,要让他水平动的话,是要改变它的origin.x(而非普通精灵的 x) ,所以继续修改我们的update方法
var _myScene_Title_update = Scene_Title.prototype.update; Scene_Title.prototype.update = function() { _myScene_Title_update.call(this); //this._myBackSprite.x += 1 ; this._myBackSprite.origin.x += 1 ; }
var _myScene_Title_update = Scene_Title.prototype.update;
Scene_Title.prototype.update = function() {
_myScene_Title_update.call(this);
//this._myBackSprite.x += 1 ;
this._myBackSprite.origin.x += 1 ;
}
如此,就能看到效果,背景平铺的动起来了,滚动的快慢与我们设置每一帧执行update移动的大小有关
比如你这样设置 this._myBackSprite.origin.x += 100 ;
这样屏幕动得飞快(当然你还可以更快 -- ),这里希望大家把脑洞打开,知道超级机器人大战吧?里面的必杀场景是不是特流弊的场景飞快滚动?是的,我们如果去写个插件,当使用某个必杀的时候,这样把战斗背景一弄,就能做出流弊的必杀场景了。
继续来完成这次的目标,放个人物立绘上去,我这里选择的是dlc Cover Art Characters 里面的Package2_3这个人物,把他放在了我们项目文件的picture文件里。同样,我们在创建我们标题页的方法里面新增一个普通精灵放上去。
Scene_Title.prototype.create_myTitleSprite = function(){ //this._myBackSprite = new Sprite(ImageManager.loadParallax('SeaofClouds'));//普通精灵 this._myBackSprite = new TilingSprite(ImageManager.loadParallax('SeaofClouds'));//平铺精灵 //平铺精灵需要设置他默认的位置,否则是看不到的 //通过平铺精灵的move函数设置他的位置 //参数1 TilingSprite(平铺精灵) 的 X 坐标 //参数2 TilingSprite(平铺精灵) 的 Y 坐标 //参数3 TilingSprite(平铺精灵) 的宽度 //参数4 TilingSprite(平铺精灵) 的高度 //这里的Graphics的width和height是游戏窗口显示的宽度和高度,我们这样设置就会让这个平铺精灵全部占满屏幕 this._myBackSprite.move(0,0,Graphics.width,Graphics.height); this._myForeSprite = new Sprite(ImageManager.loadPicture('Package2_3'));//因为这里我仅是放一个人物立绘上去,所以就使用平铺精灵就好了 //设置人物立绘的位置 this._myForeSprite.anchor.x = 0.5; //设置立绘精灵的横向锚点,初始值是0,最大值为1,从左到右,最左是0,最右是1,这里设置的0.5就表示正中间 this._myForeSprite.anchor.y = 1; //设置立绘精灵的纵向锚点,初始值是0,最大值为1,从上到下,最上是0,最下是1,这里设置的1就表示最底部 this._myForeSprite.x = Graphics.width / 2; //设置立绘精灵的水平坐标为整个屏幕宽度的一半,与我们之前设置的横向锚点配合,立绘精灵就会在屏幕的水平正中间 this._myForeSprite.y = Graphics.height; //设置立绘精灵的纵向坐标为整个屏幕的高度,与我们之前设置的纵向锚点配合,立绘精灵的最底部就会跟屏幕的最底部重合 //将我们的精灵添加到标题页 this.addChild(this._myBackSprite); this.addChild(this._myForeSprite); };
Scene_Title.prototype.create_myTitleSprite = function(){
//this._myBackSprite = new Sprite(ImageManager.loadParallax('SeaofClouds'));//普通精灵
this._myBackSprite = new TilingSprite(ImageManager.loadParallax('SeaofClouds'));//平铺精灵
//平铺精灵需要设置他默认的位置,否则是看不到的
//通过平铺精灵的move函数设置他的位置
//参数1 TilingSprite(平铺精灵) 的 X 坐标
//参数2 TilingSprite(平铺精灵) 的 Y 坐标
//参数3 TilingSprite(平铺精灵) 的宽度
//参数4 TilingSprite(平铺精灵) 的高度
//这里的Graphics的width和height是游戏窗口显示的宽度和高度,我们这样设置就会让这个平铺精灵全部占满屏幕
this._myBackSprite.move(0,0,Graphics.width,Graphics.height);
this._myForeSprite = new Sprite(ImageManager.loadPicture('Package2_3'));//因为这里我仅是放一个人物立绘上去,所以就使用平铺精灵就好了
//设置人物立绘的位置
this._myForeSprite.anchor.x = 0.5; //设置立绘精灵的横向锚点,初始值是0,最大值为1,从左到右,最左是0,最右是1,这里设置的0.5就表示正中间
this._myForeSprite.anchor.y = 1; //设置立绘精灵的纵向锚点,初始值是0,最大值为1,从上到下,最上是0,最下是1,这里设置的1就表示最底部
this._myForeSprite.x = Graphics.width / 2; //设置立绘精灵的水平坐标为整个屏幕宽度的一半,与我们之前设置的横向锚点配合,立绘精灵就会在屏幕的水平正中间
this._myForeSprite.y = Graphics.height; //设置立绘精灵的纵向坐标为整个屏幕的高度,与我们之前设置的纵向锚点配合,立绘精灵的最底部就会跟屏幕的最底部重合
//将我们的精灵添加到标题页
this.addChild(this._myBackSprite);
this.addChild(this._myForeSprite);
};
这样背景屏幕水平滚动的时候,中间还会有一个人物立绘在屏幕正中间,并且底部与屏幕底部贴合。
接下来做个看上去奇怪的效果,让人物立绘背后有个一模一样的人物扩散开来,一直循环,同样继续修改create_myTitleSprite方法
Scene_Title.prototype.create_myTitleSprite = function(){ //this._myBackSprite = new Sprite(ImageManager.loadParallax('SeaofClouds'));//普通精灵 this._myBackSprite = new TilingSprite(ImageManager.loadParallax('SeaofClouds'));//平铺精灵 //平铺精灵需要设置他默认的位置,否则是看不到的 //通过平铺精灵的move函数设置他的位置 //参数1 TilingSprite(平铺精灵) 的 X 坐标 //参数2 TilingSprite(平铺精灵) 的 Y 坐标 //参数3 TilingSprite(平铺精灵) 的宽度 //参数4 TilingSprite(平铺精灵) 的高度 //这里的Graphics的width和height是游戏窗口显示的宽度和高度,我们这样设置就会让这个平铺精灵全部占满屏幕 this._myBackSprite.move(0,0,Graphics.width,Graphics.height); this._myForeSprite = new Sprite(ImageManager.loadPicture('Package2_3'));//因为这里我仅是放一个人物立绘上去,所以就使用平铺精灵就好了 //设置人物立绘 this._myForeSprite.anchor.x = 0.5; //设置立绘精灵的横向锚点,初始值是0,最大值为1,从左到右,最左是0,最右是1,这里设置的0.5就表示正中间 this._myForeSprite.anchor.y = 1; //设置立绘精灵的纵向锚点,初始值是0,最大值为1,从上到下,最上是0,最下是1,这里设置的1就表示最底部 this._myForeSprite.x = Graphics.width / 2; //设置立绘精灵的水平坐标为整个屏幕宽度的一半,与我们之前设置的横向锚点配合,立绘精灵就会在屏幕的水平正中间 this._myForeSprite.y = Graphics.height; //设置立绘精灵的纵向坐标为整个屏幕的高度,与我们之前设置的纵向锚点配合,立绘精灵的最底部就会跟屏幕的最底部重合 this._myForeSprite2 = new Sprite(ImageManager.loadPicture('Package2_3'));//背后闪现的幻影 //设置人物立绘的幻影,与人物立绘相同 this._myForeSprite2.anchor.x = 0.5; this._myForeSprite2.anchor.y = 1; this._myForeSprite2.x = Graphics.width / 2; this._myForeSprite2.y = Graphics.height; //将我们的精灵添加到标题页 this.addChild(this._myBackSprite); this.addChild(this._myForeSprite2); //这里添加的时候,我们首先是添加的幻影的那个精灵,再添加的立绘的精灵,因为我想达到的效果是在人物立绘的背后出现幻影,如果先添加立绘精灵的话,这个幻影就会在立绘精灵的前面闪动,这里各位可以试着调换一下顺序就明白了 this.addChild(this._myForeSprite); };
Scene_Title.prototype.create_myTitleSprite = function(){
//this._myBackSprite = new Sprite(ImageManager.loadParallax('SeaofClouds'));//普通精灵
this._myBackSprite = new TilingSprite(ImageManager.loadParallax('SeaofClouds'));//平铺精灵
//平铺精灵需要设置他默认的位置,否则是看不到的
//通过平铺精灵的move函数设置他的位置
//参数1 TilingSprite(平铺精灵) 的 X 坐标
//参数2 TilingSprite(平铺精灵) 的 Y 坐标
//参数3 TilingSprite(平铺精灵) 的宽度
//参数4 TilingSprite(平铺精灵) 的高度
//这里的Graphics的width和height是游戏窗口显示的宽度和高度,我们这样设置就会让这个平铺精灵全部占满屏幕
this._myBackSprite.move(0,0,Graphics.width,Graphics.height);
this._myForeSprite = new Sprite(ImageManager.loadPicture('Package2_3'));//因为这里我仅是放一个人物立绘上去,所以就使用平铺精灵就好了
//设置人物立绘
this._myForeSprite.anchor.x = 0.5; //设置立绘精灵的横向锚点,初始值是0,最大值为1,从左到右,最左是0,最右是1,这里设置的0.5就表示正中间
this._myForeSprite.anchor.y = 1; //设置立绘精灵的纵向锚点,初始值是0,最大值为1,从上到下,最上是0,最下是1,这里设置的1就表示最底部
this._myForeSprite.x = Graphics.width / 2; //设置立绘精灵的水平坐标为整个屏幕宽度的一半,与我们之前设置的横向锚点配合,立绘精灵就会在屏幕的水平正中间
this._myForeSprite.y = Graphics.height; //设置立绘精灵的纵向坐标为整个屏幕的高度,与我们之前设置的纵向锚点配合,立绘精灵的最底部就会跟屏幕的最底部重合
this._myForeSprite2 = new Sprite(ImageManager.loadPicture('Package2_3'));//背后闪现的幻影
//设置人物立绘的幻影,与人物立绘相同
this._myForeSprite2.anchor.x = 0.5;
this._myForeSprite2.anchor.y = 1;
this._myForeSprite2.x = Graphics.width / 2;
this._myForeSprite2.y = Graphics.height;
//将我们的精灵添加到标题页
this.addChild(this._myBackSprite);
this.addChild(this._myForeSprite2);
//这里添加的时候,我们首先是添加的幻影的那个精灵,再添加的立绘的精灵,因为我想达到的效果是在人物立绘的背后出现幻影,如果先添加立绘精灵的话,这个幻影就会在立绘精灵的前面闪动,这里各位可以试着调换一下顺序就明白了
this.addChild(this._myForeSprite);
};
到此,实际的效果只是立绘精灵和幻影精灵重叠了而已,没有任何动作,我们修改update方法来让幻影精灵动起来,实现思路是,我让幻影精灵的透明度(Opacity)慢慢的减弱,并且让幻影精灵的缩放(Scale)慢慢的变大,就能表现出一种向外拓展的效果了,同时幻影精灵完全变成透明的时候,我们要重置他的缩放(Scale)和透明度(Opacity)。
var _myScene_Title_update = Scene_Title.prototype.update; Scene_Title.prototype.update = function() { _myScene_Title_update.call(this); //this._myBackSprite.x += 1 ; this._myBackSprite.origin.x += 1 ; //幻想精灵透明度(Opacity)完全透明的时候,重置他的缩放和透明度 if(this._myForeSprite2.opacity <= 0){ this._myForeSprite2.opacity = 255; this._myForeSprite2.scale.x = 1; this_myForeSprite2.scale.y = 1 ; } //幻想精灵并没有完全透明的时候,我们让他的透明度一直减小,同时通过改变他的缩放来看上去一种扩散的感觉 else{ this._myForeSprite2.opacity -= 3 ; this._myForeSprite2scale.x += 0.003; this._myForeSprite2.scale.y += 0.003; }
var _myScene_Title_update = Scene_Title.prototype.update;
Scene_Title.prototype.update = function() {
_myScene_Title_update.call(this);
//this._myBackSprite.x += 1 ;
this._myBackSprite.origin.x += 1 ;
//幻想精灵透明度(Opacity)完全透明的时候,重置他的缩放和透明度
if(this._myForeSprite2.opacity <= 0){
this._myForeSprite2.opacity = 255;
this._myForeSprite2.scale.x = 1;
this_myForeSprite2.scale.y = 1 ;
}
//幻想精灵并没有完全透明的时候,我们让他的透明度一直减小,同时通过改变他的缩放来看上去一种扩散的感觉
else{
this._myForeSprite2.opacity -= 3 ;
this._myForeSprite2scale.x += 0.003;
this._myForeSprite2.scale.y += 0.003;
}
最后把插件加入到游戏里面去
到此,我们这次的目的就能完成了,最后的效果就是这样(脑补一下,动起来的喔)
只要大家脑洞大开,这样继续拓展,我觉得做些啥流弊效果都没问题的吧 |