#java #udp
Вопрос:
в моей многопользовательской танковой игре есть проблема. резервуары на стороне клиента нарисованы неправильно. последний, отправленный с сервера, хорош. но остальные моргают. я нашел проблему в клиенте. при разборе сообщений он получает координаты и направление танков x, y с правильной очередью. но когда я отправляю их в метод рисования, он получает последний. когда я пишу координаты x,y в методе рисования, подавляющее большинство координат x и y принадлежат последнему танку. так что последний танк не мигает, но остальные мигают. вот мой код;
public void run() {
byte[] data= new byte[1024];
while(true) {
try {
DatagramPacket packetreceived = new DatagramPacket(data, data.length);
soket.receive(packetreceived);
messagereceived=new String(packetreceived.getData(),0,packetreceived.getLength());
setmesaj(messagereceived);
parsemessage(messagereceived);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//soket.close();
}}
public String incomingmessage() {
return messagereceived;
}
public void setmesaj(String messagereceived) {
this.messagereceived=messagereceived;
}
public void senddata(byte[] data) {
try {DatagramPacket packet = new DatagramPacket(data, data.length,host,port );
soket.send(packet);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void parsemessage(String messagereceived) {
String[] msg= messagereceived.split(",");
if(msg[0].equalsIgnoreCase("playtank")) {
tankno=Integer.parseInt(msg[1]);
setTankno(Integer.parseInt(msg[1]));
switch(tankno) {
default:
x=Integer.parseInt(msg[2]);
y=Integer.parseInt(msg[3]);
direction=Integer.parseInt(msg[4]);
}
}
if(msg[0].equalsIgnoreCase("addnewtanks")) {
this.tankno=Integer.parseInt(msg[1]);
this.x=Integer.parseInt(msg[2]);
this.y=Integer.parseInt(msg[3]);
this.direction=Integer.parseInt(msg[4]);
this.health=Integer.parseInt(msg[5]);
this.say=Integer.parseInt(msg[6]);
this.tip=Integer.parseInt(msg[7]);
}
System.out.println(this.x " " this.y " " this.tankno);
** when i write these values, it is written properly to console everything is ok**
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getdir() {
return direction;
}
public void setdir(int direction) {
this.direction = direction;
}
public int getTankno() {
return tankno;
}
public void setTankno(int tankno) {
this.tankno = tankno;
}
public void draw(Graphics g,Bufferedimagex bf1) {
//System.out.println(this.x " " this.y " " this.tankno);
**when the values are written here most of the written value on the console is the third one (there are 0,1,2,3 tanks).**
g.drawImage(bf1.sprite(this.getdir()*32-32, this.tip*16), this.getX(), this.getY(), 48, 48,null);
}
Ответ №1:
У вас есть отдельные объекты для каждого танка? По — видимому, это не так. Мне кажется, что у вас есть один run
цикл для чтения сообщений для всех 4 танков, и все танки используют одни и те же поля объектов класса. Если это так, то вы, вероятно, постоянно перезаписываете поля участника, когда приходит другой пакет.
Вероятно, вам следует подумать о создании отдельного класса танков.
напр..,
class Tank
{
int x;
int y;
int direction;
}
Затем создайте массив, список или карту танков.
Tank[] tanks = new Tank[4];
for(int i=0;i<tanks.length;i )
{
tanks[i] = new Tank();
}
Когда вы получите сообщение, вам нужно будет выбрать, какой резервуар обновить. Вот пример использования массива.
String[] msg= messagereceived.split(",");
if(msg[0].equalsIgnoreCase("playtank")) {
tankno=Integer.parseInt(msg[1]);
// Choose which tank to update
Tank tank = tanks[tankno];
tank.x=Integer.parseInt(msg[2]);
etc...
Создавая отдельный объект для каждого резервуара, вы будете изолировать данные каждого резервуара от других, и у вас не возникнет проблем с перезаписью данных.
Комментарии:
1. спасибо, Джейми. да, у меня есть отдельный класс танков. я добавил танки в список arraylist. затем инициализируйте танки в игровой панели. но результат был тот же. поэтому я добавил метод рисования в клиентский класс, чтобы достичь всех значений. последнее выше, но оно не работает. я вижу танки на экране, но последний хорошо виден, а остальные появляются в кадре и быстро исчезают. они двигаются по кругу. их координаты меняются.
2. Ваш
parsemessage
метод не создает впечатления сохранения данных в отдельных объектах… он просто записывает данные в себя:x=Integer.parseInt(msg[2]);
. Где он выбирает объект резервуара для обновления?