Creating the Client (1)
The client is obviously the program that the player runs in order to
play the game. Create a class called MTDClient and make it look like
the following:-
import com.scs.stevetech1.client.AbstractGameClient;
import com.scs.stevetech1.client.AbstractSimpleGameClient;
import com.scs.stevetech1.components.IEntity;
import com.scs.stevetech1.netmessages.NewEntityData;
public class MTDClient extends AbstractSimpleGameClient {
private MTDClientEntityCreator entityCreator = new MTDClientEntityCreator(); public static void main(String[] args) {
try {
new MTDClient("localhost", 6000, "My Name");
} catch (Exception e) {
e.printStackTrace(); }
}
private MTDClient(String gameIpAddress, int gamePort, String _playerName) {
super("MTD", gameIpAddress, gamePort, _playerName);
start();
}
@Override
protected IEntity actuallyCreateEntity(AbstractGameClient client, NewEntityData msg) {
return entityCreator.createEntity(client, msg);
}
Notice that in the above code, we've put "localhost" for the server's address. If you're rich enough to have separate computers to run the client and the server, you'll need to replace this with the IP address of your server.
When you've created the above class, there is only one method that needs properly completing, and that's the actuallyCreateEntity() method. I prefer to delegate this to another class since it can turn into something big, since it needs to create every entity that the server tells it to.
You'll remember in the Entities section of this tutorial that we created a class called MTDClientEntityCreator. Go back to this class and add the following method:-
import com.jme3.math.Vector3f;
import com.scs.stevetech1.client.AbstractGameClient;
import com.scs.stevetech1.components.IEntity;
import com.scs.stevetech1.entities.AbstractClientAvatar;
import com.scs.stevetech1.entities.AbstractOtherPlayersAvatar;
import com.scs.stevetech1.netmessages.NewEntityData;
public IEntity createEntity(AbstractGameClient game, NewEntityData msg) {
int id = msg.entityID;
Vector3f pos = (Vector3f)msg.data.get("pos");
switch (msg.type) {
case AVATAR:
{
int playerID = (int)msg.data.get("playerID");
byte side = (byte)msg.data.get("side");
String playersName = (String)msg.data.get("playersName");
if (playerID == game.playerID) {
AbstractClientAvatar avatar = new WizardClientAvatar(game, id, game.input, game.getCamera(), id, pos.x, pos.y, pos.z, side);
return avatar;
} else {
// Create a simple avatar since we don't control these
AbstractOtherPlayersAvatar avatar = new OtherWizardAvatar(game, id, pos.x, pos.y, pos.z, side, playersName);
return avatar;
}
}
case FLOOR:
{
Vector3f size = (Vector3f)msg.data.get("size");
String tex = (String)msg.data.get("tex");
Floor floor = new Floor(game, id, pos.x, pos.y, pos.z, size.x, size.y, size.z, tex);
return floor;
}
default:
throw new RuntimeException("Unknown entity type: " + msg.type);
}
}
This method takes the details sent by the server, and instantiates the correct entity. You'll notice that when we created the Floor class, we added some details to the creationData HashMap. This data gets sent to the client, so if there are any extra details that the client requires to create an entity (e.g. the texture to use) add them to this and the client can read them.
Is that it? You should now have a fully compiling server and client. Run them and see what happens (spoiler: you'll get an error). This is because we haven't added the assets yet. See you in the next part to do that.
import com.scs.stevetech1.client.AbstractGameClient;
import com.scs.stevetech1.client.AbstractSimpleGameClient;
import com.scs.stevetech1.components.IEntity;
import com.scs.stevetech1.netmessages.NewEntityData;
public class MTDClient extends AbstractSimpleGameClient {
private MTDClientEntityCreator entityCreator = new MTDClientEntityCreator(); public static void main(String[] args) {
try {
new MTDClient("localhost", 6000, "My Name");
} catch (Exception e) {
e.printStackTrace(); }
}
private MTDClient(String gameIpAddress, int gamePort, String _playerName) {
super("MTD", gameIpAddress, gamePort, _playerName);
start();
}
@Override
protected IEntity actuallyCreateEntity(AbstractGameClient client, NewEntityData msg) {
return entityCreator.createEntity(client, msg);
}
Notice that in the above code, we've put "localhost" for the server's address. If you're rich enough to have separate computers to run the client and the server, you'll need to replace this with the IP address of your server.
When you've created the above class, there is only one method that needs properly completing, and that's the actuallyCreateEntity() method. I prefer to delegate this to another class since it can turn into something big, since it needs to create every entity that the server tells it to.
You'll remember in the Entities section of this tutorial that we created a class called MTDClientEntityCreator. Go back to this class and add the following method:-
import com.jme3.math.Vector3f;
import com.scs.stevetech1.client.AbstractGameClient;
import com.scs.stevetech1.components.IEntity;
import com.scs.stevetech1.entities.AbstractClientAvatar;
import com.scs.stevetech1.entities.AbstractOtherPlayersAvatar;
import com.scs.stevetech1.netmessages.NewEntityData;
public IEntity createEntity(AbstractGameClient game, NewEntityData msg) {
int id = msg.entityID;
Vector3f pos = (Vector3f)msg.data.get("pos");
switch (msg.type) {
case AVATAR:
{
int playerID = (int)msg.data.get("playerID");
byte side = (byte)msg.data.get("side");
String playersName = (String)msg.data.get("playersName");
if (playerID == game.playerID) {
AbstractClientAvatar avatar = new WizardClientAvatar(game, id, game.input, game.getCamera(), id, pos.x, pos.y, pos.z, side);
return avatar;
} else {
// Create a simple avatar since we don't control these
AbstractOtherPlayersAvatar avatar = new OtherWizardAvatar(game, id, pos.x, pos.y, pos.z, side, playersName);
return avatar;
}
}
case FLOOR:
{
Vector3f size = (Vector3f)msg.data.get("size");
String tex = (String)msg.data.get("tex");
Floor floor = new Floor(game, id, pos.x, pos.y, pos.z, size.x, size.y, size.z, tex);
return floor;
}
default:
throw new RuntimeException("Unknown entity type: " + msg.type);
}
}
This method takes the details sent by the server, and instantiates the correct entity. You'll notice that when we created the Floor class, we added some details to the creationData HashMap. This data gets sent to the client, so if there are any extra details that the client requires to create an entity (e.g. the texture to use) add them to this and the client can read them.
Is that it? You should now have a fully compiling server and client. Run them and see what happens (spoiler: you'll get an error). This is because we haven't added the assets yet. See you in the next part to do that.
Comments
Post a Comment