Anuncios Google

Colisiones al estilo Pacman

Hola amigos, hoy vengo con una gran duda.

 

estaba pensando en como se podria crear colisiones al estilo pacman con muchas paredes, al estilo pacman xD , normalmente las colosiones o se hacen en los limites (paredes )o a un objeto (generelmente cuadrado) pero si es algo asi ?

 

 

 

Gracias por su ayuda.


 

 


Anuncios Google

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Almamu

Ejemplo

-- Informacion de pacman
pacman_x			=  0
pacman_y			=  0
pacman_ancho		= 64
pacman_alto			= 64
pacman_altomitad	= math.floor(pacman_alto  / 2)
pacman_anchomitad	= math.floor(pacman_ancho / 2)
pacman_color		= color.new(255, 0, 255)
pacman				= image.create(10, 10, pacman_color)
 
-- Colores del mapa de colisiones
color_solido		= color.new(0, 0, 0)
color_camino		= color.new(255, 255, 255)
 
-- fondos y colisiones
fondo_colisiones	= image.load("colisiones.png")
fondo_tablero		= image.load("tablero.png")
 
-- esta funcion se encarga de comprobar una colision
function comprobar_colisiones()	
	-- estos bucles lo que nos evitan es que pacman pueda atravesar
	-- la pared hasta la mitad por ir muy rapido
 
	-- colision superior
	while image.pixel(fondo_colisiones, pacman_x + pacman_anchomitad, pacman_y - 1) == color_solido then
		pacman_y = pacman_y + 1
	end
 
	-- colision inferior
	while image.pixel(fondo_colisiones, pacman_x + pacman_anchomitad, pacman_y + pacman_alto + 1) == color_solido then
		pacman_y = pacman_y - 1
	end
 
	-- colision izquierda
	while image.pixel(fondo_colisiones, pacman_x - 1, pacman_y + pacman_altomitad) == color_solido then
		pacman_x = pacman_x + 1
	end
 
	-- colision derecha
	while image.pixel(fondo_colisiones, pacman_x + pacman_ancho + 1, pacman_y + pacman_altomitad) == color_solido then
		pacman_x = pacman_x - 1
	end
end
 
while true do
	-- primero actualizamos la informacion de los controles
	controls.read()
 
	-- mostramos solo el fondo de juego
	fondo_tablero:blit(0, 0)
 
	-- primero movemos al pacman
	-- el movimiento podria quedar anulado
	-- por el codigo de las colisiones
	if controls.up() then
		pacman_y = pacman_y - 1
	elseif controls.down() then
		pacman_y = pacman_y + 1
	elseif controls.left() then
		pacman_x = pacman_x - 1
	elseif controls.right() then
		pacman_x = pacman_x + 1
	end
 
	-- esto se encarga de ajustar al posicion de pacman
	comprobar_colisiones()
 
	-- por ultimo, para evitar movimientos raros de pacman
	-- mostramos el sprite
	pacman:blit(pacman_x, pacman_y)
 
	screen.flip()
end

Si no me equivoco, ese codigo, junto a estas dos imagenes deberia de producirte los resultados deseados. Teniendo en cuenta el sistema de movimiento de pacman las colisiones deberian de funcionar como deben incluso al ser un codigo que busque el centro del personaje (este mismo lo he usado en un juego de pelea, por lo que está diseñado para tal).

tablero.png

Image Hosting

colisiones.png

Image Hosting

Ahora mismo no tengo tiempo para explicarte el codigo, pero supongo que lo podrás entender con los comentarios.


Imagen de AdriGV

Un detalle

Los colores guardados en variables con color.new no se puede comparar con los que retorna image.pixel, por lo que para hacer una comparacion tendrias que hacerlo asin:

 

color_solido = image.pixel(fondo_coliciones, 240, 136)
 
if image.pixel(fondo_colisiones, pacman_x + pacman_anchomitad, pacman_y - 1) == color_solido then
	pacman_y = pacman_y + 1
