2017-05-30 10 views
0

YouTubeでThinMatrixのチュートリアルを使用して作成しているマルチプレイヤーゲームにいくつかのコードを追加するにはどうすればよいですか?私は自分のチュートリアルに従っていきました。正直なところ...私のゲームに自分のものを追加することを決めました。誰かが、ゲームのプレイヤーエンティティの位置を更新するコードを教えてくれますか?私はすでに(基本的な)ネットワーキングを行う方法を知っています。更新クライアントのポジションのような単純なことを行うマルチプレーヤーコード(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; 
     } 
    } 




} 

プレーヤークラス:

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

あなたが達成したいタスクが簡単なものですが、理由コードのコメントから

Cameraクラスを追加しましたあなたのコードが書かれている方法のそれは達成するために不必要に難しい仕事になっています。コードを修正することは、オブジェクト指向のコードと効率的なネットワーキングの詳細を理解することなく、準備が整ったことではありません。

この時点では、コードを修正しようとはしませんが、このコードを少しでも機能させる方法を提案します。このプロジェクトを続行すると、後で多くの問題が発生することに注意してください。

まず、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(ない最高のアイデアが、それはあなたが始めるのに役立つだろう)を使用している場合:

これは意味がないなら、私はあなたがチュートリアルので、コーディングを続行する前に、基本的なJavaチュートリアルを完了することを示唆している

//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); 

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; 
    } 
} 

は、次にソケット経由で送信するため、あなたはビットのようにそれを行うことができますJavaでのコーディングの基本的なビルディングブロックを含んでいます。あなたはそれがとてもプレーヤークラスが現在の場所に戻すことができますし、そうするようにする必要があり http://docs.oracle.com/javase/tutorial/index.html

+0

私はかなりの時間をそこに持ってきましたが、私はそこに混乱するようです。 – rjhwinner03

+0

何がうまいですか...しかし、クライアントに他のプレイヤーのものを送ってもらうにはどうすればいいですか?世界の立場など?私はちょうど入力を終えた私の最新のクライアントとサーバーコードをコメントしました。私はそれが助けることを願う – rjhwinner03

+0

また助けてくれてありがとう! – rjhwinner03

0

:あなたは偉大なプロジェクトを作るために構築することができますが、その知識がなくてもあなたは決して終わることのない問題を抱えているために運命づけされている知識を持ちますあなたがする必要があるのは、新しいパッケージでゲームの別のインスタンスを作成して実行することなので簡単ですが、サーバ側ではプレーヤーに現在の位置を送信し、座標系を使用するので一貫して更新する必要があります非常に基本的なので、ゲームのサーバー側のプレーヤーエンティティなどのエンティティがすでにゲームに必要なので、player.getPosition()を実行してserverSideModel =プレーヤー。getPosition()を呼び出すと、両方のモデルが同じ位置に設定されるため、同じ位置に設定されます。

関連する問題