Bonjour,
Cette semaine j’ai du rendre pour l’école des gobelins le jeux que j’ai fait avec un framework java. Comme ce projet est fini, et que je ne pense pas que je vais en faire grand chose de mon coté, je vais vous en expliquer le fonctionnement. Peut être que ça vous sera utile.
I) Installation
L’installation de slick dans un projet eclipse est assez déroutante pour un newbie JAVA (j’y ai passé une demi journée de cours ^^) même avec un très bon (l’unique ?) tutoriel d’installation. Faites bien attention au dernier point, c’est important.
En fait Slick est basé sur un autre framework nommée lwgl, il y a donc deux librairies pour le prix d’une. Vive la réutilisation ! Slick étant un framework dédié aux un jeux 2D, il fait le ménage dans lwgl des choses non indispensables et rajoute tout ce qui va bien pour la 2D.
Passons au code !
II) Premier Exemple
Je pars du principe que votre installation est fonctionnelle. Voici le code de mon premier test slick. Il s’agissait d’afficher une image, un test, et grâce au clavier de faire pivoter cette image. Le principe de base est le même pour le jeux final.
J’ai commenter tout le code pour vous expliquer pas à pas ce qu’il se passe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | import org.newdawn.slick.BasicGame; import org.newdawn.slick.GameContainer; import org.newdawn.slick.Graphics; import org.newdawn.slick.Image; import org.newdawn.slick.Input; import org.newdawn.slick.SlickException; import org.newdawn.slick.AppGameContainer; import org.newdawn.slick.util.Log; //Il faut étendre la classe BasicGame public class SimpleTest extends BasicGame { // L'image tourne, il faut un petit angle non ? // En fait il en faut un pour se souvenir d'un FPS à l'autre de combien il // faut tourner l'image. public Integer angle_image = 0; public Image imgToTurn; // Il faut un constructeur de base. // Vous noterez que toutes les erreurs seront catchés au moment de // l'exécution. (c'est à dire, dans le main) public SimpleTest() throws SlickException { // Initialise le nom de la fenetre .. super("SimpleTest"); // Très pratique pour débuger l'application. Remplace le // System.out.println .. et plus si affinié Log.info("je viens d'être initialisé"); } // Initialise mes objets. Exécuté au lancement du jeux. @Override public void init(GameContainer container) throws SlickException { // J'ai besoin d'une image. imgToTurn = new Image("ressources/images/woman.jpg"); } // Méthode appelé en boucle. C'est ici que l'on fait vivre nos objets // "non graphique" comme la gestion des touches, de nos propriétés (comme // angle) etc @Override public void update(GameContainer container, int delta) throws SlickException { // Si on appuie sur la fleche Haut if (container.getInput().isKeyDown((Input.KEY_UP))) { angle_image++; } // Si on appuie sur la fleche Bas if (container.getInput().isKeyDown(Input.KEY_DOWN)) { angle_image--; } // On fait en sorte que notre angle "tourne en rond" ^^ if (angle_image > 360) angle_image = 0; } // Méthode appelé en boucle. C'est ici qu'on gére l'affichage. @Override public void render(GameContainer container, Graphics g) throws SlickException { // Affiche un hello world en x:0 et y:100 g.drawString("Hello, Slick world!", 0, 100); g.drawString("coucou", 0, 150); // Je fais tourner l'image imgToTurn.setRotation(angle_image); // Et je la rajoute à ma fenetre g.drawImage(imgToTurn, 200, 0); } public static void main(String[] args) { try { // Démarre un jeux à partir de ma classe AppGameContainer app = new AppGameContainer(new SimpleTest()); app.setTargetFrameRate(500); app.start(); } catch (SlickException e) { // Et c'est ici que je catch les erreurs de toutes mes méthodes. e.printStackTrace(); } } } |
Wahou non ? on a fait un jeux à partir de 5 fonctions, dans l’ordre :
- constructeur() – Spécifie la fenetre de jeux (icone, intitulé de fenetre ..)
- init() – Initialise tout nos objets
- update() – Gestion du clavier et mis à jours d’objet non graphique
- render() – Gestion de l’affichage, c’est là qu’on affiche ou non des éléments graphiques (image, texte, animation, etc)
- main() – Il faut bien un point d’entré non ? On peut aussi s’en servir comme point de récupération des erreurs.
Bon ca casse pas trois pattes à un canard, mais en moins de 100 lignes de codes avec les commentaires on s’en sort plutôt pas mal non ?
![]() |
![]() |
III) Pour aller plus loin
Vous avez vu comment créer une fenetre, l’animer, et utiliser les écouteurs de touches. A ce stade là, vous pouvez commencer à créer vos jeux. Mais ne partez pas sans connaitre une fonctionnalité vraiment sympa dans Slick, le support de Tiled.
Tiled est un générateur de carte en java comme vous pouvez le voir 
En fait, en créant une carte avec Tiled, vous avez la possibilité de définir des propriétés pour chaque case (appelé tile) et vous pouvez les lire en Java très simplement. Voici un extrait de ma fonction init() (souvenez vous, c’est là qu’on initialise tout le jeux). Action !
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // Charge la map map = new TiledMap("ressources/level/lvl1.tmx"); // Initialise mes différents vecteurs caseGagnante = new Vector(); blocked = new Vector(); // build a collision map based on tile properties in the TileD map for (int x = 0; x < map.getWidth(); x++) { for (int y = 0; y < map.getHeight(); y++) { int tileID = map.getTileId(x, y, 1); // Hydratation du vecteur de Collision String value = map.getTileProperty(tileID, "blocked", "false"); if ("true".equals(value)) { blocked.add(new Point(x, y)); } // Hydratation du vecteur de case Gagnante String value2 = map.getTileProperty(tileID, "winCase", "false"); if ("true".equals(value2 )) { caseGagnante.add(new Point(x, y)); } } } |
Et voilà, vous avez deux beaux vecteur rempli de bonne choses que vous pourrez exploiter par la suite. Par exemple, pour savoir si la position où l’on veut allé est « blocked » :
1 2 3 4 | private boolean blocked(float x, float y) { // Log.info((int)x+"-"+(int)y +" bloquer ?"); return blocked.contains(new Point((int) x, (int) y)); } |
Ou bien, autre façon pour savoir si on est sur une case gagnante c’est de parcourir le vecteur à la main :
1 2 3 4 5 6 7 8 9 10 | // Test si on est sur une case Gagnante for (int j = 0; j < caseGagnante.size(); j++) { Point point = caseGagnante.elementAt(j); if ((int) point.getX() == (int) playerX && (int) point.getY() == (int) playerY) { lvlComplete = true; } } // que l'on aurait pu simplifier par lvlComplete = caseGagnante.contains( new Point( (int)playerX, (int) playerY)); |
IV) Autres éléments
Vous avez vu que les images sont gérer de façon vraiment simple dans Slick (cf SimpleTest), et bien les sons c’est la même chose. Voyez par vous même :
1 2 3 4 5 6 7 8 | // On joue un son wav try { Sound fireSound = new Sound("ressources/sound/rocket-Part1.wav"); fireSound.play(); } catch (SlickException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } |
Et il y a la classe Animation, qui permet à partir de plusieurs images de créer dynamiquement une animation type gif. Si votre personnage est définit sur plusieurs images, vous pouvez le faire courir très simplement :
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Charge la libraire graphique SpriteSheet sheet = new SpriteSheet("ressources/images/sprites.png", 32, 32); // create the player sprite based on a set of sprites from the sheet // loaded above (tank tracks moving) Animation player = new Animation(); for (int frame = 0; frame < 7; frame++) { player.addFrame(sheet.getSprite(frame, 1), 150); // 150 est la duré de l'animation en milliseconde } player.setAutoUpdate(false); // Puis quand vous voulez jouer l'animation, dans la méthode update par exemple player.update(delta); // delta représente un entier, la clé de la frame à afficher. |
Voici d’autres éléments que je n’ai pas testé mais qui ont l’air bien :
- Il y a une classe Music qui a l’air sympa vu que l’on peut ajouter des écouteurs d’évènement sur la musique en cours..
- Le pathFinding est aussi géré. Ça a l’air assez simple.
- Un générateur de particule est intégré O_o J’aurais pu faire mes explosions avec ^^
V) Conclusion
Voici mon projet éclipse au complet, libre à vous de vous en inspirer/copier/critiquer.
Sinon mon jeux est bidon au passage. C’est un pauvre Tank qui doit se déplacer d’un point A à un point B sans se faire exploser par des tourelles, et y a 5 map (la flemme d’en générer plus avec Tiled). Voilà voilà.
Pour en revenir à Slick :
- c’est sympa
- c’est simple
- Y a une bonne documentation dans l’ensemble (en francais aussi O_o)
- faut essayer.
Bonne journée









