En este tutorial, aprenderás a crear., Carretera dodge, Un juego simple, pero adictivo. Highway Dodge es fácil de aprender y jugar, pero proporciona la calidad adictiva de otros juegos populares en el App Store.
Highway Dodge comienza colocando al jugador en un auto de carreras en la carretera. Durante el juego, el jugador debe esquivar el tráfico que se aproxima en la carretera tocando en uno de los tres carriles disponibles. Por cada automóvil esquivado, el jugador recibe un punto y se le termina el juego cuando un automóvil que se aproxima golpea el auto de carrera. Con el tiempo, los autos que se aproximan salen cada vez más rápido para brindar un verdadero desafío al jugador..
Este juego está construido usando Lua y el Corona SDK. Como mínimo, debe tener una cuenta con Corona Labs y el Corona SDK instalado. Puede obtener el Corona SDK gratis en el sitio web de Corona Labs. Para este tutorial, utilicé build 2015.2731 del Corona SDK.
Saltemos a la derecha y comencemos Highway Dodge creando una plantilla en blanco. Abre el Simulador de corona y elige Nuevo proyecto desde el Expediente menú. Una vez que tengas la Crear nuevo proyecto ventana abierta, entrar Carretera dodge como nombre del proyecto, elija una plantilla en blanco y establezca el ancho en 400 y la altura a 600. Deje la orientación predeterminada establecida en Vertical.
Después de configurar su proyecto, descargue las imágenes para Highway Dodge. Cree una nueva carpeta en su nuevo proyecto, nómbrela como imagen y agregue las imágenes a esta carpeta. Tu proyecto ahora debería verse así:
Con el proyecto configurado, echemos un vistazo rápido a dos archivos importantes, build.settings y config.lua.
Este archivo maneja las propiedades de tiempo de construcción del juego. Almacena información sobre la orientación de su aplicación, información de iconos, configuración de iOS y configuración de Android. La configuración por defecto es adecuada para nuestro juego..
Este archivo de configuración controla las propiedades de tiempo de ejecución del juego. Esto incluye anchura
, altura
, escala
, fps
(cuadros por segundo), y imageSuffix
. La propiedad que tenemos que echar un vistazo es imageSuffix
. los imageSuffix
La propiedad se utiliza para la selección dinámica de imágenes. En pocas palabras, le dice a la aplicación que use una imagen de mayor resolución cuando está en un dispositivo de mayor resolución.
He proporcionado imágenes de alta resolución en la carpeta de imágenes, por lo que necesitamos actualizar config.lua en consecuencia. De tu proyecto config.lua El archivo debería verse como el de abajo. He omitido la sección de notificaciones push, que está comentada.
application = content = width = 400, height = 600, scale = "letterBox", fps = 30, imageSuffix = ["@ 2x"] = 2,,,
Con el proyecto y la selección de imagen dinámica configurada, pasemos a main.lua. Este archivo es el punto de inicio de todas las aplicaciones creadas con Corona SDK. En nuestro juego, va a contener tres líneas de código..
La primera línea oculta la barra de estado en dispositivos iOS. Abierto main.lua y añadir la siguiente línea después del comentario. -- Tu codigo aqui
.
display.setStatusBar (display.HiddenStatusBar)
A continuación, comenzamos a utilizar el compositor al requerir la biblioteca en nuestro juego. Hacemos esto agregando la siguiente línea:
compositor local = require ("compositor")
A continuación, utilizamos compositor para mover a la escena del menú. Movemos escenas llamando a la función. composer.gotoScene ()
, pasando el valor "scene_menu"
como el parametro. El valor "scene_menu"
es el nombre de la escena y el nombre del archivo que creamos en la siguiente sección.
composer.gotoScene ("scene_menu")
Compositor es la biblioteca oficial de gestión de escenas de Corona. Composer permite a los desarrolladores crear fácilmente una escena y hacer una transición entre escenas. En dos líneas, pude pasar de la escena principal a la escena del menú. Si desea leer más sobre Compositor, visite Corona's Guía de la biblioteca del compositor Disponible en el sitio web de Corona Labs Docs..
La escena del menú de nuestro juego consistirá de solo un par de elementos. La escena contendrá un gráfico de fondo, un título y un botón de inicio. Usaremos la biblioteca de widgets incorporados de Corona para crear el botón de inicio. La biblioteca de widgets nos permite crear rápida y fácilmente elementos comunes de la interfaz de usuario. En nuestro juego, lo usaremos solo para la creación de botones..
En la carpeta de proyectos de Highway Dodge, crea un nuevo archivo., scene_menu.lua, y ábrelo en el editor de texto que elijas. En lugar de empezar de cero, vamos a utilizar la plantilla de escena disponible en el sitio web de Corona Labs Docs. Con su plantilla, podremos movernos mucho más rápido. Dirígete a Corona Labs Docs y copia / pega la plantilla de escena para scene_menu.lua.
Agregue la biblioteca de widgets a nuestro juego agregando la siguiente línea, justo debajo de la biblioteca del compositor.
local widget = require ("widget")
Añadimos nuestro fondo utilizando los gráficos que descargaste anteriormente. El fondo debe colocarse en el centro de la pantalla. En el escena: crear ()
función y después de la grupo de pantalla
Se declara la variable, agregue el siguiente código:
local background = display.newImageRect (sceneGroup, "images / background.png", 475, 713) background.x = display.contentCenterX background.y = display.contentCenterY
A continuación, debemos agregar los tres carriles que representan la carretera. Hacemos esto usando una tabla para mantener los carriles y creando un para
bucle que se ejecuta tres veces. Coloque este fragmento después del gráfico de fondo:
local lanes = for i = 1,3 do lanes [i] = display.newImageRect (sceneGroup, "images / lane.png", 79, 713) carriles [i] .x = (display.contentCenterX - 79 * 2 ) + (i * 80) carriles [i] .y = display.contentCenterY end
Para asegurarme de que los carriles estén siempre centrados, he colocado los carriles en el eje x usando un poco de matemáticas. Esto garantiza que los carriles permanezcan centrados, independientemente del dispositivo en el que se ejecute el juego..
También agregamos nuestro logotipo para Highway Dodge colocando un objeto de imagen cerca de la parte superior de la pantalla.
local logo = display.newImageRect (sceneGroup, "images / logo.png", 300, 150) logo.x = display.contentCenterX logo.y = 75
Antes de poder agregar nuestro widget de botón, debemos crear una función que responda cuando se toca el botón. Nombraremos la función handleButtonEvent ()
y mueve el jugador a la escena del juego usando composer.gotoScene ()
. Solo responderemos cuando el jugador haya levantado su dedo del botón o al terminó
fase del evento.
función local handleButtonEvent (event) if ("finalizado" == event.phase) luego composer.gotoScene ("scene_game", "slideLeft") end end end
Con la función agregada, podemos agregar el botón. Creamos el botón utilizando widget.newButton
Y le pasa algunos valores. Especificamos el ancho y el alto del botón, los archivos de imagen para el botón, el texto que se mostrará, el tipo de fuente, el tamaño de la fuente y el color de la fuente..
También le decimos a Corona a qué función llamar cuando se presiona el botón y lo colocamos en el centro de la pantalla. Los archivos de origen de este tutorial incluyen comentarios que explican cada uno de los valores utilizados para configurar el botón..
local btn_startPlaying = widget.newButton width = 220, height = 100, defaultFile = "images / btn-blank.png", overFile = "images / btn-blank-over.png", label = "Start Playing", font = system.defaultFontBold, fontSize = 32, labelColor = default = 0, 0, 0, over = 0, 0, 0, 0.5, onEvent = handleButtonEvent btn_startPlaying.x = display.contentCenterX btn_startPlaying.y = display .contentCenterY sceneGroup: insert (btn_startPlaying)
Para finalizar la escena del menú, debemos eliminar la escena del juego cuando se cierre. Cuando Corona se mueve entre escenas, no siempre elimina la escena anterior. Sin estas líneas, el juego siempre estará en un juego sobre escena después de que se haya jugado una vez..
Para eliminar la escena anterior, obtenemos el nombre de la escena y llamamos composer.removeScene ()
para eliminarlo si existe. Agregue el siguiente código a la escena: show ()
función.
local prevScene = composer.getSceneName ("previous") if (prevScene) luego composer.removeScene (prevScene) end
Ahora podemos empezar a trabajar en la escena del juego. Usaremos el mismo flujo de trabajo que usamos para crear la escena del menú. Crear un nuevo archivo, scene_game.lua, y copie / pegue la plantilla de escena disponible en Corona Labs Docs. Una vez que tenga el código en su lugar, abra scene_game.lua en tu editor de texto favorito.
Para facilitar la codificación de la escena del juego, utilizaremos la biblioteca de widgets y la biblioteca de física. Este último se utiliza para la detección de colisiones. Agregue el siguiente código a scene_game.lua:
local widget = require ("widget") local physics = require ("physics") physics.start () physics.setGravity (0,0)
En la primera y segunda líneas, requerimos la biblioteca de widgets y la biblioteca de física respectivamente. Entonces comenzamos la física y deshabilitamos la gravedad. No necesitamos la gravedad para nuestro juego de carretera, en lugar de eso usaremos transición a()
mover los carros.
En el escena: crear ()
función, declaramos una serie de variables que utilizaremos en el juego. Estas variables serán responsables del carro del jugador, los carriles, los coches enemigos y la puntuación del jugador. Para hacer las cosas más fáciles de leer, he añadido algunos comentarios..
-- "scene: create ()" function scene: create (event) local lanes = - crea una tabla llamada lanes local playerCar - una variable para el carro del jugador local laneID = 1 - una variable para la identificación de la tierra local enemyCars = - una mesa para mantener los coches enemigos local enemyCounter = 1 - inicia el contador enemigo en 1 para hacer un seguimiento de los coches enemigos local sendEnemyFrequency = 2500 - define con qué frecuencia enviar los coches enemigos en milisegundos local tmrToSendCars - una variable para mantener una referencia al temporizador de envío de coches local playerScore = 0 - iniciar la puntuación del jugador en 0 local playerScoreText - un objeto para mantener el final del objeto de texto de puntuación
Debajo de las declaraciones de variables, configuramos las funciones para el juego. Implementaremos cada función en un paso posterior. Agregue el siguiente código después de las declaraciones de variables en el escena: crear ()
función.
función local incrementScore () fin función local moveCar (evento) fin función local sendEnemyCar () fin función local onPlayAgainTouch () fin función local onGlobalCollision (evento) fin
Después de las funciones, agregamos el fondo y los carriles. Para los carriles, adjuntamos un detector de eventos a cada carril para que respondan a los eventos táctiles. Cuando se toca, el oyente llama al moveCar ()
función.
local background = display.newImageRect (sceneGroup, "images / background.png", 475, 713) background.x = display.contentCenterX background.y = display.contentCenterY para i = 1,3 do lanes [i] = display.newImageRect (sceneGroup, "images / lane.png", 79, 713) carriles [i] .x = (display.contentCenterX - 79 * 2) + (i * 80) carriles [i] .y = display.contentCenterY lanes [i ] .id = i lanes [i]: addEventListener ("touch", moveCar) end
Con el fondo y los carriles configurados, es hora de crear un objeto de texto para mantener la puntuación del jugador y crear el carro del jugador. El puntaje estará en la parte superior de la pantalla y el carro del jugador se ubicará en el carril de la izquierda. Además, haremos del coche del jugador un objeto de física dinámica..
playerScoreText = display.newText (sceneGroup, "Score:"… playerScore, 0, 0, native.systemFont, 36) playerScoreText.x = display.contentCenterX playerScoreText.y = 25 playerCar = display.newImageRect (sceneGroup, "images / playerCar. png ", 50, 100) playerCar.anchorY = 1 playerCar.x = lanes [1] .x playerCar.y = display.contentHeight physics.addBody (playerCar) playerCar.bodyType =" dynamic "
A continuación, configuramos un temporizador para enviar un automóvil en función del valor del sendEnemyFrequency
variable y crear un detector de eventos de tiempo de ejecución para colisiones globales.
tmrToSendCars = timer.performWithDelay (sendEnemyFrequency, sendEnemyCar, 0) Runtime: addEventListener ("collision", onGlobalCollision)
Finalmente podemos agregar funcionalidad a nuestro juego. Esta sección agregará código adicional a cada función que declaramos en la sección anterior. Empezaremos con incrementScore ()
y terminar con onGlobalCollision ()
.
incrementScore ()
Esta función se llama cuando un automóvil enemigo pasa por el jugador y la transición se completa. Cuando se llama, la puntuación del jugador se incrementa en 1. Agregue la siguiente implementación a la incrementScore ()
función.
-- Esta función incrementará la puntuación del jugador en 1. Esta función se llama cuando la transición para el automóvil enemigo está completa y está fuera de pantalla. función local incrementScore () playerScore = playerScore + 1 playerScoreText.text = "Puntuación:"… playerScore end
moveCar ()
los moveCar ()
La función se llama cuando se toca un carril. Sobre el terminó
En la fase del evento, tomamos el identificador de carril y movemos el automóvil al carril correcto. Regresamos cierto
al final para indicar un evento táctil exitoso. Agregue la siguiente implementación a la moveCar ()
función.
-- moveCar responderá al evento táctil en la función local de carriles moveCar (evento) si (event.phase == "finalizó") entonces laneID = event.target.id - toma el ID de carril que será 1, 2 o 3 transition.to (playerCar, x = lanes [laneID] .x, time = 50): mueve el carro del jugador al carril apropiado. devuelve true - para indicar un evento táctil exitoso, devuelve true end end
sendEnemyCar ()
los sendEnemyCar ()
La función crea un automóvil enemigo, asigna el automóvil a un carril, une un cuerpo de física al automóvil y usa transición a()
Para enviar el coche hacia la parte inferior de la pantalla. Para empezar, vamos a crear el objeto del coche enemigo..
enemyCars [enemyCounter] = display.newImageRect (sceneGroup, "images / enemyCar" ... math.random (1,3) ... ".png", 50, 100)
A continuación, configuramos la ubicación xey del coche enemigo. También creamos un si-entonces
declaración para asignar el carro enemigo al mismo carril que el carro del jugador en el 50% del tiempo. Esto obligará al jugador a moverse más a menudo y hará que el juego sea más divertido..
enemyCars [enemyCounter] .x = lanes [math.random (1, # lanes)]. x - coloca el carro en un carril aleatorio si (math.random (1,2) == 1) luego enemyCars [enemyCounter]. x = carriles [laneID] .x; final: 50% del tiempo, coloca el carro enemigo en el carril del carro del jugador. enemyCars [enemyCounter] .y = -125 - coloca al enemigo fuera de la pantalla en la parte superior
También necesitamos rotar el carro enemigo para que esté hacia abajo y agregar un tipo de cuerpo de física cinemática al carro enemigo..
enemyCars [enemyCounter]: scale (1, -1) - gira los coches para que estén boca abajo physics.addBody (enemyCars [enemyCounter]) - agrega un cuerpo de física a los coches enemigos enemyCars [enemyCounter] .bodyType = "kinematic" - Hacer los cuerpos cinemáticos.
Con el coche enemigo configurado, usamos el transición a()
Función para enviar el coche enemigo por uno de los carriles. Cuando se completa la transición, el juego llama a una función para eliminar el objeto. Yo tambien incremento la variable Contador de enemigos
por 1 para realizar un seguimiento de la cantidad de coches enemigos en el juego.
transition.to (enemyCars [enemyCounter], y = display.contentHeight + enemyCars [enemyCounter] .height + 20, time = math.random (2250,3000), onComplete = function (self) display.remove (self); incrementScore (); final) - una transición que mueve el carro enemigo hacia la parte inferior de la pantalla. Al completarlo, el objeto del coche enemigo se elimina del juego. enemyCounter = enemyCounter + 1: aumenta el contador de enemigos en uno para seguir
Finalmente, queremos que el juego se acelere con el tiempo. Para cada otro automóvil que se envíe, el juego volverá a crear el temporizador y lo pondrá 200 ms más rápido.
if (enemyCounter% 2 == 0) entonces sendEnemyFrequency = sendEnemyFrequency - 200 if (sendEnemyFrequency < 800) then sendEnemyFrequency = 800; end timer.cancel(tmrToSendCars) tmrToSendCars = timer.performWithDelay(sendEnemyFrequency, sendEnemyCar, 0) end
onPlayAgainTouch ()
La función más corta., onPlayAgainTouch ()
, Regresa el reproductor al menú principal. Esto es lo que la implementación de la onPlayAgainTouch ()
la función parece.
-- Permitir que el jugador regrese a la función local del menú onPlayAgainTouch () composer.gotoScene ("scene_menu", "fade") - mover el reproductor al final del menú
onGlobalCollision ()
los onGlobalCollision ()
La función se utiliza para detectar colisiones entre dos objetos físicos en la pantalla. En nuestro juego, solo tenemos dos tipos de objetos de física:
Cuando estos dos objetos chocan, el juego detiene todos los temporizadores, transiciones y escuchas de eventos. Además, el juego muestra un juego sobre escena que le permite al jugador volver a jugar.
Primero, creamos un si-entonces
declaración que escucha la empezó
fase.
si (event.phase == "comenzó") entonces termina
En el si-entonces
Enunciado, paramos el juego. Hacemos una pausa en todas las transiciones, cancelamos el temporizador, hacemos una pausa en la física (incluso si no es necesaria, es una buena llamada de limpieza) y eliminamos el detector de eventos de los tres carriles. Agregue el siguiente código dentro de la si-entonces
declaración:
transition.pause () timer.cancel (tmrToSendCars) physics.pause () para i = 1,3 do lanes [i]: removeEventListener ("touch", moveCar) end
Después de que la mecánica del juego se haya detenido, agregamos un rectángulo opaco y un objeto de texto que dice "¡Juego terminado!". Esto da una buena indicación visual de que el juego ha terminado..
local gameOverBackground = display.newRect (sceneGroup, 0, 0, display.actualContentWidth, display.actualContentHeight) gameOverBackground.x = display.contentCenterent gameCapaz de las partes de las partes de las partes de la reunión. .newText (sceneGroup, "Game Over!", 100, 200, native.systemFontBold, 36) gameOverText.x = display.contentCenterX gameOverText.y = 150 gameOverText: setFillColor (1, 1, 1)
Para finalizar la función de colisión global, agregamos el botón de reproducción nuevamente que envía al jugador de vuelta al menú.
local playAgain = widget.newButton width = 220, height = 100, defaultFile = "images / btn-blank.png", overFile = "images / btn-blank.png", label = "Menu", font = system.defaultFontBold , fontSize = 32, labelColor = default = 0, 0, 0, over = 0, 0, 0, 0.5, onEvent = onPlayAgainTouch playAgain.x = display.contentCenterX playAgain.y = gameOverText.y + 100 sceneGroup: insert (playAgain)
Ejecute la aplicación para ver si todo funciona como se espera. Debes poder jugar el juego, los coches enemigos deberían aparecer desde la parte superior de la pantalla y tu puntuación debería aumentar por cada coche enemigo que esquives con éxito..
Gracias por leer mi tutorial sobre la creación de Highway Dodge con el Corona SDK. Puedes descargar los archivos de origen para este juego desde GitHub. Tómate un momento para pensar cómo puedes mejorar aún más el juego. Si estás buscando algunas sugerencias, te recomendaría agregar otro carril, agregar más tipos de enemigos e incluso agregar algunos potenciadores geniales..