赞 | 65 |
VIP | 231 |
好人卡 | 2 |
积分 | 19 |
经验 | 35171 |
最后登录 | 2024-9-15 |
在线时间 | 1554 小时 |
Lv3.寻梦者
- 梦石
- 0
- 星屑
- 1912
- 在线时间
- 1554 小时
- 注册时间
- 2013-4-13
- 帖子
- 917
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 沉滞的剑 于 2019-8-20 22:32 编辑
希望论坛能支持直接写Markdown啊
==============================
在Window_Selectable之后,
RM还再次拓展了Window_Command类, 引入了Command的概念
将item封装成名称, 对应handler, 可用状态等属性的新对象
下面我们将按照惯例通过各个生命周期来了解它的原理
- Window_Command.prototype.initialize = function (x, y) {
- this.clearCommandList();
- this.makeCommandList();
- var width = this.windowWidth();
- var height = this.windowHeight();
- Window_Selectable.prototype.initialize.call(this, x, y, width, height);
- this.refresh();
- this.select(0);
- this.activate();
- };
复制代码
Window_Command具有_list属性
代表其维护的Command列表
- Window_Command.prototype.clearCommandList = function () {
- this._list = [];
- };
- Window_Command.prototype.makeCommandList = function () {
- };
- Window_Command.prototype.addCommand = function (name, symbol, enabled, ext) {
- if (enabled === undefined) {
- enabled = true;
- }
- if (ext === undefined) {
- ext = null;
- }
- this._list.push({ name: name, symbol: symbol, enabled: enabled, ext: ext });
- };
复制代码
基础的对command列表的各种操作
makeCommandList是个虚函数, 需要各个子类对其进行实现
在addCommand里可以看出来Command总共有4个属性
name, symbol, enabled 和 ext
name对应的是绘制名
symbol对应的是选择后对应的handler
enabled控制是否可选
ext应该是携带的 拓展信息
对于单个command, 也有相应的获取其属性的方法
- Window_Command.prototype.commandName = function (index) {
- return this._list[index].name;
- };
- Window_Command.prototype.commandSymbol = function (index) {
- return this._list[index].symbol;
- };
- Window_Command.prototype.isCommandEnabled = function (index) {
- return this._list[index].enabled;
- };
复制代码
对于当前Command获取属性的方法
- Window_Command.prototype.currentData = function () {
- return this.index() >= 0 ? this._list[this.index()] : null;
- };
- Window_Command.prototype.isCurrentItemEnabled = function () {
- return this.currentData() ? this.currentData().enabled : false;
- };
- Window_Command.prototype.currentSymbol = function () {
- return this.currentData() ? this.currentData().symbol : null;
- };
- Window_Command.prototype.currentExt = function () {
- return this.currentData() ? this.currentData().ext : null;
- };
复制代码 还有一些检索特定属性, 找到command的方法
- Window_Command.prototype.findSymbol = function (symbol) {
- for (var i = 0; i < this._list.length; i++) {
- if (this._list[i].symbol === symbol) {
- return i;
- }
- }
- return -1;
- };
- Window_Command.prototype.selectSymbol = function (symbol) {
- var index = this.findSymbol(symbol);
- if (index >= 0) {
- this.select(index);
- } else {
- this.select(0);
- }
- };
- Window_Command.prototype.findExt = function (ext) {
- for (var i = 0; i < this._list.length; i++) {
- if (this._list[i].ext === ext) {
- return i;
- }
- }
- return -1;
- };
复制代码
讲讲绘制, 首先在Window_Selectable里有item的矩形区域的定义
- Window_Selectable.prototype.itemRect = function (index) {
- var rect = new Rectangle();
- var maxCols = this.maxCols();
- rect.width = this.itemWidth();
- rect.height = this.itemHeight();
- rect.x = index % maxCols * (rect.width + this.spacing()) - this._scrollX;
- rect.y = Math.floor(index / maxCols) * rect.height - this._scrollY;
- return rect;
- };
复制代码
每个item按照横向铺满换行的方式排列
对于每一个itemRect, 还有一个由textPadding控制的textRect
- Window_Selectable.prototype.itemRectForText = function (index) {
- var rect = this.itemRect(index);
- rect.x += this.textPadding();
- rect.width -= this.textPadding() * 2;
- return rect;
- };
复制代码
在Window_Command中, 我们就是在这个textRect中绘制name
- Window_Command.prototype.drawItem = function (index) {
- var rect = this.itemRectForText(index);
- var align = this.itemTextAlign();
- this.resetTextColor();
- this.changePaintOpacity(this.isCommandEnabled(index));
- this.drawText(this.commandName(index), rect.x, rect.y, rect.width, align);
- };
复制代码
其中resetTextColor:
- Window_Base.prototype.resetTextColor = function () {
- this.changeTextColor(this.normalColor());
- };
- Window_Base.prototype.changeTextColor = function (color) {
- this.contents.textColor = color;
- };
- Window_Base.prototype.normalColor = function () {
- return this.textColor(0);
- };
复制代码
嗯, 还记得Window_Base里讲的那个复古的取色写法么...
- Window_Base.prototype.changePaintOpacity = function (enabled) {
- this.contents.paintOpacity = enabled ? 255 : this.translucentOpacity();
- };
- Window_Base.prototype.translucentOpacity = function () {
- return 160;
- };
复制代码
这个就是根据当前command是否是enabled来确定字体的透明度了
update其实没有多少变化不过Window_Command覆写了callOkHandler
先来看一下这个方法在Window_Selectable中的调用栈
- Window_Selectable.prototype.update = function () {
- // ...略
- this.processHandling();
- // ...略
- };
- Window_Selectable.prototype.processHandling = function () {
- // 略....
- if (this.isOkEnabled() && this.isOkTriggered()) {
- this.processOk();
- }
- // 略....
- };
- Window_Selectable.prototype.processOk = function () {
- if (this.isCurrentItemEnabled()) {
- // ... 略
- this.callOkHandler();
- // ... 略
- }
- };
复制代码
Window_Command修改了callOkHandler的方法:
- Window_Command.prototype.callOkHandler = function () {
- var symbol = this.currentSymbol(); // 获取当前command的symbol
- if (this.isHandled(symbol)) { // 如果存在该symbol的handler
- this.callHandler(symbol); // 则呼叫这个handler
- } else if (this.isHandled('ok')) { // 否则判断是否有ok
- Window_Selectable.prototype.callOkHandler.call(this); // 呼叫ok
- } else {
- this.activate(); // 否则就重新选择一下
- }
- };
复制代码
这里贴个activate供大家参考一下
- Window_Selectable.prototype.activate = function () {
- Window_Base.prototype.activate.call(this);
- this.reselect();
- };
- Window_Selectable.prototype.reselect = function () {
- this.select(this._index);
- };
复制代码 最后一个refresh重绘也没有太多内容
- Window_Command.prototype.refresh = function () {
- this.clearCommandList();
- this.makeCommandList();
- this.createContents();
- Window_Selectable.prototype.refresh.call(this);
- };
复制代码
需要注意的是每次重绘Command list都会被清空重新添加
内容也要重绘, 绘制部分参见上面的drawItem
这里把相关的父类函数贴一下
- Window_Selectable.prototype.refresh = function () {
- if (this.contents) {
- this.contents.clear();
- this.drawAllItems();
- }
- };
- Window_Selectable.prototype.drawAllItems = function () {
- var topIndex = this.topIndex();
- for (var i = 0; i < this.maxPageItems(); i++) {
- var index = topIndex + i;
- if (index < this.maxItems()) {
- this.drawItem(index);
- }
- }
- };
复制代码
收工~收工~
下次应该有新的练手内容
明天见...大概吧
|
评分
-
查看全部评分
|