This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
es:orx:tutorials:aplicación_standard [2017/05/30 07:50 (8 years ago)] – external edit 127.0.0.1 | es:orx:tutorials:aplicación_standard [2020/08/20 04:14 (5 years ago)] (current) – Old content sausage | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Tutorial de Ejecutable Independiente ====== | ||
- | |||
- | ===== Sumario ===== | ||
- | |||
- | Este es nuestro primer tutorial básico de C++. También muestra como escribir un ejecutable independiente usando orx y como usar el módulo de localización ('' | ||
- | |||
- | Como **NO** estamos usando el ejecutable por defecto para este tutoriales, su código será directamente compilado en un ejecutable y no dentro de una librería externa.\\ | ||
- | |||
- | Esto implica que **NO** tendremos comportamiento codificado por defecto que tuvimos en los tutoriales anteriores: | ||
- | * F11 no afectará el cambiador de sincronia vertical. | ||
- | * Escape no saldrá de la aplicación automáticamente. | ||
- | * F12 no captura una imagen | ||
- | * Backspace no recarga ficheros de configuración | ||
- | * La sección [Main] en el fichero de configuración no será usada para cargar un plugin ('' | ||
- | |||
- | Un programa basado directamente en orx ((ej. sin la ayuda del lanzador orx)), por defecto, **NO** saldrá de la aplicación si recibe el evento orxSYSTEM_EVENT_CLOSE.\\ | ||
- | Para hacer esto, o tendriamos que usar la función auxiliar '' | ||
- | |||
- | Ver los anteriores [[main# | ||
- | |||
- | Como estamos por nuestra cuenta aquí, necesitamos escribir la función principal e inicializarla manualmente con orx.\\ | ||
- | Lo parte buena es que podemos entonces especificar que módulo queremos usar, y desactivar la pantalla o cualquier otro módulo a voluntad, si fuera necesario. | ||
- | |||
- | Si quisieramos mantener una semi automática inicialización de orx, podemos usar la función '' | ||
- | Este tutorial cubrirá el uso de orx con su función auxiliar, pero puedes decidir si no la usas su su comportamiento no sirve para tus necesidades. | ||
- | |||
- | Esta función auxiliar tendrá cuidado de inicializar todo correctamente y salir adecuadamente.\\ | ||
- | Estará también segura que el módulo del reloj está marcando constantemente (como parte del núcleo de orx) y que podamos salir si el evento orxSYSTEM_EVENT_CLOSE fue enviado.\\ | ||
- | Este evento es enviado cuando cerramos una ventana, por ejemplo, pero puede ser enviado por criterio propio (la tecla escape es presionado, por ejemplo). | ||
- | |||
- | Este código es un ejemplo básico de C++ para mostrar como usar orx sin tener que escribir código de C.\\ | ||
- | Este tutorial pudo haber estado mejor estructurado de una mejor manera (cortandolo en piezas con encabezados de ficheros, por ejemplo) pero queremos mantener un solo fichero por tutorial *básico*. | ||
- | |||
- | Este ejecutable independiente también crea una consola (como hace el ejecutable de orx por defecto), pero tu puedes tener tu propio programa sin consola si así lo deseas.\\ | ||
- | A fin de lograr eso, solo necesitas proveer un listado | ||
- | Si no, el fichero cargado por defecto será orx.ini en vez del que está basado en el nombre de nuestro ejecutable (ej. 10_StandAlone.ini). | ||
- | |||
- | Los usuarios(windows) de [[http:// | ||
- | |||
- | Este tutorial simplemente muestra el logo de orx y una leyenda localizada. Presione espacio o el botón click izquierdo para pasar por todas las lenguas disponibles para la leyenda del texto. | ||
- | |||
- | Algunas explicaciones acerca de elementos del núcleo puedes encontrarlas en este tutorial: | ||
- | |||
- | * '' | ||
- | |||
- | * '' | ||
- | |||
- | * '' | ||
- | ===== Detalles ===== | ||
- | |||
- | Empecemos con los includes. | ||
- | |||
- | <code cpp># | ||
- | |||
- | Eso es todo lo que necesitas para incluir a fin de utilizar orx. Este include trabaja igualmente con un compilador de C o C++ ((en este caso el macro preprocesador < | ||
- | |||
- | Veamos ahora a nuestra clase '' | ||
- | |||
- | <code cpp> | ||
- | { | ||
- | public: | ||
- | static orxSTATUS orxFASTCALL | ||
- | static orxSTATUS orxFASTCALL | ||
- | static void orxFASTCALL | ||
- | static orxSTATUS orxFASTCALL | ||
- | |||
- | void SelectNextLanguage(); | ||
- | |||
- | StandAlone() : m_poLogo(NULL), | ||
- | ~StandAlone() {}; | ||
- | |||
- | private: | ||
- | orxSTATUS | ||
- | |||
- | Logo *m_poLogo; | ||
- | orxS32 s32LanguageIndex; | ||
- | };</ | ||
- | |||
- | Todas las llamadas de retorno pueden actualmente haber sido definidas fuera de cualquier clase. Esto es hecho justamente aquí para mostrar como hacerlo si lo necesitaras luego.\\ | ||
- | Podemos ver que nuestra clase '' | ||
- | |||
- | Echemos un vistazo a la definición de nuestra clase '' | ||
- | |||
- | <code cpp> | ||
- | { | ||
- | private: | ||
- | orxOBJECT *m_pstObject; | ||
- | orxOBJECT *m_pstLegend; | ||
- | |||
- | public: | ||
- | Logo(); | ||
- | ~Logo(); | ||
- | };</ | ||
- | |||
- | Nada fantasioso aquí, tenemos una referencia a un '' | ||
- | Como puedes ver no usamos una referencia a todo en este ejecutable, que acabamos de mantenerlos, | ||
- | |||
- | Veamos ahora su constructor. | ||
- | |||
- | <code cpp> | ||
- | { | ||
- | m_pstObject = orxObject_CreateFromConfig(" | ||
- | orxObject_SetUserData(m_pstObject, | ||
- | |||
- | m_pstLegend = orxObject_CreateFromConfig(" | ||
- | }</ | ||
- | |||
- | Como hemos visto en tutoriales anteriores creamos nuestros dos objetos ('' | ||
- | |||
- | <code cpp> | ||
- | { | ||
- | orxObject_Delete(m_pstObject); | ||
- | orxObject_Delete(m_pstLegend); | ||
- | }</ | ||
- | |||
- | Fácil de limpiar aquí, ya que solo elimina los dos objetos. | ||
- | |||
- | Veamos ahora nuestra función principal. | ||
- | |||
- | <code cpp>int main(int argc, char **argv) | ||
- | { | ||
- | orx_Execute(argc, | ||
- | |||
- | return EXIT_SUCCESS; | ||
- | }</ | ||
- | |||
- | Como podemos ver, estamos usando el auxiliar '' | ||
- | |||
- | Con el fin de hacer esto, necesitamos proveerle el nombre de nuestro ejecutable y los parámetros de línea de comando, junto con tres devoluciones de llamada de: '' | ||
- | Solo saldremos de esta función auxiliar cuando orx termine. | ||
- | |||
- | Tengamos un pequeño vistazo a la versión de consola para windows. | ||
- | |||
- | <code cpp># | ||
- | |||
- | int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, | ||
- | { | ||
- | // Inits and executes orx | ||
- | orx_WinExecute(StandAlone:: | ||
- | |||
- | // Done! | ||
- | return EXIT_SUCCESS; | ||
- | } | ||
- | |||
- | # | ||
- | |||
- | Lo mismo que para la tradicional version '' | ||
- | Esto solo funciona para un juego en windows sin consola ((que usa WinMain() en vez de main () )). | ||
- | |||
- | Veamos ahora como luce nuestro código de '' | ||
- | |||
- | <code cpp> | ||
- | { | ||
- | orxLOG(" | ||
- | |||
- | return soMyStandAloneGame.InitGame(); | ||
- | }</ | ||
- | |||
- | Simplemente inicializaremos nuestra instancia '' | ||
- | Veamos su contenido. | ||
- | |||
- | <code cpp> | ||
- | |||
- | m_poLogo = new Logo(); | ||
- | |||
- | std::cout << "The available languages are:" << std::endl; | ||
- | for(orxS32 i = 0; i < orxLocale_GetLanguageCounter(); | ||
- | { | ||
- | std::cout << " - " << orxLocale_GetLanguage(i) << std::endl; | ||
- | } | ||
- | |||
- | orxViewport_CreateFromConfig(" | ||
- | |||
- | Simplemente registramos un callback para capturar todos los eventos '' | ||
- | Instanciamos entonces nuestro objeto '' | ||
- | También se emiten todos los idiomas disponibles que han sido definidos en los ficheros de configuración.\\ | ||
- | Terminamos por crear nuestra vista, como se ha dicho en todos los tutoriales anteriores. | ||
- | |||
- | Veamos ahora nuestra callback '' | ||
- | |||
- | <code cpp>void StandAlone:: | ||
- | { | ||
- | delete soMyStandAloneGame.m_poLogo; | ||
- | soMyStandAloneGame.m_poLogo = NULL; | ||
- | |||
- | orxLOG(" | ||
- | }</ | ||
- | |||
- | Simple borrado del objeto '' | ||
- | |||
- | Veamos ahora nuestra callback '' | ||
- | |||
- | <code cpp> | ||
- | { | ||
- | orxSTATUS eResult = orxSTATUS_SUCCESS; | ||
- | |||
- | if(orxInput_IsActive(" | ||
- | { | ||
- | soMyStandAloneGame.SelectNextLanguage(); | ||
- | } | ||
- | |||
- | if(orxInput_IsActive(" | ||
- | { | ||
- | orxLOG(" | ||
- | eResult = orxSTATUS_FAILURE; | ||
- | } | ||
- | |||
- | return eResult; | ||
- | }</ | ||
- | |||
- | Se hacen dos cosas aquí.\\ | ||
- | Primero cuando la entrada '' | ||
- | Cuando la callback '' | ||
- | |||
- | Veamos rápidamente al método '' | ||
- | |||
- | <code cpp>void StandAlone:: | ||
- | { | ||
- | s32LanguageIndex = (s32LanguageIndex == orxLocale_GetLanguageCounter() - 1) ? 0 : s32LanguageIndex + 1; | ||
- | |||
- | orxLocale_SelectLanguage(orxLocale_GetLanguage(s32LanguageIndex)); | ||
- | }</ | ||
- | |||
- | Básicamente vamos al próximo idioma disponible (regresando al principio de la lista cuando llegamos al último) y lo seleccionamos con la función '' | ||
- | Cuando hacemos esto, todos los objetos '' | ||
- | Podemos atrapar la selección de cualquier idioma como se hace en nuestra '' | ||
- | |||
- | <code cpp> | ||
- | { | ||
- | switch(_pstEvent-> | ||
- | { | ||
- | case orxLOCALE_EVENT_SELECT_LANGUAGE: | ||
- | |||
- | orxLOCALE_EVENT_PAYLOAD *pstPayload; | ||
- | pstPayload = (orxLOCALE_EVENT_PAYLOAD *)_pstEvent-> | ||
- | orxLOG(" | ||
- | break; | ||
- | |||
- | default: | ||
- | |||
- | break; | ||
- | } | ||
- | |||
- | return orxSTATUS_FAILURE; | ||
- | }</ | ||
- | |||
- | Como puedes ver, solo rastreamos el evento '' | ||
- | |||
- | Hemos terminado ahora con la parte del código de este tutorial. Veamos la configuración. | ||
- | |||
- | Primero que todo, como has podido ver, usamos diferentes carpetas para diferentes arquitecturas.\\ | ||
- | En otras palabras, el tutorial para Mac OS X está en la carpeta /mac, la de Linux en /linux, etc... | ||
- | |||
- | Por defecto, para un proyecto independiente, | ||
- | |||
- | Como no queremos duplicar el fichero de configuración en las carpetas de todas las arquitecturas, | ||
- | |||
- | Veamos ahora como hacemos esto mirando en el contenido de '' | ||
- | |||
- | <code ini> | ||
- | |||
- | |||
- | Es todo lo que podemos encontrar ahí. Como puedes ver en los [[es: | ||
- | |||
- | Miremos en el fichero de configuración quien es guardado en la carpeta padre (ie. [[https:// | ||
- | |||
- | Definamos nuestra pantalla. | ||
- | |||
- | <code ini> | ||
- | ScreenWidth | ||
- | ScreenHeight | ||
- | Title = Stand Alone/ | ||
- | |||
- | Como puedes ver, estamos creando una ventana de resolución 800x600 y definiendo su título. | ||
- | |||
- | Necesitamos ahora proveer información para nuestras vista y cámara. | ||
- | |||
- | <code ini> | ||
- | Camera | ||
- | BackgroundColor = (20, 10, 10) | ||
- | |||
- | [Camera] | ||
- | FrustumWidth | ||
- | FrustumHeight = @Display.ScreenHeight | ||
- | FrustumFar | ||
- | Position | ||
- | |||
- | Nada nuevo aquí, ya que todo ya estaba cubierto en el [[viewport|tutorial de vistas]]. | ||
- | |||
- | Veamos que entradas son definidas. | ||
- | |||
- | <code ini> | ||
- | SetList = MainInput | ||
- | |||
- | [MainInput] | ||
- | KEY_ESCAPE | ||
- | KEY_SPACE | ||
- | MOUSE_LEFT | ||
- | |||
- | En la sección '' | ||
- | |||
- | La '' | ||
- | * '' | ||
- | * '' | ||
- | |||
- | |||
- | Podemos añadir tantas entradas como queramos en esta sección y atadlas a las teclas, botones del ratón(incluyendo rueda arriba/ | ||
- | |||
- | Veamos como definimos idiomas que serán usados por el módulo '' | ||
- | |||
- | <code ini> | ||
- | LanguageList = English# | ||
- | |||
- | [English] | ||
- | Content | ||
- | Lang = (English) | ||
- | |||
- | [French] | ||
- | Content | ||
- | Lang = (Français) | ||
- | LocalizedFont = CustomFont | ||
- | |||
- | [Spanish] | ||
- | Content | ||
- | Lang = (Español) | ||
- | |||
- | [German] | ||
- | Content | ||
- | Lang = (Deutsch) | ||
- | LocalizedFont = CustomFont | ||
- | |||
- | [Finnish] | ||
- | Content | ||
- | Lang = (Suomi) | ||
- | |||
- | [Swedish] | ||
- | Content | ||
- | Lang = (Svenska) | ||
- | LocalizedFont = CustomFont | ||
- | |||
- | [Norwegian] | ||
- | Content | ||
- | Lang = (Norsk) | ||
- | |||
- | [Chinese] | ||
- | Content | ||
- | Lang = (Chinese) | ||
- | LocalizedFont = CustomChineseFont</ | ||
- | |||
- | |||
- | |||
- | Para definir idiomas para localización solo necesitamos definir una sección '' | ||
- | Después de esto necesitamos definir una sección por idioma y para cada tecla necesitada (aquí '' | ||
- | De la misma manera, definimos '' | ||
- | |||
- | Como el sistema de localización está basado en una configuración de orx, podemos usar su capacidad hereditaria para fácilmente añadir nuevos idiomas a la lista(en otro fichero externo, por ejemplo), incluso para completar idiomas que han sido parcialmente definidos. | ||
- | |||
- | Veamos ahora como definimos nuestro objeto '' | ||
- | |||
- | <code ini> | ||
- | Texture = ../ | ||
- | Pivot = center | ||
- | |||
- | [Logo] | ||
- | Graphic | ||
- | FXList | ||
- | Smoothing = true</ | ||
- | |||
- | De nuevo, todo lo que podemos ver aquí está cubierto en el [[object|tutorial de objeto]].\\ | ||
- | //Si eres curioso puedes mirar directamente en [[https:// | ||
- | |||
- | Próxima cosa a chequear: nuestro objeto '' | ||
- | |||
- | <code ini> | ||
- | ChildList = Legend1 # Legend2</ | ||
- | |||
- | Sorpresa! Actualmente es un objeto vacío que reproducirá dos objetos hijos: '' | ||
- | |||
- | El código-sabio fue creado en un solo objeto llamado '' | ||
- | El mismo tipo de técnica puede ser usada para generar un sin número grupo de objetos, o un completo escenario, por ejemplo, sin tener que crearlos uno a uno con código-sabio.\\ | ||
- | Es posible encadenar objetos con '' | ||
- | Sin embargo, no tenemos punteros directos en ellos, lo que significa que no seremos capaces de manipularlos directamente.\\ | ||
- | Siendo esto dicho, para todos los objetos no-interactivos/ | ||
- | Sea consciente de que sus fotogramas (rf. [[frame|tutorial de fotogramas]]) se reflejarán en la jerarquía de la cadena '' | ||
- | |||
- | Ok, ahora regresemos a nuestros dos objetos, '' | ||
- | |||
- | <code ini> | ||
- | Graphic | ||
- | Position | ||
- | FXList | ||
- | ParentCamera | ||
- | |||
- | [Legend2] | ||
- | Graphic | ||
- | Position | ||
- | FXList | ||
- | ParentCamera | ||
- | |||
- | Eso luce muy básico, ellos dos están usando el mismo FX('' | ||
- | |||
- | //PD: Podemos ver que definimos el atributo '' | ||
- | Sin embargo '' | ||
- | |||
- | Terminemos de echarle un vistazo a sus objetos '' | ||
- | |||
- | <code ini> | ||
- | String = $Content | ||
- | Font = $LocalizedFont | ||
- | |||
- | [Legend2Text] | ||
- | String = $Lang | ||
- | |||
- | [Legend1Graphic] | ||
- | Pivot = center | ||
- | Text = Legend1Text | ||
- | |||
- | [Legend2Graphic] | ||
- | Pivot = center | ||
- | Text = Legend2Text</ | ||
- | |||
- | Podemos ver que cada '' | ||
- | Ellos ambos tienen diferentes '' | ||
- | El carácter inicial $ indica que no mostramos un texto crudo pero usamos el contenido como llave para el sistema de localización.\\ | ||
- | Entonces, al final, el objeto '' | ||
- | |||
- | Todo el tiempo cambiaremos a otro idioma, ambos objetos '' | ||
- | Como vimos anteriormente, | ||
- | |||
- | Podemos ver también que '' | ||
- | En nuestro caso, uno de los idiomas está definiendo '' | ||
- | |||
- | Veamos ahora como las fuentes personalizadas son declaradas en orx. | ||
- | |||
- | <code ini> | ||
- | Texture = ../ | ||
- | CharacterList = " !""# | ||
- | CharacterSize = (19, 24, 0) | ||
- | |||
- | [CustomChineseFont] | ||
- | Texture = ../ | ||
- | CharacterList = " | ||
- | CharacterSize = (24, 24, 0) | ||
- | CharacterSpacing = (2, 2, 0) | ||
- | </ | ||
- | |||
- | La primera linea especifica la '' | ||
- | |||
- | La segunda linea, sin embargo, es un poco especial. Contiene todos los caracteres definidos en la textura de nuestra fuente, en orden de aparición.\\ | ||
- | Tenga en cuenta que tenemos que duplicar el caracter '' | ||
- | Aquí definimos todos los caracteres de ISO Latin 1. | ||
- | |||
- | Por último, la propiedad '' | ||
- | |||
- | La fuente Chinese fue automáticamente generada por una herramienta llamada [[es: | ||
- | Como solo necesitamos muy pocos caracteres aquí. El resultado es una micro-fuente.\\ | ||
- | [[es: | ||
- | Los espacios vacíos son útiles cuando se muestra el texto suavizado para evitar artefactos de caracteres vecinos que aparezcan en los bordes. | ||
- | |||
- | //Nota: Como has podido ver, las fuentes comunes necesitan ser monoespaciadas, | ||
- | ===== Recursos ===== | ||
- | |||
- | Código fuente: [[https:// | ||
- | |||
- | Fichero de configuración: |