Yo también voy a subir el mio porque este fin de semana no voy a tener tiempo para seguir con él...
Controles: Disparas con espacio, te mueves con las flechas del teclado, y aquí la principal novedad de jugabilidad, tienes el novedoso poder de cargar un nivel nuevo presionando la letra R del teclado por si el nivel que te ha generado es injugable xDD.
#60 lo ideal para estos casos es tirar de GPU y no así, ayer ya estuve haciendo alguna optimización,pero no se si me dará tiempo
Pero bueno,primero que funcione y luego que funcione bien xD. Por ejemplo si quiero tirar de ridig body para que los cubos no floten en el aire,tengo que tirar de una tabla hash si o si...
Yo me estoy liando con calculo de geodesicas... xD mi idea era hacer un mapa del layout de una ciudad en un mundo toroidal (un donut) a partir de un par de puntos con mas densidad de poblacion. Y mas o menos sale pero no esta acabado. Espero tenerlo para domingo aunque me pilla un vuelo largo asi que no se como ire de jetlag.
A mi no me va a dar tiempo a implementar lo que quería al final, así que tal cual lo tenga lo subiré.
a mi tampoco me da tiempo y encima no lo he exportado a html5 ni nada de eso xD os lo podéis descargar de aquí:
https://www.dropbox.com/s/2p3dw6sc21ewdb2/sloppy_football.zip?dl=0
Estaria genial que cada uno explicase mas o menos ( ya el nivel de detalle es opcional ) los pasos / algoritmo / recursos que ha utilizado para su proyecto, asi se pueden usar de inspiracion para otras cosillas
#66 lo mio es muy sencillo, simplemente estoy generando un césped de forma aleatoria. Hay un generador de tiles que lo que hace es ir generando un array 2D y colocando todo en posicion. Las columnas impares se colocan más arriba que las pares, para hacer el grid hexagonal. Hay mayor % de que salga hierba normal, y menor del resto de tiles.
Después, el terreno sobre el que está el jugador/balón aplica mayor o menor rozamiento, disminuyendo la velocidad al pasar por encima. Básicamente es un generador de patatales.
#68 basicamente un generador de terreno (en 2d en mi caso) usando (intentando) esos dos algoritmos (q se usa para esto y para tras muchas cosas). Problemas q me estoy encontrando? todos, q pretendo conseguir? una "isla" realista, ¿q he conseguido por ahora? ruido xd. Yo estoy usando python,pygame,numpy con "tiles" 2d de 5x5px en un array de 257x257 66000 tiles..
#67 yo tambien lo estaba haciendo con perlin noise, pero me da que con todo el lio de la ludum presencial y demas, no voy a terminarlo
Yo estoy en pausa ahora mismo, que tengo que ponerme al día de otras cosillas, a ver si el domingo puedo pegar el último empujoncito y dejar listo algo decente.
#49 Cuando esté todo listo os colgaré el proyecto entero (ya veré si lo hago vía repositorio u os paso un zip) y que os divirtáis poniendo verde mi código.
Por ahora tengo justo lo que dice el enunciado, un mapa aleatorio, pero me gustaria que tenga algo más de lógica que un simple (50%), y si ya soy capaz de meterle a un personaje con físicas, mejor que mejor
Quería poner mecánicas aleatorias para cambiar la experiencia de juego según la semilla, pero quiero ir a tres torneos de Magic este fin de semana y se van a comer todo mi tiempo libre.
El domingo subiré lo que tenga, pero seguiré desarrollando el proyecto hasta implementar lo que tengo en mente.
Ah! entonces entiendo que los tres mapas que has posteado no son tres pasos de un mismo proceso? sí no es así, entonces he entendido mal xD
#67 Un Diamon Square es bastante fácil, para el perlin noise te aconsejo usarlo con Brownian Motion que genera mapas maś bonicos. Y sí, yo estoy haciendo lo mismo aunque en 3D xD
Mi idea es generar el terreno no muy irregular, generar las montañas sobre ese terreno y luego meterle agua.
Espero que me de tiempo xD
#67 #72 #76 No tenía ni idea de esos algoritmos, gracias por nombrarlos. Yo siempre he trabajado con mis propios algoritmos para cualquier cosa y, la verdad, nunca me he planteado ni he necesitado buscar si había unos ya hechos para utilizarlos. Si tengo tiempo miraré a ver como funcionan porque lo cierto es que lo poco que acabo de mirar no me he enterado de nada.
No me he apuntado por dos motivos, el primero es porque quiero terminar mi actual proyecto cuanto antes y por lo tanto no quiero dedicar tiempo a otra cosa y, el segundo es, precisamente, que en mi actual proyecto la generación procedural está a la orden del día ya que todo, TODO (menos la GUI) se genera en tiempo real para reducir al máximo el tamaño del proyecto. En algunos casos a partir de valores establecidos por mi y en otros de manera aleatoria para reducirme trabajo.
Un ejemplo son los "mapas" de selección de nivel, que aquí os muestro:
Se que parece muy psicodélico pero este finde o la próxima semana ya os presentaré el proyecto para que veais en que consiste. No es nada raro, aunque pediré opiniones.
Os dejo por aquí mi juego.
http://gamebucket.io/game/84cd665b-fe02-499a-bd1a-56cd3ca0c999
Me ha quedado un poco mierder, porque no me da tiempo a implementar lo que yo quería, que era como una especie de juego de preguntas. Al final, es un juego de a ver quien consigue pasar por mas tiles antes de llegar a la salida del nivel.
Me hubiera gustado haberme currado un poco más este post, explicando que cosas he hecho y demás, pero no me da tiempo
#76 #72 solo estuve unas horas el otro dia y la verdad sq no logre resultados aceptables xd Mejore rendimiento eso si. Espero este finde estar mas centrado con ganas y sacarlo. Aunque con pygame la verdad sq no queda tan bonico como con cosas como xna o unity etc.. (da la sensacion de q es mas medieval xd )
#77 te recomiendo q les eches un vistazo, son bastante intesantes los dos. Pd la psicodelia mola, mas si el resultado es inesperado xD
Yo tambien me uno al microdesafio, he hecho algo simple con phaser, se trata de un cuadrado que tiene que ir recolectando la moneda para que se generen mas obstaculos aleatorios en el mapa, pudiendo destruir estos disparandoles (con la Z).
http://flopivg.xyz/MapaAleatorio/
Tiene algun que otro bug, y el resultado no me gusto mucho, asi que ahora andare a darle a Unity a ver que puede ofrecerme.
Disclaimer: Sorry por el tocho que se viene...
Generación Mapa Procedural
Bueno, lo que llevo haciendo desde el jueves por la noche es un sistema de generación de un mundo 3D basado en cubos, estilo Minecraft. Para la generación de los biomas y/o restricciones he preferido calentarme la cabeza,no tirar de los métodos habituales,simplificarlo un poco (Obviamente ha quedado peor, que lo que existe, que funciona, por algo está). A continuación voy a tratar de explicar un poco los pasos a seguir. Partiré de donde lo dejé en #59, con los tiles creados, así cómo la lógica del rellenado de la región de forma puramente aleatoria. Básicamente pues, lo que tenemos es una región 3D rellena a base de cubos tal que así:
Los pasos que he diseñado en el algoritmo son los siguientes:
-
Rellenado de la región.
-
Búsqueda de vecinos.
-
Aplicación custom-pseudoalgoritmo de restricciones.
-
Aplicación custom-pseudoalgoritmo de "biomas"
-
Destrucción de los tiles TyleTipe.Air (Aire)
-
Busqueda de los tiles de "Tierra" que debieran ser de Hierba por su condición y resolución de los cambios.
(El rellenado de la región no lo voy a explicar, básicamente recorro todo el espacio de dentro con un triple bucle for y voy rellenando sin control xD)
Búsqueda de vecinos
Una vez finalizado el rellenado de la región, tengo todos los cubos instanciados y ocupando su huequecito en memoria, dejándolos sin protección ante mis maldades. Cada cubo tiene implementado un método que hace que se busquen los vecinos que tiene "inmediatamente" al lado. Para cada cubo 3D tenemos, 999 cubos . Es decir, 27 'vecinos'. PERO el la posición central que la ocupa el propio cubo que busca el vecino no la contamos, por lo que cada cubo podrá llegar a un máximo de 26 vecinos. Ilustro un poco:
*Esto representa el volumen que comprueba cada Cubo para determinar sus vecinos, estando el cubo que realiza la comprobación en el centro del volumen
public void FindNeighbour (Vector3 globalpos)
{
//Position Values Storage
float x = globalpos.x;
float y = globalpos.y;
float z = globalpos.z;
/* check 26 neighbours and ourselves */
/* This line check with an Sphere of Sqrt(2) radius,
* from each cube position, if it collides with any collider */
Collider[] hitColliders = Physics.OverlapSphere(this.transform.position, 1.41f);
/* For loop in order to add the "Tile3D" component to local neighbour list*/
for(int i = 0; i < hitColliders.Length;i++)
{
//Check if colllider does not return null value
if(hitColliders[i] != null)
{
//Check id collider does not take in count the floor collider
if(hitColliders[i].gameObject.name != "Floor")
{
/*Check if we are not taking in count ourselves (we compare both NB list
* since we will never have the same NB list for two or more Tile3D component*/
if(hitColliders[i].gameObject.GetComponent<Tile3D>().NB != this.NB)
{
//Finally we add the Component to the NB list.
NB.Add(hitColliders[i].gameObject.GetComponent<Tile3D>());
}
}
}
}
}
De esta forma, cada Cubo/Tile, en su componente Tile3D tendrá una lista de sus vecinos.
Aplicación custom-pseudoalgoritmo de restricciones
Aquí básicamente, asigno un porcentaje de aparición a cada tile según el % de terreno ( en relación a la ALTURA de la región ) en el que se encuentre.
Debido a la longitud, voy a poner un ejemplo, una imagen que he hecho desempolvando "Fotochó" y ya os imaginais el resto xD...
void CreateConstraints ()
{
//If this tile is over the 80% of the terrain, it will be ALWAYS Air.
if(this.gameObject.transform.localPosition.y >= mapr.transform.localScale.y - (mapr.transform.localScale.y*.2))
this.Type = TileType.Air;
//If this tile is at or under the 10% of the terrain..
if(this.gameObject.transform.localPosition.y <= mapr.transform.localScale.y - (mapr.transform.localScale.y*.9))
{
//Random.value always return a random value(juejj) between 0.0f and 1.0f;
if(Random.value <= .90f)
this.Type = TileType.Water; //90% Water
else
this.Type = TileType.Stone; //10% Stone
}
...
...
...
Ilustro: (Se aceptan criticas acerca de los porcentajes xD)
Aplicación custom-pseudoalgoritmo de "biomas"
Bueno, aquí básicamente lo que he hecho ha sido,realizar comprobaciones. Cada cubo comprueba de qué tipo son sus vecinos. Cada comprobación "añade uno" al contador de vecinos. Por ejemplo:
El cubo situado en (4,5,8) tiene:
Aire: 4
Tierra:6
Piedra: 6
Agua: 10
En función de los resultados obtenidos, calculo el porcentaje que representa dentro de la nube de vecinos. Por ejemplo, si tiene 13 de los 26 vecinos son Agua, almaceno que el 50% de los vecinos son del tipo Agua. Posteriormente, utilizo ese porcentaje, como probabilidad de que el cubo que realiza la comprobación se convierta transforme a cubo de ese mismo tipo. Para el mismo ejemplo, el cubo que realiza la comprobación, ahora tiene un 50% de probabilidades de convertirse en Agua puesto que el 50% de sus vecinos lo son.
En cuanto al código chustero..:
private void CreateBiomes()
{
/* First at all, see the freQ of the Types in each Tile neighbourhood */
int WatC = 0,AirC = 0,StoC = 0,DirC = 0;
foreach(Tile3D t3 in NB)
{
//check if null
if(t3 != null)
{
//Check if neighbour type is Air.
if(t3.Type == TileType.Air)
{
//We are not counting the 20% of Air at the top of the region, in order to prevent TONS OF AIR tiles
if(t3.transform.localPosition.y < mapr.transform.localScale.y - (mapr.transform.localScale.y*.2))
AirC++;
}
if(t3.Type == TileType.Stone) //if stone
StoC++;
if(t3.Type == TileType.Dirt) //if dirt
DirC++;
if(t3.Type == TileType.Water) //if water
WatC++;
}
}
/*********************************************************************/
/* Once que have the amount of tyles of every type, we assing a percentage */
watP= WatC/26.0f;
AirP= AirC/26.0f;
StoP= StoC/26.0f;
DirP= DirC/26.0f;
/**********************************************************************/
//Calculate rand value and checks
float rand = Random.value;
if(rand >= 0.0f && rand <= watP)
{
this.Type = TileType.Water;
}
if(rand > watP && rand <= watP+AirP)
{
this.Type = TileType.Air;
}
if(rand > watP+AirP && rand <= watP+AirP+StoP)
{
this.Type = TileType.Stone;
}
if(rand > watP+AirP+StoP && rand <= watP+AirP+StoP+DirP )
{
this.Type = TileType.Dirt;
}
}
Ya tenemos los "biomas" mejorados, para que se formen grupos 'grandes' del mismo tipo de material.
Destrucción de los tiles TyleTipe.Air
No tiene ningún misterio. Cada tile comprueba su material y si es Aire. Se inmola ( muahahahah) y mi memoria me lo agradece...
void DisableAir ()
{
//IF I AM FUCKING AIR,THEN FUCK YOU IM LEAVING
if(this.Type == TileType.Air)
DestroyImmediate(this.gameObject);
}
Por último...
Busqueda de los tiles de "Tierra" que debieran ser de Hierba por su condición y resolución de los cambios
Aquí básicamente comprobamos si estamos justo debajo del primer tile superior de aire, es decir, en la superficie. Además, siempre que un tile de tierra no tenga ningún bloque más en toda la altura de la región, será Hierba, de lo contrario, Tierra ( Quiero modificar esta para que si hubiere construcciones rarunas tambien pudiera haber hierba, ya la tengo pensada más o menos como...)
void FixGrass ()
{
//since 80% and above will be always AIR, if im DIRT, im actually Grass
if(this.Type == TileType.Dirt && this.gameObject.transform.localPosition.y >= mapr.transform.localScale.y - (mapr.transform.localScale.y*.3))
{
this.Type = TileType.Grass;
}
else
{
//if im Dirt..
if(this.Type == TileType.Dirt)
{
//We throw a Raycast "region.scale.y" meters in order to check if we have any block over our position.
RaycastHit hit;
Ray ray = new Ray(this.transform.localPosition,Vector3.up);
//if we have some block, then i'll be always dirt.
if (Physics.Raycast(ray,out hit, mapr.transform.localScale.y))
{
this.Type = TileType.Dirt;
}
//if not, im going to be a nice grass tile.
else
this.Type = TileType.Grass;
}
}
}
Y eso es todo. Sorry again por el tocho
Resultado
Esta tarde/noche generaré algún video para que veais como se mueve (ha mejorado muy mucho-bastante el tema FPS ). Haré algo "jugable" para que navegueis por el mundo y enseñaré varios escenarios distintos ( distintas dimensiones ), por ahora, y para no cargarme Mediavida, solo una foto de un 'chunk' pequeñito.(si me da tiempo hasta mañana por la noche mejoraré los materiales :3 )
Para ser un algoritmo homemade no ha quedado tan mal xD, pero existirán 300.000 mejoras, empezando por usar técnicas/algoritmos que ya existen para estas cosas...pero así es más divertido!
Saludos!
#81 Pues me lo he leido de arriba abajo y creo que te has explicado muy bien, hasta lo he entendido.
Es un gustazo que la gente se pegue estas currada para intentar explicar como lo ha hecho todo. Muchas gracias por el curro
#82 Muchas gracias! solo por el curro en el gráfico en photoshop de la explicación de los porcentajes ya quieres que alguien se lo lea! (que es complicado leerse tal tocho, lo se xD) >.<. He estado entretenido 45min - 1 hora fácilmente xD.
En un ratito o igual esta noche si me da por arrancar el bloodborne me pongo a meterle mano para generar más terrenos, algun video y hacerlo 'jugable'. A ver que sale
Bueno yo me he quedado a medias aunque satisfecho con mi progreso. Mi idea era construir un mapa en un mundo con forma de donut a base de geodesicas (de manera que sobre el mapa se vieran curvas raras pero al verlo en el donut se vieran normales, un poco como cuando vemos la ruta de un avion en un mapa proyección de Mercator). A partir de eso usar un L-system (reglas para bifurcar y tal) y crear el mapa. El problema viene con la pesima estructura de datos que usaba y no supe mejorar a tiempo. Estoy satisfecho no obstante porque sigue siendo código completado y práctica adquirida .
Pues vista la hora que es, ya puedo dar por aparcado el proyecto, he hecho unos sprites muy monos con unas enredaderas que iban a ser las escaleras... Y tenía pensado un sistema de generación de plataformas a partir de nodos bastante curioso, pero que no acababa de funcionar...
Así que no me ha dado tiempo de implementar todo el rollito de la generación de plataformas, ni ningún tipo de personaje ni na de na.
Voy a ponerme con "Mi proyecto principal" a ver si puedo dejar algo listo hoy, y una vez que lo tenga, limpio el mini reto para no colgarlo con todo el merder de funciones que no he llegado a usar.
El nuevo tema de esta semana: Sistema de sigilo.
Estuve probando, por si la idea era complicada e hice una gilipollez, en un ratito.
Entrad en la parte oscura o id por detras del guardia, a lo largo de la semana lo mejorare mas aun xD (usad W,A,S,D).
Tanto el tema anterior como este me vienen bien para el juego de practica que toy haciendo, a ver si esta vez me puedo poner
Esta semana estaba haciendo un laberinto aleatorio en ue4.. no deberia haberme complicado tanto para el tiempo que tengo, siempre me pasa!! xD (esta casi hecho pero nada subible )
A ver que sale del nuevo tema ^^
#87 Yo he metido la región generada y un sistema de cubos destruibles a lo minecraft en mi versión "jugable" pero pff, quería hacer más cosas...al final este domingo lo he tenido hasta arriba. Pero bueno, el reto del desafio está en #81, lo otro era por adornar D:
Aqui dejo un video con unos 3.000 cubos
Voy a pensar a ver si podría hacer algo para este desafio semanal, aunque tengo poco más de 3 días para hacerlos T_T