查看: 3098|回复: 28

[交流讨论] 脚本实现【图片移动】的简单探索

[复制链接]
梦石
0
星屑
2419
在线时间
411 小时
注册时间
2021-11-7
回帖
171
发表于 2021-12-10 10:54:34 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 夏虫沉默 于 2021-12-22 21:40 编辑

在用纯脚本模拟重装机兵.金属探测仪的效果时,发现了几个问题:
[pre lang="javascript" line="1"]
        let x=$gamePlayer.screenX(), y=$gamePlayer.screenY();//获取玩家的画面xy位置
        let xTemp=x-24,yTemp=y-48;//设置绘制图案起点是玩家所在方格左上角
        $gameScreen.showPicture("1","$探测图2",0,xTemp,yTemp,100,100,255,0);
        var picture = $gameScreen.picture(1);//获取图片id为1的对象
        picture.move(0,xTemp,yTemp+48,100,100,255,0,30);//向下移动48pix距离
        this.wait(30);//等待0.5秒
        picture.move(0,xTemp+48,yTemp+48,100,100,255,0,30);//向右移动48pix距离[/pre]上述代码的this.wait()方法可以用在事件插入的脚本里,但是封装成方法后,此时this.wait()就提示找不到wait方法的异常。
通过百度后,我找到一个解决办法,JS的一个setTimeout方法(延时执行函数),那么理论上只要在规定的时间之后运行图片移动的方法也可以实现效果了,然后就可以写出类似下面的代码。[pre lang="javascript"]function detectorTest(){
        let x=$gamePlayer.screenX(), y=$gamePlayer.screenY();//获取玩家的画面xy位置
        let xTemp=x-24,yTemp=y-48;//设置绘制图案起点是玩家所在方格左上角
        $gameScreen.showPicture("1","$探测图2",0,xTemp,yTemp,100,100,255,0);
        var picture = $gameScreen.picture(1);
        picture.move(0,xTemp,yTemp+48,100,100,255,0,30);//图片向下移动一个单位长度
        setTimeout(picture.move(0,xTemp+48,yTemp+48,100,100,255,0,30),500);//0.5秒后图片向右移动一个单位长度,参数500也就是0.5秒
}[/pre]然后测试一下,你就会发现图像是直接向右下方移动48√ ̄2的距离,而且图片的移动并没有等待0.5秒,如图1;

图1

图1

通过进一步的学习,https://www.w3school.com.cn/js/js_asynchronous.asp,原来setTimeOut方法的第一个参数是不能加括号()的,那么一个有需要参数的方法要怎么作为参数代入给延时执行函数setTimeout呢?
结合回调函数的特性https://www.cnblogs.com/minshia/p/5935951.html
js代码会至上而下一条线执行下去,但是有时候我们需要等到一个操作结束之后再进行下一个操作,这时候就需要用到回调函数。
可以把上一段代码的第7行修改为[pre lang="javascript" line="7"]setTimeout(()=>{picture.move(0,xTemp+48,yTemp+48,100,100,255,0,30);},500)[/pre]
也可以这样写[pre lang="javascript" line="7"]setTimeout(picture.move.bind(picture,0,xTemp+48,yTemp+48,100,100,255,0,30),500);[/pre]两种写法运行的效果是一样的,我们可以看到图像是分步移动,先往下走,再往右走,如图2;

图2

图2
欲速春风山劝阻,不得恰恰不得呼。
梦石
0
星屑
2866
在线时间
446 小时
注册时间
2016-9-26
回帖
1175
发表于 2021-12-10 11:43:25 | 显示全部楼层
大佬大佬,为什么写插件时,thiswait有时用不了,还有音乐怎么才能一首一首轮着播放

点评

可能涉及到文件的读取,大概就是要先获取歌曲的时长,时长到了就播放下一首吧  发表于 2021-12-10 15:48
这个是因为this是指代当前对象,有时对象不存在,或者对象没有这个方法,都不能调用wait方法  发表于 2021-12-10 15:42
回复

使用道具 举报

梦石
0
星屑
2866
在线时间
446 小时
注册时间
2016-9-26
回帖
1175
发表于 2021-12-10 15:20:14 | 显示全部楼层
大佬试过封装后连续多次等待和执行某些操作是否可行吗?

然后,关于this,我找到了一些资料,但我只能给大佬研究
,因为我暂时理解不了

https://blog.csdn.net/Lixam/article/details/12493245

点评

what' up.我觉得应该浅尝辄止,不知其所以然也  发表于 2021-12-11 15:10
回复

使用道具 举报

梦石
0
星屑
2866
在线时间
446 小时
注册时间
2016-9-26
回帖
1175
发表于 2021-12-11 14:23:15 | 显示全部楼层
自问自答的我又来了,写插件用的等待可能用的是以下格式来实现等待
this._waitCount = 500;
五百可能就是五百帧,我没完全实测,正在实验

点评

