Java 多人游戏中的线性脉冲和错误位置
我正在用LibGDX创建一个游戏。起初,我在youtube上观看一个超级马里奥兄弟游戏的教程,但是,我改变了游戏,加入了我自己的角色和图形。我使用Kryonet作为在我的游戏中加入多人游戏功能的一种手段。这就是我遇到几个问题的地方 首先,我使用线性冲动进行移动,所以当我的角色上电时,会应用线性冲动,并赋予他们力量以更快地向前移动。这很好,直到你看到两个屏幕,角色A在一个玩家的屏幕上的位置不同,在另一个玩家的屏幕上的位置不同。我得到的两个角色的线性脉冲值也不同。我正常的右、左、上的动作也是用线性冲动完成的。由于线性脉冲值的随机性,我得到了这个误差,我想说的是,就像滑动冰误差一样,推动冰块穿过表面并不总是保证相同的位置。下面是我的多人客户端类的一些代码Java 多人游戏中的线性脉冲和错误位置,java,android,libgdx,game-physics,kryonet,Java,Android,Libgdx,Game Physics,Kryonet,我正在用LibGDX创建一个游戏。起初,我在youtube上观看一个超级马里奥兄弟游戏的教程,但是,我改变了游戏,加入了我自己的角色和图形。我使用Kryonet作为在我的游戏中加入多人游戏功能的一种手段。这就是我遇到几个问题的地方 首先,我使用线性冲动进行移动,所以当我的角色上电时,会应用线性冲动,并赋予他们力量以更快地向前移动。这很好,直到你看到两个屏幕,角色A在一个玩家的屏幕上的位置不同,在另一个玩家的屏幕上的位置不同。我得到的两个角色的线性脉冲值也不同。我正常的右、左、上的动作也是用线性冲
client.addListener(new ThreadedListener(new Listener() {
// What to do with the packets.
public void connected(Connection connection) {
}
public void received(Connection connection, Object object) {
if (object instanceof MovementJump) {
MovementJump packet = (MovementJump) object;
PlayScreen.player.b2body.applyLinearImpulse(new Vector2(0, 4f),
PlayScreen.player.b2body.getWorldCenter(), true);
}
if (object instanceof MovementRight) {
MovementRight packet = (MovementRight) object;
PlayScreen.player.b2body.applyLinearImpulse(new Vector2(packet.impulse, 0),
PlayScreen.player.b2body.getWorldCenter(), true);
}
if (object instanceof MovementLeft) {
MovementLeft packet = (MovementLeft) object;
PlayScreen.player.b2body.applyLinearImpulse(new Vector2(-packet.impulse, 0),
PlayScreen.player.b2body.getWorldCenter(), true);
}
if (object instanceof MovementP2Jump) {
MovementP2Jump packet = (MovementP2Jump) object;
PlayScreen.player2.b2body.applyLinearImpulse(new Vector2(0, 4f),
PlayScreen.player2.b2body.getWorldCenter(), true);
}
if (object instanceof MovementP2Right) {
MovementP2Right packet = (MovementP2Right) object;
PlayScreen.player2.b2body.applyLinearImpulse(new Vector2(packet.impulse, 0),
PlayScreen.player2.b2body.getWorldCenter(), true);
}
if (object instanceof MovementP2Left) {
MovementP2Left packet = (MovementP2Left) object;
PlayScreen.player2.b2body.applyLinearImpulse(new Vector2(-packet.impulse, 0),
PlayScreen.player2.b2body.getWorldCenter(), true);
}
}
}));
}
这是我的游戏屏幕上的一些代码
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)
&& player.b2body.getLinearVelocity().x <= player.getMinSpeed()) {
MovementRight pos = new MovementRight();
MPClient.client.sendTCP(pos);
}
if (Gdx.input.isKeyPressed(Input.Keys.LEFT)
&& player.b2body.getLinearVelocity().x >= -player.getMinSpeed()) {
MovementLeft pos = new MovementLeft();
MPClient.client.sendTCP(pos);
}
if(Gdx.input.isKeyPressed(input.Keys.RIGHT)
&&player.b2body.getLinearVelocity().x=-player.getMinSpeed()){
MovementLeft pos=新的MovementLeft();
MPClient.client.sendTCP(pos);
}
您应该发送每个字符的坐标,而不是发送力
为什么??如果应用一个脉冲并发送一个数据包通知其他客户机该脉冲,那么在ping延迟之后,将首先添加他们的脉冲,ping延迟永远不会为0。这意味着他们的脉搏将在之后被添加,因此他们的角色将永远在后面
我可以想出两种方法来实现这一点,但可能还有很多其他方法!第一种是客户端,第二种是服务器端,两者都有优点和缺点。就我个人而言,我推荐服务器端的结构,因为被黑客攻击的MP游戏确实会让玩家感到厌烦
客户端结构:
优点(较少的滞后,对滞后的玩家更灵敏的控制)缺点:(易于破解)
PositionUpdatePacket
。此数据包只需要包含(float x,float y,byte characterID
)MoveRequestPacket
。当方向改变或播放器停止时,只需通过TCP发送一次PositionUpdatePacket
,其中包含当前角色位置PositionUpdatePacket
连续发送到所有连接的客户端,这意味着此数据包将被大量发送。为了降低性能影响,您应该通过UDP发送,并且每秒仅发送x次。地雷船以20吨/秒的速度发送其位置
如果发送PositionUpdatePacket
的频率低于#update
或#step
方法,则每个字符都会结巴和延迟。为了解决这个问题,可以使用插值来平滑运动
我希望这有帮助。祝你好运 您应该发送每个字符的坐标,而不是发送力 为什么??如果应用一个脉冲并发送一个数据包通知其他客户机该脉冲,那么在ping延迟之后,将首先添加他们的脉冲,ping延迟永远不会为0。这意味着他们的脉搏将在之后被添加,因此他们的角色将永远在后面 我可以想出两种方法来实现这一点,但可能还有很多其他方法!第一种是客户端,第二种是服务器端,两者都有优点和缺点。就我个人而言,我推荐服务器端的结构,因为被黑客攻击的MP游戏确实会让玩家感到厌烦 客户端结构: 优点(较少的滞后,对滞后的玩家更灵敏的控制)缺点:(易于破解)
PositionUpdatePacket
。此数据包只需要包含(float x,float y,byte characterID
)MoveRequestPacket
。当方向改变或播放器停止时,只需通过TCP发送一次PositionUpdatePacket
,包括