布尔值在线程中不变
Boolean not changing in thread
我有一个 class MPClient 和 MultiplayerMatch。 MultiplayerMatch 在他的构造函数中创建了一个 MPClient 运行nable 线程。
为了避免数据溢出,我在 MultiplayerMatch 中有一个名为 "moved" 的布尔值,当玩家移动时它会变为 true。
在 updateMatch 方法中,如果有任何玩家移动,"moved" 变为 true,这允许 MPClient 输入一个 if 语句(在 while 内)。这样 MPClient 仅在游戏发生变化时才向服务器发送数据。
然而,当标志为真时,在 MPClient 中没有注册更改! MPClient 仍然 "thinks" 移动等于 false,即使在 MultiplayerMatch 中更改了该标志之后,结果,没有任何内容被发送到服务器...
经过几次测试,我注意到如果我在调试模式下 运行 它,因为我有一些断点,该更改被注册并且一切正常!
为什么在调试模式下布尔值仅更改 "seen"?是不是和app有关系"running speed",因为有断点?
这里只是代码的重要部分:
MP 客户端:
public class MPClient {
static final int TIME_OUT = 5000;
Client client;
MultiPlayMatch match;
public MPClient(String name, int team, MultiPlayMatch match) {
this.match = match;
client = new Client();
client.start();
Network.registerPackets(client);
addListeners();
try {
client.connect(TIME_OUT, "127.0.0.1", Network.PORT);
} catch (IOException e) {
e.printStackTrace();
client.stop();
}
/*this comment is just to show that here is the place where the login information is sent to the server, instead of showing all the code*/
PlayerInfo playerInfo = new PlayerInfo();
Network.UpdatePlayer updatePlayer = new Network.UpdatePlayer();
updatePlayer.name = name;
updatePlayer.team = team;
while(true) {
if(match.moved) { //--> this is the variable that is always false
playerInfo.x = match.getClientPlayerX(team);
playerInfo.y = match.getClientPlayerY(team);
updatePlayer.x = playerInfo.x;
updatePlayer.y = playerInfo.y;
client.sendTCP(updatePlayer);
match.moved = false;
}
}
}
private void addListeners() {
client.addListener(new Listener.ThreadedListener(new Listener() {
@Override
public void received(Connection connection, Object object) {
if(object instanceof Network.UpdatePlayer) {
Network.UpdatePlayer updatePlayer = (Network.UpdatePlayer) object;
match.setPlayerPosition(updatePlayer.x, updatePlayer.y, updatePlayer.name, updatePlayer.team);
}
}
}));
}
}
多人比赛:
public class MultiPlayMatch extends Match {
public boolean moved;
public MultiPlayMatch(){
super(0);
Random r = new Random();
int aux = r.nextInt(2);
aux = 0;
if(aux == 0){
homeTeam = new Team("Benfica", Team.TeamState.Attacking, w);
visitorTeam = new Team("Porto", Team.TeamState.Defending, w);
} else{
homeTeam = new Team("Benfica", Team.TeamState.Defending, w);
visitorTeam = new Team("Porto", Team.TeamState.Attacking, w);
}
//homeTeam.controlPlayer(0);
numberOfPlayers = 0;
moved = false;
}
@Override
public void updateMatch(float x, float y, Rain rain, float dt) {
homeTeam.updateControlledPlayerOnline(x, y);
rain.update();
w.step(Constants.GAME_SIMULATION_SPEED, 6, 2);
if(x != 0 || y != 0) moved = true; //this is the place the variable is changed, but if it isn't in debug mode, MPClient thinks it's always false
}
public void setPlayerPosition(float x, float y, String name, int team) {
if(team == 0)
homeTeam.changePlayerPosition(x, y, name);
else
visitorTeam.changePlayerPosition(x, y, name);
}
}
这是因为它正在读取 match.moved
变量的缓存值而不是最新的值。为避免这种情况,将变量声明为 volatile
public volatile boolean moved;
阅读更多here
我有一个 class MPClient 和 MultiplayerMatch。 MultiplayerMatch 在他的构造函数中创建了一个 MPClient 运行nable 线程。
为了避免数据溢出,我在 MultiplayerMatch 中有一个名为 "moved" 的布尔值,当玩家移动时它会变为 true。
在 updateMatch 方法中,如果有任何玩家移动,"moved" 变为 true,这允许 MPClient 输入一个 if 语句(在 while 内)。这样 MPClient 仅在游戏发生变化时才向服务器发送数据。
然而,当标志为真时,在 MPClient 中没有注册更改! MPClient 仍然 "thinks" 移动等于 false,即使在 MultiplayerMatch 中更改了该标志之后,结果,没有任何内容被发送到服务器...
经过几次测试,我注意到如果我在调试模式下 运行 它,因为我有一些断点,该更改被注册并且一切正常! 为什么在调试模式下布尔值仅更改 "seen"?是不是和app有关系"running speed",因为有断点?
这里只是代码的重要部分:
MP 客户端:
public class MPClient {
static final int TIME_OUT = 5000;
Client client;
MultiPlayMatch match;
public MPClient(String name, int team, MultiPlayMatch match) {
this.match = match;
client = new Client();
client.start();
Network.registerPackets(client);
addListeners();
try {
client.connect(TIME_OUT, "127.0.0.1", Network.PORT);
} catch (IOException e) {
e.printStackTrace();
client.stop();
}
/*this comment is just to show that here is the place where the login information is sent to the server, instead of showing all the code*/
PlayerInfo playerInfo = new PlayerInfo();
Network.UpdatePlayer updatePlayer = new Network.UpdatePlayer();
updatePlayer.name = name;
updatePlayer.team = team;
while(true) {
if(match.moved) { //--> this is the variable that is always false
playerInfo.x = match.getClientPlayerX(team);
playerInfo.y = match.getClientPlayerY(team);
updatePlayer.x = playerInfo.x;
updatePlayer.y = playerInfo.y;
client.sendTCP(updatePlayer);
match.moved = false;
}
}
}
private void addListeners() {
client.addListener(new Listener.ThreadedListener(new Listener() {
@Override
public void received(Connection connection, Object object) {
if(object instanceof Network.UpdatePlayer) {
Network.UpdatePlayer updatePlayer = (Network.UpdatePlayer) object;
match.setPlayerPosition(updatePlayer.x, updatePlayer.y, updatePlayer.name, updatePlayer.team);
}
}
}));
}
}
多人比赛:
public class MultiPlayMatch extends Match {
public boolean moved;
public MultiPlayMatch(){
super(0);
Random r = new Random();
int aux = r.nextInt(2);
aux = 0;
if(aux == 0){
homeTeam = new Team("Benfica", Team.TeamState.Attacking, w);
visitorTeam = new Team("Porto", Team.TeamState.Defending, w);
} else{
homeTeam = new Team("Benfica", Team.TeamState.Defending, w);
visitorTeam = new Team("Porto", Team.TeamState.Attacking, w);
}
//homeTeam.controlPlayer(0);
numberOfPlayers = 0;
moved = false;
}
@Override
public void updateMatch(float x, float y, Rain rain, float dt) {
homeTeam.updateControlledPlayerOnline(x, y);
rain.update();
w.step(Constants.GAME_SIMULATION_SPEED, 6, 2);
if(x != 0 || y != 0) moved = true; //this is the place the variable is changed, but if it isn't in debug mode, MPClient thinks it's always false
}
public void setPlayerPosition(float x, float y, String name, int team) {
if(team == 0)
homeTeam.changePlayerPosition(x, y, name);
else
visitorTeam.changePlayerPosition(x, y, name);
}
}
这是因为它正在读取 match.moved
变量的缓存值而不是最新的值。为避免这种情况,将变量声明为 volatile
public volatile boolean moved;
阅读更多here