SOP aplicado em um jogo tipo de
corrida usando a arquitetura
cliente e servidor
Alisson Rafael Appio
[email protected]
Descrição da Aplicação




Um jogo tipo de carrinho, onde cada usuário
controla o seu carrinho (telcas up, down, left
e right)
Arquitetura cliente/servidor
Em Java
Cada movimento do carrinho de um usuário é
enviado aos outros usuários (clientes),
mantendo um estado consistente do jogo.
2-11
Descrição do Problema





Duas equipes escrevem o código do jogo.
A primeira equipe conhece os conceitos necessários
para fazer um jogo (lógica de jogo e render).
A segunda equipe sabe como replicar os objetos
mantendo o estado sincronizado em todos os clientes
(multiplayer)
As equipes não tem acesso direto ao código da outra
equipe, porém a API foi bem definida, separando a
camada de jogo da camada de network
A equipe de network deve suportar os protocolos
TCP/IP e UDP/IP
3-11
Solução Proposta


Uma das maneiras de resolver o
problema sem adicionar overhead na
aplicação é usar técnicas de SOP
Usar SOP para adicionar suporte de
comunicação de rede (TCP e UDP) ao
jogo de corrida
Diagrama de classes do cliente –
RENDER (entidades do domínio)
5-11
Diagrama de classes do cliente
Model + Render
6-11
Diagrama de classe do servidor
7-11
Diagrama de classes do Game
Componente (usando SOP)
8-11
Diagrama de classes do Server
Componente (Usando SOP)
VehicleGameServer
+addVehicle(VehicleModel)
+removeVehicle(VehicleModel)
+updatePosition(VehicleModel)
+run()
+initialize()
+initializeOidTo(VehicleModel)
+positionChanged(VehicleModel)
+vehicleAdded(VehicleModel)
+vehicleRemove(VehicleModel)
<<SOP>>
VehicleGameServerComponent
+setVehicleOid(VehicleModel)
+initialize()
+initializeOidTo(VehicleModel)
+run()
+positionChanged(VehicleModel)
+vehicleAdded(VehicleModel)
+vehicleRemoved(VehicleModel)
ServerNetwork
9-11
+sendBroadcast()
+startServer()
+send()
Diagrama de classes do
VehicleModel Componente (Usando
SOP)
10-11
Diagrama de componente do
Server
11-11
Código Component Game

public class Game {


public void run() {
GameThread t = new
GameThread(this, renderer);
t.setDaemon(true);
t.start();
}








network = ClientNetwork.instance;
network.connect("localhost", 65000);
network.startNetwork();
...
//initialize serializers
}


public void setMyVehicle(VehicleRender
myVehicle) {
network.send(0, METHODS.createVehicle,
new NetworkCommand(
NetworkCommand.CREATE));

}

public void removeVehicle(VehicleRender



myVehicle) {
this.myVehicle = myVehicle;
}



public void setMyVehicle(VehicleRender







//Component - SOP
public class Game {
public void run() {
}
....

vehicle) {
vehicles.remove(vehicle);
renderer.removeDrawable(vehicle);
public void removeVehicle(VehicleRender

vehicle) {
if (vehicle.getModel().getOid() ==
getMyVehicle().getModel().getOid()) {

network.send(0,
METHODS.deleteVehicle,
vehicle.getModel());
}

}
Código Componente
VehicleModel

public class VehicleModel {


public void move(int x, int y) {
this.position.move(x, y);
}






//Component - SOP
public class VehicleModel {
public void move(int x, int y) {
ClientNetwork network =
ClientNetwork.instance;
}




network.send(0,
METHODS.updatePosition, this);
}
}
Código Componente
GameServer

public class VehicleGameServer {


public void addVehicle(VehicleModel vehicle,
int connectionOwner){



clientsMap.put(connectionOwner,
vehicle);
for (Entry<Integer, VehicleModel> entry:
clientsMap.entrySet()) {
Integer connectionId = entry.getKey();
if (!connectionId.equals(connectionOwner)){


//Component - SOP
public class VehicleGameServer {
void vehicleAdded(VehicleModel
vehicle, Integer connectionId) {

network.send(connectionId, 0,

METHODS.vehicleAdded,
vehicle);
}

vehicleAdded(vehicle, connectionId);


vehicleAdded(entry.getValue(),
connectionOwner);
}

}





network.send(connectionId, 0,
METHODS.vehicleDeleted,
vehicle);
}


void vehicleRemoved(VehicleModel
vehicle, Integer connectionId) {
void vehicleAdded(VehicleModel vehicle, Integer
connectionId) {
// not implemente here
}



}
Código Componente
GameServer (cont.)

public void removeVehicle(VehicleModel vehicle,
int connectionOwner) {



clientsMap.remove(connectionOwner);

for (Entry<Integer, VehicleModel> entry:
clientsMap.entrySet()) {
vehicleRemoved(vehicle,

public void run() {
try {
network.startServer(65000);





entry.getKey());
}
}


void vehicleRemoved(VehicleModel vehicle,
Integer
key) {
// not implemente here
}


public void run() {

System.out.println("running");


}






} catch (IOException
e) {
}
.....

}
throw new RuntimeException(e);
}
.....
//other initialization related with network
}
Dificuldades Encontradas



Novo paradigma de programação
Ferramenta HyperJ sem código aberto
(apenas os bytecodes)
Algumas limitações da ferramenta HyperJ
como, geração automática de construtor
(protegidos) que não fazem parte da
aplicação, problemas de acesso a atributos
Java (AlgumaClasse.class), Enums, Innerclasses
Demonstração da Aplicação
Conclusões



Apesar das limitações da ferramenta HyperJ
foi possível realizar o trabalho com sucesso,
aplicando esse novo paradigma de
programação
HyperJ, atualmente é a única implementação
que suporta SOP em Java
Uma API bem definida torna fácil a evolução
e manutenção de aplicativos que usam SOP
Perguntas?
Download

final-presentation