我暂时是用来实现纯脚本的普通传送而已,不行也没啥吧,嗯  发表于 2021-12-11 16:18
不过,太复杂的话就算了  发表于 2021-12-11 16:14
this._waitCount-- 这样?,还是。。。话说,能不能举个播放音乐的例子?  发表于 2021-12-11 16:14
字面上只是设置了等待的帧,并没有设置减少waitcount  发表于 2021-12-11 15:51
。。。好像还是需要回调嘛(一等待就全停止?)  发表于 2021-12-11 15:29
回复

使用道具 举报

梦石
0
星屑
2866
在线时间
446 小时
注册时间
2016-9-26
回帖
1175
发表于 2021-12-13 14:36:03 | 显示全部楼层
setTimeout好像不能在插件里用,我猜测可能是function套function再套function太多次不行的问题

点评

暂时能用一点,看来可能是我理解得不够  发表于 2021-12-22 00:16
你可以把代码的写法编辑一下  发表于 2021-12-13 15:07
回复

使用道具 举报

梦石
0
星屑
2419
在线时间
411 小时
注册时间
2021-11-7
回帖
171
 楼主| 发表于 2021-12-13 16:01:17 | 显示全部楼层
任小雪 发表于 2021-12-13 14:36
setTimeout好像不能在插件里用,我猜测可能是function套function再套function太多次不行的问题 ...

rpg_core.js文件里8124行有一个seek方法[pre lang="javascript" line="8124"]WebAudio.prototype.seek = function() {
    if (WebAudio._context) {
        var pos = (WebAudio._context.currentTime - this._startTime) * this._pitch;//pitch是音频的声调,这里可以看出声调会影响播放的速度
        if (this._loopLength > 0) {
            while (pos >= this._loopStart + this._loopLength) {
                pos -= this._loopLength;
            }
        }
        return pos;
    } else {
        return 0;
    }
};[/pre]
8051行的play方法[pre lang="javascript" line="8051"]WebAudio.prototype.play = function(loop, offset);//loop控制是否循环播放,offset控制音频从几秒开始播放[/pre]
8269行的_createEndTimer方法[pre lang="javascript" line="8269"]WebAudio.prototype._createEndTimer = function() {//这个方法涉及到setTimeout和计时器timer
    if (this._sourceNode && !this._sourceNode.loop) {
        var endTime = this._startTime + this._totalTime / this._pitch;
        var delay =  endTime - WebAudio._context.currentTime;
        this._endTimer = setTimeout(function() {
            this.stop();
        }.bind(this), delay * 1000);
    }
};

WebAudio.prototype._removeEndTimer = function() {
    if (this._endTimer) {
        clearTimeout(this._endTimer);
        this._endTimer = null;
    }
};[/pre]
这些都是WebAudio类的方法

点评

while是循环,然后,好像学习成本有点高(或许大概能看懂这些代码,但不会用),我暂时就浅尝辄止吧,唔  发表于 2021-12-13 17:14
至于例子,还需要花时间研究  发表于 2021-12-13 16:03
欲速春风山劝阻,不得恰恰不得呼。
回复

使用道具 举报

梦石
0
星屑
2866
在线时间
446 小时
注册时间
2016-9-26
回帖
1175
发表于 2021-12-22 00:14:25 | 显示全部楼层
https://www.w3school.com.cn/js/js_asynchronous.asp
有一个等待间隔的东西,不过没实操过。
然后有一个等待文件的东西,不知道是不是就是等待音乐和对话,以实现轮着播放的(我还不想研究,就分享一下而已)

点评

不过我发现BGM和BGS都是循环播放的,但是ME和SE都是只播放一遍的  发表于 2021-12-25 17:25
。。。  发表于 2021-12-22 18:09
链接的等待文件是指加载文件时,如果没有加载到则显示错误信息,否则是显示加载的信息。这个和你要的应该不是不一样  发表于 2021-12-22 16:12
如果是无参方法还好办,有参的话,就是使用回调函数了。顺便说下,setTimeOut方法的第一个参数是方法名,这个本身就是一个回调函数  发表于 2021-12-22 00:42
怪不得大家都又function一次,唔  发表于 2021-12-22 00:35
回复

使用道具 举报

梦石
0
星屑
2419
在线时间
411 小时
注册时间
2021-11-7
回帖
171
 楼主| 发表于 2021-12-22 00:47:53 | 显示全部楼层
方法和函数是同一概念,其实只用setTimeOut方法也可以实现间隔执行的效果,在一个方法里使用setTimeOut方法,参数是这个方法的名称,这种写法类型叫递归。(说得太复杂了,还是循序渐进吧,欲速不达也)
欲速春风山劝阻,不得恰恰不得呼。
回复

使用道具 举报

梦石
0
星屑
927
在线时间
152 小时
注册时间
2018-3-16
回帖
50
发表于 2022-5-17 16:04:42 | 显示全部楼层
厉害!不愧是你!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部