Karoshi MSX Community
05 de Julio de 2021, 11:56:58 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: COLISIONES ENTRE SPRITES DE VARIOS COLORES  (Leído 4894 veces)
0 Usuarios y 1 Visitante están viendo este tema.
msx dummie
Karoshi Lover
***
Mensajes: 162



Email
« : 16 de Septiembre de 2007, 04:37:50 pm »

Saludos de nuevo.
Despues de haber estado empollando un poco mas a fondo el tema de los sprites, tengo una duda:

se supone que cuando tenemos un sprite de varios colores no podemos tener activado el modo de deteccion de colision entre sprites, lo cual me sorprende bastante porque pensaba que al estar en distintos planos no tendria porque detectar que colisionasen, pero al grano:
He leido que existe una manera alternativa de hacer esto sin tener activo el modo de deteccion de colisión entre sprites...
Alguien sabe algo?? Huh

Gracias!!!
En línea
ARTRAG
Visitante
« Respuesta #1 : 16 de Septiembre de 2007, 06:03:27 pm »

Some rules:
1) design each color layer of the same object in order to not overlap the others. You do not miss anything as in MSX1 one layer masks the other, so in the overlap area you would see in any case only one color
2) move all the layers of the same sprite together in the Vsync time. In this case you do not get false detections due to the collision among layers
3) use an asm code to test the collision. You need it in any case, as there is no other way to know which objects collided

This is an adaptation for colecovision:

Pass in DE and BC the pointers to the SAT (in ram) of the two sprites
and on the stack the following 8 bytes : xoffeset1,xsize1, yoffeset1,ysize1, xoffeset2,ysize2,yoffeset2,ysize2
where x/y offset_N is the first bit set within the sprite in direction x/y
and    x/y size_N is the length of the direction box in direction x/y


Código:
                global  _check_collision
                ; check_collision
                ; (byte *sprite1,                            DE
                ;  byte *sprite2,                            BC
                ;  unsigned sprite1_size_hor,           ix+4
                ;  unsigned sprite1_size_vert,          ix+6
                ;  unsigned sprite2_size_hor,           ix+8
                ;  unsigned sprite2_size_vert);         ix+10
                ; sizes decode as follows:
                ; lobyte - first pixel set
                ; hibyte - number of pixels set
_check_collision:
                push    ix
                ld  ix,0
                add ix,sp

                PUSH BC
                PUSH DE

                LD  A,(DE)              ; TEST Y

                add     a,32
                add     a,(ix+6)        ; Y offeset within the sprite 1               
                ld      e,a
                ld      d,0             ; DE=vertical pos. sprite 1 + 32 (i.e. Y1+Yoffset1+32)


                LD  A,(BC)

                add     a,32
                add     a,(ix+10)       ; Y offeset within the sprite 2               
                ld      l,a
                ld      h,0             ; HL=vertical pos. sprite 2 + 32 (i.e. Y2+Yoffset2+32)

                ld      b,(ix+11)       ; B=number of pixels, sprite 2 (i.e. Ysize2)
                ex      de,hl           ; swap DE and HL
                or      a
                sbc     hl,de
                jr      nc,1f           ; if HL<DE swap sprites

                ld      b,(ix+7)        ; B=number of pixels, sprite 1 (i.e. Ysize1)
                add     hl,de
                ex      de,hl
                or      a
                sbc     hl,de

1:              ld      a,l             ; A = abs(Y2+Yoffset2+32-(Y1+Yoffset1+32)); B = (Y2+Yoffset2+32>Y1+Yoffset1+32) ? Ysize1 : Ysize2;
                cp      b
                jr      nc,9f           ; the test in Y failed

                POP     HL              ; TEST X

                inc     hl
                ld      e,(hl)
                inc     hl
                inc     hl
                ld      a,(hl)
                and     128
                rrca
                rrca
                xor     32
                add     a,(ix+4)     
                add     a,e
                ld      e,a
                ld      a,0
                adc     a,a
                ld      d,a             ; de=horizontal pos. sprite 1 + 32

                POP     HL

                inc     hl
                ld      c,(hl)
                inc     hl
                inc     hl
                ld      a,(hl)
                and     128
                rrca
                rrca
                xor     32
                add     a,(ix+8)
                add     a,c
                ld      l,a
                ld      a,0
                adc     a,a
                ld      h,a             ; hl=horizontal pos. sprite 2 + 32

                PUSH AF
                PUSH AF
               
                ld      b,(ix+9)        ; B = number of pixels, sprite 2
                ex      de,hl
                or      a
                sbc     hl,de
                jr      nc,1f
                ld      b,(ix+5)        ; swap sprites
                add     hl,de
                ex      de,hl
                or      a
                sbc     hl,de
