Skins de CS:GO e Programação Orientada a Objetos
Certa feita tive a oportunidade de utilizar o grande mercado de skins de e-sports para escrever um texto explicando noções básicas de economia (How CS:GO skins market explains basic economics). Agora, reutilizando-me deste mesmo fenômeno, tentarei mostrar como essa modalidade de games online pode se relacionar com a Programação Orientada a Objetos.
Para isso tomaremos como base o jogo Counter-Strike: Global Offensive, pelo óbvio motivo de: é o melhor FPS de toda a Via Láctea (e região).
De forma bastante simplificada, podemos dizer que uma partida do jogo contém jogadores (que podem ser Terroristas ou Contra-terroristas) e armas (rifles, pistolas, facas, granadas etc.). Os jogadores escolhem suas armas e, juntos com seu time, vão matar os jogadores do outro time.
Nesse cenário, já pensando em POO, podemos enxergar tanto “Jogadores” quanto “Armas de fogo” como objetos, dado que são “entes” existentes no mundo (no jogo, neste caso), dotados de características (atributos) e realizam ações (métodos). Desse modo, para enxergarmos melhor como os universos CS:GO e POO se correlacionam, utilizaremos a linguagem de programação Java.
Ao iniciar o jogo, todas as armas com suas respectivas skins já estão dadas, já que isso depende do inventário do jogador. Portanto, para representar isso em Java, criamos a classe Skin (com um método “mostrarNome()”) e três exemplos de subclasses (“Redline”, “FuelInjector” e “Asiimov”), as quais evidentemente herdam o método da superclasse.
public class Asiimov extends Skin {@Override
public void mostrarNome() {System.out.println("A skin de sua escolha para esta partida foi: Asiimov\n");
}
}
No entanto as skins não se sustentam por si só. Para elas poderem existir, devem ser aplicadas em uma arma. Dessa forma, também criamos a classe ArmasDeFogo e as subclasses AK47, M4A4 e AWP, que herdam os atributos e métodos da classe mãe.
public abstract class ArmaDeFogo {private double preco;
private String nome;
private Skin skin;public double getPreco() {
return preco;
}public String getNome() {
return nome;
}public Skin getSkin() {
return skin;
}
}--------------------------------------------------------------------public class AK47 extends ArmaDeFogo {private final int quantidadeCarregadores = 3;
private int municoesPorCarregador = 30;
private final double preco = 2700;
private final String nome = "AK-47";
private Skin skin;public AK47(Skin skin) {
this.skin = skin;
}
…
}
Neste exemplo, temos a classe AK47, que em seu construtor recebe uma Skin como parâmetro. Dessa forma, conseguimos atrelar a criação de um objeto AK47 a uma skin, de modo que a arma, portanto, jamais fique sem pintura (mesmo a skin default é considerada uma skin).
Agora falta o jogador. Para representá-lo, criamos a classe Jogador (com os atributos “nickname”, “dinheiroAtual” e “armaDeFogo”), a qual contém o método “comprarArmaDeFogo()”. Aqui também temos subclasses: Terrorista e Contra-terrorista, sendo que aqueles possuem o atributo booleano “temC4” e estes o atributo booleano “temDefuseKit”.
public class Terrorista extends Jogador {private boolean temC4;public Terrorista(String nickname, double dinheiroAtual, boolean temC4, ArmaDeFogo armaDeFogo) {
super(nickname, dinheiroAtual, armaDeFogo);
this.setTemC4(temC4);
}@Override
public void comprarArmaDeFogo() {
ArmaDeFogo armaDeFogo = this.getArmaDeFogo();super.setDinheiroAtual(super.getDinheiroAtual() - armaDeFogo.getPreco());System.out.print("O Terrorista " + super.getNickname() + " comprou uma " + armaDeFogo.getNome() + ". ");
}
}
Vimos que para criarmos uma arma precisamos antes ter criado uma skin. No caso da criação do Jogador, vemos agora uma situação semelhante: para criá-lo, devemos antes ter criado uma arma — dado que todo jogador, ao entrar numa partida, já possui um inventário com todas as armas e suas respectivas skins. Essa relação é mostrada no construtor da classe Jogador, que exige um parâmetro ArmaDeFogo.
Agora que temos todas as classes do projeto implementadas, podemos iniciar uma partida e ver como a coisa funciona. Para isso temos a classe Partida, que contém o método “main()”.
public class Partida {public static void main(String[] args) {Skin redline = new Redline();
Skin asiimov = new Asiimov();
Skin fuelInjector = new FuelInjector();AK47 ak1 = new AK47(redline);
AK47 ak2 = new AK47(asiimov);
AK47 ak3 = new AK47(fuelInjector);
M4A4 m41 = new M4A4(asiimov);
AWP awp1 = new AWP(asiimov);
AWP awp2 = new AWP(redline);Terrorista t1 = new Terrorista("'FalleN'", 5000, true, ak1);
Terrorista t2 = new Terrorista("'coldzera'", 8600, false, ak2);
Terrorista t3 = new Terrorista("'gla1ve'", 6200, false, awp1);
Terrorista t4 = new Terrorista("'valde'", 7800, false, ak3);
ContraTerrorista ct1 = new ContraTerrorista("'s1mple'", 16000, false, awp2);
ContraTerrorista ct2 = new ContraTerrorista("'olofmeister'", 5000, true, m41);t1.comprarArmaDeFogo();
t1.getArmaDeFogo().getSkin().mostrarNome();t2.comprarArmaDeFogo();
t2.getArmaDeFogo().getSkin().mostrarNome();t3.comprarArmaDeFogo();
t3.getArmaDeFogo().getSkin().mostrarNome();t4.comprarArmaDeFogo();
t4.getArmaDeFogo().getSkin().mostrarNome();ct1.comprarArmaDeFogo();
ct1.getArmaDeFogo().getSkin().mostrarNome();ct2.comprarArmaDeFogo();
ct2.getArmaDeFogo().getSkin().mostrarNome();System.out.println("O Terrorista 1 está com a C4? " + t1.isTemC4());System.out.println("\nO Contra-terrorista 1 possui Defuse Kit? " + ct1.isTemDefuseKit());System.out.println("\nQual a quantidade de carregadores de uma AK-47? " + ak1.getQuantidadeCarregadores());System.out.println("\nQuantas munições por carregador possui uma M4A4? " + m41.getMunicoesPorCarregador());System.out.println("\nQual o preço de uma AWP? " + awp1.getPreco());System.out.println("\nCom quanto de dinheiro ficou o Terrorista 2 após comprar sua arma? " + t2.getDinheiroAtual());System.out.println("\nQual o nickname do Contra-terrorista 2? " + ct2.getNickname());
}
}
Ao executarmos esse programa Java, temos o seguinte resultado:
O Terrorista ‘FalleN’ comprou uma AK-47. A skin de sua escolha para esta partida foi: Redline.
O Terrorista ‘coldzera’ comprou uma AK-47. A skin de sua escolha para esta partida foi: Asiimov.
O Terrorista ‘gla1ve’ comprou uma AWP. A skin de sua escolha para esta partida foi: Asiimov.
O Terrorista ‘valde’ comprou uma AK-47. A skin de sua escolha para esta partida foi: Fuel Injector.
O Contra-terrorista ‘s1mple’ comprou uma AWP. A skin de sua escolha para esta partida foi: Redline.
O Contra-terrorista ‘olofmeister’ comprou uma M4A4. A skin de sua escolha para esta partida foi: Asiimov.
O Terrorista 1 está com a C4? true
O Contra-terrorista 1 possui Defuse Kit? false
Qual a quantidade de carregadores de uma AK-47? 3
Quantas munições por carregador possui uma M4A4? 30
Qual o preço de uma AWP? 4750.0
Com quanto de dinheiro ficou o Terrorista 2 após comprar sua arma? 5900.0
Qual o nickname do Contra-terrorista 2? ‘olofmeister’
Nesse programa podemos perceber algumas coisas. Como dissemos acima, para criarmos uma arma, precisamos de uma skin. Somado a isso, para que um jogador compre uma arma, evidentemente essa arma já deve ter sido criada.
Além disso, podemos notar que uma mesma skin pode ser aplicada em armas diferentes — como é o caso da Asiimov, que existe nos três rifles — e também que armas do mesmo tipo podem ter diferentes skins.
Outra coisa perceptível é o fato de que uma arma, após ter sido criada, permanecerá com sua skin durante toda a partida, visto que não é possível fazer esse tipo de alteração (a definição da skin está restrita ao construtor). Sendo assim, se um jogador entra numa partida com uma arma que tem uma determinada skin, toda compra dessa arma realizada por ele ao longo da partida terá apenas essa skin até o fim.
Nesse simples programa foi possível expor como os conceitos-chave da POO se encaixam em um dos e-sports mais jogados no mundo todo. Utilizamos encapsulamento, polimorfismo e herança e, com isso, pudemos criar nossos objetos da forma desejada, respeitando as regras do jogo.
Assim sendo, pudemos compreender melhor como e por que um jogador pode ter skins diferentes para a mesma arma ou para diversas armas, ter a mesma skin para armas diferentes e também por qual motivo ele poderá equipar somente uma skin de determinada arma por partida.
Siga-me no LinkedIn.