2017-05-30 37 views
0

如何在我使用ThinMatrix的YouTube教程创建的多人游戏中添加一些代码?我一直在跟着他的教程,当我决定去...呃......切入并开始将我自己的东西添加到我的游戏中。有人可以用一些代码来帮助我更新游戏中玩家实体的位置吗?我已经知道如何做(基本)网络。如何添加一些多人游戏代码(用于java),可以执行更新客户位置等简单工作

谢谢!


编辑:代码从评论

添加

相机类:

package entities; 

import org.lwjgl.input.Keyboard; 
import org.lwjgl.input.Mouse; 
import org.lwjgl.util.vector.Vector3f; 

public class Camera { 

    private float distanceFromPlayer = 35; 
    private float angleAroundPlayer = 0; 

    private Vector3f position = new Vector3f(0, 0, 0); 
    private float pitch = 20; 
    private float yaw = 0; 
    private float roll; 

    private Player player; 

    public Camera(Player player){ 
     this.player = player; 
    } 

    public void move(){ 
     calculateZoom(); 
     calculatePitch(); 
     calculateAngleAroundPlayer(); 
     float horizontalDistance = calculateHorizontalDistance(); 
     float verticalDistance = calculateVerticalDistance(); 
     calculateCameraPosition(horizontalDistance, verticalDistance); 
     this.yaw = 180 - (player.getRotY() + angleAroundPlayer); 
    } 

    public Vector3f getPosition() { 
     return position; 
    } 

    public float getPitch() { 
     return pitch; 
    } 

    public float getYaw() { 
     return yaw; 
    } 

    public float getRoll() { 
     return roll; 
    } 

    private void calculateCameraPosition(float horizDistance, float verticDistance){ 
     float theta = player.getRotY() + angleAroundPlayer; 
     float offsetX = (float) (horizDistance * Math.sin(Math.toRadians(theta))); 
     float offsetZ = (float) (horizDistance * Math.cos(Math.toRadians(theta))); 
     position.x = player.getPosition().x - offsetX; 
     position.z = player.getPosition().z - offsetZ; 
     position.y = player.getPosition().y + verticDistance + 4; 
    } 

    private float calculateHorizontalDistance(){ 
     return (float) (distanceFromPlayer * Math.cos(Math.toRadians(pitch+4))); 
    } 

    private float calculateVerticalDistance(){ 
     return (float) (distanceFromPlayer * Math.sin(Math.toRadians(pitch+4))); 
    } 

    private void calculateZoom(){ 
     float zoomLevel = Mouse.getDWheel() * 0.03f; 
     distanceFromPlayer -= zoomLevel; 
     if(distanceFromPlayer<5){ 
      distanceFromPlayer = 5; 
     } 
    } 

    private void calculatePitch(){ 
     if(Mouse.isButtonDown(1)){ 
      float pitchChange = Mouse.getDY() * 0.2f; 
      pitch -= pitchChange; 
      if(pitch < 0){ 
       pitch = 0; 
      }else if(pitch > 90){ 
       pitch = 90; 
      } 
     } 
    } 

    private void calculateAngleAroundPlayer(){ 
     if(Mouse.isButtonDown(0)){ 
      float angleChange = Mouse.getDX() * 0.3f; 
      angleAroundPlayer -= angleChange; 
     } 
    } 




} 

Player类:

package entities; 

import models.TexturedModel; 

import org.lwjgl.input.Keyboard; 
import org.lwjgl.util.vector.Vector3f; 

import renderEngine.DisplayManager; 
import terrains.Terrain; 

public class Player extends Entity { 

    private static final float RUN_SPEED = 40; 
    private static final float TURN_SPEED = 160; 
    private static final float GRAVITY = -50; 
    private static final float JUMP_POWER = 18; 

    private float currentSpeed = 0; 
    private float currentTurnSpeed = 0; 
    private float upwardsSpeed = 0; 

    private boolean isInAir = false; 

    public Player(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, 
      float scale) { 
     super(model, position, rotX, rotY, rotZ, scale); 
    } 

    public void move(Terrain terrain) { 
     checkInputs(); 
     super.increaseRotation(0, currentTurnSpeed * DisplayManager.getFrameTimeSeconds(), 0); 
     float distance = currentSpeed * DisplayManager.getFrameTimeSeconds(); 
     float dx = (float) (distance * Math.sin(Math.toRadians(super.getRotY()))); 
     float dz = (float) (distance * Math.cos(Math.toRadians(super.getRotY()))); 
     super.increasePosition(dx, 0, dz); 
     upwardsSpeed += GRAVITY * DisplayManager.getFrameTimeSeconds(); 
     super.increasePosition(0, upwardsSpeed * DisplayManager.getFrameTimeSeconds(), 0); 
     float terrainHeight = terrain.getHeightOfTerrain(getPosition().x, getPosition().z); 
     if (super.getPosition().y < terrainHeight) { 
      upwardsSpeed = 0; 
      isInAir = false; 
      super.getPosition().y = terrainHeight; 
     } 
    } 

    private void jump() { 
     if (!isInAir) { 
      this.upwardsSpeed = JUMP_POWER; 
      isInAir = true; 
     } 
    } 

    private void checkInputs() { 
     if (Keyboard.isKeyDown(Keyboard.KEY_W)) { 
      this.currentSpeed = RUN_SPEED; 
     } else if (Keyboard.isKeyDown(Keyboard.KEY_S)) { 
      this.currentSpeed = -RUN_SPEED; 
     } else { 
      this.currentSpeed = 0; 
     } 

     if (Keyboard.isKeyDown(Keyboard.KEY_D)) { 
      this.currentTurnSpeed = -TURN_SPEED; 
     } else if (Keyboard.isKeyDown(Keyboard.KEY_A)) { 
      this.currentTurnSpeed = TURN_SPEED; 
     } else { 
      this.currentTurnSpeed = 0; 
     } 

     if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) { 
      jump(); 
     } 
    } 

} 
+3

