190 likes | 296 Views
SOP aplicado em um jogo tipo de corrida usando a arquitetura cliente e servidor. Alisson Rafael Appio alisson.appio@gmail.com. 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
E N D
SOP aplicado em um jogo tipo de corrida usando a arquitetura cliente e servidor Alisson Rafael Appio alisson.appio@gmail.com
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 suportede 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 VehicleModel Componente (Usando SOP) 10-11
public class Game { public void run() { GameThread t = new GameThread(this, renderer); t.setDaemon(true); t.start(); } public void setMyVehicle(VehicleRender myVehicle) { this.myVehicle = myVehicle; } public void removeVehicle(VehicleRender vehicle) { vehicles.remove(vehicle); renderer.removeDrawable(vehicle); } .... } //Component - SOP public class Game { public void run() { 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 vehicle) { if (vehicle.getModel().getOid() == getMyVehicle().getModel().getOid()) { network.send(0, METHODS.deleteVehicle, vehicle.getModel()); } } } Código Component Game
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 VehicleModel
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)){ vehicleAdded(vehicle, connectionId); vehicleAdded(entry.getValue(), connectionOwner); } } } void vehicleAdded(VehicleModel vehicle, Integer connectionId) { // not implemente here } //Component - SOP public class VehicleGameServer { void vehicleAdded(VehicleModel vehicle, Integer connectionId) { network.send(connectionId, 0, METHODS.vehicleAdded, vehicle); } void vehicleRemoved(VehicleModel vehicle, Integer connectionId) { network.send(connectionId, 0, METHODS.vehicleDeleted, vehicle); } Código Componente GameServer
public void removeVehicle(VehicleModel vehicle, int connectionOwner) { clientsMap.remove(connectionOwner); for (Entry<Integer, VehicleModel> entry: clientsMap.entrySet()) { vehicleRemoved(vehicle, entry.getKey()); } } void vehicleRemoved(VehicleModel vehicle, Integer key) { // not implemente here } public void run() { System.out.println("running"); } ..... } public void run() { try { network.startServer(65000); } catch (IOException e) { throw new RuntimeException(e); } ..... //other initialization related with network } } Código Componente GameServer (cont.)
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, Inner-classes
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