0) Initialisation :
Lancer gdx_setup remplir les champs et cliquez sur Advanced et cochez IDEA puis generate
1°) Mise en place du cadre du jeux :
Remarque : pour le debug, précisez :
Gdx.app.setLogLevel(Application.LOG_DEBUG);
Après la méthode create()
Et en cours de jeux utilisez
Gdx.app.log("MyTag", "my informative message");
a) délimitation de la zone de jeux :
La zone de l’écran est à différentier de la zone de jeux. Il est préférable de définir une classe « Constants » qui contiendra les paramètres de la taille d’écran souhaité. Pour plus d’info : http://www.gamefromscratch.com/post/2014/12/09/LibGDX-Tutorial-Part-17-Viewports.aspx
public class Constants {
//-- Dimension de la fenêtre visible
//800x480 = paysage ; 768x1280 = portrait
public final static int V_WIDTH = 800;//768;
public final static int V_HEIGHT = 480;//1280;
//-- Dimensions de la zone de jeux
public static int VIEWPORT_WIDTH = 312;
public static int VIEWPORT_HEIGHT = 192;
}
Ensuite, il suffit dans DesktopLauncher.java de préciser :
config.width=V_WIDTH; config.height=V_HEIGHT;
Avant la ligne « new LwjglApplication(new MyGdxGame(), config); »
Pour gérer les écrans voir le paragraphe sur les écrans
Pour gérer l’espace de jeux, il est nécessaire d’utiliser une « caméra orthographique ». Cette caméra sera définie par « OrthographicCamera cam; » dans la classe de l’écran de jeux et initialisée dans la méthode create par les instructions :
cam =
new
OrthographicCamera();
cam.setToOrtho(
false
, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
où les paramètres sont false pour utiliser l’axe des y, et les paramètres de taille définis dans la classe « Constants ».
Pour faire en sorte que l’écran du jeux soit en phase avec la camera utilisez :
batch.setProjectionMatrix(camera.combined);
Pour placer une texture (un sprite) dans la vue de la caméra, dans la méthode create placez :
sb =
new
SpriteBatch();
sb.setProjectionMatrix(cam.combined);
img =
new
Texture(
"badlogic.jpg"
);
Puis dans la méthode render
sb.begin();
sb.draw(img, 0, 0);
sb.end();
Désinnera l’image aux coordonnées 0,0 de la vue de la caméra.
Références :
http://www.norakomi.com/tutorial_mambow2_config.php
https://www.badlogicgames.com/wordpress/?p=1550
ATTENTION : tout objet graphique doit libérer la mémoire à la fin du jeux donc ajouter la méthode dispose :
@Override public void dispose() { this.img.dispose(); this.sb.dispose(); }
b) gestion des enchaînements des écrans de jeux :
Un jeux se compose souvent d’un écran d’accueil, un ou plusieurs écrans de jeux (tableaux), puis un écran de fin de jeux avec le score.
La classe principale du jeux doit étendre Game
public class MyGdxGame extends Game {
Le SpriteBatch, consommant beaucoup de mémoire doit être déclaré public pour pouvoir être utilisé dans tous les écrans.
Et dans la méthode Create
setScreen(new PlayScreen(this));
Dans render uniquement
super.render();
Afin de déléguer la gestion des écrans aux écrans. Ainsi la classe principale du jeux sera :
public class MyGdxGame extends Game {
public SpriteBatch batch;
@Override
public void create() {
batch = new SpriteBatch();
setScreen(new PlayScreen(this));
}
@Override
public void render() {
super.render();
}
}
Puis créez un package « Screens » dans lequel sera placé vos classes des écrans (notamment « PlayScreen »)
public class PlayScreen implements Screen {
private MyGdxGame game;
public PlayScreen(MyGdxGame game) {
this.game = game;
}
@Override
public void show() {
}
@Override
public void render(float delta) {
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
}
@Override
public void dispose() {
}
}
Pour dessiner une texture dans « render » il faudra écrire :
game.batch.begin();
game.batch.draw(texture,0,0);
game.batch.end()
Pour définir une caméra et avoir un écran qui puisse se redimentionner sans déformer les images utilisez
FitViewport
Ecrans de jeux :
Scene2D : permet de manipuler tous les éléments d’un jeux (cf. Acteurs et actions…)
Un « HUD » est un écran permettant d’afficher en continu les variables d’un jeux (score, vies,…) il se défini par la classe :
public class Hud {
//head-up display : show Most info that stay visible during gameplay
public Stage stage;
private Viewport viewport; //-- Specific viewport for the static view of the HUD
private Integer worldTimer;
private float timeCount;
private Integer score;
Label countdownLabel;
Label scoreLabel;
Label timeLabel;
Label levelLable;
Label worldLabel;
Label gameLabel;
public Hud(SpriteBatch sb)
{
worldTimer=300;
timeCount=0;
score=0;
viewport=new FitViewport(V_WIDTH,V_HEIGHT,new OrthographicCamera());
//-- Définition de l'écran
stage=new Stage(viewport,sb);
//-- On rempli notre écran
Table table=new Table();
table.top(); //-- Bandeau haut
table.setFillParent(true);
countdownLabel=new Label(String.format("%3d",worldTimer),new Label.LabelStyle(new BitmapFont(), Color.WHITE));
scoreLabel =new Label(String.format("%6d",score),new Label.LabelStyle(new BitmapFont(), Color.WHITE));
timeLabel =new Label("TIME",new Label.LabelStyle(new BitmapFont(), Color.WHITE));
levelLable =new Label("1-1",new Label.LabelStyle(new BitmapFont(), Color.WHITE));;
worldLabel =new Label("WORLD",new Label.LabelStyle(new BitmapFont(), Color.WHITE));
gameLabel =new Label("GAME",new Label.LabelStyle(new BitmapFont(), Color.WHITE));
table.add(gameLabel).expandX().padTop(10);
table.add(worldLabel).expandX().padTop(10);
table.add(timeLabel).expandX().padTop(10);
table.row();
table.add(scoreLabel).expandX();
table.add(levelLable).expandX();
table.add(countdownLabel).expandX();
stage.addActor(table);
}
}
Son appel dans la classe de jeux :
hud=new Hud(game.batch); (dans le constructeur)
Et
game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
hud.stage.draw();
dans la methode « render »
Pour modifier la taille de la police :
scoreLabel.setFontScale(3);
xxxxxxxxxxxxxxxxxxxxxxxx
https://www.google.fr/search?q=libgdx+menu+and+screen+tutorial&oq=libgdx+menu+and+screen+tutorial&aqs=chrome..69i57.13431j0j7&sourceid=chrome&ie=UTF-8
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
https://stackoverflow.com/questions/32451921/how-to-create-libgdx-main-menu-screen
********************
http://tuto-libgdx.blogspot.fr/2013/08/8-interface-utilisateur.html
***********************
*************************
c) Utilisation d’une maps et de tuiles :
Réutilisez une map ou créez là à l’aide de Tiled Map Editor . Le plus souvent, vous récupérez ou créez un ou plusieurs fichiers images de « tuiles » au format png d’une dimension puissance de 2 (exemple 512×512 pixels).
Puis vous créez une nouvelle carte en précisant sa taille et la dimension des tuiles (normalement 32×32). Une fois la carte chargée choissez Fichier->Nouveau Tilset / basé sur l’image / embarquer dans la carte et choisissez le fichier png de votre tilset.
Les Tilsets peuvent être récupérés sur https://www.spriters-resource.com/
Les Spirites sur : http://spritedatabase.nethttp://spritedatabase.net
Il est conseillé d’utiliser des calques pour placer les éléments. Par exemple un calque « fond », un autre « obstacles » etc…
Pour remplir les cases faire un glissé/déplacé et utilisez le pot de peinture pour tout remplir ou utilisez le tampon pour remplir des zones.
Une fois la carte terminée, copiez la carte et les fichiers « tile » dans le dossier « Assets » de votre jeux.
Déclarez une carte, son « render » et son « loader »:
TiledMap tiledMap; TiledMapRenderer tiledMapRenderer;
Dans « create » ou dans le constructeur de la classe :
tiledMap = new TmxMapLoader().load("MyCrappyMap.tmx"); tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);
Vous pouvez rajouter un recentrage de la caméra :
gamecam.position.set(gamePort.getWorldWidth() / 2, gamePort.getWorldHeight() / 2, 0);
Dans « render » :
tiledMapRenderer.setView(camera); tiledMapRenderer.render();
Ou pour que le décors avance en fonction de l’appui sur une touche ajoutez :
public void handleInput(float dt) { if (Gdx.input.isTouched()) gamecam.position.y += 100 * dt; } public void update(float dt) { handleInput(dt); gamecam.update(); renderer.setView(gamecam); }
et dans « render » :
renderer.render();
Après glClear…
A la fin du jeux n’oubliez pas d’ajouter dans la méthode « dispose » :
this.tiledMap.dispose();
*****
*********************
********************
http://www.alcove-games.com/opengl-es-2-tutorials/vertex-shader-for-tiled-water/
******************
d) animation et collisions :
Pour gérer un scrolling de la caméra, dans la méthode « render » initialisez une variable delta enregistrement le rafraîchissement des frames :
float delta = Gdx.graphics.getDeltaTime();
puis ajouter un appel à une méthode cameraUpdate(delta);
La méthode étant définie par :
public void cameraUpdate(float delta) { //-- Vertical cam mouvement cam.translate(0, 30 * delta, 0); //10 =lent,120=rapide cam.update(); }
Pour placer un spirite sur la carte, définir :
Texture texture; Sprite sprite;
Dans « create » :
sb = new SpriteBatch(); texture = new Texture(Gdx.files.internal("pik.png")); sprite = new Sprite(texture); sprite.scale(1.5f); //-- Echelle du spirite
Dans « render » :
sb.begin(); sprite.setposition(0,0); sprite.draw(sb); sb.end();
Pour placer un spirite au milieu de l’écran :
sprite.setPosition(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2);
Pour les collisions, dans Tiled définir des zones
Créez dans votre classe principale un listener de contact :
world.setContactListener(new WorldContactListener());
Avec la classe WorldContactListener :
Placer un « sensor » au dessus de l’objet à bouger (dans la méthode « define ») :
EdgeShape head; head = new EdgeShape(); head.set(new Vector2(-2 / PPM, 7/ PPM), new Vector2(2 / PPM, 7/ PPM)); fdef.shape=head; fdef.isSensor=true; b2body.createFixture(fdef).setUserData("Head");
Un spirite animé sera
http://tutoriel-libgdx-android.blogspot.fr/2012/12/faire-une-animation-avec-libgdx-9.html
*******************
http://tuto-libgdx.blogspot.fr/?view=classic
******************
http://www.html5gamedevs.com/topic/1471-how-to-handle-collision-between-sprite-and-tilemap/
e) mouvements :
http://www.norakomi.com/tutorial_mambow2_input.php
********************
http://examples.phaser.io/_site/view_full.html?d=tilemaps&f=tile+callbacks.js&t=tile%20callbacks
f) Box 2D :
Box 2D défini pour un « monde de jeux » (world) des attributs pour chaque « entité » (bodies) constituant ce « monde ». Chaque « Bodies » a des propriétés (Masse, vitesse, localisation, angles, et « fixtures » (forme, densité, friction, restitution).
Pour utiliser Box2D il faut définir un « monde » et un « renderer » :
//-- Box2D Variables private World world; private Box2DDebugRenderer b2dr;
Puis
world=new World(new Vector2(0, 0),true); b2dr = new Box2DDebugRenderer();
Ensuite il faut définir des objets
BodyDef bdef = new BodyDef(); PolygonShape shape = new PolygonShape(); FixtureDef fdef = new FixtureDef(); Body body;
Dans le cadre d’une carte (MAP) avec des tiles et des calques objets Box2D sera utilisé pour définir le type de chaque objet du calque selon le code suivant :
//-- Create Ground Bodies/Fictures (agencements) for(MapObject object:map.getLayers().get(3).getObjects().getByType(RectangleMapObject.class)){ Rectangle rect = ((RectangleMapObject) object).getRectangle(); bdef.type=BodyDef.BodyType.StaticBody; bdef.position.set(rect.getX()+rect.getWidth()/2,rect.getY()+rect.getY()+rect.getHeight()/2); body = world.createBody(bdef); shape.setAsBox(rect.getWidth()/2,rect.getHeight()/2); fdef.shape=shape; body.createFixture(fdef); }
Spirites :
Pour le cadre :
public class SpriteJoueur extends Sprite { public World world; public Body b2body; public SpriteJoueur (World world){ this.world=world; defineSpriteJoueur(); } public void defineSpriteJoueur(){ BodyDef bdef = new BodyDef(); bdef.position.set(32/PPM,32/PPM); bdef.type= BodyDef.BodyType.DynamicBody; b2body=world.createBody(bdef); FixtureDef fdef = new FixtureDef(); CircleShape shape = new CircleShape(); shape.setRadius(5/PPM); fdef.shape=shape; b2body.createFixture(fdef); } }
L’appel dans la classe de jeux (après avoir défini la variable
private SpriteJoueur player;
player = new Bateau(world);
Après avoir initialisé le « monde » de jeux du Spirite par :
world=new World(new Vector2(10, 0),true);
Pour gérer l’appui sur les touches :
public void handleInput(float dt) { if (Gdx.input.isTouched()) // gamecam.position.y += 10 * dt; player.b2body.applyLinearImpulse(-0.4f, 0, 0, 0, true); if (Gdx.input.isKeyPressed(Input.Keys.UP) && player.b2body.getLinearVelocity().y<=2 ) player.b2body.applyLinearImpulse(new Vector2(0f, 1f), player.b2body.getWorldCenter(), true); if (Gdx.input.isKeyPressed(Input.Keys.DOWN)&& player.b2body.getLinearVelocity().y>=-2 ) player.b2body.applyLinearImpulse(new Vector2(0f, -1f), player.b2body.getWorldCenter(), true); if (Gdx.input.isKeyJustPressed(Input.Keys.LEFT) ) player.b2body.applyLinearImpulse(new Vector2(-4f, 0), player.b2body.getLocalCenter(), true);
Pour que la caméra suive le Spirite (dans update) :
gamecam.position.y=player.b2body.getPosition().y;
Pour la musique et les sons :
Exemples :Et
SuperKoalio LibGdx
http://www.mets-blog.com/libgdx-tutorial-beginner-part-1/
https://www.youtube.com/user/Profyx/playlists
http://tuto-libgdx.blogspot.fr/?view=timeslide