La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Dév. d’application interactive III Tile Engine. Plan de leçon  Moteur de tuiles (tile engine)  Définition  Classes  Dans le cadre de ce cours, nous.

Présentations similaires


Présentation au sujet: "Dév. d’application interactive III Tile Engine. Plan de leçon  Moteur de tuiles (tile engine)  Définition  Classes  Dans le cadre de ce cours, nous."— Transcription de la présentation:

1 Dév. d’application interactive III Tile Engine

2 Plan de leçon  Moteur de tuiles (tile engine)  Définition  Classes  Dans le cadre de ce cours, nous allons construire un moteur de tuile (tile engine) qui pourra être utilisé dans tous les projets XNA  Ce sera un développement itératif, i.e. que l’on fera plusieurs versions

3 Moteur de tuile : Définition  Un moteur de tuile (TE) est une technique qui permet de générer une grand objet graphique à partir de plus petits objets  Cette technique permet d’économiser de l’espace mémoire (RAM) ainsi que d’améliorer le processus d’affichage

4 Moteur de tuile : Définition  Le principe est d’utiliser une feuille de textures qui contient plusieurs tuiles ainsi qu’une matrice de deux dimensions qui contient des adresses de tuiles  En adressant chaque tuile à chaque cellule de la matrice, on peut générer une grande image de façon efficace  En plus de l’affichage, on peut ajouter des éléments de collision ainsi que plusieurs couches à l’intérieur de la même matrice

5 Moteur de tuile  Dans la première version, nous allons utiliser une feuille de tuile simple avec seulement 1 rangée de 4 tuiles

6 Les classes  Les classes utilisées seront les suivantes pour la version 1

7 Les classes  MapCell représente une cellule de la carte  MapRow représente une rangée de la carte et contient une liste de cellules  TileMap représente la carte et contient une collection de MapRow  Tile est la texture  Camera est la vue de la carte

