Antecedentes
Ha pasado bastante tiempo desde la redacción del
artículo anterior. Como prometí, escribí la segunda parte. Me gustaría agradecer a todos los que dieron consejos en los comentarios, de todos ellos pude aprender algo nuevo. Bueno, para aquellos que desean ver el proyecto de inmediato,
aquí hay un enlace al proyecto GitHub.
Solo quiero señalar que todo lo que se agregó y cambió en esta versión se hizo con un muy
mucho trabajo, muchos errores. Mi Google se llenó con una gran cantidad de solicitudes, que van desde las características de la implementación de MVP hasta métodos asincrónicos.

Actualizaciones
- Agregó su propio editor de mapas (como en el juego original).
- Sonda implementada.
- Se agregó la capacidad de atrapar al donk y al girar.
- Se agregaron muchos tipos de peces.
- Gran rendimiento del proyecto mejorado.
- Se corrigió una gran cantidad de errores.
- Además, una mejora significativa en la arquitectura de la aplicación (más precisamente, su apariencia).
- Se agregó el perfil del jugador para guardar.
- Trofeos realizados.
- Se agregó un cambio de día y de noche.
- Viaje agregado.
- Implementé una tienda de abarrotes.
- Implementado el patrón MVP.
- Implementado un sistema de eventos en el juego.
- Cebo implementado, con la capacidad de mezclar ingredientes
- Actuación de voz agregada
- Animaciones agregadas
- Se implementa el desgaste de las varillas, dependiendo del tamaño del pez y el tiempo de supervivencia.
Agregaré más cambios al archivo de proyecto README Git.
Cómo se equivocó el código de otra persona.

Vemos en la captura de pantalla el editor de mapas para la pesca, es decir, la cuadrícula de profundidad para cada ubicación (estos son elementos de etiqueta con FormBorderStyle = 0, para mostrar el marco). Por cierto, la captura de pantalla se realizó con mis propias
tijeras. Cual era el problema
Código fuentefor (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); } }
Aquí vemos un paso simple a través de una matriz bidimensional (y no la correcta). Luego calculamos la hipotenusa por el teorema de Pitágoras, y si es <20, determinamos la celda deseada. Pero este método funciona muy mal incluso con un cuadrado. Y aquí están los rectángulos. Por lo tanto, la célula a menudo se detecta incorrectamente. En mi defensa, puedo decir que tomé este código de YouTube.
Entonces, necesitamos determinar en qué celda está el cursor. Para hacer esto, puede usar este código fuente:
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 } } }
Aquí tomamos las coordenadas del cursor, las pegamos en un PointToClient y las pasamos al constructor Rectangle, especificamos los tamaños 1 y 1. Luego usamos el método de verificación IntersectsWith estándar, la intersección del cursor y la etiqueta. Además, no podemos procesar simplemente un clic en una etiqueta, ya que no se muestra un formulario con ellos.
Además, permitió implementar soporte para 3 cañas de pescar.
Generación de peces
Entonces, la parte principal del juego es la generación de peces. Ocurre en varias etapas:
1. Al ingresar a la ubicación, somos de una línea como:
Goldfish: 25 250-400 [Queso, Gusano, Gusano, Maíz] ¿Dónde está el tamaño del pez como porcentaje del máximo, la profundidad mínima, la profundidad máxima y una lista de cebo para obtener el objeto de pez (No olvide comprobar previamente la línea a través de expresiones regulares). Por la belleza del código, definí un operador que lanza una cadena para pescar.
public static explicit operator Fish(FishString fs) { return fs.GetFishByStr(); }
Como resultado, este enfoque nos permite escribir:
Fish fish = (Fish)new FishString(" : 25 250 - 400 [ , , , ]");
El código se proporciona como ejemplo y no se encuentra en el proyecto en este formulario.
2.Ahora tenemos que esperar a que se arrojen las cañas de pescar, después de eso comenzamos el temporizador (el nuestro para cada caña de pescar) con un tiempo de mordida aleatorio, luego seguimos el tictac del temporizador de nuestra lista de peces con tamaños de 1000 unidades, seleccionamos peces cuya profundidad de hábitat incluye profundidad Cañas de pescar.
3. De esta lista, seleccione al azar un pez. Verificamos si se puede comer el cebo establecido y también que la hora del día de la actividad del pez corresponde a la hora actual del juego.
4. Si el pez puede comer el cebo, atacaremos el cebo. Calculamos si habrá un descenso y después de qué hora, en función de la posibilidad del descenso del gancho instalado. Si el pez no puede comer el cebo, entonces pasamos por el cebo actual (si lo hay). Verificamos si hay un pez cercano que pueda picotear el cebo, y repetimos lo mismo.
Gracias al proceso de generación, me he convertido en un usuario seguro de LINQ.
Juego en sí

Captura de pantalla de la tienda de comestibles.
Su fuente se puede ver en el repositorio. Allí, los controladores MouseEnter y MouseLeft para modificar imágenes de alimentos se ejecutan de manera bastante interesante.

Captura de pantalla del formulario de viaje. (Todos los cuerpos de agua son de prueba y sus nombres no son genuinos).

Captura de pantalla del juego
Planes
- Crea un servidor cliente para el juego
- Desarrollador Junior FPGA (FPGA)
- Reconocimiento facial a través de la cámara web (estoy buscando literatura que pueda ser útil)
- Reemplazar un ListView normal con un ObjectListView
Al final del artículo anterior, escribí que quiero conseguir un trabajo. Bueno, en septiembre, cerré mi primer TOR por SNMP, aunque en C.
Conclusión
El proyecto se ha vuelto bastante grande, con al menos una base de código ideal, pero muy decente, conveniente de mantener. En algún lugar se pueden violar los principios de SOLID, pero esto se debe al hecho de que el proyecto fue muy largo. Además, si usted es un desarrollador principiante y está buscando un proyecto en el que pueda participar, puede comprometerse con este repositorio. La lista de cambios esperados se puede encontrar en el archivo README del proyecto.
También me gustaría señalar que no veo ninguna perspectiva en la carrera de desarrollador de C #, o más bien me gustaría algo más cercano al hardware, por lo que trato de estudiar idiomas de nivel inferior.
Gracias a todos los que leyeron hasta el final, cualquier crítica al código fuente es bienvenida y será considerada de inmediato.