Título: Deteccion sprite vs caracter Publicado por: cybernoid en 01 de Mayo de 2009, 11:05:52 am Hola,
Cual es la mejor manera para detectar sobre que caracter esta un sprite ? ayer entube haciendo pruebas en CM pero no encuentro ninguna manera que me convenza aquí posteo mi ultimo código, a ver si alguien me sabe dar una solución mejor, ahora estaba pensando en almacenar en la ram la posición de cada carácter pero en alta resolucion (ej caracter 1 en 100,128 caracter 2 108,128,etc,etc) Código: ; check collision ;--------------------------------------------------------- ; CONSTANTS ;--------------------------------------------------------- ; VRAM addresses CHRTBL equ 0000h ; Pattern table NAMTBL equ 1800h ; Name table CLRTBL equ 2000h ; Colour table SPRTBL equ 3800h ; Sprite pattern table SPRATR equ 1b00h ; Sprite attributtes ; System variables CLIKSW equ 0f3dbh ; Keyboard sound FORCLR equ 0f3e9h ; Foreground colour ;--------------------------------------------------------- ; ASSEMBLER DIRECTIVES (asMSX) ;--------------------------------------------------------- .bios ; Defines MSX BIOS routines .page 2 ; Assembly starts at 8000h .rom ; Selected format .db "CheckCollision",1Ah ; Text header - not MSX standard .start INIT ; Program start ;--------------------------------------------------------- ;--------------------------------------------------------- INIT: ; Program start ;--------------------------------------------------------- call INIT_GRAPHICS call DEFINE_SPRITES call INITVARS ld de,NAMTBL ld hl,MAPA1 ld bc,912 call LDIRVM buc: call DRAW_PROTA call MOVE_PROTA ld a,[protatny] ld b,a ld a,[protatnx] ld c,a call GET_POS ld a,65 call WRTVRM halt ld a,[protatny] ld b,a ld a,[protatnx] ld c,a ld a,32 call DRAW_CHAR jp buc ;--------------------------------------------------------- INIT_GRAPHICS: ; Initialise the graphic mode and define graphic elements ;--------------------------------------------------------- ; Set proper colours ; BASIC: COLOR 15,0,0 ld hl,FORCLR ld [hl],15 inc hl ld [hl],0 inc hl ld [hl],0 ; Set text mode II ; BASIC: SCREEN 1 call INIT32 ; Erase all sprite data call CLRSPR ; 16x16 Sprite mode ; BASIC: SCREEN ,2 ld bc,0e201h call WRTVDP ret ;--------------------------------------------------------- MOVE_PROTA: ; Mueve la raqueta ;--------------------------------------------------------- ld a,0 call GTSTCK cp 1 jp nz,@@PRSDOWN ;-- desplaza el muñeco ld a,[protay] dec a ld [protay],a ;-- ld a,[offsety] ; decrementa offsety dec a ld [offsety],a ;-- cp 255 ret nz ; if offsety=255 then offsety=7:protatny-- else ret ld a,7 ld [offsety],a ld a,[protatny] dec a ld [protatny],a ret @@PRSDOWN: cp 5 jp nz,@@PRSLEFT ld a,[protay] ; incrementa protay inc a ld [protay],a ;-- ld a,[offsety] ; incrementa el offsety inc a ld [offsety],a ;-- cp 8 ; if offsety=8 then offsety=0:protatny++ else ret ret nz ld a,0 ld [offsety],a ld a,[protatny] inc a ld [protatny],a ret @@PRSLEFT: cp 7 jp nz,@@PRSRIGHT ld a,[protax] dec a ld [protax],a ;-- ld a,[offsetx] ; decrementa offsetx dec a ld [offsetx],a ;-- cp 255 ret nz ; if offsetx=255 then offsetx=7:protatnx-- else ret ld a,7 ld [offsetx],a ld a,[protatnx] dec a ld [protatnx],a ret @@PRSRIGHT: cp 3 ret nz ;-- comprueba que no haya ningun caracter a la derecha ld a,[protatnx] inc a inc a ld c,a ld a,[protatny] ld b,a call GET_POS call RDVRM cp '0' ret z ;-- desplaza el muñeco ld a,[protax] inc a ld [protax],a ;-- ld a,[offsetx] ;incrementa offsetx inc a ld [offsetx],a ;-- cp 8 ; if offsetx=8 then offsetx=0:protatnx++ else ret ret nz ld a,0 ld [offsetx],a ld a,[protatnx] inc a ld [protatnx],a ret ret ;--------------------------------------------------------- DRAW_PROTA: ; Inicializa las variables ;--------------------------------------------------------- ld hl,SPRATR ld a,[protay] call WRTVRM ld hl,SPRATR+1 ld a,[protax] call WRTVRM ld hl,SPRATR+2 ld a,0 call WRTVRM ld a,15 ld hl,SPRATR+3 call WRTVRM ret ;--------------------------------------------------------- INITVARS: ; Inicializa las variables ;--------------------------------------------------------- ; posiciona el sprite del prota ld a,88 ld [protax],a dec a ld [protay],a ; posiciona el prota en relacion a la pantalla de texto ld a,11 ld [protatnx],a ld [protatny],a ; pone los offsets a 0 ld a,4 ld [offsetx],a ld [offsety],a ret ;--------------------------------------------------------- DEFINE_SPRITES: ; define los sprites ;--------------------------------------------------------- ; -Bat ld hl,SPRTBL ld bc,32 ld a,129 call FILVRM ret ;--------------------------------------------------------- GET_POS: ; retorna la direccion de la tabla de nombre seleccionada en X e Y ; B=Y ; C=X ; hl= direccion ;--------------------------------------------------------- ld a,b and 11111000b ; pilla los 5 ultimos bytes de b srl a srl a srl a ; los corre 3 posiciones a la derecha ld h,a ; lo deposita el H ld a,b and 00000111b ; pilla los 3 primeros bytes de b rl a rl a rl a rl a rl a ; los corre 5 posiciones a la izquierda or c ; lo mezcla con C ld l,a ; lo deposita el L ld bc,NAMTBL ; suma la direccion de la tabla de patrones add hl,bc ret ;--------------------------------------------------------- ; MAPAS ;--------------------------------------------------------- MAPA1: db "00000000000000000000000000000000" db "0 0" db "0 0" db "0 0" db "0 0" db "0 0" db "0 0" db "0 0" db "0 0 0" db "0 0 0" db "0 0 0" db "0 0 0" db "0 0 0" db "0 0 0" db "0 0 0" db "0 0" db "0 0" db "0 0" db "0 0" db "0 0" db "00000000000000000000000000000000" ;--------------------------------------------------------- ; VARIABLES ;--------------------------------------------------------- .page 3 ; posicion prota protax: .ds 1 protay: .ds 1 ; posicion del prota en la tabla de nombres protatnx: .ds 1 protatny: .ds 1 offsetx: .ds 1 offsety: .ds 1 Viejo, podrias explicarme como lo haces en Phantomas Saga? gracias compeñeros :) Título: Re: Deteccion sprite vs caracter Publicado por: kabish en 01 de Mayo de 2009, 01:23:35 pm Yo para TOGK reemplace una rutina que hice por el snippet "Fast NAMTBL address calculation" de jltursan. Lo tienes en la seccion de snippets de este foro, mas concretamente http://msxgamesbox.com/karoshi/index.php?topic=424.0 (http://msxgamesbox.com/karoshi/index.php?topic=424.0).
¿es esto a lo que te referias? Título: Re: Deteccion sprite vs caracter Publicado por: Dioniso en 01 de Mayo de 2009, 04:07:56 pm Viejo, podrias explicarme como lo haces en Phantomas Saga? Hombre, por fin nos escribimos por aquí también :) Estás pensando en hacer un juego tipo Phantomas Saga?... ;) Bueno, ya te han respondido. De todos modos, si quisieras hacer una array en RAM (o en ROM), hazlo seguido, no dejes bytes sueltos. Lo de saltar de 100,128 a 108,128 solo sirve para perder 7 bytes de RAM por cada tile. Además, si llegaras a situar tu SPRITE dentro del array, podrías ver fácilmente que tienes a los lados utilizando IX, por ejemplo. Si sabes la posición del SPRITE en el array (que sería una copia de lo que hay en pantalla, VRAM) y la pasas de HL a IX, por ejemplo (PUSH HL, POP IX), podrías ver fácilmente qué hay en las 4 direcciones (LD A,(IX-1), LD A,(IX+1), LD A,(IX-32), LD A,(IX+32) ), o en alguna posición cercana (IX+128, IX-127). Al tener en A la tile que quieres comprobar, tan sólo debes dibujar las paredes, techo, columnas, a partir de una tile determinada. Es decir, que si tienes esas paredes, techo, columnas, escaleras, y demás tiles que el protagonista no puede atravesar definidas de 200 a 255, por ejemplo, con hacer un CP 200 y comprobar el flag de C puedes saber si el SPRITE puede moverse en esa dirección o no. Así no tienes que hacer demasiadas comprobaciones (es una pared?, es una escalera?, es una columna?, es el techo?). Y como me estoy dando cuenta de que esta explicación está resultando una caca, y además es una explicación caótica, te digo: "hasta luego". Título: Re: Deteccion sprite vs caracter Publicado por: cybernoid en 01 de Mayo de 2009, 09:15:45 pm Hola Dioniso y kabish
no me explicado bien con la idea, desde luego no pienso dejar 8 bytes sueltos xDD yo lo que decia era guardar las posiciones de los caracteres en una tabla por ejemplo el carácter 1,1(x,y) en mi tabla estaría en 8,8 y el carácter que esta en 2,1(x,y) estaría en 16,8 como se que cada caracter es de 8 pixeles x 8 pixeles podría hacer boundingbox para comprobar colisiones, pero es un poco mas lió, creo que el sistema que recomienda kabish estará bien :) igualmente quedo a la espera que viejo me explique como lo hace el :) Dioniso, tal vez un Phantomas saga no, pero hay que estar preparado :) por que colisiones fijo que hay :) Título: Re: Deteccion sprite vs caracter Publicado por: Jon_Cortazar en 02 de Mayo de 2009, 06:20:09 am A ver si me se explicar. Te digo como lo hago yo, que probablemente no sea la forma más óptima, pero bueno ;)
Vale, en RAM siempre me guardo la pantalla entera en patrones, (namtbl, es decir, los 768 bytes que componen la pantalla). Esto es importante para chequear, porque si vas a buscar la info en VRAM la cosa se te va a ralentizar cosa mala. Teniendo esa información en RAM, lo que tienes que hacer es ANTES de que tu sprite llegue a PISAR un nuevo patrón, mirar a ver que hay, y si es una tile "pisable", dejarle pasar y si no es "pisable" pues impedir el movimiento. Yo lo que suelo hacer es definir los patrones "pisables" todos juntos y los "no pisables" todos juntos también, de forma que puedo comprobar fácilmente si puedo atravesarlos o no (si tengo de 0-127 los pisables y de 128-255 los no pisables, es una simple comprobación. Si es mayor que 128, entonces no puedes pasar: si no, si puedes. Así te evitas una lista definiendo que patrones son pisables y cuales no). Además, la comprobación no la hago cada pixel. La hago solo cuando el personaje se va a mover, y solo si se encuentra en una coordenada crítica, es decir, si está a punto de pisar un nuevo patrón. En ese momento, miro lo que va a haber, lo chequeo, y dejo moverse al personaje si veo que es un patrón atravesable. Título: Re: Deteccion sprite vs caracter Publicado por: cybernoid en 02 de Mayo de 2009, 07:21:39 am A ver si me se explicar. Te digo como lo hago yo, que probablemente no sea la forma más óptima, pero bueno ;) Vale, en RAM siempre me guardo la pantalla entera en patrones, (namtbl, es decir, los 768 bytes que componen la pantalla). Esto es importante para chequear, porque si vas a buscar la info en VRAM la cosa se te va a ralentizar cosa mala. Teniendo esa información en RAM, lo que tienes que hacer es ANTES de que tu sprite llegue a PISAR un nuevo patrón, mirar a ver que hay, y si es una tile "pisable", dejarle pasar y si no es "pisable" pues impedir el movimiento. Yo lo que suelo hacer es definir los patrones "pisables" todos juntos y los "no pisables" todos juntos también, de forma que puedo comprobar fácilmente si puedo atravesarlos o no (si tengo de 0-127 los pisables y de 128-255 los no pisables, es una simple comprobación. Si es mayor que 128, entonces no puedes pasar: si no, si puedes. Así te evitas una lista definiendo que patrones son pisables y cuales no). Además, la comprobación no la hago cada pixel. La hago solo cuando el personaje se va a mover, y solo si se encuentra en una coordenada crítica, es decir, si está a punto de pisar un nuevo patrón. En ese momento, miro lo que va a haber, lo chequeo, y dejo moverse al personaje si veo que es un patrón atravesable. y para saber que patron tienes en cada posición utilizas una rutina como la que comenta kabish pero apuntado a ram? o tienes otro método? gracias por la explicación:) seguro que me viene bien Título: Re: Deteccion sprite vs caracter Publicado por: Jon_Cortazar en 02 de Mayo de 2009, 07:51:12 am Sip, eso hago gobblin, pero no olvides que no debes mirar el tile de la posición de tu personaje, sino el/las tiles en las que VA A ESTAR tu personaje. Habrá veces que tendrás que comprobar 2 tiles y otras 3 (las más de las veces), siempre hablando de un sprite 16x16. Es decir:
O=cuarta parte de sprite 16x16 X=tile a comprobar ---------derecha X -? OOX OOX ---------izquierda X -? XOO XOO ---------arriba XXX-? OO OO ---------abajo OO OO XXX-? En los casos en que la posición X o Y no sea exactamente mútliplo de 8 en el momento de hacer la comprobación, tendrás que leer el valor de 3 tiles, ya que en realidad tu sprite iría a pisar las 3 (aunque parcialmente). Solo en los casos en los que tu sprite esté "centrado" en la rejilla de patrones en la X o en la Y será cuando debas comprobar tan solo 2. Idem para un sprite 8x8... en este caso tendrás que comprobar 2 tiles en vez de 1 si tienes las coordenadas de tu sprite "descentradas" con respecto a las posiciones multiplos de 8 de los tiles de fondo. Título: Re: Deteccion sprite vs caracter Publicado por: cybernoid en 02 de Mayo de 2009, 10:30:34 am Bien bien :) muchas gracias por toda la información con esto ya tengo una buena base de las técnicas utilizadas
Título: Re: Deteccion sprite vs caracter Publicado por: OKI09 en 02 de Mayo de 2009, 11:23:13 am Estoy de acuerdo con Viejo y Dioniso, es la forma mas sencilla de hacerlo.
No te compliques la vida con otros metodos gobblin, funciona a la perfeccion. ;) Título: Re: Deteccion sprite vs caracter Publicado por: Tragamanzanas en 06 de Mayo de 2009, 07:47:55 pm En los casos en que la posición X o Y no sea exactamente mútliplo de 8 en el momento de hacer la comprobación, tendrás que leer el valor de 3 tiles, ya que en realidad tu sprite iría a pisar las 3 (aunque parcialmente). ¿Como se comprueba que X ó Y sea múltiplo de 8? Si, ya se, dividiendolo entre 8 y si hay decimales no lo es, pero como se programa eso en ensamblador. Título: Re: Deteccion sprite vs caracter Publicado por: SapphiRe_MSX en 06 de Mayo de 2009, 07:54:46 pm ¿Como se comprueba que X ó Y sea múltiplo de 8? Si, ya se, dividiendolo entre 8 y si hay decimales no lo es, pero como se programa eso en ensamblador. Si tienes el valor en A, simplemente haces AND 7 y si da 0 (se enciende el flag Z) es múltiplo de 8, si no... pues no. |