RPGMZ游戏引擎教程 菜单 物品栏 添加跟随物品移动提示窗口

目录

本文知识点如下

正文

1.继承Window_Base 创建一个窗口显示物品数据信息

2.获取物品的真实显示坐标 而不是虚拟坐标

3. Window_ItemList.prototype.initialize 初始化变量数据

4. Window_ItemList.prototype.update 刷新窗口内容

5. Window_ItemList.prototype.processCancel 返回上一级关闭窗口

6. 为什么要将核心代码 而不是直接给插件

结尾总结


本文知识点如下

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论坛的小圈子 离开

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值