向我们展示你迄今为止尝试过,因为我们不能没有代码帮助。 (同时把你的问题分解成几部分,并一次提出一件事)。没有代码,我们有各种问题,例如:玩家实体如何暴露/管理?你的问题是网络相关还是java方法问题?玩家实体是一个自定义类吗?你有没有设置方法,以便玩家实体可以通过方法调用进行移动? – sorifiend

+0

我可以提供下载链接的代码,因为有20个类。是的,我确实有一些用户输入系统,可以移动角色并移动相机。我无法弄清楚如何做诸如发送大量字节的事情,比如世界,天空盒和实体。如果你的意思是我自己创造了它们,那么是的。不。但如果你想,我可以给你一个下载链接。感谢您的回复 – rjhwinner03

+1

这里没有人会翻阅这么多的代码。您需要将问题缩小到特定问题。要发送数据,请考虑您可以发送的最小数量。例如,在处理移动时,您只需发送x,y,z坐标以获取俯仰和偏航的位置以查看方向,并且可以通过tcp或udp连接更新,发送的数据非常少。您还需要有代码发送,然后解释您发送/接收的内容,但这不是发送大量信息的问题,而是发送智能信息。这是一个非常重要的话题...... – sorifiend

回答

0

你想达到的任务很简单,但由于你的代码写入的方式已经成为一项不必要的艰巨任务。如果不了解更多关于面向对象代码和高效网络的信息,修复代码并不是您已准备好的。

所以在这一点上,我不会试图修复你的代码,但我会简单地建议一种方法来使它工作一些,并且要知道如果你继续这个项目,你将会有很多问题。

首先我们需要一个简单的方法来处理更新Player实体的位置。

public void moveByFloatInput(fload newX, float newY, float newY) { 
    //Here you need to get the current terrain object for this player entity 
    Terrain currentTerrain = getTerrain(); 
    //Now update the terrain object with your new x,y,z points (not sure what methods Terrain contains, you may need to make changes or expose more variables) 
    currentTerrain.setNewPosition(newX, newY, newZ); 
    //Now call the normal move method using the updated terrain with a new position 
    move(updatedTerrainObject); 
} 

注:我们可以通过添加一个方法到您的播放器类有点​​像这样做有可能是一个更好的办法做到这一点,但我不知道地形类是如何构建的,以及什么方法可以被调用。另外请注意,你会想通过玩家正在寻找的方向,但为了保持这个例子简单,我没有包括任何这个。

现在,当我们收到来自客户机/服务器的XY和Z的信息,我们可以更新播放器的实体,例如,如果你在哪里使用的InputStreamReader(不是最好的办法,但它会帮助你开始):

float x; 
float y; 
float z; 
while ((message = myBufferedReaderInputFromSocket.readLine()) != null) { 
    if (message != null) { 
     //check if X 
     if (message.startsWith("moveX")) 
      //save new X so we can update a player entity 
      x = Float.parseFloat(message.substring(5)); 
     //check if Y 
     if (message.startsWith("moveY")) 
      //save new Y so we can update a player entity 
      y = Float.parseFloat(message.substring(5)); 
     //check if Z 
     if (message.startsWith("moveZ")) 
      //save new Z so we can update a player entity 
      z = Float.parseFloat(message.substring(5)); 
    } 
    //when x, y and y all have a new position we can update a player entity 
    if(x != null && y != null && z != null) 
    { 
     //call our new player move method and change that player entities position 
     playerEntityForThisSocket.moveByFloatInput(x, y, z); 
     //reset x,y,z to null so that the server can receive the next movement 
     x = null; 
     y = null; 
     z = null; 
    } 
} 

然后发送了一个插座,你可以做到这一点有点像:

//you could create a Print writer for your socket: 
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); 
//then simply send a players new position info 
//inculde the "moveX" keyword before the Float x,y,z so that the server/client at the other end knows how to process the info: 
out.println(moveX + newXposition); 
out.println(moveY + newYposition); 
out.println(moveZ + newZposition); 

如果这是没有意义的话,我建议你完成基本的Java教程,你继续编码之前,因为教程包含使用Java进行编码的基本构建块,以及有了这些知识你就可以建立一个伟大的项目,但没有这些知识,你注定会遇到永无止境的问题: http://docs.oracle.com/javase/tutorial/index.html

+0

我已经在那里好几次了,但我似乎在那里搞砸了。 – rjhwinner03

+0

什么事情都很好,但是我怎么让客户发送其他玩家的东西呢?如世界位置?我评论了我刚输入的最新客户端和服务器代码。我希望它可以帮助 – rjhwinner03

+0

也感谢您的帮助! – rjhwinner03

0

你需要使它成为你的播放器类可以返回当前位置并且这样做因为所有你需要做的就是用新包创建另一个游戏实例并运行它,但是在服务器端,你需要发送玩家当前位置并一致地进行更新,因为这会使用坐标系,但这是非常基本,因此您已经需要游戏中的实体(例如游戏服务器端的玩家实体),并且您需要此实体更新其位置,以便您可以执行类似于player.getPosition()和serverSideModel =播放器。getPosition(),因为它将两个模型设置为相同的位置,如果这使得sence

相关问题