1:              ld      a,h
                or      a
                jr      nz,9f
                ld      a,l
                cp      b

9:              ld      hl,0
                adc     hl,hl

                POP AF
                POP AF

                pop     ix

                pop bc

                POP AF ; free the stack from passed parameters
                POP AF
                POP AF
                POP AF
               
                push    bc
                ret


that can be called in hi-tech C (v7.X) with the following definition:

Código:
/* Check collision between two sprites. Sizes decode as follows:
 lobyte - first pixel set
 hibyte - number of pixels set */
 

int check_collision  (uchar *sprite1,uchar *sprite2,
                        uint sprite1_size_hor,uint sprite1_size_vert,
                        uint sprite2_size_hor,uint sprite2_size_vert);


En línea
msx dummie
Karoshi Lover
***
Mensajes: 162



Email
« Respuesta #2 : 19 de Septiembre de 2007, 08:02:12 pm »

thanks a lot...
but this is "codigo maquina" isn't it? Huh
i mean... i need to know how to do this in basic.
is it possible?
thank u!
En línea
ARTRAG
Visitante
« Respuesta #3 : 19 de Septiembre de 2007, 08:09:49 pm »

sorry, in basic things change a lot.

1) u can in any case design sprites in order to have layers of different colours not overlapping

2) u can in any case test VDP(0) to see if there is any collision

if (VDP(0) and 64) than goto XXXX  REM goto collision test

3) if all the sprites have the same size just verify this

if abs(x1-x2)<16  and abs(y1-y2)<16 than collision
« Última modificación: 20 de Septiembre de 2007, 12:20:07 pm por ARTRAG » En línea
pitpan
Karoshi Forum's Guru
*******
Mensajes: 1812


« Respuesta #4 : 20 de Septiembre de 2007, 07:56:14 am »

Me imagino que más bien te refieres a detectar colisiones entre sprites constituidos por varios sprites solapados.

Lo primero es asegurarte que el sprite multicolor que construyas no tiene píxeles solapados. Es decir, que en cada pixel de pantalla hay como mucho un pixel de sprites. Ya sé que siempre se verá el que tiene preferencia más alta (número de plano más bajo), pero te complicará la detección de colisiones si hay solapamiento.

La idea es la siguiente:

ON SPRITE GOSUB 10000: REM esto define interrupciones de sprites
...

SPRITE OFF
... (aquí tienes que poner todos los movimientos de sprites, tanto cambios de variables como put sprites correspondientes)
SPRITE ON: REM con esto, si hay alguna colisión entre planos de sprite, la ejecución irá a la línea 10000
...

10000 REM rutina de colision
10010 VIDAS=VIDAS-1
10020 IF VIDAS=0 THEN GOTO 10100
10030 RETURN

10100 PRINT "GAME OVER"
10110 FOR I=0 TO 50*6:NEXT
10120 RUN

Es un ejemplo muy sencillo.

Advertencias: el método del ON SPRITE es muy lento en BASIC. Tenlo en cuenta, consume bastantes recursos.

En línea
Jon_Cortazar
Administrator
Karoshi Forum's God
********
Mensajes: 2777



WWW Email
« Respuesta #5 : 20 de Septiembre de 2007, 09:37:00 am »

Tal vez es un poco obvio, pero prefiero hacer el apunte por si acaso: esta rutina de robs solo sería válida si los sprites ENEMIGOS no se tocan nunca, ya que si lo hicieran saltaría la rutina también y te quitarían una vida!. En ese caso, borjazoo, ya debe ser labor tuya que, cuando se dé la colisión, compruebes donde está cada cosa con condicionales para ver realmente qué es lo que ha colisionado.
En línea

