2016-03-20 10 views
0

В настоящее время я пытаюсь создать очень простую многопользовательскую игру в java (с OpenGL (LWJGL)), и в настоящее время программа работает на двух разных потоках.Проблема с несколькими потоками - Передача объектов между потоками

Тема 1: Запускает всю логику игры и рендеринга

резьбы 2: Ручки соединения между сервером и клиентом

Так в основном распараллеливания 2 сидит и ждать входящих пакетов и всякий раз, когда он получает логин-пакет Я хочу, чтобы он создавал объект-плеер, но кажется, что новый объект создается в потоке 2, и при попытке визуализации возникает следующая ошибка:

Исключение из потока «Thread-2» java.lang.IllegalStateException : Экземпляр GLCapabilities не установлен для текущего thre объявление.

Я довольно новичок как в OpenGL, так и в многопоточном режиме, и, вероятно, это довольно простое и простое решение, но мне интересно, как я могу создать объект при получении пакета и добавить его в поток 1 .

тема 2:

public void run() { 
    while (running) { 
     byte[] data = new byte[1024]; 
     DatagramPacket packet = new DatagramPacket(data, data.length); 
     try { 
      socket.receive(packet); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     parsePacket(packet.getData(), packet.getAddress(), packet.getPort()); 
     } 
    } 

parsePacket() проверяет тип пакета и, если это Логин-пакет будет вызывать следующий метод:

public void addPlayerToGame(byte[] data, InetAddress address, int port) { 
    Packet00Login packet = new Packet00Login(data); 

    level.addObject(new PlayerMP(packet.getUsername(), new Vector3f(0.0f, 0.0f, 0.0f), address, port)); 
} 

Метод addObject просто добавляет объекты в arraylist.

public void addObject(GameObject o) { 
    this.objects.add(o); 
} 

Все объекты затем визуализируемый с этим вызовом на резьбе 1:

public void render() { 
    for (GameObject o : objects) { 
     o.render(); 
    } 
    player.render(); 
} 
+0

Показать (по крайней мере) конструктор 'PlayerMP' и соответствующих частей трассировки стека. Скорее всего, вы выполняете GL-операции в конструкторе, и это происходит в неправильном потоке. Тогда решение могло бы обрабатывать информацию, необходимую для создания игрока в потоке GL, и позволить потоку GL фактически создавать плеер. – Marco13

+0

@ Marco13 Да, я вызывал GL-операции в конструкторе! Я переместил все эти операции в «готовый» метод, который я вызываю прямо перед добавлением объекта в список (по GL-потоку), и теперь он работает! Спасибо за вашу помощь! :) – Estrozix

ответ

0

Вы не должны изменять свой список геймобжектов из второго потока, поскольку изменения чрезвычайно высоки вы будете перебором на что список в первом потоке. Это приведет к возникновению текущего исключения модификации. Или, что еще хуже, создание неопределенного поведения с помощью openGL.

Что вам нужно сделать, так это иметь список задач в вашей первой теме. В каждом цикле вы выполняете все задачи в списке задач, затем очищаете его.

Так что вместо прямого добавления игрового объекта в список добавьте задачу для добавления объекта.

(Кроме того, убедитесь, чтобы сделать выполнение задач Потокобезопасная)

+0

Я сделал отдельный массив-список, в который я добавляю все вещи, которые нужно добавить, а затем прокручивать через него! Работает как шарм, спасибо! :) – Estrozix

+0

По-моему, у вас должен быть список задач в любом случае. Поскольку вам, вероятно, придется обновлять объекты в текущем списке в какой-то момент (например, когда игрок движется), а другой список не поможет вам в этом. Кроме того, не забудьте подтвердить ответ – Gaktan

+0

А это правда!Я никогда не делал ничего подобного раньше, и я ценю всю помощь, которую я могу получить. Я обязательно посмотрю на это, спасибо :) – Estrozix