bytes.cat

La wiki d'FP d'informàtica

Eines de l'usuari

Eines del lloc


jocs_libgdx

Diferències

Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.

Enllaç a la visualització de la comparació

Ambdós costats versió prèvia Revisió prèvia
Següent revisió
Revisió prèvia
jocs_libgdx [2023/04/18 00:34]
enric_mieza_sanchez [Desenvolupament de jocs amb libGDX]
jocs_libgdx [2024/04/12 11:52]
enric_mieza_sanchez [Desenvolupament de jocs amb libGDX]
Línia 3: Línia 3:
  
 En aquest article utilitzarem una llibreria específica, libGDX per realitzar el joc. Aquesta té molts avantatges, sobretot que permet compilar en diverses plataformes (Android, Desktop, iOS, HTML). A més, ens permetrà utilitzar recursos gràfics específics que ens facilitaran operacions complexes en 2D i 3D amb acceleració OpenGL. En aquest article utilitzarem una llibreria específica, libGDX per realitzar el joc. Aquesta té molts avantatges, sobretot que permet compilar en diverses plataformes (Android, Desktop, iOS, HTML). A més, ens permetrà utilitzar recursos gràfics específics que ens facilitaran operacions complexes en 2D i 3D amb acceleració OpenGL.
- +{{ libgdx.png?250 }}
 {{tag> #FpInfor #Dam #DamMp08 #DamMp08Uf3 #DamMp08Uf03 jocs games}} {{tag> #FpInfor #Dam #DamMp08 #DamMp08Uf3 #DamMp08Uf03 jocs games}}
  
  
 Enllaços: Enllaços:
 +  - [[libGDX Comunicacions]] en aquesta wiki.
   - [[https://github.com/libgdx/libgdx/wiki|Documentació libGDX]].   - [[https://github.com/libgdx/libgdx/wiki|Documentació libGDX]].
   - [[https://libgdx.com/dev/project_generation/|Descàrrega eina per iniciar projectes]].   - [[https://libgdx.com/dev/project_generation/|Descàrrega eina per iniciar projectes]].
   - [[https://libgdx.com/dev/simple_game/#the-game|Tutorial joc Drop]].   - [[https://libgdx.com/dev/simple_game/#the-game|Tutorial joc Drop]].
  
-{{ drop-game.jpeg |Joc Drop del tutorial libGDX}}+\\ 
 + 
 +===== Instal·lació ===== 
 +Necessites tenir instal·lat Android Studio. 
 + 
 +Crea el projecte amb l'[[https://libgdx.com/dev/project_generation/|eina per iniciar projectes libGDX]]. 
 + 
 +==== Troubleshooting ==== 
 +Si t'apareix l'[[https://stackoverflow.com/questions/70340427/unable-to-find-method-void-org-apache-commons-compress-archivers-zip-zipfile|error relacionat amb la llibreria ZIP]] tens 2 opcions: 
 +  - Eliminar la compilació de la plataforma iOS. 
 +  - Editar ''android/build.gradle'' i ajustar les llibreries:<file text android/build.gradle> 
 +buildToolsVersion "33.0.0" 
 +</file> 
 + 
 +\\ 
 + 
 +===== Definicions ===== 
 +Objectes principals del //framework//: 
 +  * ''Game'': classe principal del joc, contenidor de pantalles. 
 +  * ''Screen'': hi encapsulem una pantalla (game over, presentació, etc.), nivell, minijoc. Cadascuna és independent de l'altra. 
 +  * ''OrtographicCamera'': objecte per traduir coordenades. Pot servir per adaptar tamanys de pantalla o per projectar en 2D una imatge 3D. 
 +  * ''SpriteBatch'': objecte per pintar //sprites// (imatges, animacions). 
 +  * ''ShapeRenderer'': objecte per pintar formes geomètriques (cercles, el·lipses, rectangles, triangles, etc. 
 +  * ''BitmapFont'': objecte per pintar lletres. 
 +  * ''Texture'': imatge. 
 +  * ''TextureRegion'': fragment d'una imatge. 
 +  * ''Animation'': objecte per gestionar les animacions i //spritesheets//
 +  * ''Actor'': objecte tipus //widget//, que pot ser alhora un element gràfic i una entrada de dades. Exemples: Button, Dialog, TextInputListener, etc. 
 +  * ''Stage'': objecte per renderitzar ''Actors''
 +  * ''Skin'': conjunt de imatges i fonts per renderitzar ''Actors''. Imprescindible si es vol emprar ''Actor'' i ''Stage''
 + 
 +\\
  
 ===== Primer joc: Drops ===== ===== Primer joc: Drops =====
 +
 +{{ drop-game.jpeg }}
 +
 <WRAP todo> <WRAP todo>
   - Crea un [[https://libgdx.com/dev/project_generation/|nou projecte amb aquesta eina]]. Puja'l a Github (i al Moodle).   - Crea un [[https://libgdx.com/dev/project_generation/|nou projecte amb aquesta eina]]. Puja'l a Github (i al Moodle).
Línia 295: Línia 329:
 <code java> <code java>
 Rectangle up, down, left, right, fire; Rectangle up, down, left, right, fire;
 +final int IDLE=0, UP=1, DOWN=2, LEFT=3, RIGHT=4;
 </code> </code>
  
Línia 340: Línia 375:
 ===== Comunicacions ===== ===== Comunicacions =====
  
-Llibreries de comunicacions: +<WRAP info> 
-  [[https://libgdx.com/wiki/networking|libGDX Networking doc]] per comunicacions HTTP. +Vés a l'article [[libGDX Comunicacions]] on podràs aprendre utilitzar: 
-  * [[https://github.com/MrStahlfelge/gdx-websockets|WebSockets plugin per a libGDX]] que ens permetran accions en temps real 8)+  * Crides HTTP/S estàndard 
 +  * Ús WebSockets per comunicacions a temps real
 +</WRAP>
  
 \\ \\
  
-==== WebSockets ==== +===== Ortographic Camera ===== 
-Podem seguir la [[https://github.com/MrStahlfelge/gdx-websockets|doc oficial del plugin de WebSockets per a libGDX]] però amb un canviposant ''api'' enlloc de ''compile''.+Tal i com explica el tutorial del Drop Game, la ''OrtographicCamera'' ens facilitarà la traducció entre les coordenades que hem definit pel joc (o "coordenades virtuals") i les coordenades reals del dispositiu (//device//), que poden tenir dimensions diferents. A més, al treballar amb una llibreria multiplataformavoldrem fer un sol joc a la carpeta ''core/'', i el codi de les carpetes de les plataformes (''android/'', ''ios/'', ''html/'') haurà de ser fix (no hem de repetir el joc a cada plataforma).
  
---> Arxius de configuració (Gradle, etc.)+Les operacions que realitzarà la càmera seran: 
-Afegiu les següent línies a les seccions adequades: +  Coordenades virtuals -> project -> Coordenades reals (//device//
-<file gradle build.gradle> +  Coordenades virtuals <- unproject <- Coordenades reals (//device//)
-allprojects { +
-    ext { +
-        wsVersion = '1.9.10.3' +
-    } +
-    repositories { +
-        maven { url "https://jitpack.io"+
-    } +
-}+
  
-project(":desktop") { +Posant que volem una pantalla de 800x480
-    dependencies { +
-        api "com.github.MrStahlfelge.gdx-websockets:common:$wsVersion" +
-    } +
-}+
  
-project(":android") { +<file java DesktopLauncher.java> 
-    dependencies { +public class DesktopLauncher 
-        api "com.github.MrStahlfelge.gdx-websockets:common:$wsVersion" +    public static void main (String[] arg) { 
-    +        Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); 
-+        config.setWindowedMode(480, 800);
- +
-project(":html"+
-    dependencies +
-        api "com.github.MrStahlfelge.gdx-websockets:core:$wsVersion:sources" +
-        api "com.github.MrStahlfelge.gdx-websockets:html:$wsVersion" +
-        api "com.github.MrStahlfelge.gdx-websockets:html:$wsVersion:sources" +
-    } +
-+
- +
-project(":core"+
-    dependencies { +
-        api "com.github.MrStahlfelge.gdx-websockets:core:$wsVersion" +
-    } +
-}+
 </file> </file>
  
-<file xml GdxDefinition.gwt.xml> +A l'arxiu de ''Game'' o ''Screen'':
-  <inherits name='com.github.czyzby.websocket.GdxWebSocketGwt/> +
-  <inherits name='com.github.czyzby.websocket.GdxWebSocket/> +
-</file>+
  
-Recordeu també que per tal que funcionin les comunicacions en Android cal activar els permisos adequats:+<code java> 
 +public final int GAME_WIDTH = 800; 
 +public final int GAME_HEIGHT = 480;
  
-<file xml AndroidManifest.xml> +public void create() { 
-    <uses-permission android:name="android.permission.INTERNET" /> +        camera new OrthographicCamera(); 
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> +        camera.setToOrtho(false, GAME_WIDTHGAME_HEIGHT); 
-</file> +         
-<-- +        //...
- +
-Per connectar-nos al servidor des de l'app libGDX ho fem així: +
-<file java GameScreen.java> +
-class GameScreen extends Screen { +
-    WebSocket socket; +
-    String address = "localhost"; +
-    int port = 8888; +
-     +
-    // constructor de l'objecte Screen +
-    public GameScreen { +
-        if( Gdx.app.getType()== Application.ApplicationType.Android ) +
-            // en Android el host és accessible per 10.0.2.2 +
-            address = "10.0.2.2"; +
-        socket = WebSockets.newSocket(WebSockets.toWebSocketUrl(address, port)); +
-        socket.setSendGracefully(false); +
-        socket.addListener((WebSocketListener) new MyWSListener()); +
-        socket.connect(); +
-        socket.send("Enviar dades"); +
-    } +
-     +
-    // Es poden enviar dades al render() en tems real! +
-    // Millor no fer-ho a cada frame per no saturar el server +
-    // ni ralentitzar el joc +
-    public void render() { +
-        if( stateTime-lastSend > 1.0f ) { +
-            lastSend stateTime; +
-            socket.send("Enviar dades"); +
-        +
-    } +
- +
-    // COMUNICACIONS (rebuda de missatges) +
-    ///////////////////////////////////////////// +
-    class MyWSListener implements WebSocketListener { +
- +
-        @Override +
-        public boolean onOpen(WebSocket webSocket) { +
-            System.out.println("Opening..."); +
-            return false+
-        } +
-     +
-        @Override +
-        public boolean onClose(WebSocket webSocketint closeCodeString reason+
-            System.out.println("Closing..."); +
-            return false+
-        +
- +
-        @Override +
-        public boolean onMessage(WebSocket webSocket, String packet) { +
-            System.out.println("Message:"); +
-            return false; +
-        } +
-     +
-        @Override +
-        public boolean onMessage(WebSocket webSocket, byte[] packet) { +
-            System.out.println("Message:"); +
-            return false; +
-        } +
- +
-        @Override +
-        public boolean onError(WebSocket webSocket, Throwable error) { +
-            System.out.println("ERROR:"+error.toString()); +
-            return false; +
-        } +
-    }+
 } }
-</file>+</code>
  
-=== Servidor WebSockets en NodeJS ===+Per fer que el ''SpritBatch'' tradueixi automàticament en totes les accions de dibuix, el configurarem a l'inici del ''render()'': 
  
-Podem emprar la [[https://www.npmjs.com/package/ws|llibreria WS per a NodeJS]]. +<code java
-   +public void render() { 
---Servidor HTTP + WebSockets amb NodeJS# +        camera.update(); 
- +        spriteBatch.setProjectionMatrix(camera.combined); 
-Ens caldrà crear un projecte NodeJS i instal·lar les llibreries: +         
-  $ mkdir ws1 +        //...
-  $ cd ws1 +
-  $ npm init +
-  $ npm install http ws +
- +
-Afegeix ''index.js'' i posa'l en marxa: +
-  $ node index.js +
- +
-Cal indicar el projecte com a "module": +
-<file javascript package.json> +
-{ +
-  "name": "ws1", +
-  "type": "module", +
-  ...+
 } }
-</file>+</code>
  
-<file javascript index.js> +Si estem capturant entrades de la pantalla, caldrà la operació contrària: ''unproject()''
-import { createServer } from 'http'+
-import { WebSocketServer } from 'ws';+
  
-const server = createServer(); +<code java> 
-const wss = new WebSocketServer({ server });+protected int virtual_joystick_control() 
 +    // iterar per multitouch 
 +    // cada "i" és un possible "touch" d'un dit a la pantalla 
 +    for(int i=0;i<10;i++) 
 +    if (Gdx.input.isTouched(i)) { 
 +        Vector3 touchPos = new Vector3(); 
 +        touchPos.set(Gdx.input.getX(i), Gdx.input.getY(i), 0); 
 +        // traducció de coordenades reals (depen del dispositiu) a 800x480 
 +        game.camera.unproject(touchPos); 
 +        // les dades convertides s'enregistren a la mateixa variable touchPos 
 +        //... 
 +</code>
  
-wss.on('connection', function connection(ws) { +\\
-  console.log("Nova connexió."); +
-  ws.send('something');+
  
-  ws.on('error'console.error);+===== Actors, Scenes i Skins ===== 
 +Per fer controls avançats com Buttons, Dialogs, etchem de tenir en compte que son elements tant de renderització com de entrada de dadesi es tracten de forma especialEn caldrà emprar els objectes ''Stage'' i ''Skin'':
  
-  ws.on('message', function message(data) { +Algunes referències: 
-    console.log('received: %s', data); +  * [[https://stackoverflow.com/questions/33062574/how-to-properly-implement-a-dialog-box-using-libgdx|Com fer un Dialog]]
-  });+  * [[https://github.com/BlueBoxWare/LibGDXPlugin|libGDX plugin per IntelliJ (Android Studio)]] 
 +  * [[https://github.com/libgdx/libgdx-skins/tree/master/skins|Skins bàsics]] 
 +  * [[https://github.com/czyzby/gdx-skins|Mes skins]]
  
-  ws.on('close', function close() { +IMPORTANT: perquè funcioni el skin cal descarregar tots els arxius a la carepta assets.
-    console.log("Tancant connexió."+
-  }) +
- +
-}); +
- +
-server.listen( 8888, function() { +
-  console.log("listening..."); +
-}); +
- +
-</file> +
-<-- +
- +
-=== Exercicis === +
-<WRAP todo> +
-Implementa el servidor NodeJS indicat. +
- +
-Afegeix la llibreria de WebSockets al teu joc libGDX i fes que envii la posició del nostre personatge 1 cop per segon. +
- +
-Assegura't que funciona comprovant que el servidor mostra el missatge de posicionament del personatge a la seva consola. +
-</WRAP>+
  
 \\ \\
  
-==== JSON and Jackson ==== 
-Per treballar amb comunicacions és probable que us calgui codificar i descodificar JSON. Una opció és la [[https://www.arquitecturajava.com/java-json-con-jackson/|llibreria Jackson de Java]], que podem afegir al projecte amb Gradle: 
-<file gradle gradle.settings> 
-project(":core") { 
-    dependencies { 
-        implementation 'com.fasterxml.jackson.core:jackson-core:2.10.1' 
-        implementation 'com.fasterxml.jackson.core:jackson-annotations:2.10.1' 
-        implementation 'com.fasterxml.jackson.core:jackson-databind:2.10.1' 
-    } 
-} 
-</file> 
jocs_libgdx.txt · Darrera modificació: 2024/04/12 11:52 per enric_mieza_sanchez