lunes, 27 de febrero de 2017

SpaceInvaderClon - Paso 1

SpaceInvaderClon - Paso 1

Hola buenas, 
Seguimos en nuestro afán, de nuestro primer juego. Aquí puedes ver la parte previa PASO 0
En este paso 1, vamos a crear la lógica entre pantalla, así seguimos avanzando.
Primero creamos la clase Utils y creamos el paquete: sv.com.chuckle.game.spaceinvaderclon.utils
Código clase Utils:
package sv.com.chuckle.game.spaceinvaderclon.utils;

import com.badlogic.gdx.Gdx;

public class Utils {
    public static int ANCHO = 480;
    public static int ALTO = 650;
    public static boolean IS_DEBUG = true;

    public static void log(String tag,String message){
        if(IS_DEBUG)
            Gdx.app.log(tag, message);
    }
}

En esta clase, hemos definido de forma estática, el ancho y alto de nuestra pantalla.
Los valores 480x650, hacen referencia una pantalla en vertical(Portrait). También hemos 
definido una variable tipo booleana llamada "IS_DEBUG", la cual será nuestra bandera 
si deseamos escribir en la consola y para dibujar los elementos geométricos, para las 
colisiones.


Modificar pantalla Desktop y Android
Para ello primero nos dirigiremos a la clase DesktopLauncher, de nuestro subproyecto 
"desktop", aqui agregamos las definiciones del ANCHO y ALTO, de la clase Utils, asi:

package sv.com.chuckle.game.spaceinvaderclon.desktop;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import sv.com.chuckle.game.spaceinvaderclon.GameLoop;
import sv.com.chuckle.game.spaceinvaderclon.utils.Utils;

public class DesktopLauncher {
   public static void main (String[] arg) {
      LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
      config.width = Utils.ANCHO;
      config.height = Utils.ALTO;
      config.resizable =  false;
      config.title = "Space Invader - CLON";
      new LwjglApplication(new GameLoop(), config);
   }
}
Creo que se entiende que se está haciendo.

Luego vamos por el archivo de configuración de android el AndroidManifest.xml 
del subproyecto "android' y cambiaremos la linea donde se encuentre la etiqueta:
android:screenOrientation, por esto: android:screenOrientation="portrait"


Crear las Pantallas
Para esto creamos el paquete: 
sv.com.chuckle.game.spaceinvaderclon.screen
Y creamos tres clases llamadas: MainScreen, GameScreen y GameOverScreen.
Estas clases deben de implementarse con la interfaz llamada: Screen
Y su constructor debe de recibir como parámetro el objeto GameLoop, que es el que extiéndete de Game(Este controla nuestro juego).
Clase MainScreen:
package sv.com.chuckle.game.spaceinvaderclon.screen;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import sv.com.chuckle.game.spaceinvaderclon.GameLoop;
import sv.com.chuckle.game.spaceinvaderclon.utils.Utils;

public class MainScreen implements Screen{
    private GameLoop game;
    private BitmapFont font;
    private Batch batch;

    public MainScreen(GameLoop game){
        this.game = game;
        font = new BitmapFont();
        batch = new SpriteBatch();
    }

    @Override    public void show() {

    }

    @Override    public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        if(Gdx.input.justTouched())
            game.setScreen(new GameScreen(game));
        batch.begin();
        font.draw(batch, "SPACE INVADER", Utils.ANCHO/2-60, Utils.ALTO/2+100);
        font.draw(batch, "Presione sobre la pantalla para iniciar el juego", Utils.ANCHO/2-150, Utils.ALTO/2+50);
        batch.end();

    }

    @Override    public void resize(int width, int height) {

    }

    @Override    public void pause() {

    }

    @Override    public void resume() {

    }

    @Override    public void hide() {

    }

    @Override    public void dispose() {
        font.dispose();
        batch.dispose();
    }
}

Las otras dos clases son iguales, solo cambian las posiciones del texto.
Clase GameScreen:
@Overridepublic void render(float delta) {
    Gdx.gl.glClearColor(0, 0, 0, 0);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    if(Gdx.input.justTouched())
        game.setScreen(new GameOverScreeen(game));
    batch.begin();
    font.draw(batch, "Pantalla De Juego", Utils.ANCHO/2-50, Utils.ALTO/2+100);
    font.draw(batch, "Presione sobre la pantalla para continuar", Utils.ANCHO/2-120, Utils.ALTO/2+50);
    batch.end();

}

