Karoshi MSX Community
05 de Julio de 2021, 03:37:14 pm *
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.

Ingresar con nombre de usuario, contraseña y duración de la sesión
Noticias:
 
   Inicio   Ayuda Buscar Ingresar Registrarse  
Páginas: [1]
  Imprimir  
Autor Tema: BASIC y bit de colisión de sprites  (Leído 3788 veces)
0 Usuarios y 1 Visitante están viendo este tema.
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« : 03 de Noviembre de 2011, 10:26:27 pm »

¡Hola!

Estaba optimizando el código de Pérez the Mouse. Había conseguido una mejora de rendimiento suficientemente alta como para permitirme poner un segundo sprite para el ratón y los enemigos. Después de diseñarlos, añadirlos al código, etc. todo funciona maravillosamente bien: tengo tres sprites dobles moviéndose por la pantalla, se ve de lujo y no se detecta colisión ninguna mientras no te pille ningún enemigo (es decir, los sprites están bien diseñados y no se solapan enrte ellos). No utilizo ON SPRITE; las colisiones las miro, una vez actualizados todos los sprites, con VDP(8 ) AND &H20

El problema es que a partir de determinado punto (concretamente, al entregar una moneda, que se oculta dicho sprite en la línea $D1), se empiezan a detectar colisiones aleatoriamente y no entiendo por qué.
Al principio pensaba que era que los sprites en la $D0/$D1 podían colisionar entre ellos... pero eso no tendría sentido porque me hubiera pasado con la versión anterior del programa (la de 1 sprite por personaje). Estuve mirando todos los valores de la tabla de atributos de sprites a ver si veía algo raro... pero nada. Al final puse un bucle infinito después de la primera detección y ¡bingo! Si me encuentro con un malo (colisión real) el bucle infinito permanece (el bit está siempre a 1)... pero en las colisiones ficticias pasa de 1 a 0 sin que se mueva ningún sprite.

Sabiendo eso, he conseguido filtrar dichas colisiones ficticias metiendo un pequeño retardo y volviendo a comprobar (nota: el cambio de color de fondo es simplemente para ver cuándo va detectando falsas colisiones)...
IF (VDP(8 ) AND &H20) THEN FOR I=0TO9:NEXT:COLOR ,,PEEK(&HF3EB) XOR 15:IF (VDP(8 ) AND &H20) THEN COLISION
...pero me parece "poco serio"; el 9 es el mínimo con el que he conseguido completar una pantalla de juego sin que diera una falsa colisión, pero nada me asegura que en otra partida ese valor no se quede corto. Y además mete un retardo aleatorio que, cuando da de vez en cuando, no se nota mucho, pero cuando empieza a detectar colisiones como si no hubiera un mañana, da al traste con lo que había ganado optimizando.

He leído vaios post al respecto de dicho bit, que está mal emulado o que no funciona como se espera... En ensamblador miraría las colisiones por software y listo, pero en BASIC no puedo hacer eso eficientemente. Yo creo que el problema viene de que el "recálculo" de ese bit coincida entre medias de los cambios de los patrones de un sprite doble (momento en el que algún píxel puede coincidir), pero no entiendo por qué empieza a hacerlo sólo a partir de determinado momento y no antes.

¿Se conoce alguna solución? Si no hay remedio tendré que resignarme a que mis personajes no tengan sombra, ¡con lo bonita que quedaba! snif, snif

P.D.: Todo esto lo he probado con el meisei y el BlueMSX emulando MSX1; no sé si funcionará en un MSX real, pero me gustaría encontrar una solución emulador-friendly.
En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
Mortimer
Karoshi Lover
***
Mensajes: 216


WWW
« Respuesta #1 : 03 de Noviembre de 2011, 10:44:47 pm »

Ese bit siempre da problemas...

