Crear un Juego: patada al balón

Dic 30

Crear un Juego: patada al balón

Demo del juego versión 0.1: SoccerShoot

En este tutorial sencillo vamos a utilizar las siguientes herramientas:

  • Un framework de programación,i.e., un editor de scripts, un motor de videojuegos: Shiva de Stonetrip (o puede ser Unity3D si lo prefieres)
  • Un editor de objetos 3D: 3DStudio Max, Maya, Blender, el que quieras, con tal de que exporte al motor de videojuegos utilizado
  • Editor de imágenes: photoshop, corel draw, paint shop pro, gimp, el que queráis
  • Muchas ganas de divertirse jeje

Empezaremos por dar la idea de lo que queremos hacer: Programar una parábola de lanzamiento de un balón de modo que simule la trayectoria de una esfera al ser golpeada por un futbolista.

Pasos a seguir:

  1. Conseguir las fórmulas para realizar el tiro. Estas fórmulas matemáticas son la base para escribir nuestro algoritmo de lanzamiento de la bola. Es la parte física, de hecho contiene una parte matemática que es la traducción de la fórmula a lenguaje matemático, y de ahí al lenguaje de programación utilizado, en mi caso el lenguaje de scripts LUA para el motor Shiva.
    Identificación del problema: trayectoria de un proyectil con gravedad, solución del problema: simplificación por el método de los cuadrados de Taylor. Ahora simplemente tomaremos las ecuaciones y escribiremos el código fuente. Recordar que debemos obtener un valor del tiempo para que la parábola de la trayectoria esté en función del t. Escribiremos siempre el código fuente en inglés con comentarios en inglés para que se pueda “internacionalizar” 😀 y así será más fácil para todo el mundo del planeta mundial XD
    Función Loop:

    
    if (this.shooting ( )==false) then return nil end
    local nTime = application.getTotalFrameTime ( )
    if (nTime - this.time ( ) > 0.1) then
    this.time ( nTime )
    local t = this._t ( )+0.01
    local g = application.getCurrentUserEnvironmentVariable ( "g" )
    local b = scene.getTaggedObject ( application.getCurrentUserScene ( ), "myBall" )
    local x,y,z = object.getTranslation ( b, object.kGlobalSpace )
    
    local vz = 0
    --local newy = y + (vy-(0.5*g*t*t))
    local p = this.vx()
    local q = this.vy()
    local h = 0.05
    local f1=this.fnf(p,q)
    local g1=this.fng(p,q,g)
    local f2=this.fnf(p+h*f1/2, q+h*g1/2)
    local g2=this.fng(p+h*f1/2, q+h*g1/2,g)
    local f3=this.fnf(p+h*f2/2, q+h*g2/2)
    local g3=this.fng(p+h*f2/2, q+h*g2/2,g)
    local f4=this.fnf(p+h*f3, q+h*g3)
    local g4=this.fng(p+h*f3, q+h*g3,g)
    
    local dp=(f1+2*(f2+f3)+f4)/6
    local dq=(g1+2*(g2+g3)+g4)/6
    
    local newx = x + p*h+0.5*dp*h*h --three-term-Taylor approximation
    local newy = y + q*h+0.5*dq*h*h
    
    this.vx ( p + dp*h )
    this.vy ( q + dq*h )
    
    --local newy = y - (vy * t - ( 0.5*g*t*t))*10
    -- Check if the collision detection is lagged:
    if (y
    this.shooting ( false )
    return nil
    end
    
    object.setTranslation ( b, newx, newy, z+vz , object.kGlobalSpace )
    -- add a smooth rotation in the air 🙂
    object.rotate ( b, math.random ( 0, 3*this.init_speed ( ) ), math.random ( 0,3*this.init_speed ( ) ),math.random ( 0,3*this.init_speed ( ) ), object.kGlobalSpace )
    else
    --log.message ( nTime-this.time ( ) )
    end
    
  2. Crear la escena: ahora que tenemos el código para cada bucle de renderizado, necesitamos además de crear las variables locales y globales, las funciones de cálculos intermedios de posición y otras, generar un espacio donde colocar todos los objetos: el suelo y la esfera dentro de una escena de un juego, una escena puede ser como la siguiente:
  3. Crear la interfaz: para interactuar con los objetos de la escena necesita crear una interfaz de usuario, necesitaremos un control de velocidad y otro para el ángulo de modo que al modificarlos resetearemos la posición inicial de la esfera (con la textura del balón) y mediante un botón ejecutaremos el inicio de la trayectoria, hasta que choque con el suelo donde comenzará el “rebote” y la aceleración inversa mayor a la gravedad así como el frenado hasta pararse totalmente (la deformación es opcional)

    En la captura se pueden ver los objetos a crear, el código asociado a estos es sencillo, cuando cambiamos el valor del ángulo o la velocidad, recalculamos los parámetros iniciales de la trayectoria como son, las componentes x e y de la velocidad, guardar el ángulo, reposicionar la esfera, etc.
    Entonces de esta manera el bucle de trayectoria tiene los datos con los que calcular el nuevo efecto…podemos añadir una rotación al balón, en mi caso la he hecho aleatoria como veís en el ejemplo.

Ser detallista
Es importante, que ahora que tenemos el proyecto funcionando como queremos, podremos añadir cosas como sonidos, puntuaciones, una portería, un jugador de fútbol con una animación sencilla, etc. como siempre, en los juegos mientras más cosas añadimos y que sean divertidas tanto mejor pero sin llegar a ser barroco jeje

Aquí tenéis el código fuente como un proyecto de Shiva para descargar:

Download Práctica de Física: Parábola del movimiento rectilíneo uniformemente acelerado por gravedad en 3D.

Estos son algunos de los ejemplos de los juegos que podéis hacer, hay modelos y animaciones en mixamo que son recursos gratuitos…

Si necesitáis ayuda con las animaciones de los personajes, esto es sencillo, una vez que habéis importado los modelos, sus animaciones y creado las asociaciones entres estos dos cosas, simplemente en el código, en el evento de pulsación de ratón tenéis que colocar , algo tan sencillo como esto:

function main.onMouseButtonUp ( nButton, nPointX, nPointY, nRayPntX, nRayPntY, nRayPntZ, nRayDirX, nRayDirY, nRayDirZ )
--------------------------------------------------------------------------------
	
	local f = scene.getTaggedObject ( application.getCurrentUserScene ( ), "futbolista" )
    animation.setPlaybackCursor ( f, 0,1 )
	animation.setPlaybackKeyFrameBegin ( f, 0, 1)
    animation.setPlaybackKeyFrameEnd ( f,0,92 )
    animation.setPlaybackMode ( f, 0, animation.kPlaybackModeOnce )
   --object.setTranslation ( f, 0,5.707,0,object.kGlobalSpace )

	
--------------------------------------------------------------------------------
end

Para los que no quieren instalar el player de shiva o bien están en Linux y no quieren hacerlo a mano, aquí un vídeo de como funciona:

Cualquier comentario o aporte es bien recibido…

Artículos relacionados

Exprésate dejando un comentario:

Introduce el captcha

Por favor escriba los caracteres de la imagen captcha en el cuadro de entrada