Antecedentes
Já faz um bom tempo desde a redação do
artigo anterior. Como prometido, escrevi a segunda parte. Gostaria de agradecer a todos que deram conselhos nos comentários, de todos eles pude aprender algo novo. Bem, para quem deseja ver o projeto imediatamente,
aqui está um link para o projeto GitHub.
Quero apenas observar que tudo o que foi adicionado e alterado nesta versão foi feito com muito
muito trabalho, muitos erros. Meu Google foi preenchido com um grande número de solicitações, desde os recursos da implementação do MVP até métodos assíncronos.

Atualizações
- Adicionado seu próprio editor de mapas (como no jogo original).
- Sirene implementada.
- Adicionada a capacidade de capturar o donk e girar.
- Adicionado muitos tipos de peixe.
- Melhorou muito o desempenho do projeto.
- Corrigido um grande número de bugs.
- Além disso, uma melhoria significativa na arquitetura do aplicativo (mais precisamente, sua aparência).
- Adicionado salvando o perfil do jogador.
- Troféus realizados.
- Adicionado uma mudança de dia e noite.
- Viagem adicionada.
- Implementou uma mercearia.
- Implementado o padrão MVP.
- Implementou um sistema de eventos no jogo
- Isca implementada, com a capacidade de misturar ingredientes
- Atuação por voz adicionada
- Animações adicionadas
- O desgaste das varas é implementado, dependendo do tamanho do peixe e do tempo de sobrevivência
Adicionarei mais alterações ao arquivo de projeto README Git.
Como o código de outra pessoa enganou.

Vemos na captura de tela o editor de mapas para pescar, ou seja, a grade de profundidade para cada local (estes são os elementos Label com FormBorderStyle = 0, para mostrar o quadro). A propósito, a captura de tela foi feita usando minha própria
tesoura. Qual foi o problema?
Código fontefor (int x = 0; x < 51; x++){ for (int y = 0; y < 18; y++){ Point between = new Point(Game.CastPoint.X - LVL.Deeparr[x, y].Location.X, Game.CastPoint.Y - LVL.Deeparr[x, y].Location.Y); float distance = (float)Math.Sqrt(between.X * between.X + between.Y * between.Y); if (distance < 20){ if (Player.getPlayer().lure != null){ Game.gui.DeepLabel.Text = LVL.Deeparr[x, y].Tag.ToString(); Sounder.setY(x); Sounder.setX(y); } } Game.Deep = Convert.ToInt32(Game.gui.DeepLabel.Text); } }
Aqui vemos uma passagem simples através de uma matriz bidimensional (e não a correta). Então calculamos a hipotenusa pelo teorema de Pitágoras e, se for <20, determinamos a célula desejada. Mas esse método funciona muito mal, mesmo com um quadrado. E aqui estão os retângulos. Portanto, a célula é frequentemente detectada incorretamente. Em minha defesa, posso dizer que peguei esse código do YouTube.
Portanto, precisamos determinar em qual célula o cursor está. Para fazer isso, você pode usar este código-fonte:
Código for (var y = 0; y < CurLvl.Height; y++) { for (var x = 0; x < CurLvl.Widgth; x++) { var r = new Rectangle(CurLvl.DeepArray[x, y].Location, new System.Drawing.Size(LabelInfo.Width, LabelInfo.Height)); if (r.IntersectsWith(new Rectangle(point, new System.Drawing.Size(1, 1)))) { //SomeCode } } }
Aqui, pegamos as coordenadas do cursor, colamos em um PointToClient e passamos para o construtor Rectangle, especificamos os tamanhos 1 e 1. Em seguida, usamos o método de verificação padrão IntersectsWith, interseção do cursor e rótulo. Além disso, não podemos apenas processar um clique em um rótulo, pois um formulário com eles não é exibido.
Além disso, permitiu implementar suporte para 3 varas de pesca.
Geração de peixes
Então, a parte principal do jogo é a geração de peixes. Ocorre em várias etapas:
1. Ao entrar no local, somos de uma linha como:
Peixe dourado: 25 250-400 [Queijo, Verme, Larva, Milho] Onde está o tamanho do peixe como uma porcentagem do máximo, da profundidade mínima, da profundidade máxima e de uma lista de iscas para obter o objeto de peixe (não se esqueça de verificar previamente a linha através de expressões regulares). Pela beleza do código, defini um operador que lança uma string para pescar.
public static explicit operator Fish(FishString fs) { return fs.GetFishByStr(); }
Como resultado, essa abordagem nos permite escrever:
Fish fish = (Fish)new FishString(" : 25 250 - 400 [ , , , ]");
O código é dado como exemplo e não é encontrado no projeto neste formulário.
2.Agora, precisamos aguardar o lançamento das varas de pescar; depois disso, iniciaremos o cronômetro (próprio para cada vara de pescar) com um tempo de mordida aleatória; em seguida, seguiremos o tiquetaque do cronômetro da nossa lista de peixes com tamanhos de 1000 unidades, selecionar peixes cuja profundidade do habitat inclua profundidade varas de pesca.
3. Nesta lista, selecione aleatoriamente um peixe. Verificamos se a isca definida pode ser consumida e também se a hora do dia da atividade do peixe corresponde à hora atual do jogo.
4. Se o peixe pode comer a isca, atacamos a isca. Calculamos se haverá uma descida e depois de que horas, com base na chance da descida do gancho instalado. Se o peixe não puder comer a isca, então percorreremos a isca atual (se houver). Verificamos se há algum peixe por perto que possa bicar a isca e repetimos a mesma coisa.
Graças ao processo de geração, me tornei um usuário LINQ confiante.
Jogo em si

Captura de tela da mercearia.
Sua fonte pode ser visualizada no repositório. Lá, os manipuladores MouseEnter e MouseLeft para modificar imagens de alimentos são executados de maneira bastante interessante.

Captura de tela do formulário de viagem. (Todos os corpos d'água são testados e seus nomes não são genuínos.)

Captura de tela do jogo
Planos
- Crie um servidor cliente para o jogo
- Desenvolvedor Júnior FPGA (FPGA)
- Reconhecimento de rosto via webcam (estou procurando literatura que possa ser útil)
- Substituindo um ListView regular por um ObjectListView
No final do artigo anterior, escrevi que queria conseguir um emprego. Bem, em setembro, fechei meu primeiro TOR pelo SNMP, embora em C.
Conclusão
O projeto tornou-se bastante amplo, com pelo menos uma base de código ideal, mas muito decente, conveniente de manter.Em algum lugar os princípios do SOLID podem ser violados, mas isso se deve ao fato de o projeto ter sido muito longo. Além disso, se você é um desenvolvedor iniciante e procura um projeto no qual possa participar, pode fazer confirmações neste repositório. A lista de alterações esperadas pode ser encontrada no arquivo README do projeto.
Também gostaria de observar que não vejo perspectivas na carreira de desenvolvedor de C #, ou melhor, gostaria de algo mais próximo do hardware, por isso tento estudar linguagens de nível inferior.
Obrigado a todos que leram até o final, qualquer crítica ao código-fonte é bem-vinda e será considerada imediatamente.