end

 

En las funcion comprobar_coliciones, en ves de IF as puesto WHILE, y eso te dara error.

Por lo demas lo veo bien.

Soy un amigo de Andres y le ayude con image.pixel, el no hos a podido responder porque esta de vacaciones y no tiene un PC cerca.

Saludos.


Programador en C++ y Lua.

Creando un Juego con Unity3D para Android.

Deseo poder crear mi propio IDE para C++ y un Motor de Videojuegos.

Imagen de Almamu

Realmente, lo que está mal no

Realmente, lo que está mal no es el while, si no el then, es un do. Fallo mio.

Imagen de AdriGV

De todas formas

De todas formas no hace falta un WHILE en la funcion, con un IF es suficienta, ademas me parece que no funcionaria bien con WHILE.

 

Saludos.


Programador en C++ y Lua.

Creando un Juego con Unity3D para Android.

Deseo poder crear mi propio IDE para C++ y un Motor de Videojuegos.

Imagen de Almamu

El while hace falta, está ahí

El while hace falta, está ahí por una razón y está explicado en los comentarios. Acabo de probar el código en mi PSP, y arreglando el tema del "then" y lo de declarar los colores todo funciona correctamente (eso sí, cambia el tamaño de la imágen de pacman a 64x64, si no colisionará sin que lo parezca). Si no te lo crees, haz la prueba.


Imagen de Almamu

Para este tipo de juegos se

Para este tipo de juegos se suele usar un mapa de colisiones, que no es más una imágen con un par de colores que indica por donde puede pasar el sprite y por donde no. Para comprobar la colisión basta con comprobar que color hay delante del sprite, si es el color que indica colisión paras al jugador y si no lo dejas continuar. Obviamente hacerlo en forma de imagen es la forma más sencilla, pero según que lenguaje te puede venir más facil usar un array del tamaño del mapa en píxeles (o tiles) con 0 para indicar colisión y 1 para indicar hueco libre, por poner un ejemplo.


Imagen de Andres_Ne

Claro el de los colores es

Claro el de los colores es magnifica idea, mas aun porque las barras de pacman son de un color solido asi que eso me servira. Gracias


 

 

Imagen de Andresmargar

Ten en cuenta de que si vas a

Ten en cuenta de que si vas a optar por calcular las colisiones por medio de la imagen del mapa (no el mapa de colisiones), debes poner la velocidad de pacman a 1 pixel/frame (si no el personaje puede salirse del mapa, debido a que la pared tiene 1 pixel de grosor, según se ve en la imagen).

 

Es solo un consejo xD

 

Saludos!!

 


~Actualmente estudiando Ingeniería de las Tecnologías de la Telecomunicación en la Escuela de Ingenieros~

Imagen de Andres_Ne

Hola

No se porque, pero me parecio mas facil tratar de crear las colisiones haciendo un detector de color para que cuando pacman tocara las barras azules pues se detuviera, trate de ingeniarme un codigo parecido a un detector que fuera alrededor de mi personaje y asi detectara el color, use la funcion image.pixel pero no me detecta mas que un solo color, hice un dibujo con los obstaculos de color azul, pero el detector no me reconoce mas que un color y ademas la memoria se me llena muy rapido y da error. aqui dejo mi codigo.

 

--DETECTANDO COLOR 
 
scan_x = 0
scan_y = 0
 
color_personaje = color.new(255,0,100)
color_limitador = color.new(0,18,255)
 
poscicionx_personaje = 30
posciciony_personaje = 30
 
personaje = image.create(10,10,color_personaje)
 
fondo = image.load("fondo.png")
 
function detectar_color (fondo,scan_x,scan_y)
	fondo = image.load("fondo.png")
	color_escaneado = image.pixel(fondo,scan_x,scan_y);
	screen.print(10,10,"El color es: "..color_escaneado)
