目录
1.继承Window_Base 创建一个窗口显示物品数据信息
3. Window_ItemList.prototype.initialize 初始化变量数据
4. Window_ItemList.prototype.update 刷新窗口内容
5. Window_ItemList.prototype.processCancel 返回上一级关闭窗口
本文知识点如下
1. 窗口的创建
2. 获取物品的真实显示坐标 而不是虚拟坐标
3. Window_ItemList.prototype.initialize 初始化变量数据
4. Window_ItemList.prototype.update 刷新窗口内容
5. Window_ItemList.prototype.processCancel 返回上一级关闭窗口
6. 为什么要将核心代码 而不是直接给插件
正文
1.继承Window_Base 创建一个窗口显示物品数据信息
// 自定义窗口
function Window_Item_Help() {
this.initialize(...arguments);
};
Window_Item_Help.prototype = Object.create(Window_Base.prototype);
Window_Item_Help.prototype.constructor = Window_Item_Help;
// 初始化窗口
Window_Item_Help.prototype.initialize = function(x, y, width, height) {
Window_Base.prototype.initialize.call(this, x, y, width, height);
this.contents.fontSize = 20;
this.frameVisible = false;
};
//画出内容
Window_Item_Help.prototype.refresh = function(item_data){
this.contents.clear();
let _data_zero = item_data.name+":";
let _data_one = item_data.note.split("\n");
this.drawText(_data_zero, 5, 0, this.contents.measureTextWidth(_data_zero));
for(let i=0;i<_data_one.length;i++){
this.drawText(_data_one[i], 5, 30 * i + 30, this.contents.measureTextWidth(_data_one[i]));
}
};
很简单 照着抄就行 基础知识 类的创建
2.获取物品的真实显示坐标 而不是虚拟坐标
RPGMZ 滚动坐标有两套 一个是虚拟坐标 也就是看不见的画布坐标
一个是显示坐标 也就是 滚动动画结束以后 真实显示的坐标
这是两套不同的坐标
那么在RPGMZ中没有直接的获取到显示坐标的方法 所以判断两个坐标是否相等
如果坐标不相等 说明动画还没有结束 坐标相对 说明系统动画功能 滚动功能结束
那么就可以得到真实显示坐标
3. Window_ItemList.prototype.initialize 初始化变量数据
//初始化
const _Window_ItemList_prototype_initialize = Window_ItemList.prototype.initialize;
Window_ItemList.prototype.initialize = function(rect) {
_Window_ItemList_prototype_initialize.call(this, rect);
this._Item_backup_y = -1100;
this._Item_backup_x = -1100;
};
在这里游戏初始化时 把备份变量 进行 -1100 用于和当前物品坐标区分
4. Window_ItemList.prototype.update 刷新窗口内容
const _Window_ItemList_prototype_update = Window_ItemList.prototype.update;
Window_ItemList.prototype.update = function() {
_Window_ItemList_prototype_update.call(this);
// 在 update 方法中获取坐标信息
const rect = this.itemRect(this.index());
if(!this.item()){
for(let child of this.children){
if (child instanceof Window_Item_Help) {
this.removeChild(child);
}
}
this._Item_backup_y=-1100;
this._Item_backup_x=-1100;
return;
}
for(let child of this.children){
if (child instanceof Window_Item_Help) {
child.refresh(this.item());
}
}
if(this._Item_backup_y == rect.y && this._Item_backup_x == rect.x){
return;
}
for(let child of this.children){
if (child instanceof Window_Item_Help) {
this.removeChild(child);
}
}
let _Window_Y = rect.y + this.itemHeight() + this.itemPadding();
let _data_one = this.item().note.split("\n");
console.log(_data_one.length);
let _Window_Height = (_data_one.length)*30+30;
if(this.height - rect.y < _Window_Height+this.itemHeight()){
_Window_Y = rect.y-_Window_Height - this.itemPadding();
}
this.addChild(new Window_Item_Help(new Rectangle(rect.x + this.itemPadding(), _Window_Y, rect.width + this.itemPadding(), _Window_Height)));
console.log("rect.y", rect.y);
console.log("Item_backup_y", this._Item_backup_y);
this._Item_backup_y = rect.y;
this._Item_backup_x = rect.x;
};
const rect = this.itemRect(this.index()); //得到当前光标选中的物品rect坐标
参数为 rect.x rect.y rect.width rect.height 获取到的是虚拟坐标
用这个坐标是没办法定义窗口位置的
if(!this.item()){
for(let child of this.children){
if (child instanceof Window_Item_Help) {
this.removeChild(child);
}
}
this._Item_backup_y=-1100;
this._Item_backup_x=-1100;
return;
}
判断当前物品是否为null 如果为null return; 直接跳过后续代码不执行 并且删除当前显示的窗口
并且初始化坐标备份变量 以保证 后续判断坐标是否相等
for(let child of this.children){
if (child instanceof Window_Item_Help) {
child.refresh(this.item());
}
}
只要有窗口内容 就会传入数据进行实时刷新
保证何时数据都是最新的
if(this._Item_backup_y == rect.y && this._Item_backup_x == rect.x){
return;
}
判断 备份的x坐标与物品x坐标是否相等
判断备份的y坐标与物品y坐标是否相等
完全相等 说明移动结束 return;跳过后续代码执行
for(let child of this.children){
if (child instanceof Window_Item_Help) {
this.removeChild(child);
}
}
在上面备份坐标和真实物品坐标 不相等的情况下 说明 游戏物品光标移动了
那么 开始清除掉旧的窗口 准备添加新的窗口
let _Window_Y = rect.y + this.itemHeight() + this.itemPadding();
let _data_one = this.item().note.split("\n");
let _Window_Height = (_data_one.length+1)*30;
定义窗口的Y坐标 当前的物品Y坐标是移动动画结束以后真实显示的Y坐标
分割要显示的文本内容 以\n换行进行分割
定义窗口高度 由于要添加物品名称的高度 所以+1 * 物品间距 30
if(this.height - rect.y < _Window_Height+this.itemHeight()){
_Window_Y = rect.y-_Window_Height - this.itemPadding();
}
判断物品窗口下方是否有足够的空间显示窗口 如果空间不足 移到物品的上方显示
this.addChild(new Window_Item_Help(new Rectangle(rect.x + this.itemPadding(), _Window_Y, rect.width + this.itemPadding(), _Window_Height)));
添加窗口到游戏内
this._Item_backup_y = rect.y;
this._Item_backup_x = rect.x;
这一段是核心代码 把当前物品坐标备份起来
上面代码 就可以判断 备份的坐标和新的坐标是否相同
备份的坐标是上一步的真实坐标 上面新的坐标 是移动以后的真实坐标
不相同说明 光标游戏进行的移动 以新数据为标准 创建窗口
总而言之 当物品坐标有变化之时 始终移除旧窗口添加新窗口 始终保持窗口与物品的坐标绑定
5. Window_ItemList.prototype.processCancel 返回上一级关闭窗口
const _Window_ItemList_prototype_processCancel = Window_ItemList.prototype.processCancel;
Window_ItemList.prototype.processCancel = function() {
for(let child of this.children){
if (child instanceof Window_Item_Help) {
this.removeChild(child);
}
}
this._Item_backup_y=-1100;
this._Item_backup_x=-1100;
_Window_ItemList_prototype_processCancel.call(this);
};
重写功能 当返回到上级菜单时 for循环删除 添加的所有窗口
备份坐标再次变为-1100 用于下次进入 判断新旧坐标是否相等
6. 为什么要将核心代码 而不是直接给插件
project1 论坛充斥着 毫无意义的免费插件 这是不利于新手学习的
很多人看到以后都觉得是天书 所以 要准备核心代码的教学
至于如何美化 显示哪些数据 交给开发者自行完成即可
这是我与project1论坛 某些大佬的不同之处
作为技术人员 不应该写天书 而要以 通俗易懂的方式进行教学
结尾总结
请Project1论坛的小圈子 离开