我正在使用HTML5 websockets和Java作为后端处理网络游戏。目前为每个玩家创建一个新的游戏类实例,它还创建一个带有计时器任务的计时器来运行游戏循环并每隔60fps向前端发送更新。
由于这些计时器在服务器资源上非常沉重,玩家玩的很多,我想在游戏类中应用Singleton模式并保留一系列匹配。我没有为每个玩家创建一个计时器,而是创建了一个单个计时器,用于为数组中的每个匹配更新游戏循环和for循环。
我想知道是否有更好的方法,因为我听说单身人士模式中有很多缺点,尤其是单元测试。
答案 0 :(得分:1)
假设我已正确理解你的问题,你想为所有比赛使用1个计时器,并为每场比赛使用for-loop来更新游戏。
这是一个可怕的想法。沿着该行的任何地方的任何类型的渲染阻塞都将影响整个服务器。如果第一场比赛中的某人向服务器发送了大量数据,则会阻止该线程,并使每次匹配的FPS变慢。
是的,服务器上的计时器很重要。但是如果你一次有太多活动匹配,那么对所有匹配使用一个计时器会导致线程阻塞,因为单个线程无法处理高负载并以60 FPS运行。
设计任何给定游戏服务器的最好方法是使用Threads。
您可以使用Thread.sleep创建延迟并维护给定的FPS,并使用线程而不是计时器来减轻负载。它仍然很重,但使用Threads比Timers轻。
至于实际线程,这是它的一部分:
public void run(){
long lastLoopTime = System.nanoTime();
final int TARGET_FPS = 60;//The FPS. Can be reduced or increased.
final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;//1 second = 10^9 nanoseconds
long lastFpsTime = 0;//Used to calculate delta
while(running){
long now = System.nanoTime();//Get the current time
long updateLength = now - lastLoopTime;//get the time it took to update
lastLoopTime = now;//set the last time the loop started to the current time
double delta = updateLength / ((double)OPTIMAL_TIME);//Calculate delta
lastFpsTime += updateLength;
if(lastFpsTime >= 1000000000){
lastFpsTime = 0;
}
//Right here you place your code. Update the servers, push and read data, whatever you need
try{
long gt = (lastLoopTime - System.nanoTime() + OPTIMAL_TIME) / 1000000;//calculate the time to sleep, and convert to milliseconds
Thread.sleep(gt);//And finally, sleep to maintain FPS
}catch(InterruptedException e){
}
}
}
该类扩展了Thread并且有一个名为running
的布尔值。布尔值允许在不必抛出异常的情况下停止Thread。
你为每场比赛创造一个线程(这是一个重要的点。为每个球员做它并且你杀死资源。为所有比赛做一个,你可以保持60 FPS,除非你有超级计算机(取决于匹配的数量)),并有一个主线程来管理连接和匹配线程
答案 1 :(得分:0)
singelton设计模式最简单的规则是 -
考虑一下hibernate的configure和buildsessionfactory方法的例子,使其成为我所推荐的singelton
public class Singelton {
private static SessionFactory sessionFactory=null;
static {
Configuration configuration = new Configuration();
configuration.configure();
sessionFactory = configuration.buildSessionFactory();
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
private Singelton() {
}
}