end
 
 
while true do 
 
	controls.read()
 
 
 
	scan_x = poscicionx_personaje + 0
	scan_y = posciciony_personaje + 0
 
	fondo:blit(0,0)
	detectar_color()
	personaje:blit(poscicionx_personaje,posciciony_personaje)
 
	screen.print(10,20,"Memoria: "..os.getfreememory () ) -- Memoria Libre
 
	if controls.up () then 
			posciciony_personaje = posciciony_personaje - 1
		elseif controls.down() then 
			posciciony_personaje = posciciony_personaje + 1
		elseif controls.right() then
			poscicionx_personaje = poscicionx_personaje + 1
		elseif controls.left() then
			poscicionx_personaje = poscicionx_personaje -1
	end
 
	screen.flip()
end

 


 

 

Imagen de Jepte

recueda que los pixeles

recueda que los pixeles tienen cuatro propiedades, puedes utilizar el alpha para detectar las bordes, seria cuestion de que edites la foto, en los cuadros donde coliciona el pacman edita el alpha por ejemplo dejalo a 254, no se notaria la transparencia y la funcion de :pixel si notaria la diferencia.saludos

Imagen de Andresmargar

Es completamente normal que

Es completamente normal que se te llene la memoria en un momento, porque estás cargando el fondo una vez por frame, lo suyo es que crees una variable global y cargues el fondo fuera del bucle while, entonces en la función detectar_color(fondo, x, y) te quedaría solo el image.pixel(), y justo después es solo comprobar la colisión.

Para hacerlo de manera "realista", tienes que comprobar las colisiones de pacman en las 4 esquinas, y haces algo como esto:

 

function detectar_color(fondo, x, y, ancho, alto) -- Ancho y Alto de pacman
       -- Averigua el color en las 4 esquinas
       local color_colision = {}
       color_colision[0] = image.pixel(fondo, x, y) -- Esquina superior izquierda
       color_colision[1] = image.pixel(fondo, x+ancho, y) -- Superior derecha
       color_colision[2] = image.pixel(fondo, x+ancho, y+alto) -- Inferior derecha
       color_colision[3] = image.pixel(fondo, x, y+alto) -- Inferior izquieda
       -- Comprueba las colisiones, siempre que se este pulsando la tecla apropiada
       -- Tecla derecha (comprueba esquinas de la derecha)
       if controls.right() then
             if color_colision[1] == color_limitador or color_colision[2] == color_limitador
             then
                    pacman.x -= 1  -- Direccion opuesta al movimiento (si va por la derecha entonces se mueve a la izquierda para equilibrar el movimiento)
             end
       end
       -- Tecla izquierda (comprueba esquinas de la izquierda)
       if controls.left() then
             if color_colision[0] == color_limitador or color_colision[3] == color_limitador
             then
                    pacman.x += 1 -- Lo mismo que antes
             end
       end
       -- Tecla arriba (comprueba esquinas superiores)
       if controls.up() then
             if color_colision[0] == color_limitador or color_colision[1] == color_limitador
             then
                    pacman.y -= 1 -- Idem
             end
       end
       -- Tecla abajo (comprueba esquinas inferiores)
       if controls.down() then
             if color_colision[2] == color_limitador or color_colision[3] == color_limitador
             then
                    pacman.y -= 1  -- Idem
             end
       end
end

Este código lo he escrito ahora mismo de uno que usaba en mis juegos hechos en C, pero el concepto es el mismo, las esquinas del Sprite en verdad es una especie de "Bounding Box bidimensional", entonces solo compruebas cada esquina con el escenario, en función de qué tecla estés pulsando y la posición del Sprite.

 

Saludos!!

 


~Actualmente estudiando Ingeniería de las Tecnologías de la Telecomunicación en la Escuela de Ingenieros~

Imagen de Almamu

En el caso del Pacman basta

En el caso del Pacman basta con mirar si es azul el pixel, pero eso no es un mapa de colisiones en sí. Un mapa de colisiones es una imagen aparte que únicamente contiene la información sobre las colisiones y no se le muestra al usuario.


Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.