Consulte las otras partes de esta serie:

En este tutorial, vamos a ser la creación de un juego de matemáticas en 2D, en una línea similar a Math Blaster . Este proyecto va a presentar un personaje jugador que puede moverse y volar. Por encima de ellos será un problema de matemáticas y 4 tubos con diferentes respuestas en ellos. El objetivo del juego es volar en los tubos correctos y terminar todos los problemas. Para añadir en algún desafío, habrá un temporizador de relojería para cada pregunta y obstáculos que el jugador tiene que evitar.


Este es un juego que está destinado a estimular la mente del jugador, teniendo a resolver problemas de matemáticas mientras que constantemente necesidad de centrarse en varias cosas a la vez.

El proyecto es muy extensible y contiene elementos que se pueden utilizar en futuros juegos educativos.

No se pierda! extremos oferta en

  • Accede a los más de 200 cursos
  • Nuevos cursos añadió mensual
  • Cancelar en cualquier momento
  • Los certificados de terminación

    ACCESO ahora

    Tabla de contenidos

    Proyecto Archivos

    Este proyecto contará con varios sprites, animaciones y un efecto de partículas. Puede descargar los archivos del proyecto aquí.

    Configuración del Proyecto

    En primer lugar, crear un nuevo proyecto Unity 2D. Entonces tenemos que asegurarnos de que nuestra “Cámara principal” tiene un tamaño ortográfica de 5. Esto es debido a la escala de la que estamos trabajando.


    Ya que estamos trabajando en 2D y el hecho de que estamos utilizando toda la altura y la anchura de la pantalla, es importante que sea consistente a través de la mayoría de las plataformas. Ir a la ventana de juego y establecer la relación de aspecto a 16: 9.


    En este proyecto vamos a la necesidad de añadir en algunas etiquetas, clasificación capas y una capa. Si ha descargado los archivos de proyecto y que está utilizando, entonces puede saltarse este paso.

    Etiquetas: piso, entrada, Obstáculo

    Clasificar Capas: fondo, Jetpack, Jugador, Obstáculo, Barco, la interfaz de usuario

    Asegúrese de que las capas de clasificación son en ese orden específico, ya que esto determina lo que hacen los sprites en frente de otros.

    Capas: Reproductor


    Configuración de la escena

    Ahora, crear un vacío GameObject (clic derecho Jerarquía> Crea vacío), y lo llaman “tierra”. Esto va a ser donde almacenamos todos nuestros azulejos del suelo. Luego, arrastre en el sprite “GroundTile” como un hijo del objeto.


    Para hacer que el suelo utilizable, tenemos que añadir un componente BoxCollider2D a la teja, y establecer su etiqueta de “piso”. Si usted no tiene una etiqueta de “piso”, sólo tiene que añadir uno.


    Ahora duplicar esa ficha y las ponen horizontalmente a lo largo del borde inferior del marco de la cámara.


    A continuación, arrastre en el sprite “Buque” a la parte superior del marco. Usted puede ver que es un poco demasiado pequeño, por lo que sólo aumenta la escala de 1.15. A continuación, establezca la capa de clasificación de “Ship” y añadir un componente BoxCollider2D, cambiar su tamaño para que se ajuste la nave.


    Para nuestros tubos, vamos a arrastrar en el sprite “tubo”, añadir un BoxCollider2D, define la etiqueta como “Entrada” y clasificación de capa a “Ship” con una orden de capa a 1. Esto significa básicamente que que está en la misma capa que el barco pero va a hacer en frente.

    A continuación, duplicarlas. En nuestro caso vamos a tener 4 posibles respuestas, pero usted puede tener tantos como desee.


    Ahora en este momento, nuestra formación es sólo el color azul por defecto. Entonces, ¿qué vamos a hacer es cambiar el color a algo un poco más ‘extraño’. Haga clic en la cámara y cambie la propiedad “claras las banderas” a color sólido. Entonces se puede establecer el color de fondo. Para mí he utilizado un color azul / verde (hexadecimal: 4BC1AC).


    Configuración del reproductor

    Ahora es el momento de pasar a nuestro jugador. Antes de saltar en las secuencias de comandos que, tenemos que configurar algunas cosas primero.

    Arrastrar el sprite “Player_Default” en la escena (parte de la hoja de sprites jugador). A continuación, establezca la etiqueta, la capa y la capa de clasificación de “Jugador”. Por último, añadir un CapsuleCollider2D. No estamos utilizando un colisionador de caja, ya que pueden atascarse si se mueve a lo largo de una superficie con varios otros colisionadores. colisionador cápsula nos permite deslizarnos mucho más suave.


    También es necesario añadir un componente Rigidbody2D. Ajuste el “Drag lineal” a 1 y active “Freeze rotación”. Esto evitará que el jugador se caiga.


    Para el jugador, si ha descargado los archivos de proyecto que tendrá algunas animaciones. Todos han sido conectadas y la configuración interior del control de animación “jugador”. Así que para añadirlo, sólo tiene que añadir un componente animador y ajustar el controlador a ser el controlador del “jugador”.


    Si se hace doble clic en el controlador de jugador, que se verá en la ventana animador lo que está hecho de. Nuestros diversas animaciones juegan determinan con base en el “Estado”. Este es un número que hablaremos más cuando el jugador guión.


    Para añadir algunos elementos visuales interesantes, tenemos una partícula jetpack que la explosión de partículas cuando el jugador moscas.

    Arrastre en la “FlyParticle” prefabricada en la escena como un hijo del jugador. Posición en la que de una manera para que salga del propulsor del jugador.


    Secuencias de comandos del controlador del jugador

    Para empezar, vamos a crear un nuevo guión C # llamado “PlayerController” y adjuntarlo al jugador objeto que acaba de hacer.

    de apertura hacia arriba, podemos empezar por la adición de un nuevo enumerador llamado “PlayerState” en la parte superior de nuestra clase. Esta enumeración contendrá estado actual del jugador. Si uno mira hacia atrás en el control de animación jugador, se verá que los correlatos valor flotante “estado” a la ID de cada valor de enumeración.
    PlayerState public enum {inactivo, // 0 Caminar, // 1 vuelo, // 2 // 3 Aturdido} {1234567publicenumPlayerState inactivo, 0Walking //, // 1Flying, 2Stunned // // 3}

    Ahora, de vuelta en nuestra clase, vamos a añadir las variables que vamos a utilizar. En primer lugar, tenemos nuestro estado, algunos valores para las velocidades y duraciones y, finalmente, una lista de componentes que podemos acceder.
    PlayerState curState pública; // // estado actual del reproductor valuespublic flotador velocidad de movimiento; // fuerza aplicada horizontalmente cuando el flotador movingpublic flyingSpeed; // fuerza aplicada hacia arriba cuando bool flyingpublic conectado a tierra; // es actualmente el jugador de pie en el suelo stunDuration flotación pública; // duración de un stunStartTime stunprivate flotador; // tiempo que el jugador estaba aturdido // componentspublic plataforma Rigidbody2D; // Rigidbody2D componentpublic animador anim; // animador componentpublic ParticleSystem jetpackParticle; // ParticleSystem de jetpack12345678910111213publicPlayerState curState; // // estado actual del reproductor valuespublicfloatmoveSpeed; // fuerza aplicada horizontalmente cuando movingpublicfloatflyingSpeed; // fuerza aplicada hacia arriba cuando flyingpublicboolgrounded; // es actualmente el jugador de pie en el suelo publicfloatstunDuration; // duración de una stunprivatefloatstunStartTime; // el tiempo que el jugador estaba aturdido // componentspublicRigidbody2D plataforma; // Rigidbody2D componentpublicAnimator anim; // animador componentpublicParticleSystem jetpackParticle; // ParticleSystem de jetpack

    Para comenzar con nuestra funcionalidad, vamos a añadir una función “Mover”. Esto va a ser llamado cada cuadro. Se pone el eje horizontal (-1 a 1), que se asigna a las flechas izquierda / derecha y teclas A / D. A continuación, comprobamos si el jugador se mueve hacia la izquierda o hacia la derecha y voltear la escala X en función de eso. Esto hará que el jugador mueve de un tirón su dirección de orientación. Por último, fijamos nuestra velocidad horizontal a la dirección con la velocidad de movimiento aplicada.
    // mueve el flotador dir = Input.GetAxis ( «horizontal») jugador horizontallyvoid Mover () {// obtener eje horizontal (A & D, flecha izquierda y flecha derecha); // reproductor cara de frente a la dirección que está en movimiento si (dir> 0) = transform.localScale nueva Vector3 (1, 1, 1); else if (dir <0) transform.localScale = new Vector3 (-1, 1, 1); // conjunto de cuerpo rígido rig.velocity velocidad horizontal = new Vector2 (dir * movespeed, rig.velocity.y);} // 123456789101112131415 mueve al jugador horizontallyvoidMove () {// obtener eje horizontal (A & D, flecha izquierda y flecha derecha ) = floatdir Input.GetAxis ( "horizontal"); // reproductor cara de frente a la dirección que están movingif (dir> 0) = transform.localScale newVector3 (1,1,1); elseif (dir <0) transformar. localScale = newVector3 (1,1,1); // set velocityrig.velocity horizontal cuerpo rígido = newVector2 (dir * movespeed, rig.velocity.y);}

    Otra función es “Fly”. Esto se llama cada vez que el jugador tiene la llave de flecha hacia arriba y añade fuerza ascendente al cuerpo rígido del jugador. También jugamos la partícula jetpack.
    // añade fuerza hacia arriba para Fly playervoid () {// complemento fuerza ascendente rig.AddForce (Vector2.up * flyingSpeed, ForceMode2D.Impulse); // efecto de partículas juego jetpack si jetpackParticle.Play () (jetpackParticle.isPlaying!);} // 12345678910 añade fuerza hacia arriba para playervoidFly () {// fuerza complemento upwardsrig.AddForce (Vector2.up * flyingSpeed, ForceMode2D.Impulse); (! jetpackParticle.isPlaying) // effectif de partículas juego jetpack jetpackParticle.Play ();}

    Algo que necesitamos saber para cambiar estados es si el jugador está de pie en el suelo. Para ello contamos con la función “IsGrounded” que devuelve un valor booleano verdadero o falso de.

    disparar un corto hacia abajo raycast y comprobar si se cayó al suelo. Si es así, devolver true, false en caso contrario volver.
    // devuelve verdadero si el jugador está en el suelo, falsa otherwisebool IsGrounded () {// disparar a un raycast por debajo del reproductor de RaycastHit2D golpeó = Physics2D.Raycast (nueva Vector2 (transform.position.x, transform.position.y – 0.85f) , Vector2.down, 0.3f); // nos golpeamos algo? si (hit.collider! = null) {// era que el suelo? si (hit.collider.CompareTag ( «piso»)) {return true; }} Falsa retorno;} 123456789101112131415161718 // devuelve verdadero si el jugador está en el suelo, falsa otherwiseboolIsGrounded () {// disparar a un raycast por debajo de la playerRaycastHit2D golpeó = Physics2D.Raycast (newVector2 (transform.position.x, transform.position.y -0.85f), Vector2.down, 0.3f); // hicimos llegamos a nada si (hit.collider = null) {// ¿era el piso si (hit.collider.CompareTag ( «piso»))?!? {returntrue;}} returnfalse;}

    Hablando de estados, necesitamos una manera de cambiarlo. Así que vamos a hacer una función llamada “SetState” que se llamará cada cuadro. En primer lugar, comprobamos si no estamos impresionados, porque si somos el estado no puede cambiar.

    La Inactivo Estado se determina si la velocidad del jugador es 0 y que están conectado a tierra. El caminar es, si la velocidad horizontal del jugador no es 0 y que están conectado a tierra, y Flying es, si la velocidad del jugador no es 0 y no están a tierra. Bastante simple.

    A continuación le decimos al animador hemos establecido nuestro estado, que va a cambiar la animación se está reproduciendo actualmente.
    // establece SetState statevoid del jugador () {// No se preocupe por los estados cambiantes si el (curState! = PlayerState.Stunned) {// si inactivo (rig.velocity.magnitude == 0 && a tierra) del jugador aturdido si curState = PlayerState.Idle; // pie si (rig.velocity.x = 0 && a tierra!) = CurState PlayerState.Walking; (! Rig.velocity.magnitude = 0 && a tierra!) // volar si curState = PlayerState.Flying; } // indicar el animador hemos cambiado estados anim.SetInteger ( «Estado», (int) curState);} // 1234567891011121314151617181920 conjuntos del jugador statevoidSetState () {// No se preocupe por los estados cambiantes si el jugador stunnedif ( curState = PlayerState.Stunned) {// idleif (rig.velocity.magnitude == 0 && a tierra) curState = PlayerState.Idle;! // walkingif (rig.velocity.x = 0 && a tierra) curState = PlayerState.Walking; // (! rig.velocity.magnitude = 0 && a tierra!) flyingif curState = PlayerState.Flying;} // indicar el animador hemos cambiado statesanim.SetInteger ( «Estado», (int) curState);}

    “Stun” es una función que será llamada cuando el jugador obtiene aturdido. Hemos establecido el estado y hacer su sesión de velocidad de ellos hacia abajo, por lo que cayó al suelo. También establecer el tiempo de aturdimiento y detener cualquier partícula jetpack.
    // llama cuando el jugador obtiene aturdimiento vacío stunnedpublic () {curState = PlayerState.Stunned; rig.velocity = Vector2.down * 3; stunStartTime = time.time; jetpackParticle.Stop ();} 12345678 // llama cuando el jugador consigue stunnedpublicvoidStun () {curState = PlayerState.Stunned; rig.velocity = Vector2.down * 3; stunStartTime = time.time; jetpackParticle.Stop ();}

    Entonces, ¿cómo el jugador realmente llamar a estas funciones? Con el guión “CheckInputs”. Esto llama a la función “Mover”, que tiene sus propias entradas. Para volar, comprobamos flecha hacia arriba para entradas y al final nos fijamos el estado en el que puede haber cambiado.
    // comprueba si la entrada del usuario para controlar CheckInputs playervoid () {if (curState = PlayerState.Stunned!) {// movimiento Mover (); // volar si (Input.GetKey (KeyCode.UpArrow)) Fly (); más jetpackParticle.Stop (); } // actualizar nuestro actual estado SetState ();} // 123456789101112131415161718 controles para la entrada del usuario a playervoidCheckInputs de control () {if (curState = PlayerState.Stunned!) {// movementMove (); // flyingif (Input.GetKey (KeyCode .UpArrow)) Fly (); elsejetpackParticle.Stop ();} // actualizar nuestra stateSetState actual ();}

    lo que llama “CheckInput” es la función “FixedUpdate”. Se trata de una función que es similar a la función “Actualizar”. La diferencia es que a diferencia de ser llamado cada trama, esto se llama a un ritmo constante (0.02 segundos). ¿Por qué? Bien porque estamos alterando la física del cuerpo rígido. Esto tiene que ser una tasa constante de lo contrario las cosas pueden estropear.

    En esta función, también actualizar el bool “tierra” que si el jugador se pone a tierra o no. También comprobamos si el jugador está aturdido y si es así, tiene el tiempo de aturdimiento se acabó? Si es así, hacerlos inactivo.
    void FixedUpdate () {a tierra = IsGrounded (); CheckInputs (); // es el jugador sorprendió? si (== curState PlayerState.Stunned) {// ha sido el jugador aturdido durante la duración? si (time.time – stunStartTime> = stunDuration) {curState = PlayerState.Idle; }}} 123456789101112131415voidFixedUpdate () {a tierra = IsGrounded (); CheckInputs (); // es el jugador aturdido si (== curState PlayerState.Stunned) {// el jugador tiene sido aturdido durante la duración si (time.time?? -stunStartTime> = stunDuration) {curState = PlayerState.Idle;}}}

    una última función es un cheque OnTriggerEnter2D. Estamos comprobando si estamos entrando en un objeto “obstáculo”. Si es así, obtenemos aturdido.
    // llama cuando el jugador entra collidervoid OnTriggerEnter2D (Collider2D col) de otro objeto {// si el jugador no está aturdido, aturdimiento si el objeto era un obstáculo si (curState! = PlayerState.Stunned) {if (col.GetComponent ()) {Stun (); }}} // 123456789101112 llama cuando el jugador entra collidervoidOnTriggerEnter2D (Collider2D col) de otro objeto {// si el jugador no está aturdido, aturdimiento si el objeto era un obstacleif (curState! = PlayerState.Stunned) {if (col .GetComponent ()) {aturdimiento ();}}}

    Volviendo al editor de ahora, podemos entrar en los valores de nuestro jugador y probarlo. Los mejores valores que he encontrado para el juego son:


    • movimiento Velocidad = 4
    • velocidad de vuelo = 0,28
    • Stun duración = 4


      Asegúrese de que también se añade en el juego de la prensa y los componentes!


      Creación de un obstáculo

      Ahora, vamos a empezar a crear los obstáculos para el jugador que desea evitar.

      Drag en el sprite “Obstacles_0” (una parte de la hoja de los obstáculos de sprites) en la escena. Establecer la capa de la etiqueta y la clasificación de “obstáculos” y añadir un CircleCollider2D. una cosa buena sería hacer el colisionador un poco más pequeño que el sprite real. Esto hará que sea así que cuando el jugador del get aturdido, que no creen que “ni siquiera toco eso!”. Se permite una mayor cuasi accidentes.


      Ahora cree un nuevo guión C # denominado “obstáculo”, adjuntarlo al objeto obstáculo y se abre.

      Nuestros variables son bastante simples. Tenemos la dirección en la que se va a mover en el que se determina por el desove cuando se crea. La velocidad de movimiento es la rapidez con que se mueve y aliveTime es cuánto tiempo hasta que se destruirá.
      Vector3 Mover directorio público; // dirección para mover flotador inpublic movespeed; // velocidad se mueva a lo largo de moveDirprivate flotador aliveTime = 8.0f; // tiempo antes objeto es destroyed1234publicVector3 Mover directorio; // dirección para mover inpublicfloatmoveSpeed; // velocidad para moverse a lo largo de moveDirprivatefloataliveTime = 8.0f; // tiempo antes objeto es destruido

      En la función “Inicio”, queremos llamar la función de destruir. Ahora bien, esto no va a destruir al instante, pero que puede establecer un retardo de tiempo. Esto significa que el objeto se destruye después de segundos “aliveTime”.
      vacío Inicio () {Destruir (GameObject, aliveTime);} 1234voidStart () {destroy (GameObject, aliveTime);}

      En la función “Actualizar”, queremos mover el objeto en la dirección especificada. Además, queremos rotarlo con el tiempo en la dirección que se está moviendo. Esto sólo hace que el movimiento mejor y como si algo ‘tiró’ a él.
      Actualización void () {// movimiento obstáculo en cierta dirección con el tiempo transform.position + = Mover directorio * * movespeed Time.deltaTime; // rote transform.rotate obstáculo (Vector3.back * moveDir.x * (movespeed * 20) * Time.deltaTime);} 12345678voidUpdate () {// movimiento obstáculo en cierta dirección sobre timetransform.position + = Mover directorio * movespeed * Tiempo. DeltaTime; // rotación obstacletransform.Rotate (Vector3.back * * moveDir.x (movespeed * 20) * Time.deltaTime);}

      Ahora, de vuelta en el editor, que puede duplicar el obstáculo para cada uno de los 4 sprites. Usted puede crear su propia cuenta, o utilizar los incluidos (matemáticas símbolos relacionados). A continuación, guardarlos como casas prefabricadas y ya está!


      Continúa en la Parte 2

      Ahora tenemos un personaje y algunos obstáculos a la cara, pero hay un poco para ir en el departamento de matemáticas.

      En la parte 2, que se creará un sistema para generar los obstáculos que acaba de hacer. Además, vamos a aprender cómo configurar un bucle de juego de mostrar los problemas, resolverlos, y la recepción de un nuevo problema -. Con elementos de interfaz de usuario para ayudar a cabo

      Mensajes relacionados

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *