我有一个MPClient和MultiplayerMatch类。MultiplayerMatch在其构造函数中创建一个MPClient可运行线程。
为了避免数据溢出,我在MultiplayerMatch中有一个名为“ moved”的布尔值,当播放器移动时,它会变为true。
在updateMatch方法中,如果有任何播放器移动,则“ moved”变为true,这允许MPClient输入if语句(在while内)。这样,MPClient仅在游戏发生更改时才将数据发送到服务器。
但是,当该标志为true时,则不会在MPClient中注册该更改!即使在MultiplayerMatch中更改了该标志,MPClient仍然“认为”移动等于假,结果没有任何内容发送到服务器…
经过几次测试后,我注意到如果以调试模式运行它,因为我有一些断点,则将记录该更改,并且一切正常!为什么通过调试模式只能“看到”布尔更改?由于存在断点,它是否与应用程序的“运行速度”有关?
这只是代码的重要部分:
MPClient:
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
match.moved
volatile
public volatile boolean moved;
在这里阅读更多