This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| es:orx:tutorials:aplicación_standard [2012/03/07 14:49 (14 years ago)] – [Detalles] zera | 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 ===== | ||
| - | |||