Java 以不同的长度延迟遍历文本
Bukkit/插口API-Java 以不同的长度延迟遍历文本,java,loops,runnable,bukkit,Java,Loops,Runnable,Bukkit,Bukkit/插口API- 好的,我正在尝试为我的服务器制作一个教程系统。我经常看到人们显示这样的文本: public void send(String...strings) { for (String string : strings) { player.sendMessage(string); } } public void send(String...strings) { for (String string : strings) {
好的,我正在尝试为我的服务器制作一个教程系统。我经常看到人们显示这样的文本:
public void send(String...strings) {
for (String string : strings) {
player.sendMessage(string);
}
}
public void send(String...strings) {
for (String string : strings) {
new BukkitRunnable() {
@Override
public void run() {
player.sendMessage(string);
}
}.runTaskLater(my_plugin_instance, (string.length()*2));
}
}
private void send(final Player player, String...messages) {
long delaySum = 0;
for (final String message : messages) {
Runnable myTask = new Runnable() {
public void run() {
player.sendMessage(message);
}
};
this.getServer().getScheduler().runTaskLater(this, myTask, delaySum);
delaySum += message.length() * 2;
}
}
。。这太可怕了。如你所知,它会垃圾邮件聊天,使其不可读。因此,我使用runnables以一定的延迟显示文本。我可以很容易地使用相同的特定延迟(即30个滴答声)创建一个runnable,但是我希望runnable能够基于字符串的长度()创建延迟 我试着这样做:
public void send(String...strings) {
for (String string : strings) {
player.sendMessage(string);
}
}
public void send(String...strings) {
for (String string : strings) {
new BukkitRunnable() {
@Override
public void run() {
player.sendMessage(string);
}
}.runTaskLater(my_plugin_instance, (string.length()*2));
}
}
private void send(final Player player, String...messages) {
long delaySum = 0;
for (final String message : messages) {
Runnable myTask = new Runnable() {
public void run() {
player.sendMessage(message);
}
};
this.getServer().getScheduler().runTaskLater(this, myTask, delaySum);
delaySum += message.length() * 2;
}
}
这样,是的,它将采用字符串的长度,但是for循环
将在runnable显示文本之前继续到下一个字符串。例如,如果我有这些句子(按照正确的顺序):
欢迎来到服务器,玩家代码>
这台服务器是关于bla、This和that的,还有更多关于that和This的内容
接受本教程?
订单将是
接受本教程?
欢迎来到服务器,玩家代码>
这台服务器是关于bla、This和that的,还有更多关于that和This的内容
嗯,没有人回答。。最后我自己解决了这个问题,但我并不以代码为荣。必须使用2个runnables。。
如果有人感兴趣,我会把代码留在这里
public void send(Player player, long delay, String basecolor, String... strings) {
List<String> str = Arrays.asList(strings);
new BukkitRunnable() {
int ind = 0;
boolean next = true;
@Override
public void run() {
String s = str.get(ind);
if (next) {
next = false;
Bukkit.getScheduler().runTaskLater(YOUR_PLUGIN_INSTANCE, new Runnable() {
@Override
public void run() {
player.sendMessage(ChatColor.translateAlternateColorCodes('&',
basecolor + s.replace("%p", player.getName()).replace("%s", server_name)));
next = true;
}
}, (ind == 0 ? 0 : (str.get(ind - 1).length())));
if (ind + 1 < str.size()) {
ind++;
} else {
cancel();
}
}
}
}.runTaskTimer(YOUR_PLUGIN_INSTANCE, delay, 10);
}
public void send(播放器、长延迟、字符串基色、字符串…字符串){
List str=Arrays.asList(字符串);
新的bukkitrunable(){
int ind=0;
布尔下一步=真;
@凌驾
公开募捐{
字符串s=str.get(ind);
如果(下一个){
下一个=假;
Bukkit.getScheduler().runtaskletter(您的插件实例,new Runnable()){
@凌驾
公开募捐{
player.sendMessage(ChatColor.translateAlternateColorCodes(“&”,
basecolor+s.replace(“%p”,player.getName()).replace(“%s”,server_name));
next=真;
}
},(ind==0?0:(str.get(ind-1.length());
如果(ind+1
例如,可以如下所示:
send(播放器,30,“&a”,“欢迎使用%s,%p!”,“输入要在此处显示的内容!”,“它们的顺序都正确!”)代码> 您可能想考虑使用一个单一对象(ie. Singleton)作为打印机来打印所有消息。这将避免创建太多线程
下面的解决方案使用BlockingQueue使打印线程等待下一条消息。当消息不在队列中时,run()方法将在不消耗大量CPU的情况下等待
解决方案有两种风格:
-如果您取消注释第一个msgQueue-您将得到sendMessage的阻塞行为;该方法将等待所有项目打印完毕。
-如果取消修复第二个msgQueue-消息将被添加到队列中,而无需等待打印
我添加了ExecutorService来管理线程,因为Oracle/Java认为这是使用ExecutorServices管理线程的一个良好实践。一旦不需要MessagePrinter,它将由“executor.shutdownNow();”发出信号,并和平结束
希望这有帮助
package stackoverflow;
import java.util.Arrays;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
class MessagePrinter implements Runnable {
private static MessagePrinter instance;
private MessagePrinter() {};
// Uncomment the one below to make sendText wait until methods until all items are printed:
// BlockingQueue<String> msgQueue = new LinkedBlockingQueue<>(1);
// Uncomment the one below to make sendText not wait until messages are printed:
BlockingQueue<String> msgQueue = new LinkedBlockingQueue<>(1);
public void run() {
try {
while (true) {
String str = msgQueue.take();
Thread.sleep( str.length() );
TimeUnit.MILLISECONDS.sleep( str.length() * 10 );
System.out.println(str);
}
} catch (InterruptedException e) {
System.out.println("Quitting...");
return;
}
}
public void sendText(String... txt) {
Arrays.asList(txt).stream().forEach(t -> {
try {
msgQueue.put(t);
} catch (InterruptedException e) {
// Received request to terminate.
return;
}
});
}
synchronized public static MessagePrinter getInstance() {
if (instance == null)
instance = new MessagePrinter();
return instance;
}
}
public class VarDelay {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
MessagePrinter msp = MessagePrinter.getInstance();
executor.submit(msp);
msp.sendText(new String[] {"Welcome to the server, player!",
"This server is about blablabla, this and that and a bit more of that and this",
"Accept the tutorial?" });
msp.sendText("More text to follow");
// Shutdown:
executor.shutdown();
if (!executor.awaitTermination(2, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
}
}
包堆栈溢出;
导入java.util.array;
导入java.util.concurrent.BlockingQueue;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.LinkedBlockingQueue;
导入java.util.concurrent.TimeUnit;
类MessagePrinter实现可运行{
私有静态消息打印机实例;
私有MessagePrinter(){};
//取消对以下方法的注释,使sendText在打印所有项目之前等待方法:
//BlockingQueue msgQueue=新的LinkedBlockingQueue(1);
//取消对以下内容的注释,使sendText不会等待消息打印完成:
BlockingQueue msgQueue=新的LinkedBlockingQueue(1);
公开募捐{
试一试{
虽然(正确){
String str=msgQueue.take();
睡眠(str.length());
时间单位毫秒睡眠(str.length()*10);
系统输出打印项次(str);
}
}捕捉(中断异常e){
System.out.println(“退出…”);
返回;
}
}
公共void sendText(字符串…txt){
Arrays.asList(txt.stream().forEach(t->{
试一试{
msgQueue.put(t);
}捕捉(中断异常e){
//收到终止请求。
返回;
}
});
}
同步的公共静态MessagePrinter getInstance(){
if(实例==null)
instance=newmessageprinter();
返回实例;
}
}
公共类可变延迟{
公共静态void main(字符串[]args)引发InterruptedException{
ExecutorService executor=Executors.newSingleThreadExecutor();
MessagePrinter msp=MessagePrinter.getInstance();
执行人提交(msp);
msp.sendText(新字符串[]{“欢迎来到服务器,播放器!”,
“这个服务器是关于BlaBla,这个,那个,还有更多的东西,”,
“接受教程?”});
msp.sendText(“更多要关注的文本”);
//关闭:
executor.shutdown();
如果(!执行器等待终止(2,时间单位秒)){
执行者。关机现在();
}
}
}
可能就是这样的事情:
public void send(String...strings) {
for (String string : strings) {
player.sendMessage(string);
}
}
public void send(String...strings) {
for (String string : strings) {
new BukkitRunnable() {
@Override
public void run() {
player.sendMessage(string);
}
}.runTaskLater(my_plugin_instance, (string.length()*2));
}
}
private void send(final Player player, String...messages) {
long delaySum = 0;
for (final String message : messages) {
Runnable myTask = new Runnable() {
public void run() {
player.sendMessage(message);
}
};
this.getServer().getScheduler().runTaskLater(this, myTask, delaySum);
delaySum += message.length() * 2;
}
}
这样,每个消息都会被之前计算的所有延迟延迟延迟