Clase GameOverScreen:
@Overridepublic void render(float delta) {
    Gdx.gl.glClearColor(0, 0, 0, 0);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    if(Gdx.input.justTouched())
        game.setScreen(new GameScreen(game));
    batch.begin();
    font.draw(batch, "GAME OVER", Utils.ANCHO/2-50, Utils.ALTO/2+100);
    font.draw(batch, "Presione sobre la pantalla para iniciar el juego", Utils.ANCHO/2-150, Utils.ALTO/2+50);
    batch.end();

}
Para fines prácticos, el flujo por el momento es:
MainScreen->GameScreen<->GameOverScreen

Paso Final:
Para nuestro final, solo falta modificar la clase GameLoop, para que sea esta la que controle todo nuestro juego. Para ello limpiamos toda la clase y la extendemos de Game, asi:
package sv.com.chuckle.game.spaceinvaderclon;

import com.badlogic.gdx.Game;

import sv.com.chuckle.game.spaceinvaderclon.screen.MainScreen;

public class GameLoop extends Game {

   @Override   public void create() {
      setScreen(new MainScreen(this));
   }
}
Como Game, tiene la capacidad de poner que pantalla esté activa, de esta forma al iniciar
nuestro juego, la pantalla por defecto será la MainScreen.
Ya podemos ejecutar nuestro subproyectos, y veran como nos quedó.
Aquí el resultado:


Como vemos es super sencillo hacer este juego de pantallas.
Para nuestra próxima entrega,  ya pintaremos nuestra nava y haremos que se mueva y dispare xD

Codigo fuente aqui.

Saludos

Si te gusta mi trabajo y crees que vale la pena que sigamos aprendiendo, pues dona un dólar
para esta buena causa xD

domingo, 26 de febrero de 2017

SpaceInvaderClon - Paso 0

Hola Buenas.

Ahora comenzamos con nuestro primer juego pedagógico.

Claraciones:

  • He tenido varios problemas con la versión más reciente del LibGDX(1.9.5). Sospecho que es por que hace más de 4 años que tengo instalado el SDK de android. He hecho varias pruebas si casi siempre me falla cuando quiero trabajar con la librería Box2D. Pero he logrado hacer funcionar todo con la última versión de LigGDX 1.9.5 y Android Studio 2.23, así que para este proyecto utilizaremos estas versiones.
  • Los artes las buscaremos en http://opengameart.org/

Manos a la Obra:

Como ya hemos dicho antes, descargamos la versión 1.9.5 de LibGDX aquí, en teoría con esta versiones podemos modificar que version de LibGDX queremos utilizar, guia aqui.
Por cualquier cosa también podemos descargar versiones más viejas aquí.
Una vez tengamos descargado, descomprimimos estos archivos en algun de fácil acceso, de preferencia en la raíz o home, por ejemplo C:/(si estamos en Windows).

Siguiente paso, descargar los assets, para hecho nos vamos a la pagina http://opengameart.org/,
para efectos prácticos ya los tengo listo, puedes cargarlo de aquí
Recomiendo encarecidamente tener actualizado su android studio.

Nuestro juego será más o menos como el mítico Space Invader, tratara de nuestro nave estara en la base de la pantalla, y solo se movera de izquierda y derecha, y presionando sobre la pantalla disparara hacia arriba. Por otro lado los enemigos bajarán de forma constante y aparecerán de forma aleatoria en el eje X.

Creamos una carpeta donde se generarán los archivos de LibGDX, yo utilizare: C:\workspace_libgdxelsalvador\spaceInvaderClon, le damos doble click gdx-setup.jar, de los archivos recién descargados. Y colocamos los siguientes valores:
Y presionamos el Botón Generate, y damos click en "SI" o "YES" de las advertencias que nos aparezcan. Esperamos que finalice, luego ya estamos listo para importar en nuestro Android Studio:
Luego importamos nuestro proyecto, elegimos la opción: Import Project y elegimos la carpeta donde esta los archivos generados(en mi caso: C:\workspace_libgdxelsalvador\spaceInvaderClon)

Android Studio nos dará una recomendación, en este caso le diremos que si Actualice(Update):

Esperemos que finalice toodo el proceso de actualización de Gradles, una vez se finalice se debe de configurar que el Android Studio ejecute nuestro sub proyecto de Desktop, como aplicación.
Para ello elegimos el sub proyecto "desktop" y damos click sobre Edit Configuratios...

Damos click al botón "+" y elegimos la opción "Application":

