A continuación se listan consejos y tips propuestos en base a lo entregado como avance para la T02. No duden en comentar dudas o postear issues con dudas relacionadas a esta. Pueden etiquetar issues al usar el signo gato (#) y el número de la issue.
Recuerden que el objetivo del avance de la tarea que se les pide no solo significa tener 2 décimas extras por hacer una entrega, sino que es una ayuda y oportunidad para que puedan pensar y modelar el problema planteado con anticipación. Así les resultará más fácil comenzar con el código de su programa.
Tips generales
Cuando tengan dudas en cuanto al uso de clases y funciones de PyQt5, se recomienda encarecidamente revisar los siguientes links, correspondientes a documentación:
Para la colisión con los bordes de la ventana, usen PyQt para sacar las medidas de esta o fíjenlas como constantes (en el archivo) en lugar de “harcodear” sus dimensiones en todo el código, ya que es mala práctica, hace el código más difícil de mantener y trabajar en él.
Para la entrega final, recuerden que tanto los enemigos como el personaje que manejan deben tener una animación de movimiento acorde a la dirección a la que se dirigen (ej. que el monito mire para la derecha cuando te mueves a dicha dirección).
No dejen la tarea para última hora, la tarea evalúa muchas cosas que requieren de testeos para poder ser realizadas correctamente. Como recomendación, si tienen alguna ventana o break, avancen con la tarea aunque sea unos detalles, no esperen que queden pocos días.
Recuerda utilizar variables descriptivas para tu código. Te servirá para cuando tengas que corregir tu código y facilita la corrección.
Cuidado con definir clases que solo guarden atributos (la namedtuple les puede ayudar para esto), la idea es que definan clases que en verdad les ayuden a ordenar todas las funcionalidades que tienen que hacer, por ejemplo una clase de Jugador que tenga atributos de posición y un método que controle el movimiento estaría bien implementado, en cambio no sería correcto del todo tener una clase Posición que solo almacena la posición y una clase Jugador que tenga como atributo una instancia de clase Posición. En general, las clases toman más sentido cuando modelan algo con comportamiento (es decir, con métodos). Si solo almacenan atributos, no es tan necesario crear una clase completa, hay estructuras más simples que sirven el mismo proposito:namedtupleydict`.
Tengan en cuenta los tips que aparecen en el enunciado, estos pueden ser de mucha utilidad para guiarlos en la tarea. Por ejemplo los QRect son una buena forma de revisar colisiones sin tener que crear un código más complejo.
Cuidado con las colisiones del personaje, fijense en que cuando colisione con algún objeto después pueda seguir moviéndose cuando deje de colisionar.
Recuerden que para la entrega final el movimiento del personaje debe ser continuo y el de los enemigos discreto. Varios programaron ambos movimientos de forma discreta.
Recuerden que la velocidad de un personaje continuo se puede modelar sumando una cantidad de pixeles dada (y modificable desde parametros.py) por cada tick que mantenemos una tecla apretada.
Recuerden que la velocidad de los enemigos discretos se puede considerar como el tiempo que se demoran en avanzar un cuadrado en vez de cuadrados que se avanzan por segundo.
TipsBack-end versus Front-end
En lo revisado, no existe una diferencia clara entre front-end y back-end, habiendo módulos distintos que mezclan las funciones de ambos.
En general, es bueno tener una clara distinción entre tus archivos de front-end y back-end. Cuida, al menos, de especificar cuáles son los archivos correspondientes a tu front-end y cuáles a tu back-end en tu Readme para la entrega final. Revisa que los archivos además tengan una separación coherente y consistente.
Recuerden hacer uso de señales para la comunicación entre el back-end y el front-end, ya que es evaluado en esta tarea.
En lo posible, trata de mantener en distintos archivos todo lo que esté relacionado con el back-end y el front-end. Esto es mucho mejor que mantenerlo todo en un único archivo main, ya que tendrás un código más legible, lo cual te servirá mucho al avanzar más en la tarea. Además, tendrás la facilidad de poder trabajar front-end o back-end por separado, sin preocuparte que cambiar uno afecte demasiado al otro.
Tips manejo de sprites
La base tiene un tamaño de 2x2, por lo tanto hay que asegurarse que el sprite tenga ese tamaño y que no se corte en 4 imágenes de una esquina.
Tips formato de entrega - evitar descuentos
Tip al cargar archivos, tanto de mapa como de sprites: En vez de escribir la ruta como “path/a/tu/archivo.txt”, por ejemplo, usen de la librería os, os.path.join(“path”, “a”, “tu”, “archivo.txt”). ¡No todos los SO’s utilizan el /!
No utilicen referencias absolutas para acceder a los sprites, ya que al momento de probar sus tareas, los archivos no podrán ser ubicados correctamente.
Recordar el .gitignore y no subir los archivos de sprites ni mapa, a menos de que hayan agregado los suyos propios.
Nuevamente, cuidado con el cumplimiento de PEP8. Sobretodo en lo que concierne a la máxima cantidad de caracteres permitidos en una línea (los espacios de indentación también cuentan!). Revisen la guía de Descuentos.md para estar conscientes de todos los detalles que puedan perjudicar al momento de no cumplirlas.
Revisen con cuidado el tema de la referencia circular, como en caso de entregarle a una clase hija A la instancia de la clase padre B como parámetro en su método __init__. Una de las razones principales de por qué se debe evitar la referencia circular es debido a que se genera una relación de alto acoplamiento entre A y B; esto es, cada vez que una clase se ve afectada tu programa tiene que recompilar a ambas en lugar de a una, generando problemas de desempeño o performance cuando tu programa es grande o se generan muchas instancias de alguna de las clases que sufren cambios en lapsos cortos de tiempo. Además, la legibilidad de tu código se ve afectada cuando este presenta varias referencias circulares entre todas tus clases (conocido también como código spaghetti, te imaginarás a qué se viene el nombre y espero que no lleguen a eso); asimismo, se dará que tengas que hacerle mantenimiento a tu código de forma paralela entre ambas clases para que tu programa siga funcionando como deseas. Puedes revisar la issue https://github.com/IIC2233/syllabus/issues/275 en donde se hace mención de modelación circular, o las respuestas de esta issue en stack exchange para más información respecto a por qué es una mala práctica.
Recuerden indicar qué archivo es el ejecutable. Si bien no lo pedíamos explícitamente en el avance, es de gran ayuda para los correctores saber de partida cuál archivo tiene que ejecutar para correr su programa.
Sugerencias para un mejor juego
Algo que pasa mucho al usar los keyPressEvent es que cuando mantenemos apretada la tecla y cambiamos, pareciera que el personaje se demora en efectuar el movimiento, como si tuviera una especie de lag. Esto pasa por como el teclado maneja el hecho de mantener una tecla apretada. Lo que hace el teclado es interpretarlo como muchos keyPressEvent con cierto intervalo de tiempo (predeterminado) entre estos. Una forma de hacer que el personaje se mueva más fluido es agregando un bool que nos diga si la tecla está apretada en ese momento o no. Esto evita la necesidad de que el programa interprete como muchos keyPressEvent cuando mantenemos una tecla, y solo hay que preocuparse del primer keyPressEvent y del keyReleaseEvent.
Feedback Avance T02 :star: :bug:
A continuación se listan consejos y tips propuestos en base a lo entregado como avance para la T02. No duden en comentar dudas o postear issues con dudas relacionadas a esta. Pueden etiquetar issues al usar el signo gato (#) y el número de la issue.
Recuerden que el objetivo del avance de la tarea que se les pide no solo significa tener 2 décimas extras por hacer una entrega, sino que es una ayuda y oportunidad para que puedan pensar y modelar el problema planteado con anticipación. Así les resultará más fácil comenzar con el código de su programa.
Tips generales
Cuando tengan dudas en cuanto al uso de clases y funciones de PyQt5, se recomienda encarecidamente revisar los siguientes links, correspondientes a documentación:
Para la colisión con los bordes de la ventana, usen PyQt para sacar las medidas de esta o fíjenlas como constantes (en el archivo) en lugar de “harcodear” sus dimensiones en todo el código, ya que es mala práctica, hace el código más difícil de mantener y trabajar en él.
Para la entrega final, recuerden que tanto los enemigos como el personaje que manejan deben tener una animación de movimiento acorde a la dirección a la que se dirigen (ej. que el monito mire para la derecha cuando te mueves a dicha dirección).
No dejen la tarea para última hora, la tarea evalúa muchas cosas que requieren de testeos para poder ser realizadas correctamente. Como recomendación, si tienen alguna ventana o break, avancen con la tarea aunque sea unos detalles, no esperen que queden pocos días.
Recuerda utilizar variables descriptivas para tu código. Te servirá para cuando tengas que corregir tu código y facilita la corrección.
Cuidado con definir clases que solo guarden atributos (la
namedtuple
les puede ayudar para esto), la idea es que definan clases que en verdad les ayuden a ordenar todas las funcionalidades que tienen que hacer, por ejemplo una clase deJugador
que tenga atributos de posición y un método que controle el movimiento estaría bien implementado, en cambio no sería correcto del todo tener una clasePosición
que solo almacena la posición y una claseJugador
que tenga como atributo una instancia de clasePosición. En general, las clases toman más sentido cuando modelan algo con comportamiento (es decir, con métodos). Si solo almacenan atributos, no es tan necesario crear una clase completa, hay estructuras más simples que sirven el mismo proposito:
namedtupley
dict`.Tengan en cuenta los tips que aparecen en el enunciado, estos pueden ser de mucha utilidad para guiarlos en la tarea. Por ejemplo los
QRect
son una buena forma de revisar colisiones sin tener que crear un código más complejo.Cuidado con las colisiones del personaje, fijense en que cuando colisione con algún objeto después pueda seguir moviéndose cuando deje de colisionar.
Recuerden que para la entrega final el movimiento del personaje debe ser continuo y el de los enemigos discreto. Varios programaron ambos movimientos de forma discreta.
Recuerden que la velocidad de un personaje continuo se puede modelar sumando una cantidad de pixeles dada (y modificable desde
parametros.py
) por cada tick que mantenemos una tecla apretada.Recuerden que la velocidad de los enemigos discretos se puede considerar como el tiempo que se demoran en avanzar un cuadrado en vez de cuadrados que se avanzan por segundo.
Tips Back-end versus Front-end
En lo revisado, no existe una diferencia clara entre front-end y back-end, habiendo módulos distintos que mezclan las funciones de ambos.
En general, es bueno tener una clara distinción entre tus archivos de front-end y back-end. Cuida, al menos, de especificar cuáles son los archivos correspondientes a tu front-end y cuáles a tu back-end en tu Readme para la entrega final. Revisa que los archivos además tengan una separación coherente y consistente.
Recuerden hacer uso de señales para la comunicación entre el back-end y el front-end, ya que es evaluado en esta tarea.
En lo posible, trata de mantener en distintos archivos todo lo que esté relacionado con el back-end y el front-end. Esto es mucho mejor que mantenerlo todo en un único archivo
main
, ya que tendrás un código más legible, lo cual te servirá mucho al avanzar más en la tarea. Además, tendrás la facilidad de poder trabajar front-end o back-end por separado, sin preocuparte que cambiar uno afecte demasiado al otro.Tips manejo de sprites
Tips formato de entrega - evitar descuentos
Tip al cargar archivos, tanto de mapa como de sprites: En vez de escribir la ruta como “path/a/tu/archivo.txt”, por ejemplo, usen de la librería os,
os.path.join(“path”, “a”, “tu”, “archivo.txt”)
. ¡No todos los SO’s utilizan el/
!No utilicen referencias absolutas para acceder a los sprites, ya que al momento de probar sus tareas, los archivos no podrán ser ubicados correctamente.
Recordar el
.gitignore
y no subir los archivos de sprites ni mapa, a menos de que hayan agregado los suyos propios.Nuevamente, cuidado con el cumplimiento de PEP8. Sobretodo en lo que concierne a la máxima cantidad de caracteres permitidos en una línea (los espacios de indentación también cuentan!). Revisen la guía de Descuentos.md para estar conscientes de todos los detalles que puedan perjudicar al momento de no cumplirlas.
Revisen con cuidado el tema de la referencia circular, como en caso de entregarle a una clase hija
A
la instancia de la clase padreB
como parámetro en su método__init__
. Una de las razones principales de por qué se debe evitar la referencia circular es debido a que se genera una relación de alto acoplamiento entreA
yB
; esto es, cada vez que una clase se ve afectada tu programa tiene que recompilar a ambas en lugar de a una, generando problemas de desempeño o performance cuando tu programa es grande o se generan muchas instancias de alguna de las clases que sufren cambios en lapsos cortos de tiempo. Además, la legibilidad de tu código se ve afectada cuando este presenta varias referencias circulares entre todas tus clases (conocido también como código spaghetti, te imaginarás a qué se viene el nombre y espero que no lleguen a eso); asimismo, se dará que tengas que hacerle mantenimiento a tu código de forma paralela entre ambas clases para que tu programa siga funcionando como deseas. Puedes revisar la issue https://github.com/IIC2233/syllabus/issues/275 en donde se hace mención de modelación circular, o las respuestas de esta issue en stack exchange para más información respecto a por qué es una mala práctica.Recuerden indicar qué archivo es el ejecutable. Si bien no lo pedíamos explícitamente en el avance, es de gran ayuda para los correctores saber de partida cuál archivo tiene que ejecutar para correr su programa.
Sugerencias para un mejor juego
keyPressEvent
es que cuando mantenemos apretada la tecla y cambiamos, pareciera que el personaje se demora en efectuar el movimiento, como si tuviera una especie de lag. Esto pasa por como el teclado maneja el hecho de mantener una tecla apretada. Lo que hace el teclado es interpretarlo como muchoskeyPressEvent
con cierto intervalo de tiempo (predeterminado) entre estos. Una forma de hacer que el personaje se mueva más fluido es agregando un bool que nos diga si la tecla está apretada en ese momento o no. Esto evita la necesidad de que el programa interprete como muchoskeyPressEvent
cuando mantenemos una tecla, y solo hay que preocuparse del primerkeyPressEvent
y delkeyReleaseEvent
.