Jon Cortázar Abraido (aka El Viejo Archivero)
RELEVO Videogames
[Dioniso: La cafeína está haciendo su trabajo; yo espero hacer el mío.]
[pitpan: Me sigue pareciendo más productivo jugar al SNAIL MAZE que seguir esta discusión.]
ARTRAG
Visitante
« Respuesta #6 : 20 de Septiembre de 2007, 12:23:35 pm »

Vejo is right

If the enemies have their coordinates in an array you need to do a loop to see if it is ur main character to have collided or two enemies among them

10001 for i=0 to Nenemies
10002 if abs(xmc-x(i))<16  and abs(ymc-y(i))<16 than 10010 : REM collision
10003 next
10004 return : REM no collision

En línea
msx dummie
Karoshi Lover
***
Mensajes: 162



Email
« Respuesta #7 : 21 de Septiembre de 2007, 02:18:23 pm »


SPRITE OFF
... (aquí tienes que poner todos los movimientos de sprites, tanto cambios de variables como put sprites correspondientes)

Esto no lo comprendo, quiero decir, que pensaba que Sprite off era simplemente para desactivar la detección... como defino ahi los movimientos de sprites???

Advertencias: el método del ON SPRITE es muy lento en BASIC. Tenlo en cuenta, consume bastantes recursos.

ok. y existe algún otro metodo similar en basic que chupe menos???



bueno, gracias a todos otra vez :god:
En línea
jltursan
Karoshi Forum's Guru
*******
Mensajes: 1516


¿Que es lo que has aprendido hoy?


WWW Email
« Respuesta #8 : 21 de Septiembre de 2007, 03:02:02 pm »

Citar
Esto no lo comprendo, quiero decir, que pensaba que Sprite off era simplemente para desactivar la detección... como defino ahi los movimientos de sprites???

Y así es, Robsy se refiere probablemente a que no tengas activada siempre la detección. En el ejemplo se desactiva, se hacen cosillas con los sprites y una vez hechas esas cosillas se activa de nuevo

Puedes experimentar con la velocidad, dependiendo de si son multicolores o el número de colisiones que tengas que evaluar, es posible que sea más rápido (o la única solución) el método de "bounding box" ya citado por ARTRAG. Te pondría como ejemplo el que uso en el "Maze Chase"; pero acabo de descubrir que se han fastidiado todos los enlaces a los programas del concurso de BASIC Shocked, ¡Viejooooo!

En línea

Doom dee doom dee doom
msx dummie
Karoshi Lover
***
Mensajes: 162



Email
« Respuesta #9 : 21 de Septiembre de 2007, 04:25:00 pm »

ya.
el otro dia estuve husmeando a ver si me podia bajar alguno y los enlaces me dban error...
En línea
jltursan
Karoshi Forum's Guru
*******
Mensajes: 1516


¿Que es lo que has aprendido hoy?


WWW Email
« Respuesta #10 : 21 de Septiembre de 2007, 05:06:22 pm »

Bueno, mientras se arreglan los enlaces, aquí tienes el Maze Chase. Pido perdón por lo enrevesado del código; pero aquí se trataba de optimizar a tope. En el listado podrás encontrar ejemplos de unas cuantas técnicas curiosas en BASIC.

Distribución en disco
Distribución en ROM
Listado BASIC

En la linea 60 tienes el código encargado de evaluar la colisión entre el personaje principal y el enemigo.
En línea

Doom dee doom dee doom
msx dummie
Karoshi Lover
***
Mensajes: 162



Email
« Respuesta #11 : 21 de Septiembre de 2007, 05:54:20 pm »

Gracias, pero has chekeado la rom?
a mi no me funciona... Embarrassed
En línea
msx dummie
Karoshi Lover
***
Mensajes: 162



Email
« Respuesta #12 : 21 de Septiembre de 2007, 05:58:54 pm »

despues de ver tu listado, me vuelvo a dar cuenta de lo paquete que soy...
no me entero de la mitad Undecided
sigo empollando basic, pero estas cosas me desesperan, te lo juro.
En línea
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!