Yo creo que lo que está pasando es lo que comentas de que te está pillando colisión de los sprites dobles, porque desde basic no puedes garantizar que todos se muevan a la vez dentro del mismo retrazo, así que en alguna pasadas caerán montados. Para ver si es eso, puedes probar a poner el sprite de encima de un sólo punto, y el de abajo con suficiente hueco para que nunca coincidan (Dependerá de lo rápido que muevas el sprite)
En línea
samsaga2
Karoshi Fan
**
Mensajes: 76


Email
« Respuesta #2 : 09 de Noviembre de 2011, 05:37:37 pm »

Si usas varios sprites para dar más de un color al personaje el bit de colisión de sprites siempre te dará problemas. Lo más habitual es ignorarlo y comprobar uno mismo las colisiones mirando las coordenadas de los personajes.

Código:
p1x <= p2x+16 and p1x+16 >= p2x and p1y <= p2y+16 and p1y+16 >= p2y

Condicionales no probados, pero creo que deberían ser esos.
En línea
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« Respuesta #3 : 09 de Noviembre de 2011, 06:24:14 pm »

Sí, si comprobarlo a mano puedo... pero el problema es que hay seis sprites con los que colisionar, con lo que la lentitud se haría máxima. Podría optimizar para minimizar el número de comprobaciones, pero aún así no sería más rápido que el parche del retardo y volver a comprobar el bit.
Ya he deshechado la idea de utilizar los sprites dobles y he seguido optimizando/cambiando cosas por otros lados. Pero me guardo la versión para cuando aprenda ensamblador, por si me apetece hacer el remake ^_^
En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
j4mk3
Karoshi Maniac
****
Mensajes: 376


MSx Powa!


WWW Email
« Respuesta #4 : 02 de Diciembre de 2011, 01:35:00 am »

Buenas,
Supongo que ya lo debiste leer http://karoshi.auic.es/index.php?topic=1878.0

Yo estoy seguro que tu juego en BASIC en un MSX real funciona perfectamente sin esos apaños de control de colisión.
Con Hans' Adventure, en su versión BASIC "Escape from the dwarves' goldmine" me ocurria algo parecido.
Hans tiene 3 Sprites muy cercanos: Barba,cabeza y gorrito. En fmsx no habia manera. Detectaba colisión tooodo el rato.

A Emu perfecto, no le mires el bit de colisión Wink
En línea

---  G Fan  ---  Galious & Gradius  & G Boys   ---
--- Play HANS' ADVENTURE, STAN, THE DREAMER & BITLOGIC ---
theNestruo
Karoshi Lover
***
Mensajes: 236


Email
« Respuesta #5 : 14 de Diciembre de 2011, 11:15:31 pm »

Hola j4mk3, perdona por tardar tanto en contestarte. Ese hilo en concreto no es que lo leyera... es que me lo estudié xD

Al final me olvidé del asunto y pasé de utilizar sprites dobles, pero tengo una idea rondando por mi cabeza: en vez de modificar la tabla de atributos de sprites podría tenerla en RAM, irla modificando en el bucle principal y al final del todo volcarla del tirón con una rutina LDIRVM. No sé si con eso se solucionaría pero tengo la corazonada de que sí.
Vienen malas fechas (es época de compromisos sociales, ergo poco tiempo libre) y no sé si llegaré a hacer la prueba... pero si saco un rato ya os contaré el resultado de mis investigaciones ^_^
En línea

theNestruo."Old BASIC programmers never die; they GOSUB but never RETURN."
j4mk3
Karoshi Maniac
****
Mensajes: 376


MSx Powa!


WWW Email
« Respuesta #6 : 15 de Diciembre de 2011, 12:03:02 am »

Perfecto.
Es que así es como se hace en ASM. O al menos es como lo hago yo.
Todo en RAM como seria en VRAM y luego "vomitada/ subida" a VRAM de golpe.
En línea

---  G Fan  ---  Galious & Gradius  & G Boys   ---
--- Play HANS' ADVENTURE, STAN, THE DREAMER & BITLOGIC ---
Páginas: [1]
  Imprimir  
 
Ir a:  

Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.21 | SMF © 2013, Simple Machines XHTML 1.0 válido! CSS válido!