le 15 février 2009 à 15h18
Salut !
Je ne connaissais pas Slick, je trouve ce logiciel fort intéressant et bien conçu (à vu d’oeil avec Tiled il semble assez facile à prendre en mains et permet visiblement de produire quelquechose en peu de temps).
C’est donc le type de soft que je recherche, pour créer des maps 2D et pour gérer facilement les collisions.
J’aimerais développer un petit jeu pour NintendoDS, je ne suis pas seul sur ce projet. Je code en C, mais j’aimerais trouver un logiciel très similaire pour faire mes maps aisément… que me conseillez-vous ?
Je reviendrais ici pour voir la rep’ ;)
Par avance merci, et bonne continuation :)
le 15 février 2009 à 16h11
Salut,
Wahou mon premier commentaire d’un inconnu ! Je vais essayer d’être utile pour une fois :)
Petite précision : slick est un framework, non un logiciel. Il permet d’en créer si on veut. C’est qu’une couche « sur » le java, qui permet d’automatiser un certain nombre de choses, dont la gestion de la map.
Je ne verse pas encore dans le développement sous DS (ça ne saurait tarder ^^) et je suis allé voir ton site et ton projet de jeux, Cells. Tu as l’air d’avoir une alpha alpha beta test fort sympathique et ça serait bien, pour toi comme pour les autres, que tu présente ton code comme je l’ai fait pour cet article. (Pourquoi pas sur ce blog :D) enfin bon passons.
Alors, pour te répondre, si tu es un cador en C tu peux quand même utilisé Titled qui te fournira un fichier xml « .tmx » qui, une fois parser, permettra de retrouver tout tes éléments en code. Mais bon le parsage et l’exploitation d’un tel fichier peut quand même s’avérer chiante. Essayons de voir ceux que google en pense.
Après quelque recherche, je vois que nintendo DS repose en partie sur la librairie SDL, et je suis tombé sur ces posts qui m’ont l’air intéressant :
http://www.gamedev.net/community/forums/topic.asp?topic_id=218066
http://forums.devshed.com/game-development-141/c-c-2d-sdl-tile-based-game-gravity-problem-422769.html
Bref, « tile SDL game » dans google donne de bon résultat. Mais bon nous on a « Tiled » et si on veut l’utiliser correctement le parsage de l’xml a sous doute était déjà fait ! Alors testons « tiled C++ » dans google… et marche encore mieux :
http://gametuto.com/in-game-c-map-editor-tutorial-with-indielib-engine-that-dosent-use-tiles-but-pieced-images-like-in-braid-or-aquaria-games/
et
http://files.codes-sources.com/fichier.aspx?id=48005&f=Sources%2fOpenGLMap.h
Je pense que le deuxième lien pourrait t’intéresser. C’est le portage de Tiled en C++.
Have Fun !
le 18 mars 2010 à 21h38
J’apprécie beaucoup le » Thu Mar 18 20:34:16 CET 2010 INFO:supprime toi connard » dans la console ^^.
le 18 mars 2010 à 22h29
Ma marque de fabrique !