8 Classe : MapCell package models; public class MapCell { int tileID; public int getTileID() { return tileID; } public void setTileID(int tileID) { this.tileID = tileID; } public MapCell(int tileID) { super(); this.tileID = tileID; }

9 Classe : MapRow public class MapRow { ArrayList columns; public MapRow() { columns = new ArrayList (); } public MapCell getCell(int cellIndex) { return columns.get(cellIndex); }

10 Classe : TileMap public class TileMap { ArrayList rows = new ArrayList (); int mapWidth = 50; int mapHeight = 50; public TileMap() { super(); for (int y = 0; y < mapHeight; y++) { MapRow currentRow = new MapRow(); for (int x = 0; x < mapWidth; x++) { currentRow.columns.add(new MapCell(0)); } rows.add(currentRow); } generateTest(); } Fait une carte 2D Dimension de la carte en nombre de tuiles Initialisation de la carte

11 Classe : TileMap private void generateTest() { // Début de la création rows.get(0).columns.get(3).setTileID(2); rows.get(0).columns.get(4).setTileID(2); rows.get(0).columns.get(5).setTileID(2); rows.get(0).columns.get(6).setTileID(2); rows.get(0).columns.get(7).setTileID(2); rows.get(1).columns.get(3).setTileID(1); rows.get(1).columns.get(4).setTileID(1); rows.get(1).columns.get(5).setTileID(1); rows.get(1).columns.get(6).setTileID(1); rows.get(1).columns.get(7).setTileID(1); rows.get(2).columns.get(2).setTileID(3); rows.get(2).columns.get(3).setTileID(3); rows.get(2).columns.get(4).setTileID(3); rows.get(2).columns.get(5).setTileID(3); rows.get(2).columns.get(6).setTileID(3); rows.get(2).columns.get(7).setTileID(1); rows.get(3).columns.get(2).setTileID(3); rows.get(3).columns.get(3).setTileID(1); rows.get(3).columns.get(4).setTileID(1); rows.get(3).columns.get(5).setTileID(2); rows.get(3).columns.get(6).setTileID(2); rows.get(3).columns.get(7).setTileID(2); rows.get(4).columns.get(2).setTileID(3); rows.get(4).columns.get(3).setTileID(1); rows.get(4).columns.get(4).setTileID(1); rows.get(4).columns.get(5).setTileID(2); rows.get(4).columns.get(6).setTileID(2); rows.get(4).columns.get(7).setTileID(2); rows.get(5).columns.get(2).setTileID(3); rows.get(5).columns.get(3).setTileID(1); rows.get(5).columns.get(4).setTileID(1); rows.get(5).columns.get(5).setTileID(2); rows.get(5).columns.get(6).setTileID(2); rows.get(5).columns.get(7).setTileID(2); // Fin de la création }

12 Classe : Tile public final class Tile { static final int TILESIZE = 32; static Texture tileSetTexture; public static Rectangle getSourceRectangle(int tileIndex) { return new Rectangle(tileIndex * TILESIZE, 0, TILESIZE, TILESIZE); } public static Texture getTileSetTexture() { return tileSetTexture; } public static void setTileSetTexture(Texture tileSetTexture) { Tile.tileSetTexture = tileSetTexture; } Retourne le rectangle représentant la position de la tuile en index

13 Classe : Camera /// /// Classe statique permettant de définir la position de la vue sur /// la carte /// public final class Camera { static Vector2 location = Vector2.Zero; public static Vector2 getLocation() { return location; }

14 Test //Dans la zone de déclaration de variables SpriteBatch batch; TileMap map = new TileMap(); int carreLargeur = 5; int carreHauteur = 5; int tileSize = 32; //Dans le Create Tile.setTileSetTexture (new Texture("part1_tileset.png")); Ce que l’on veut afficher de la carte

15 Test Gdx.gl.glClearColor(1, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); /** * Calculs pour le premier carré en haut à gauche */ Vector2 firstSquare = new Vector2( Camera.getLocation().x / (float)tileSize, Camera.getLocation().y / (float)tileSize); int firstX = (int) firstSquare.x; int firstY = (int) firstSquare.y; /** * Calcul pour le décalage pour la camera pour les côtés */ Vector2 squareOffset = new Vector2( Camera.getLocation().x % tileSize, Camera.getLocation().y % tileSize); int offsetX = (int)squareOffset.x; int offsetY = (int)squareOffset.y; //…

16 Test //… for (int y = 0; y < carreHauteur; y++) { int positionY = (y * tileSize) - offsetY; for (int x = 0; x < carreLargeur; x++) { // Va chercher le rectangle de la tuile à afficher Rectangle srcRect = Tile.getSourceRectangle(map.getRow(y + firstY).getCell(x + firstX).getTileID()); batch.draw(Tile.getTileSetTexture(), (x * tileSize) - offsetX, positionY, (int)srcRect.x, (int)srcRect.y, (int)srcRect.width, (int)srcRect.height); } batch.end(); Après ce code, il devrait être exécutable

17 Test 2  Dans le Update KeyboardState ks = Keyboard.GetState(); // Allows the game to exit if (ks.IsKeyDown(Keys.Escape)) this.Exit(); if (ks.IsKeyDown(Keys.Left)) Camera.Location.X = MathHelper.Clamp(Camera.Location.X - 2, 0, (myMap.MapWidth - squaresAcross) * tileSize); if (ks.IsKeyDown(Keys.Right)) Camera.Location.X = MathHelper.Clamp(Camera.Location.X + 2, 0, (myMap.MapWidth - squaresAcross) * tileSize); //…

18 Test 2  Dans le Update if (ks.IsKeyDown(Keys.Up)) Camera.Location.Y = MathHelper.Clamp(Camera.Location.Y - 2, 0, (myMap.MapHeight - squaresDown) * tileSize); if (ks.IsKeyDown(Keys.Down)) Camera.Location.Y = MathHelper.Clamp(Camera.Location.Y + 2, 0, (myMap.MapHeight - squaresDown) * tileSize); } On déplace la caméra en X et Y en limitant entre deux bornes

19 Résultats  On observe que la carte affichée est de 5 x 5, soit les valeurs de carreHauteur et carreLargeur  Ainsi on limite l’affichage dans le Draw  La limite est de 50 tuiles de largeur et hauteur  Cette valeur est définie dans TileMap

20 Moteur de tuiles Version 2 Tuile transparente

21 Description  Dans la version 1, le jeu de tuiles n’avait qu’une seule rangée avec des tuiles de dimensions fixes  Dans un premier temps nous allons utiliser un autre jeu de tuiles.  Ensuite mettre à jour la classe Tile et le Update du jeu pour éliminer les valeurs « hardcodées »

22 Jeu de tuiles Ajouter ce jeu dans le même que le premier jeu

23 Classe : Tile  Modifier les dimensions pour qu’elles soient de 48x48 en ajoutant les propriétés TileWidth et TileHeight  Maintenant que c’est un jeu de tuile 2D, il faudra modifier la méthode GetSourceRectangle pour retourner la bonne position int tileY = tileIndex / (TileSetTexture.Width / TileWidth); int tileX = tileIndex % (TileSetTexture.Width / TileWidth); return new Rectangle(tileX * TileWidth, tileY * TileHeight, TileWidth, TileHeight);

24 Game  Dans Game Update, modifier le code où est utilisé la variable tileSize pour utiliser les nouvelles propriétés publics de Tile  Faire de même pour la méthode Draw  Si on exécute, on devrait avoir un résultant un peu désorganisé  Pourquoi et comment on corrige?

25 Les couches  Dans la première version, on ne pouvait qu’afficher qu’une seule texture par cellule  Ce n’était pas un problème car chaque tuile occupait l’espace entier  Cependant la transition entre deux terrains était brusque  Plusieurs options existent, mais certaines sont meilleures que d’autres

26 Les couches  On pourrait dessiner chaque transition existante pour chaque tuile  C’est commun et ce n’est pas un problème si le nombre de tuiles est petit  Dans le cas de 4 tuiles différentes, il faudrait 16 transitions et ce seulement dans le sens des transitions horizontales  Pas efficace…  Si on augmente le nombre de tuiles, il faudrait faire le carré pour obtenir le nombre de transitions possibles (horizontales)

27 Les couches  Une autre méthode serait de programmer des règles pour limiter les choix  Par exemple la transition désert/glace serait impossible  Une autre façon est d’utiliser la transparence des tuiles. Ainsi ces tuiles pourraient être dessinées par dessus d’autres tuiles de base  Cette méthode sera préconisée car elle réduit considérablement le nombre de tuiles

28 Classe : MapCell  Pour faire en sorte que l’on accepte plusieurs tuiles empilées, il faudra modifier la définition de la cellule  Modifier la classe MapCell pour ajouter la liste suivante  public List BaseTiles = new List ();  Cela permettra d’empiler un nombre infini de tuiles sur la même cellule

29 Classe : MapCell  Modifier la propriété TileID de la classe MapCell public void setTileID(int tileID) { if (baseTiles.size() > 0) { baseTiles.set(0, tileID); } else baseTiles.add(tileID); }

30 Classe : MapCell  Ajouter la méthode suivante public void AddBaseTile(int tileID) { BaseTiles.Add(tileID); }  Cette commande permet d’empiler les tuiles  La première tuile sera celle de base

31 Dessiner les tuiles  Une fois que la classe des cellules a été modifiée, on voudrait dessiner chaque tuile de chaque cellule  Dans la méthode Draw, trouver le draw du batch et modifier celle-ci par le code suivant for (int tileId : map.getRow(y + firstY).getCell(x + firstX).getBaseTiles()) { // Va chercher le rectangle de la tuile à afficher Rectangle srcRect = Tile.getSourceRectangle(tileId); batch.draw(Tile.getTileSetTexture(), (x * Tile.tileWidth) - offsetX, positionY, (int)srcRect.x, (int)srcRect.y, (int)srcRect.width, (int)srcRect.height); }

32 Dessiner les tuiles  On se retrouve à parcourir 3 boucles pour dessiner la carte  En gros, on enveloppe batch.draw pour qu’elle dessine chaque tuile

33 Classe : TileMap  Pour tester la transition, ajoutons des tuiles à la carte actuelle  À la fin de la création de la méthode drawTest() dans TileMap, ajouter les tuiles suivantes Rows[3].Columns[5].AddBaseTile(30); Rows[4].Columns[5].AddBaseTile(27); Rows[5].Columns[5].AddBaseTile(28); Rows[3].Columns[6].AddBaseTile(25); Rows[5].Columns[6].AddBaseTile(24); Rows[3].Columns[7].AddBaseTile(31); Rows[4].Columns[7].AddBaseTile(26); Rows[5].Columns[7].AddBaseTile(29); Rows[4].Columns[6].AddBaseTile(104);

34 Exercices  Dans le fichier de jeu, modifiez la dimension d’affichage de la caméra pour qu’elle s’adapte à la dimension de l’écran  Créez une carte avec les tuiles à votre disposition


Télécharger ppt "Dév. d’application interactive III Tile Engine. Plan de leçon  Moteur de tuiles (tile engine)  Définition  Classes  Dans le cadre de ce cours, nous."

Présentations similaires


Annonces Google