Aquí hay que llenar los datos que se nos piden, podemos hacer uso de los botones que nos ayudan a buscar por medio de un explorador. Aquí podemos resaltar la opción Working directory, es donde se encuentran nuestros ASSETS:
Aplicamos los cambio y presionamos el OK.
Listo, ya podemos ejecutar nuestro subproyecto Desktop.

Haremos algo de limpieza antes de comenzar todo.
En nuestro subproyecto "android", eliminamos la imagen "badlogic.jpg" de la carpeta "assets" y luego copias todos los archivos descargados de nuestro assets_libgdxelsalvador.blogspot.com.zip, siempre en la carpeta "assets", así:

En la clase "GameLoop", del subproyecto "core", lo dejamos así:
package sv.com.chuckle.game.spaceinvaderclon;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class GameLoop extends ApplicationAdapter {
   SpriteBatch batch;
   Texture img,img2,img3;

   @Override   public void create () {
      batch = new SpriteBatch();
      img = new Texture("alien.png");
      img2 = new Texture("Starfighter.png");
      img3 = new Texture("missile.png");
   }

   @Override   public void render () {
      Gdx.gl.glClearColor(1, 0, 0, 1);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
      batch.begin();
      batch.draw(img, 0, 0);
      batch.draw(img2, 100, 0);
      batch.draw(img3,200,0);
      batch.end();
   }
   
   @Override   public void dispose () {
      batch.dispose();
      img.dispose();
      img2.dispose();
      img3.dispose();
   }
}

Guardamos, y ejecutamos el subproyecto desktop:

 También podemos correr el proyecto de "android", para ello tenemos que tener un dispositivo físico conectado a nuestro computador o algún emulador.
Listo ya tenemos nuestro ambiente listo para comenzar con la logica xD
En la siguiente entrega, haremos el juego entre pantallas de los juegos.
Codigo fuente aqui
Saludos

Si te gusta mi trabajo y el esfuerzo, pues puedes donar un $1, a esta causa xD

sábado, 25 de febrero de 2017

2017 - Disculpas, Continuidad y Más

Hola Buenas.
Se que no he continuado con el contenido que me había propuesto. Por eso me disculpo sinceramente.
Prometo subir material por lo menos una vez al mes en el peor de los casos.

Continuaré donde nos habíamos quedado, en seguir preparándonos para hacer un juego funcional, que ponga en práctica todo lo que hemos aprendido. La meta es hacer un mini juego que cumpla con todo el ciclo de vida de un videojuego normal, claro este juego es con fines pedagógicos.
Que incluirá este juego:

  1. Manejo de pantallas(Principal, Juego, GameOver, etc.).
  2. Manipulación de sonidos y música de fondo.
  3. Colisiones entre los diferentes objetos.
  4. Manipulación de controles para nuestro juego(Desktop: por medio de las flechas cursoras y Android: por medio del giroscopio.)
  5. Claro, manipulación de los Sprite. 
Y que viene luego de nuestro gran proyecto?
Pues existen muchas cosas un poco más avanzadas, que iremos aprendiendo de poco a poco.
Entre la cuales podemos mencionar:
  1. Editor de Mapas por medio de patrones: Tiled
  2. Cómo utilizar la librería Box2D, puedes ver algunos demos aquí.
  3. Editor de niveles como Overlap2D y VisEditor.
  4. Editor de Sistemas de Partículas.
  5. Técnicas de rendimiento(Sprite Sheet, Asset Manager y Pooling).
  6. Manipulación de GUI.
  7. Manipulación de FONT.
  8. ETC.
Como ven esto se pone SABROSO, así que pendientes xD

En diciembre del año pasado(2016), fue liberada la versión 1.9.5 de libgdx. He tratado de trabajar con él y resulta que tiene unos problemas con la sincronización de las API's de Android. Quizá sea porque tengo ratos de no actualizar mis SDK de Android, aún utilizado Eclipse.
Por esta razón, utilizaremos la versión 1.6.1 LibGdx, la cual podemos descargar de AQUI

Desde este punto esta es la versión que utilizaremos en todos los artículos del presente Blog.

Como siempre todo el contenido de este Blog, estará en GitHub y tratare de colgar un video demostrativo.

Creo que es todo xD
El siguiente post, estaremos preparando todo el ambiente, sonidos, música y sprite. Para comenzar nuestro proyecto del juego. Lo que no se, cuantas partes o tutoriales haré para terminar el juego.

Nos vemos la otras semana, ya con el inicio del juego insignia xD

Saludos.