Se puede considerar que casi todos los juegos tienen una función principal que contiene toda la lógica del juego, y que se ejecuta cuando el usuario hace algo, o después de un cierto tiempo. Este ciclo de ejecución de la misma función central una y otra vez se denomina bucle de juego, Y es crucial de entender para cualquier tipo de desarrollo de juegos..
Probablemente has jugado al juego de mesa Chutes and Ladders (o Snakes and Ladders como lo llamamos en el Reino Unido).
(Crédito de la foto incurable_hippie en Flickr)
Cada jugador tira el dado (o hace girar la ruleta) y avanza el número de casillas indicado. La plaza en la que aterrizan puede indicar que se desplacen hacia atrás o que suban varios espacios hacia adelante. El jugador gana el juego cuando llega a la casilla final..
Entonces, en la imagen de arriba, aterrizar en la Plaza 6 te hace subir cuatro casillas a la Plaza 10; aterrizar en la Plaza 19 te hace retroceder 15 casillas a la Plaza 4; y aterrizar en la Plaza 64 significa que ganas el juego.
Ahora supongamos que estás jugando solo jugador, para practicar. Hace lo mismo que arriba, una y otra vez, hasta que llegue a la Plaza 64. ¿Cómo representaría esto en el código??
Probablemente comenzarías creando una matriz para almacenar los valores de los cuadrados. La mayoría de los elementos contendrían cero, pero algunos contendrían un número positivo (indicando una escalera) o un número negativo:
Nota: Esto es pseudocódigo, no AS3
var specialSquares: Array = []; specialSquares [0] = 0; // la casilla en la que comienzan los jugadores, antes de 1 specialSquares [1] = 0 ;? specialSquares [6] = +4 ;? specialSquares [19] = -15;
? y así. Luego, tendrías una función para mover el jugador según el número en el dado:
function movePlayer (squares: Number) newSquare = currentSquare + squares; newSquare + = specialSquares [newSquare]; currentSquare = newSquare;
Luego puedes poner esto dentro de una función más grande que representa un turno completo:
función takeATurn () diceNumber = random (1, 6); // número aleatorio entre 1 y 6 movePlayer (diceNumber); if (currentSquare == 64) // el jugador ha ganado! juego terminado
Esta función, TakeATurn ()
, encapsula la lógica del juego principal para los jugadores y escaleras de un solo jugador. Pero, ¿cómo conseguimos esta función para ejecutar? Hay varias opciones:
Podríamos colocar un botón en la pantalla, y hacer que llame. TakeATurn ()
Cada vez que se hace clic. Si alguna vez has jugado a Facebook Scrabble o Words With Friends, has visto esta opción en acción..
Podriamos hacer TakeATurn ()
correr cada sesenta segundos.
En realidad, esta opción es un poco más complicada de lo que parece. En la práctica nunca vemos ningún juego sin algunos entrada del jugador; Sin interacción, realmente no puede ser considerado un juego. Pero aún así, algunos juegos tienen un elemento de "tiempo calendario" involucrado. Considere FarmVille: usted, el jugador, siembra sus cultivos, y luego cada pocos minutos (u horas) se desarrollan un poco más, desde las semillas hasta los brotes y los frutos. Y en algunos modos de Civilización, se te da una cantidad de tiempo establecida (por ejemplo, cinco minutos) para hacer todos tus movimientos por un "turno"; Una vez que esos cinco minutos terminan, la función de lógica del juego principal se activa..
Algunos juegos usan una mezcla de estas dos opciones: por ejemplo, Mafia Wars tiene un recurso llamado "energía" que recarga una unidad cada cinco minutos; toma acciones en el juego utilizando este recurso, por lo que la función de lógica del juego principal todavía se activa mediante una acción del usuario, solo está restringida por el tiempo.
Este es un patrón común para la mayoría de los juegos: una pieza de código que contiene la lógica del juego principal se activa repetidamente. Llamamos a esto el bucle de juego.
Hay un término para la acción o el período de tiempo que también activa el código lógico del juego principal: un garrapata (como el sonido que hace un reloj).
Así que en Civilization, la garrapata es cada cinco minutos. En palabras con amigos, jugando tu turno. causas una garrapata. En otras palabras, el bucle del juego se ejecuta una vez por tic.
Super Mario Bros no parece encajar en ninguna de estas categorías. Mario responde a la entrada del jugador? y sin embargo, todo tipo de cosas están sucediendo sin que usted tenga que hacer nada (los Goombas caminan, el temporizador cuenta atrás, los objetos caen). Hay dos bucles de juego?
No. Solo hay uno, y se activa solo por el tiempo, pero con un tic de solo una fracción de segundo.
En Civilization, tienes un período de cinco minutos para ingresar todo lo que quieres hacer en el turno actual, antes de que el juego "haga tic" y ejecute el ciclo del juego nuevamente en función de todos tus comentarios. Así que si dices, en la curva 23, que quieres que tus guerreros ataquen a un ciervo, entonces en la curva 24 todos vengan a cenar..
Es lo mismo con Mario. Si presionas el botón Saltar durante una marca, entonces en la siguiente iteración del bucle del juego, Mario comenzará a saltar..
Tenga en cuenta que usted no hacer tiene que cronometrar la presión de salto para que se produzca justo cuando se activa la función de lógica del juego principal: todas sus acciones durante un período de marcación se registran y se utilizan durante la próxima iteración del bucle del juego.
Toda la lógica del juego se maneja en el bucle del juego. Pero hay más en un juego que su lógica, los gráficos son el ejemplo principal..
Dibujar gráficos en la pantalla es un trabajo duro para la computadora. Supongamos que tienes un juego de acción con un tic de 1/60 de segundo; Eso debería hacer que el juego se sienta como si reaccionara fluidamente a los controles del jugador. Pero, ¿qué sucede si la computadora del jugador es demasiado lenta para ejecutar todo el código de la lógica del juego (responder a la entrada, simular la gravedad, ejecutar rutinas de IA)? y dibuja todo en la pantalla dentro de 1/60 de segundo?
En este escenario, podemos usar dos bucles separados: un bucle de juego y un dibujar bucle. Entonces podríamos ejecutar el ciclo de sorteo a una frecuencia mucho menor que el ciclo de juego; digamos que actualizamos la mitad de la pantalla con la frecuencia, es decir, cada 1/30 de segundo.
La cantidad de potencia de procesamiento requerida por el juego puede variar de un nivel a otro. Considera un juego de disparos: los primeros niveles tendrán muy pocas naves en la pantalla, para facilitar al jugador con suavidad, mientras que los últimos niveles podrían tener docenas de naves enemigas y cientos de balas volando alrededor de la misma escena en una vez. El bucle del juego tiene que averiguar cómo deben moverse todos esos objetos, y el bucle de dibujar tiene que renderizar cada uno, por lo que aunque puede haber sido posible ejecutar tanto el bucle de juego como el bucle de dibujar cada 1/60 de segundo en el inicio del juego, al final algo tiene que dar..
Por lo general, es más sencillo ralentizar el ciclo de sorteo que el circuito de juego, si tiene que elegir. Ajustar la longitud de tic del bucle del juego significa ajustar todo en tu juego que se basa en el tiempo; Si Mario se ejecuta a una velocidad de 20 píxeles / segundo, y diseñas el juego con una longitud de tick de 1/60 de segundo, entonces debes moverlo a 1/3 de un píxel por tick. Si ajustas el bucle del juego para que tenga una duración de tick de 1/30 de segundo, entonces tienes que ajustarlo a 2/3 de un píxel por tick, e incluso eso es un cambio simple comparado con mantener los cálculos físicos y las rutinas de IA consistente.
Por esta razón, los juegos a menudo tienen como objetivo mantener la marca del bucle del juego consistente y ralentizar el ciclo de dibujo si se necesita más potencia. Si alguna vez ha activado el contador de FPS (abreviatura de cuadros por segundo, la cantidad de veces que se ejecuta el ciclo de dibujo por segundo) en un juego de acción en primera persona, habrá visto que cambia según la cantidad que haya en la pantalla. ; La frecuencia de actualización del ciclo de dibujo se ajusta automáticamente. Es posible que el juego tenga un aspecto escalofriante, como un video en vivo con una conexión lenta de Internet, pero a menos que se esté ejecutando en una computadora con mucha menos potencia de la que los desarrolladores de juegos tenían en mente, todos los objetos del mundo del juego continuarán Moverse e interactuar a las velocidades correctas..
Para un excelente artículo que explica cómo Flash se enfrenta a esto, echa un vistazo a la publicación de Sean Christmann en 'Elastic Racetrack'.