Bienvenidos sean a este post, hoy les traigo todos los codigos y elementos necesarios para nuestro sexto proyecto.
Al igual que en los proyectos anteriores este sera un post para que puedas descargar todos los assets necesarios y los codigos, sin explicacion, para crear este juego, esto puede ser util para compararlo con el tuyo en caso de ser necesario ante alguna eventualidad, por lo pronto si queres saber el porque de alguna parte del codigo te dejo el siguiente listado con los posts donde se explico:
- Nuestro sexto proyecto
- Las especificaciones de los objetos
- Continuando con las especificaciones de los objetos
- Creando las interfaces de componentes
- Agregando otras interfaces
- El patron singleton
- HashMap
- La clase BitmapAlmacen
- La clase Transformar
- Componentes decorativos e inanimados
- Los niveles
- GameObjetoFabrica
- GameObjeto
- GameState
- SoundEngine
- La engine de las fisicas
- ManagerNivel
- Renderer
- La camara
- HUD
- UIcontroladora
- La actividad
- GameEngine
- Animadora
- La clase JugadorTransformar
- Componentes del jugador
- El fondo parallax
- Aplicando los ultimos cambios
- Moviendo las plataformas
- Detectar colisiones
Descarga los siguientes archivos para los assets en el caso de sonido y para el recurso drawable para los graficos:
Con esto tenemos lo basico vamos a comenzar con la creacion del proyecto con las siguientes caracteristicas:
- Dispositivos: Phone and Tablet
- Actividad: Empty Activity
- Nombre: La gran aventura de Pepe
- Nombre de paquete: org.example.pepeaventura
- API Minimo: API 14 (Android 4.0)
Los codigos que especificare a continuacion son para la base de nuestro juego, luego vendran los paquetes que necesitaremos, recuerden que primero especifico el nombre de la clase y luego va el codigo, y les recuerdo que los siguientes hasta que notifique lo contrario seran parte del paquete principal:
Animadora
package org.example.pepeaventura;
import android.graphics.Rect;
class Animadora {
private Rect mRectFuente;
private int mCuentaFrame;
private int mActualFrame;
private long mCorazonFrame;
private int mPeriodoFrame;
private int mAnchoFrame;
Animadora(float alturaFrame,
float anchoFrame,
int cuentaFrame,
int pixelsPorMetro){
final int ANIM_FPS = 10;
this.mActualFrame = 0;
this.mCuentaFrame = cuentaFrame;
this.mAnchoFrame = (int) anchoFrame * pixelsPorMetro;
alturaFrame = alturaFrame * pixelsPorMetro;
mRectFuente = new Rect(
0,0,
mAnchoFrame,
(int)alturaFrame);
mPeriodoFrame = 1000 / ANIM_FPS;
mCorazonFrame = 0L;
}
Rect getTiempoActual(long tiempo){
if (tiempo > (mCorazonFrame + mPeriodoFrame)){
mCorazonFrame = tiempo;
mActualFrame++;
if (mActualFrame >= mCuentaFrame)
mActualFrame = 0;
}
this.mRectFuente.left = mActualFrame * mAnchoFrame;
this.mRectFuente.right = this.mRectFuente.left + mAnchoFrame;
return mRectFuente;
}
}
BitmapAlmacen
package org.example.pepeaventura;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import java.util.HashMap;
import java.util.Map;
class BitmapAlmacen {
private static Map mBitmapMap;
private static Map mBitmapInversoMap;
private static BitmapAlmacen mNuestraInstancia;
static BitmapAlmacen getInstancia(Context contexto){
mNuestraInstancia = new BitmapAlmacen(contexto);
return mNuestraInstancia;
}
private BitmapAlmacen(Context c){
mBitmapMap = new HashMap();
mBitmapInversoMap = new HashMap();
agregarBitmap(c,
"muerte_visible",
new PointF(1,1),
128,
true);
}
static Bitmap getBitmap(String nombreBitmap){
if (mBitmapMap.containsKey(nombreBitmap)){
return mBitmapMap.get(nombreBitmap);
} else {
return mBitmapMap.get("muerte_visible");
}
}
static Bitmap getBitmapInverso(String nombreBitmap){
if (mBitmapInversoMap.containsKey(nombreBitmap)){
return mBitmapInversoMap.get(nombreBitmap);
} else {
return mBitmapInversoMap.get("muerte_visible");
}
}
static void agregarBitmap(Context c,
String nombreBitmap,
PointF tamanoObjeto,
int pixelsPorMetro,
boolean necesitaInverso){
Bitmap bitmap;
Bitmap bitmapInverso;
int resId = c.getResources().getIdentifier(nombreBitmap,
"drawable",
c.getPackageName());
bitmap = BitmapFactory.decodeResource(
c.getResources(),
resId);
bitmap = Bitmap.createScaledBitmap(bitmap,
(int) tamanoObjeto.x * pixelsPorMetro,
(int) tamanoObjeto.y * pixelsPorMetro,
false);
mBitmapMap.put(nombreBitmap,bitmap);
if (necesitaInverso){
Matrix matrix = new Matrix();
matrix.setScale(-1,1);
bitmapInverso = Bitmap.createBitmap(bitmap,
0,0,
bitmap.getWidth(),
bitmap.getHeight(),
matrix,
true);
mBitmapInversoMap.put(nombreBitmap,bitmapInverso);
}
}
static void limpiaAlmacen(){
mBitmapMap.clear();
mBitmapInversoMap.clear();
}
}
Camara
package org.example.pepeaventura;
import android.graphics.PointF;
import android.graphics.Rect;
class Camara {
private PointF mCamaraActualCentroMundo;
private Rect mRectConvertido;
private int mPixelsPorMetro;
private int mCentroPantallaX;
private int mCentroPantallaY;
Camara(int resolucionPantallaX, int resolucionPantallaY){
mCentroPantallaX = resolucionPantallaX / 2;
mCentroPantallaY = resolucionPantallaY / 2;
final int pixelsPorMetroAradioResolucion = 48;
mPixelsPorMetro = resolucionPantallaX /
pixelsPorMetroAradioResolucion;
mRectConvertido = new Rect();
mCamaraActualCentroMundo = new PointF();
}
int getmPixelsPorMetroY(){
return mPixelsPorMetro;
}
int getCentro(){
return mCentroPantallaY;
}
float getCentroMundoCamaraY(){
return mCamaraActualCentroMundo.y;
}
void setCentroMundo(PointF centroMundo){
mCamaraActualCentroMundo.x = centroMundo.x;
mCamaraActualCentroMundo.y = centroMundo.y;
}
int getPixelsPorMetro(){
return mPixelsPorMetro;
}
Rect mundoApantalla(float objetoX,
float objetoY,
float objetoAncho,
float objetoAlto) {
int izquierda = (int) (mCentroPantallaX
- ((mCamaraActualCentroMundo.x - objetoX)
* mPixelsPorMetro));
int arriba = (int) (mCentroPantallaY
- ((mCamaraActualCentroMundo.y - objetoY)
* mPixelsPorMetro));
int derecha = (int) (izquierda
+ (objetoAncho * mPixelsPorMetro));
int abajo = (int) (arriba
+ (objetoAlto * mPixelsPorMetro));
mRectConvertido.set(izquierda, arriba, derecha, abajo);
return mRectConvertido;
}
}
ComponenteActualizaBloqueDecorativo
package org.example.pepeaventura;
class ComponenteActualizaBloqueDecorativo
implements ComponenteActualizar {
@Override
public void actualizar(
long fps,
Transformar t,
Transformar transformarJugador) {
}
}
ComponenteActualizaBloqueInanimado
package org.example.pepeaventura;
class ComponenteActualizaBloqueInanimado
implements ComponenteActualizar {
private boolean mChocadorNoSeteado = true;
@Override
public void actualizar(
long fps,
Transformar t,
Transformar transformarJugador){
if (mChocadorNoSeteado){
t.actualizaChocador();
mChocadorNoSeteado = false;
}
}
}
ComponenteActualizaBloqueMovible
package org.example.pepeaventura;
import android.graphics.PointF;
class ComponenteActualizaBloqueMovible
implements ComponenteActualizar {
@Override
public void actualizar(
long fps,
Transformar t,
Transformar jugadorTransformar){
PointF ubicacion = t.getUbicacion();
if (t.apuntandoArriba()){
ubicacion.y -= t.getVelocidad() / fps;
} else if (t.apuntandoAbajo()){
ubicacion.y += t.getVelocidad() / fps;
} else {
t.apuntarAbajo();
}
if (t.apuntandoArriba() && ubicacion.y
= (t.getPosicionInicial().y
+ t.getTamano().y * 10)) {
t.apuntarArriba();
}
t.actualizaChocador();
}
}
ComponenteActualizaJugador
package org.example.pepeaventura;
import android.graphics.PointF;
class ComponenteActualizaJugador implements ComponenteActualizar {
private boolean mEstaSaltando = false;
private long mTiempoInicioSalto;
private final long TIEMPO_MAX_SALTO = 400;
private final float GRAVEDAD = 6;
public void actualizar(long fps,
Transformar t,
Transformar jugdaorTransfromar){
JugadorTransformar jt = (JugadorTransformar) t;
PointF ubicacion = t.getUbicacion();
float velocidad = t.getVelocidad();
if (t.apuntandoIzquierda()){
ubicacion.x -= velocidad / fps;
} else if (t.apuntandoDerecha()){
ubicacion.x += velocidad / fps;
}
if (jt.cabezaGolpeada()){
mEstaSaltando = false;
jt.manejandoCabezaGolpeada();
}
if (jt.saltoIniciado()
&& !mEstaSaltando
&& jt.estaEnTierra() ){
SoundEngine.playSalto();
mEstaSaltando = true;
jt.manejandoSalto();
mTiempoInicioSalto = System.currentTimeMillis();
}
if (!mEstaSaltando){
ubicacion.y += GRAVEDAD / fps;
} else if (mEstaSaltando) {
jt.setNoEnTierra();
if (System.currentTimeMillis()
< mTiempoInicioSalto + (TIEMPO_MAX_SALTO / 1.5)){
ubicacion.y -= (GRAVEDAD * 1.8) / fps;
} else if (System.currentTimeMillis()
mTiempoInicioSalto + TIEMPO_MAX_SALTO){
mEstaSaltando = false;
}
}
t.actualizaChocador();
}
}
ComponenteActualizar
package org.example.pepeaventura;
interface ComponenteActualizar {
void actualizar(long fps,
Transformar t,
Transformar jugadorTransformar);
}
ComponenteActualizarFondo
package org.example.pepeaventura;
class ComponenteActualizarFondo implements ComponenteActualizar {
@Override
public void actualizar(long fps,
Transformar t,
Transformar jugadorTransformar){
TransformarFondo tf = (TransformarFondo) t;
JugadorTransformar jt =
(JugadorTransformar) jugadorTransformar;
float actualRecortarX = tf.getRecortarX();
if (jugadorTransformar.apuntandoDerecha()){
actualRecortarX -= t.getVelocidad() / fps;
tf.setRecortarX(actualRecortarX);
} else if (jugadorTransformar.apuntandoIzquierda()){
actualRecortarX += t.getVelocidad() / fps;
}
if (actualRecortarX >= t.getTamano().x){
tf.setRecortarX(0);
tf.volteaPrimeroInvertido();
} else if (actualRecortarX <= 0){
tf.setRecortarX((int)t.getTamano().x);
tf.volteaPrimeroInvertido();
}
}
}
ComponenteEntradaJugador
package org.example.pepeaventura;
import android.graphics.Rect;
import android.view.MotionEvent;
import java.util.ArrayList;
class ComponenteEntradaJugador implements ObservadorEntrada {
private Transformar mJugadoresTransformar;
private JugadorTransformar mJugadorJugadoresTransformar;
ComponenteEntradaJugador(GameEngine ger){
ger.addObservador(this);
}
public void setTransformar(Transformar transformar){
mJugadoresTransformar = transformar;
mJugadorJugadoresTransformar =
(JugadorTransformar) transformar;
}
public void handleInput(MotionEvent evento,
GameState gameState,
ArrayList botones){
int i = evento.getActionIndex();
int x = (int) evento.getX(i);
int y = (int) evento.getY(i);
if (!gameState.getPausado()){
switch (evento.getAction() & MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_UP:
if (botones.get(HUD.IZQUIERDA).contains(x,y)
|| botones.get(HUD.DERECHA)
.contains(x,y)){
mJugadoresTransformar.detenerHorizontal();
}
break;
case MotionEvent.ACTION_DOWN:
if (botones.get(HUD.IZQUIERDA).contains(x,y)){
mJugadoresTransformar.apuntarIzquierda();
} else if (botones.get(HUD.DERECHA).contains(x,y)){
mJugadoresTransformar.apuntarDerecha();
} else if (botones.get(HUD.SALTAR).contains(x,y)){
mJugadorJugadoresTransformar.iniciaSalto();
}
break;
case MotionEvent.ACTION_POINTER_UP:
if (botones.get(HUD.IZQUIERDA).contains(x,y)
|| botones.get(HUD.DERECHA)
.contains(x,y)){
mJugadoresTransformar.detenerHorizontal();
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (botones.get(HUD.IZQUIERDA).contains(x,y)){
mJugadoresTransformar.apuntarIzquierda();
} else if (botones.get(HUD.DERECHA).contains(x,y)){
mJugadoresTransformar.apuntarDerecha();
} else if (botones.get(HUD.SALTAR).contains(x,y)){
mJugadorJugadoresTransformar.iniciaSalto();
}
break;
}
}
}
}
ComponenteGraficoBloqueInanimado
package org.example.pepeaventura;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import org.example.pepeaventura.especoj.EspecJuegoObjeto;
class ComponenteGraficoBloqueInanimado
implements ComponenteGraficos {
private String mBitmapNombre;
@Override
public void inicializar(Context contexto,
EspecJuegoObjeto espec,
PointF tamanoObjeto,
int pixelsPorMetro){
mBitmapNombre = espec.getBitmapNombre();
BitmapAlmacen.agregarBitmap(
contexto,
mBitmapNombre,
tamanoObjeto,
pixelsPorMetro,
false);
}
@Override
public void dibujar(Canvas canvas,
Paint pincel,
Transformar t,
Camara cam){
Bitmap bitmap = BitmapAlmacen.getBitmap(mBitmapNombre);
Rect coordenadasPantalla = cam.mundoApantalla(
t.getUbicacion().x,
t.getUbicacion().y,
t.getTamano().x,
t.getTamano().y);
canvas.drawBitmap(bitmap,
coordenadasPantalla.left,
coordenadasPantalla.top,
pincel);
}
}
ComponenteGraficos
package org.example.pepeaventura;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import org.example.pepeaventura.especoj.EspecJuegoObjeto;
interface ComponenteGraficos {
void inicializar(Context c,
EspecJuegoObjeto espec,
PointF tamanoObjeto,
int pixelPorMetro);
void dibujar(Canvas canvas, Paint pincel,
Transformar t, Camara cam);
}
ComponenteGraficosAnimados
package org.example.pepeaventura;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import org.example.pepeaventura.especoj.EspecJuegoObjeto;
class ComponenteGraficosAnimados implements ComponenteGraficos {
private String mNombreBitmap;
private Animadora mAnimadora;
private Rect mSeccionAdibujar;
@Override
public void inicializar(Context contexto,
EspecJuegoObjeto espec,
PointF tamanoObjeto,
int pixelsPorMetro){
mAnimadora = new Animadora(
tamanoObjeto.y,
tamanoObjeto.x,
espec.getNumFrames(),
pixelsPorMetro);
float anchoTotal = tamanoObjeto.x
* espec.getNumFrames();
mNombreBitmap = espec.getBitmapNombre();
BitmapAlmacen.agregarBitmap(
contexto,
mNombreBitmap,
new PointF(anchoTotal, tamanoObjeto.y),
pixelsPorMetro,
true );
mSeccionAdibujar = mAnimadora.getTiempoActual(
System.currentTimeMillis());
}
@Override
public void dibujar(Canvas canvas,
Paint pincel,
Transformar t,
Camara cam) {
if (t.apuntandoDerecha()
|| t.apuntandoIzquierda()
|| t.getVelocidad() == 0) {
mSeccionAdibujar = mAnimadora.getTiempoActual(
System.currentTimeMillis());
}
Rect coordenadasPantalla = cam.mundoApantalla(
t.getUbicacion().x,
t.getUbicacion().y,
t.getTamano().x,
t.getTamano().y);
if (t.getMirandoDerecha()){
canvas.drawBitmap(BitmapAlmacen.getBitmap(mNombreBitmap),
mSeccionAdibujar,
coordenadasPantalla,
pincel);
} else {
canvas.drawBitmap(BitmapAlmacen.getBitmapInverso(mNombreBitmap),
mSeccionAdibujar,
coordenadasPantalla,
pincel);
}
}
}
ComponenteGraficosFondo
package org.example.pepeaventura;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import org.example.pepeaventura.especoj.EspecJuegoObjeto;
class ComponenteGraficosFondo implements ComponenteGraficos {
private String mNombreBitmap;
@Override
public void inicializar(Context contexto,
EspecJuegoObjeto espec,
PointF tamanoObjeto,
int pixelsPorMetro){
mNombreBitmap = espec.getBitmapNombre();
BitmapAlmacen.agregarBitmap(contexto,
mNombreBitmap,
tamanoObjeto,
pixelsPorMetro,
true);
}
@Override
public void dibujar(Canvas canvas,
Paint pincel,
Transformar t,
Camara cam) {
TransformarFondo tf = (TransformarFondo) t;
Bitmap bitmap = BitmapAlmacen.getBitmap(mNombreBitmap);
Bitmap bitmapInverso = BitmapAlmacen
.getBitmapInverso(mNombreBitmap);
int recortarXescalado = (int) tf.getRecortarX()
* cam.getPixelsPorMetro();
int ancho = bitmap.getWidth();
int alto = bitmap.getHeight();
PointF ubicacion = t.getUbicacion();
float inicioYflotante = ((cam.getCentro() -
((cam.getCentroMundoCamaraY() - ubicacion.y) *
cam.getmPixelsPorMetroY())));
int inicioY = (int) inicioYflotante;
float finalYflotante = ((cam.getCentro() -
((cam.getCentroMundoCamaraY() - ubicacion.y -
t.getTamano().y) *
cam.getmPixelsPorMetroY())));
int finalY = (int) finalYflotante;
Rect desdeRect1 = new Rect(0, 0,
ancho - recortarXescalado, alto);
Rect haciaRect1 = new Rect(recortarXescalado,
inicioY, ancho, finalY);
Rect desdeRect2 = new Rect(ancho - recortarXescalado,
0, ancho, alto);
Rect haciaRect2 = new Rect(0, inicioY,
recortarXescalado, finalY);
if (!tf.getPrimeroInvertido()) {
canvas.drawBitmap(bitmap, desdeRect1,
haciaRect1, pincel);
canvas.drawBitmap(bitmapInverso, desdeRect2,
haciaRect2, pincel);
} else {
canvas.drawBitmap(bitmap, desdeRect2,
haciaRect2, pincel);
canvas.drawBitmap(bitmapInverso,desdeRect1,
haciaRect1,pincel);
}
}
}
ControladorEngine
package org.example.pepeaventura;
interface ControladorEngine {
void iniciaNuevoNivel();
}
EngineFisicas
package org.example.pepeaventura;
import android.graphics.PointF;
import android.graphics.RectF;
import java.util.ArrayList;
class EngineFisicas {
void actualizar(long fps,
ArrayList objetos,
GameState gs){
for(GameObjeto objeto : objetos){
objeto.actualizar(fps,
objetos.get(ManagerNivel.JUGADOR_INDICE)
.getTransformar());
}
detectarColisiones(gs, objetos);
}
private void detectarColisiones(GameState gs,
ArrayList objetos){
boolean colisionDetectada = false;
Transformar jugadorTransformar = objetos.get(
ManagerNivel.JUGADOR_INDICE).getTransformar();
JugadorTransformar jugadorJugadorTransformar =
(JugadorTransformar) jugadorTransformar;
ArrayList chocadorJugador =
jugadorJugadorTransformar.getChocadores();
PointF ubicacionJugador = jugadorTransformar.getUbicacion();
for(GameObjeto go : objetos){
if (go.chekaActivo()){
if (RectF.intersects(
go.getTransformar().getChocador(),
jugadorTransformar.getChocador())){
colisionDetectada = true;
Transformar pruebaTransformar =
go.getTransformar();
PointF pruebaUbicacion =
pruebaTransformar.getUbicacion();
if (objetos.indexOf(go) !=
ManagerNivel.JUGADOR_INDICE){
for(int i = 0; i < chocadorJugador.size(); i++){
if (RectF.intersects(
pruebaTransformar.getChocador(),
chocadorJugador.get(i))){
switch (go.getTag() + " con " + i){
case "plataforma movible con 3":
jugadorJugadorTransformar.enTierra();
ubicacionJugador.y = (pruebaTransformar
.getUbicacion().y
- jugadorTransformar
.getTamano().y );
break;
case "muerte con 3":
gs.muerte();
break;
case "objeto inerte con 3":
jugadorJugadorTransformar.enTierra();
ubicacionJugador.y = (pruebaTransformar
.getUbicacion().y
- jugadorTransformar
.getTamano().y );
break;
case "objeto inerte con 0":
ubicacionJugador.y = pruebaUbicacion.y
+ pruebaTransformar.getTamano().y;
jugadorJugadorTransformar
.disparaCabezaGolpeada();
break;
case "coleccionable con 1":
SoundEngine.playMonedaRecogida();
go.setInactivo();
gs.monedasRecogidas();
break;
case "coleccionable con 2":
SoundEngine.playMonedaRecogida();
go.setInactivo();
gs.monedasRecogidas();
break;
case "objeto inerte con 1":
jugadorTransformar.detenerMovDerecha();
ubicacionJugador.x = (pruebaTransformar
.getUbicacion().x
- jugadorTransformar
.getTamano().x);
break;
case "objeto inerte con 2":
jugadorTransformar.detenerMovIzquierda();
ubicacionJugador.x = (pruebaTransformar
.getUbicacion().x
+ jugadorTransformar
.getTamano().x);
break;
case "objeto objetivo con 3":
SoundEngine.playLogrado();
gs.objetivoAlcanzado();
break;
default:
break;
}
}
}
}
}
}
}
if (!colisionDetectada){
jugadorJugadorTransformar.noEnTierra();
}
}
}
GameActivity
package org.example.pepeaventura;
import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
public class GameActivity extends Activity {
GameEngine mGameEngine;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager()
.getDefaultDisplay();
Point tamano = new Point();
display.getSize(tamano);
mGameEngine = new GameEngine(this, tamano);
setContentView(mGameEngine);
}
@Override
protected void onResume(){
super.onResume();
mGameEngine.iniciarThread();
}
@Override
protected void onPause(){
super.onPause();
mGameEngine.detenerThread();
}
}
GameEngine
package org.example.pepeaventura;
import android.content.Context;
import android.graphics.Point;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;
import java.util.concurrent.CopyOnWriteArrayList;
class GameEngine extends SurfaceView implements
Runnable,
GameEngineBroadcaster,
ControladorEngine {
private Thread mThread = null;
private long mFPS;
private GameState mGameState;
UIcontroladora mUIcontroladora;
private CopyOnWriteArrayList
observadorEntradas = new CopyOnWriteArrayList();
HUD mHUD;
ManagerNivel mManagerNivel;
EngineFisicas mEngineFisicas;
Renderer mRenderer;
public GameEngine(Context contexto, Point tamano){
super(contexto);
BitmapAlmacen ba = BitmapAlmacen.getInstancia(contexto);
SoundEngine se = SoundEngine.getInstancia(contexto);
mHUD = new HUD(contexto, tamano);
mGameState = new GameState(this, contexto);
mUIcontroladora = new UIcontroladora(this,tamano);
mEngineFisicas = new EngineFisicas();
mRenderer = new Renderer(this, tamano);
mManagerNivel = new ManagerNivel(
contexto,
this,
mRenderer.getPixelsPorMetro());
}
@Override
public void run(){
while(mGameState.getThreadCorriendo()){
long tiempoInicialFrame = System.currentTimeMillis();
if (!mGameState.getPausado()){
mEngineFisicas.actualizar(
mFPS,
mManagerNivel.getGameObjetos(),
mGameState);
}
mRenderer.dibujar(
mManagerNivel.getGameObjetos(),
mGameState,
mHUD);
long tiempoEsteFrame = System.currentTimeMillis()
- tiempoInicialFrame;
if (tiempoEsteFrame >= 1){
final int MILES_EN_SEGUNDOS = 1000;
mFPS = MILES_EN_SEGUNDOS / tiempoEsteFrame;
}
}
}
public void addObservador(ObservadorEntrada o){
observadorEntradas.add(o);
}
public void iniciaNuevoNivel(){
BitmapAlmacen.limpiaAlmacen();
observadorEntradas.clear();
mUIcontroladora.addObservador(this);
mManagerNivel.setNivelActual(mGameState.getNivelActual());
mManagerNivel.construirObjetosJuego(mGameState);
}
@Override
public boolean onTouchEvent(MotionEvent evento){
for(ObservadorEntrada o : observadorEntradas){
o.handleInput(evento,
mGameState,
mHUD.getControles());
}
return true;
}
public void detenerThread(){
mGameState.detenTodo();
mGameState.detenThread();
try {
mThread.join();
} catch (InterruptedException ie){
Log.e("Excepcion: ",
"detenerThread() " + ie.getMessage());
}
}
public void iniciarThread(){
mGameState.iniciaThread();
mThread = new Thread(this);
mThread.start();
}
}
GameEngineBroadcaster
package org.example.pepeaventura;
interface GameEngineBroadcaster {
void addObservador(ObservadorEntrada o);
}
GameObjeto
package org.example.pepeaventura;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import org.example.pepeaventura.especoj.EspecJuegoObjeto;
class GameObjeto {
private Transformar mTransformar;
private boolean mActivo = true;
private String mTag;
private ComponenteGraficos mComponenteGraficos;
private ComponenteActualizar mComponenteActualizar;
void setGraficos(ComponenteGraficos g,
Context c,
EspecJuegoObjeto espec,
PointF tamanoObjeto,
int pixelsPorMetro){
mComponenteGraficos = g;
g.inicializar(c, espec,
tamanoObjeto, pixelsPorMetro);
}
void setMovimiento(ComponenteActualizar m){
mComponenteActualizar = m;
}
void setTransformarJugadorEntrada(ComponenteEntradaJugador e){
e.setTransformar(mTransformar);
}
void setTransformar(Transformar t){
mTransformar = t;
}
void dibujar(Canvas canvas,
Paint pincel,
Camara cam){
mComponenteGraficos.dibujar(
canvas,
pincel,
mTransformar,
cam);
}
void actualizar(long fps,
Transformar jugadorTransformar){
mComponenteActualizar.actualizar(
fps,
mTransformar,
jugadorTransformar);
}
boolean chekaActivo(){
return mActivo;
}
String getTag(){
return mTag;
}
void setInactivo(){
mActivo = false;
}
Transformar getTransformar(){
return mTransformar;
}
void setTag(String tag){
mTag = tag;
}
}
GameObjetoFabrica
package org.example.pepeaventura;
import android.content.Context;
import android.graphics.PointF;
import org.example.pepeaventura.especoj.EspecJuegoObjeto;
class GameObjetoFabrica {
private Context mContexto;
private GameEngine mGameEngineReferencia;
private int mPixelsPorMetro;
GameObjetoFabrica(Context contexto,
GameEngine gameEngine,
int pixelsPorMetro){
mContexto = contexto;
mGameEngineReferencia = gameEngine;
mPixelsPorMetro = pixelsPorMetro;
}
GameObjeto crear(EspecJuegoObjeto espec,
PointF ubicacion){
GameObjeto objeto = new GameObjeto();
int mNumComponentes = espec.getComponentes().length;
objeto.setTag(espec.getTag());
switch (objeto.getTag()){
case "fondo":
objeto.setTransformar(new TransformarFondo(
espec.getVelocidad(),
espec.getTamano().x,
espec.getTamano().y,
ubicacion));
break;
case "jugador":
objeto.setTransformar(new JugadorTransformar(
espec.getVelocidad(),
espec.getTamano().x,
espec.getTamano().y,
ubicacion));
break;
default:
objeto.setTransformar(new Transformar(
espec.getVelocidad(),
espec.getTamano().x,
espec.getTamano().y,
ubicacion));
break;
}
for(int i=0; i < mNumComponentes; i++){
switch (espec.getComponentes()[i]){
case "ComponenteGraficoBloqueInanimado":
objeto.setGraficos(
new ComponenteGraficoBloqueInanimado(),
mContexto,
espec,
espec.getTamano(),
mPixelsPorMetro);
break;
case "ComponenteActualizaBloqueInanimado":
objeto.setMovimiento(
new ComponenteActualizaBloqueInanimado());
break;
case "ComponenteActualizaBloqueDecorativo":
objeto.setMovimiento(
new ComponenteActualizaBloqueDecorativo());
break;
case "ComponenteEntradaJugador":
objeto.setTransformarJugadorEntrada(
new ComponenteEntradaJugador(
mGameEngineReferencia));
break;
case "ComponenteGraficosAnimados":
objeto.setGraficos(new ComponenteGraficosAnimados(),
mContexto,
espec,
espec.getTamano(),
mPixelsPorMetro);
break;
case "ComponenteActualizaJugador":
objeto.setMovimiento(
new ComponenteActualizaJugador());
break;
case "ComponenteGraficosFondo":
objeto.setGraficos(new ComponenteGraficosFondo(),
mContexto,
espec,
espec.getTamano(),
mPixelsPorMetro);
break;
case "ComponenteActualizarFondo":
objeto.setMovimiento(
new ComponenteActualizarFondo());
break;
case "ComponenteActualizaBloqueMovible":
objeto.setMovimiento(
new ComponenteActualizaBloqueMovible());
break;
default:
break;
}
}
return objeto;
}
}
GameState
package org.example.pepeaventura;
import android.content.Context;
import android.content.SharedPreferences;
final class GameState {
private static volatile boolean mThreadCorriendo = false;
private static volatile boolean mPausado = true;
private static volatile boolean mGameOver = true;
private static volatile boolean mDibujando = false;
private ControladorEngine controladorEngine;
private int mCuevaMasRapida;
private int mMontanaMasRapida;
private int mCiudadMasRapida;
private long tiempoInicialEnMilis;
private int mMonedasDisponibles;
private int monedasRecogidas;
private SharedPreferences.Editor editor;
private String nivelActual;
GameState(ControladorEngine gs, Context contexto){
controladorEngine = gs;
SharedPreferences prefs = contexto.getSharedPreferences(
"Record",
Context.MODE_PRIVATE);
editor = prefs.edit();
mCuevaMasRapida = prefs.getInt(
"tiempo_cueva_masrapido",1000);
mMontanaMasRapida = prefs.getInt(
"tiempo_montana_masrapido",1000);
mCiudadMasRapida = prefs.getInt(
"tiempo_ciudad_masrapido",1000);
}
void monedasRecogidas(){
monedasRecogidas++;
}
int getMonedasRestantes(){
return mMonedasDisponibles - monedasRecogidas;
}
void monedasAgregadasAlNivel(){
mMonedasDisponibles++;
}
void reseteoMonedas(){
mMonedasDisponibles = 0;
monedasRecogidas = 0;
}
void setNivelActual(String nivel){
nivelActual = nivel;
}
String getNivelActual(){
return nivelActual;
}
void objetivoAlcanzado(){
finalJuego();
}
int getCuevaMasRapida(){
return mCuevaMasRapida;
}
int getMontanaMasRapida(){
return mMontanaMasRapida;
}
int getCiudadMasRapida(){
return mCiudadMasRapida;
}
void iniciaNuevoJuego(){
detenTodo();
controladorEngine.iniciaNuevoNivel();
iniciaTodo();
tiempoInicialEnMilis = System.currentTimeMillis();
}
int getTiempoActual(){
long MILES_EN_SEGUNDOS = 1000;
return (int) ((System.currentTimeMillis()
- tiempoInicialEnMilis) / MILES_EN_SEGUNDOS);
}
void muerte(){
detenTodo();
SoundEngine.playJugadorQuemar();
}
private void finalJuego(){
detenTodo();
int tiempoTotal = ((mMonedasDisponibles - monedasRecogidas) * 10)
+ getTiempoActual();
switch (nivelActual){
case "cueva":
if (tiempoTotal < mCuevaMasRapida){
mCuevaMasRapida = tiempoTotal;
editor.putInt("tiempo_cueva_masrapido", mCuevaMasRapida);
editor.commit();
}
break;
case "montana":
if (tiempoTotal < mMontanaMasRapida){
mMontanaMasRapida = tiempoTotal;
editor.putInt("tiempo_montana_masrapido", mMontanaMasRapida);
editor.commit();
}
break;
case "ciudad":
if (tiempoTotal < mCiudadMasRapida){
mCiudadMasRapida = tiempoTotal;
editor.putInt("tiempo_ciudad_masrapido", mCiudadMasRapida);
editor.commit();
}
break;
}
}
void detenTodo(){
mPausado = true;
mGameOver = true;
mDibujando = false;
}
void iniciaTodo(){
mPausado = false;
mGameOver = false;
mDibujando = true;
}
void detenThread(){
mThreadCorriendo = false;
}
void iniciaThread(){
mThreadCorriendo = true;
}
boolean getThreadCorriendo(){
return mThreadCorriendo;
}
boolean getDibujando(){
return mDibujando;
}
boolean getPausado(){
return mPausado;
}
boolean getGameOver(){
return mGameOver;
}
}
HUD
package org.example.pepeaventura;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import java.util.ArrayList;
class HUD {
private Bitmap mBitmapMenu;
private int mFormateoTexto;
private int mAlturaPantalla;
private int mAnchoPantalla;
final float UN_TERCIO = .33f;
final float DOS_TERCIOS = .66f;
private ArrayList mControles;
static int IZQUIERDA = 0;
static int DERECHA = 1;
static int SALTAR = 2;
HUD(Context contexto, Point tamano){
mAlturaPantalla = tamano.y;
mAnchoPantalla = tamano.x;
mFormateoTexto = tamano.x / 25;
prepararControles();
mBitmapMenu = BitmapFactory.decodeResource(
contexto.getResources(),
R.drawable.menu);
mBitmapMenu = Bitmap.createScaledBitmap(
mBitmapMenu,
tamano.x,
tamano.y,
false);
}
private void prepararControles(){
int anchoBoton = mAnchoPantalla / 14;
int altoBoton = mAlturaPantalla / 12;
int rellenoBoton = mAnchoPantalla / 90;
Rect izquierda = new Rect(rellenoBoton,
mAlturaPantalla - altoBoton - rellenoBoton,
anchoBoton + rellenoBoton,
mAlturaPantalla - rellenoBoton);
Rect derecha = new Rect(
(rellenoBoton * 2) + anchoBoton,
mAlturaPantalla - altoBoton - rellenoBoton,
(rellenoBoton * 2) + (anchoBoton * 2),
mAlturaPantalla - rellenoBoton );
Rect saltar = new Rect(
mAnchoPantalla - rellenoBoton - anchoBoton,
mAlturaPantalla - altoBoton - rellenoBoton,
mAnchoPantalla - rellenoBoton,
mAlturaPantalla - rellenoBoton);
mControles = new ArrayList();
mControles.add(IZQUIERDA,izquierda);
mControles.add(DERECHA,derecha);
mControles.add(SALTAR,saltar);
}
void dibujar(Canvas c, Paint p, GameState gs){
if (gs.getGameOver()){
c.drawBitmap(mBitmapMenu,0,0,p);
p.setColor(Color.argb(100,26,128,182));
c.drawRect(0,0,
mAnchoPantalla,mFormateoTexto * 4,p);
p.setColor(Color.argb(255,255,255,255));
p.setTextSize(mFormateoTexto);
c.drawText("Cueva",
mFormateoTexto,
mFormateoTexto*2,
p);
c.drawText("Montaña",
(mAnchoPantalla * UN_TERCIO) + mFormateoTexto,
mFormateoTexto * 2,
p);
c.drawText("Ciudad",
(mAnchoPantalla * DOS_TERCIOS) + mFormateoTexto,
mFormateoTexto * 2,
p);
p.setTextSize(mFormateoTexto/1.8f);
c.drawText("RECORD: " + gs.getCuevaMasRapida() + " segundos",
mFormateoTexto,
mFormateoTexto * 3,
p);
c.drawText("RECORD: " + gs.getMontanaMasRapida() + " segundos",
mAnchoPantalla * UN_TERCIO + mFormateoTexto,
mFormateoTexto * 3,
p);
c.drawText("RECORD: " + gs.getCiudadMasRapida() + " segundos",
mAnchoPantalla * DOS_TERCIOS + mFormateoTexto,
mFormateoTexto * 3,
p);
p.setColor(Color.argb(100,26,128,182));
c.drawRect(0,
mAlturaPantalla - mFormateoTexto * 2,
mAnchoPantalla,
mAlturaPantalla,
p);
p.setColor(Color.argb(255,255,255,255));
p.setTextSize(mFormateoTexto);
c.drawText("TOCA DOS VECES UN NIVEL PARA JUGAR",
UN_TERCIO + mFormateoTexto * 2,
mAlturaPantalla - mFormateoTexto / 2,
p);
} else {
p.setColor(Color.argb(100,0,0,0));
c.drawRect(0,0, mAnchoPantalla,mFormateoTexto, p);
p.setTextSize(mFormateoTexto / 1.5f);
p.setColor(Color.argb(255,255,255,255));
c.drawText("Tiempo: " + gs.getTiempoActual()
+ "+" + gs.getMonedasRestantes() * 10,
mFormateoTexto / 4,
mFormateoTexto / 1.5f,
p);
dibujarControles(c,p);
}
}
private void dibujarControles(Canvas c, Paint p){
p.setColor(Color.argb(100,255,255,255));
for(Rect r : mControles )
c.drawRect(r.left, r.top, r.right, r.bottom, p);
p.setColor(Color.argb(255,255,255,255));
}
ArrayList getControles(){
return mControles;
}
}
JugadorTransformar
package org.example.pepeaventura;
import android.graphics.PointF;
import android.graphics.RectF;
import java.util.ArrayList;
class JugadorTransformar extends Transformar {
private ArrayList mChocadores;
private final float DECIMO = .1f;
private final float MITAD = .5f;
private final float TERCIO = .3f;
private final float QUINTO = .2f;
private final float PIES_SALIENTE = 1.2f;
private RectF mCabezaRectF = new RectF();
private RectF mDerechaRectF = new RectF();
private RectF mIzquierdaRectF = new RectF();
private RectF mPiesRectF = new RectF();
private boolean mSaltoIniciado = false;
private boolean mCabezaGolpeadaIniciada = false;
private boolean mEnTierra;
JugadorTransformar(float velocidad,
float anchoObjeto,
float altoObjeto,
PointF ubicacionInicial){
super(velocidad,
anchoObjeto,
altoObjeto,
ubicacionInicial);
mChocadores = new ArrayList();
mChocadores.add(mCabezaRectF);
mChocadores.add(mDerechaRectF);
mChocadores.add(mIzquierdaRectF);
mChocadores.add(mPiesRectF);
}
public ArrayList getChocadores(){
actualizaChocadores();
return mChocadores;
}
public void actualizaChocadores() {
PointF ubicacion = getUbicacion();
float alturaObjeto = getTamano().y;
float anchoObjeto = getTamano().x;
mChocadores.get(0).left = ubicacion.x
+ ((anchoObjeto * TERCIO));
mChocadores.get(0).top = ubicacion.y;
mChocadores.get(0).right = ubicacion.x
+ anchoObjeto - (anchoObjeto * TERCIO);
mChocadores.get(0).right = ubicacion.y
+ (alturaObjeto * DECIMO);
mChocadores.get(1).left = ubicacion.x
+ anchoObjeto - (anchoObjeto * DECIMO);
mChocadores.get(1).top = ubicacion.y
+ (alturaObjeto * TERCIO);
mChocadores.get(1).right = ubicacion.x
+ anchoObjeto;
mChocadores.get(1).bottom = ubicacion.y
+ (alturaObjeto - (alturaObjeto * MITAD));
mChocadores.get(2).left = ubicacion.x;
mChocadores.get(2).top = ubicacion.y
+ (alturaObjeto * QUINTO);
mChocadores.get(2).right = ubicacion.x
+ (anchoObjeto * DECIMO);
mChocadores.get(2).bottom = ubicacion.y
+ (alturaObjeto - (alturaObjeto * QUINTO));
mChocadores.get(3).left = ubicacion.x
+ (anchoObjeto * TERCIO);
mChocadores.get(3).top = ubicacion.y
+ alturaObjeto - (alturaObjeto * DECIMO);
mChocadores.get(3).right = ubicacion.x
+ anchoObjeto - (anchoObjeto * TERCIO);
mChocadores.get(3).bottom = ubicacion.y
+ alturaObjeto + (alturaObjeto * PIES_SALIENTE);
}
void iniciaSalto(){
mSaltoIniciado = true;
}
void manejandoSalto(){
mSaltoIniciado = false;
}
boolean saltoIniciado(){
return mSaltoIniciado;
}
void setNoEnTierra(){
mEnTierra = false;
}
void disparaCabezaGolpeada(){
mCabezaGolpeadaIniciada = true;
}
void manejandoCabezaGolpeada(){
mCabezaGolpeadaIniciada = false;
}
boolean cabezaGolpeada(){
return mCabezaGolpeadaIniciada;
}
void noEnTierra(){
mEnTierra = false;
}
void enTierra(){
mEnTierra = true;
}
boolean estaEnTierra(){
return mEnTierra;
}
}
ManagerNivel
package org.example.pepeaventura;
import android.content.Context;
import android.graphics.PointF;
import android.util.Log;
import org.example.pepeaventura.especoj.EspecArbolMuerto;
import org.example.pepeaventura.especoj.EspecArbolNevado;
import org.example.pepeaventura.especoj.EspecCarbon;
import org.example.pepeaventura.especoj.EspecCarrito;
import org.example.pepeaventura.especoj.EspecCesped;
import org.example.pepeaventura.especoj.EspecColeccionable;
import org.example.pepeaventura.especoj.EspecConcreto;
import org.example.pepeaventura.especoj.EspecEstalactita;
import org.example.pepeaventura.especoj.EspecEstalagmita;
import org.example.pepeaventura.especoj.EspecFondoCiudad;
import org.example.pepeaventura.especoj.EspecFondoCueva;
import org.example.pepeaventura.especoj.EspecFondoMontana;
import org.example.pepeaventura.especoj.EspecFuego;
import org.example.pepeaventura.especoj.EspecJugador;
import org.example.pepeaventura.especoj.EspecLosas;
import org.example.pepeaventura.especoj.EspecMuerteInvisible;
import org.example.pepeaventura.especoj.EspecObjetivo;
import org.example.pepeaventura.especoj.EspecPilaPiedras;
import org.example.pepeaventura.especoj.EspecPisoNevado;
import org.example.pepeaventura.especoj.EspecPisoQuemado;
import org.example.pepeaventura.especoj.EspecPlataformaMovible;
import org.example.pepeaventura.especoj.EspecPosteLuz;
import org.example.pepeaventura.niveles.Nivel;
import org.example.pepeaventura.niveles.NivelCiudad;
import org.example.pepeaventura.niveles.NivelCueva;
import org.example.pepeaventura.niveles.NivelMontana;
import java.util.ArrayList;
final class ManagerNivel {
static int JUGADOR_INDICE = 0;
private ArrayList objetos;
private Nivel nivelActual;
private GameObjetoFabrica fabrica;
ManagerNivel(Context contexto,
GameEngine ge,
int pixelsPorMetro){
objetos = new ArrayList();
fabrica = new GameObjetoFabrica(
contexto,
ge,
pixelsPorMetro);
}
void setNivelActual(String nivel){
switch (nivel){
case "cueva":
nivelActual = new NivelCueva();
break;
case "ciudad":
nivelActual = new NivelCiudad();
break;
case "montana":
nivelActual = new NivelMontana();
break;
}
}
void construirObjetosJuego(GameState gs){
/*
Esto nos servira como referencia para saber a que
equivale de las claves de las losas en las clases de
los niveles.
fondos = 1,2,3 (ciudad, cueva y montaña respectivamente)
p = jugador
g = cesped
o = objetivo
m = plataforma movible
b = losas
c = carrito
s = pila de piedra
l = carbon
n = concreto
a = poste de luz
r = piso quemado
w = piso nevado
t = estalactita
i = estalagmita
d = arbol muerto
e = arbol nevado
x = collecionable (moneda)
y = muerte invisible (visible)
*/
gs.reseteoMonedas();
objetos.clear();
ArrayList nivelAcargar = nivelActual.getLosas();
for(int fila=0; fila < nivelAcargar.size(); fila++){
for(int columna = 0;
columna < nivelAcargar.get(fila).length(); columna++){
PointF coords = new PointF(columna,fila);
switch (nivelAcargar.get(fila).charAt(columna)){
case '1':
objetos.add(fabrica.crear(
new EspecFondoCiudad(),coords));
break;
case '2':
objetos.add(fabrica.crear(
new EspecFondoCueva(),coords));
break;
case '3':
objetos.add(fabrica.crear(
new EspecFondoMontana(),coords));
break;
case 'p':
objetos.add(fabrica.crear(
new EspecJugador(),coords));
JUGADOR_INDICE = objetos.size() - 1;
break;
case 'g':
objetos.add(fabrica.crear(new EspecCesped(),coords));
break;
case 'o':
objetos.add(fabrica.crear(new EspecObjetivo(),coords));
break;
case 'm':
objetos.add(fabrica.crear(new EspecPlataformaMovible(),
coords));
break;
case 'b':
objetos.add(fabrica.crear(new EspecLosas(),coords));
break;
case 'c':
objetos.add(fabrica.crear(new EspecCarrito(),coords));
break;
case 's':
objetos.add(fabrica.crear(new EspecPilaPiedras(),coords));
break;
case 'l':
objetos.add(fabrica.crear(new EspecCarbon(),coords));
break;
case 'n':
objetos.add(fabrica.crear(new EspecConcreto(),coords));
break;
case 'a':
objetos.add(fabrica.crear(new EspecPosteLuz(),coords));
break;
case 'r':
objetos.add(fabrica.crear(new EspecPisoQuemado(),coords));
break;
case 'w':
objetos.add(fabrica.crear(new EspecPisoNevado(),coords));
break;
case 't':
objetos.add(fabrica.crear(new EspecEstalactita(),coords));
break;
case 'i':
objetos.add(fabrica.crear(new EspecEstalagmita(),coords));
break;
case 'd':
objetos.add(fabrica.crear(new EspecArbolMuerto(),coords));
break;
case 'e':
objetos.add(fabrica.crear(new EspecArbolNevado(),coords));
break;
case 'x':
objetos.add(fabrica.crear(new EspecColeccionable(),coords));
break;
case 'z':
objetos.add(fabrica.crear(
new EspecFuego(),coords));
break;
case 'y':
objetos.add(fabrica.crear(
new EspecMuerteInvisible(),coords));
break;
case '.':
break;
default:
Log.e("Item no asignable aquil",
"fila:" + fila+ " columna:" + columna);
break;
}
}
}
}
ArrayList getGameObjetos(){
return objetos;
}
}
ObservadorEntrada
package org.example.pepeaventura;
import android.graphics.Rect;
import android.view.MotionEvent;
import java.util.ArrayList;
public interface ObservadorEntrada {
void handleInput(MotionEvent evento,
GameState gs,
ArrayList botones);
}
Renderer
package org.example.pepeaventura;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.util.ArrayList;
class Renderer {
private Canvas mCanvas;
private SurfaceHolder mSurfaceHolder;
private Paint mPincel;
private Camara mCamara;
Renderer(SurfaceView sh, Point tamanoPantalla){
mSurfaceHolder = sh.getHolder();
mPincel = new Paint();
mCamara = new Camara(tamanoPantalla.x, tamanoPantalla.y);
}
int getPixelsPorMetro(){
return mCamara.getPixelsPorMetro();
}
void dibujar(ArrayList objetos,
GameState gs,
HUD hud){
if (mSurfaceHolder.getSurface().isValid()){
mCanvas = mSurfaceHolder.lockCanvas();
mCanvas.drawColor(Color.argb(255,0,0,0));
if (gs.getDibujando()){
mCamara.setCentroMundo(objetos.get(ManagerNivel.JUGADOR_INDICE)
.getTransformar().getUbicacion());
for(GameObjeto objeto : objetos){
if (objeto.chekaActivo())
objeto.dibujar(mCanvas,mPincel,mCamara);
}
}
hud.dibujar(mCanvas, mPincel, gs);
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
}
SoundEngine
package org.example.pepeaventura;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.util.Log;
import java.io.IOException;
class SoundEngine {
private static SoundPool mSP;
private static int mSalto_ID = -1;
private static int mLograr_ID = -1;
private static int mMoneda_ID = -1;
private static int mFallar_ID = -1;
private static SoundEngine nuestraInstancia;
public static SoundEngine getInstancia(Context contexto){
nuestraInstancia = new SoundEngine(contexto);
return nuestraInstancia;
}
public SoundEngine(Context c){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
AudioAttributes atributos = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
mSP = new SoundPool.Builder()
.setMaxStreams(5)
.setAudioAttributes(atributos)
.build();
} else {
mSP = new SoundPool(5, AudioManager.STREAM_MUSIC,0);
}
try {
AssetManager assetManager = c.getAssets();
AssetFileDescriptor descriptor;
descriptor = assetManager.openFd("saltar.ogg");
mSalto_ID = mSP.load(descriptor,0);
descriptor = assetManager.openFd("moneda.ogg");
mMoneda_ID = mSP.load(descriptor,0);
descriptor = assetManager.openFd("lograr.ogg");
mLograr_ID = mSP.load(descriptor,0);
descriptor = assetManager.openFd("fallar.ogg");
mFallar_ID = mSP.load(descriptor,0);
} catch (IOException e){
Log.e("PepeAdventure","Ha ocurrido algun error con los archivos");
}
}
public static void playSalto(){
mSP.play(mSalto_ID,1,1,0,0,1);
}
public static void playLogrado(){
mSP.play(mLograr_ID,1,1,0,0,1);
}
public static void playJugadorQuemar(){
mSP.play(mFallar_ID,1,1,0,0,1);
}
public static void playMonedaRecogida(){
mSP.play(mMoneda_ID,1,1,0,0,1);
}
}
Transformar
package org.example.pepeaventura;
import android.graphics.PointF;
import android.graphics.RectF;
class Transformar {
RectF mChocador;
private PointF mUbicacion;
private float mVelocidad;
private float mObjetoAltura;
private float mObjetoAncho;
private PointF mPosicionInicial;
private boolean mApuntandoArriba = false;
private boolean mApuntandoAbajo = false;
private boolean mMirandoDerecha = true;
private boolean mApuntandoIzquierda = false;
private boolean mApuntandoDerecha = false;
Transformar(float velocidad,
float objetoAncho,
float objetoAltura,
PointF posicionInicial){
mChocador = new RectF();
mVelocidad = velocidad;
mObjetoAltura = objetoAltura;
mObjetoAncho = objetoAncho;
mUbicacion = posicionInicial;
mPosicionInicial = new PointF(
mUbicacion.x, mUbicacion.y);
}
public void actualizaChocador(){
mChocador.top = mUbicacion.y;
mChocador.left = mUbicacion.x;
mChocador.bottom = mChocador.top + mObjetoAltura;
mChocador.right = mChocador.left + mObjetoAncho;
}
public RectF getChocador(){
return mChocador;
}
void apuntarArriba(){
mApuntandoArriba = true;
mApuntandoAbajo = false;
}
void apuntarAbajo(){
mApuntandoAbajo = true;
mApuntandoArriba = false;
}
void apuntarDerecha(){
mApuntandoDerecha = true;
mApuntandoIzquierda = false;
mMirandoDerecha = true;
}
void apuntarIzquierda(){
mApuntandoDerecha = false;
mApuntandoIzquierda = true;
mMirandoDerecha = false;
}
boolean apuntandoArriba(){
return mApuntandoArriba;
}
boolean apuntandoAbajo(){
return mApuntandoAbajo;
}
boolean apuntandoDerecha(){
return mApuntandoDerecha;
}
boolean apuntandoIzquierda(){
return mApuntandoIzquierda;
}
void detenerHorizontal(){
mApuntandoIzquierda = false;
mApuntandoDerecha = false;
}
void detenerMovIzquierda(){
mApuntandoIzquierda = false;
}
void detenerMovDerecha(){
mApuntandoDerecha = false;
}
boolean getMirandoDerecha(){
return mMirandoDerecha;
}
float getVelocidad(){
return mVelocidad;
}
PointF getUbicacion(){
return mUbicacion;
}
PointF getTamano(){
return new PointF(
(int) mObjetoAncho,
(int) mObjetoAltura);
}
PointF getPosicionInicial(){
return mPosicionInicial;
}
}
TransformarFondo
package org.example.pepeaventura;
import android.graphics.PointF;
class TransformarFondo extends Transformar {
private float recortarX;
private boolean primeroInvertido = false;
public TransformarFondo(float velocidad,
float anchoObjeto,
float alturaObjeto,
PointF posicionInicial){
super(velocidad,
anchoObjeto,
alturaObjeto,
posicionInicial);
}
boolean getPrimeroInvertido(){
return primeroInvertido;
}
void volteaPrimeroInvertido(){
primeroInvertido = !primeroInvertido;
}
float getRecortarX(){
return recortarX;
}
void setRecortarX(float nuevoRecorteX){
recortarX = nuevoRecorteX;
}
}
UIcontroladora
package org.example.pepeaventura;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.MotionEvent;
import java.util.ArrayList;
class UIcontroladora implements ObservadorEntrada {
private float mTercero;
private boolean mPresionInicial = false;
UIcontroladora(GameEngineBroadcaster b, Point tamano){
addObservador(b);
mTercero = tamano.x / 3;
}
void addObservador(GameEngineBroadcaster b){
b.addObservador(this);
}
@Override
public void handleInput(MotionEvent evento,
GameState gs,
ArrayList<Rect> botones){
int i = evento.getActionIndex();
int x = (int) evento.getX(i);
int tipoEvento = evento.getAction()
& MotionEvent.ACTION_MASK;
if (tipoEvento == MotionEvent.ACTION_UP
|| tipoEvento == MotionEvent.ACTION_POINTER_UP){
if (gs.getGameOver() && mPresionInicial){
if (x < mTercero){
gs.setNivelActual("cueva");
gs.iniciaNuevoJuego();
} else if(x >= mTercero && x < mTercero * 2){
gs.setNivelActual("montana");
gs.iniciaNuevoJuego();
} else if (x >= mTercero * 2){
gs.setNivelActual("ciudad");
gs.iniciaNuevoJuego();
}
}
mPresionInicial = !mPresionInicial;
}
}
}
Estas son las clases que perteneceran a nuestro paquete principal, para las siguientes clases debemos crear un nuevo paquete con el siguiente nombre:
org.example.pepeaventura.especoj;
Una vez creado comenzaremos a crear las clases dentro del mismo, al igual que en los casos anteriores les pasare el nombre de la clase y el codigo:
EspecArbolMuerto
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecArbolMuerto extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "arbol_muerto";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(2f,4f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueDecorativo"
};
public EspecArbolMuerto(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecArbolNevado
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecArbolNevado extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "arbol_nevado";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(3f,6f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueDecorativo"
};
public EspecArbolNevado(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecCarbon
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecCarbon extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "carbon";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(1f,1f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueInanimado"
};
public EspecCarbon(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecCarrito
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecCarrito extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "carrito";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(2f,1f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueInanimado"
};
public EspecCarrito(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecCesped
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecCesped extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "cesped";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(1f,1f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueInanimado"
};
public EspecCesped(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecColeccionable
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecColeccionable extends EspecJuegoObjeto {
private static final String tag = "coleccionable";
private static final String bitmapNombre = "moneda";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(1f,1f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueInanimado"
};
public EspecColeccionable(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecConcreto
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecConcreto extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "concreto";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(1f,1f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueInanimado"
};
public EspecConcreto(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecEstalactita
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecEstalactita extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "estalactita";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(2f,4f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueDecorativo"
};
public EspecEstalactita(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecEstalagmita
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecEstalagmita extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "estalagmita";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(2f,4f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueDecorativo"
};
public EspecEstalagmita(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecFondoCiudad
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecFondoCiudad extends EspecJuegoObjeto {
private static final String tag = "fondo";
private static final String bitmapNombre = "ciudad";
private static final int animacionFrames = 1;
private static final float velocidad = 3f;
private static final PointF tamano = new PointF(100,70);
private static final String[] componentes = new String[] {
"ComponenteGraficosFondo",
"ComponenteActualizarFondo"
};
public EspecFondoCiudad(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecFondoCueva
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecFondoCueva extends EspecJuegoObjeto {
private static final String tag = "fondo";
private static final String bitmapNombre = "cueva";
private static final int animacionFrames = 1;
private static final float velocidad = 3f;
private static final PointF tamano = new PointF(100,70);
private static final String[] componentes = new String[] {
"ComponenteGraficosFondo",
"ComponenteActualizarFondo"
};
public EspecFondoCueva(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecFondoMontana
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecFondoMontana extends EspecJuegoObjeto {
private static final String tag = "fondo";
private static final String bitmapNombre = "montana";
private static final int animacionFrames = 1;
private static final float velocidad = 3f;
private static final PointF tamano = new PointF(100,70);
private static final String[] componentes = new String[] {
"ComponenteGraficosFondo",
"ComponenteActualizarFondo"
};
public EspecFondoMontana(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecFuego
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecFuego extends EspecJuegoObjeto {
private static final String tag = "muerte";
private static final String bitmapNombre = "fuego";
private static final int animacionFrames = 3;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(1f,1f);
private static final String[] componentes = new String[] {
"ComponenteGraficosAnimados",
"ComponenteActualizaBloqueInanimado"
};
public EspecFuego(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecJuegoObjeto
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public abstract class EspecJuegoObjeto {
private String mTag;
private String mBitmapNombre;
private float mVelocidad;
private PointF mTamano;
private String[] mComponentes;
private int mAnimacionFrames;
EspecJuegoObjeto(String tag,
String bitmapNombre,
float velocidad,
PointF tamano,
String[] componentes,
int animacionFrames){
mTag = tag;
mBitmapNombre = bitmapNombre;
mVelocidad = velocidad;
mTamano = tamano;
mComponentes = componentes;
mAnimacionFrames = animacionFrames;
}
public int getNumFrames(){
return mAnimacionFrames;
}
public String getTag(){
return mTag;
}
public String getBitmapNombre(){
return mBitmapNombre;
}
public float getVelocidad(){
return mVelocidad;
}
public PointF getTamano(){
return mTamano;
}
public String[] getComponentes(){
return mComponentes;
}
}
EspecJugador
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecJugador extends EspecJuegoObjeto {
private static final String tag = "jugador";
private static final String bitmapNombre = "jugador";
private static final int animacionFrames = 5;
private static final float velocidad = 10f;
private static final PointF tamano = new PointF(1f,2f);
private static final String[] componentes = new String[] {
"ComponenteEntradaJugador",
"ComponenteGraficosAnimados",
"ComponenteActualizaJugador"
};
public EspecJugador(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecLosas
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecLosas extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "ladrillo";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(1f,1f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueInanimado"
};
public EspecLosas(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecMuerteInvisible
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecMuerteInvisible extends EspecJuegoObjeto {
private static final String tag = "muerte";
private static final String bitmapNombre = "muerte_visible";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(10f,10f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueInanimado"
};
public EspecMuerteInvisible(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecObjetivo
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecObjetivo extends EspecJuegoObjeto {
private static final String tag = "objeto objetivo";
private static final String bitmapNombre = "objetivo";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(3f,3f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueInanimado"
};
public EspecObjetivo(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecPilaPiedras
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecPilaPiedras extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "pila_piedras";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(2f,1f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueInanimado"
};
public EspecPilaPiedras(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecPisoNevado
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecPisoNevado extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "nieve";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(1f,1f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueInanimado"
};
public EspecPisoNevado(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecPisoQuemado
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecPisoQuemado extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "quemado";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(1f,1f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueInanimado"
};
public EspecPisoQuemado(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecPlataformaMovible
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecPlataformaMovible extends EspecJuegoObjeto {
private static final String tag = "plataforma movible";
private static final String bitmapNombre = "plataforma";
private static final int animacionFrames = 1;
private static final float velocidad = 3f;
private static final PointF tamano = new PointF(2f,1f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueMovible"
};
public EspecPlataformaMovible(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
EspecPosteLuz
package org.example.pepeaventura.especoj;
import android.graphics.PointF;
public class EspecPosteLuz extends EspecJuegoObjeto {
private static final String tag = "objeto inerte";
private static final String bitmapNombre = "poste_luz";
private static final int animacionFrames = 1;
private static final float velocidad = 0f;
private static final PointF tamano = new PointF(1f,4f);
private static final String[] componentes = new String[] {
"ComponenteGraficoBloqueInanimado",
"ComponenteActualizaBloqueDecorativo"
};
public EspecPosteLuz(){
super(tag,bitmapNombre,velocidad,
tamano,componentes,animacionFrames);
}
}
Con esto tenemos completo el paquete encargado de las especificaciones de los objetos, ya sea desde como se dibujan, como se comportan y como se actualizan, para nuestro siguiente paso se debe crear otro paquete con el siguiente nombre:
org.example.pepeaventura.niveles
A diferencia del caso anterior por un tema de practicidad no les pasare el codigo por medio de texto sino que deberan descargar el siguiente archivo:
En este archivo extraeran las tres clases en la pc, las seleccionan y presionen Ctrl+C para copiarlas, luego seleccionan el nuevo paquete que crearon y presionan Ctrl+V para pegarlas, les debera aparecer una ventana que dejaran como aparece y presionan Ok para poder copiarlas, una vez hecho esto debera quedar de la siguiente manera

La unica clase que deberan crear en este paquete es la siguiente:
Nivel
package org.example.pepeaventura.niveles;
import java.util.ArrayList;
public abstract class Nivel {
ArrayList losas;
public ArrayList getLosas(){
return losas;
}
}
Con todo esto pueden probar finalmente el juego que debera ser de una forma similar a esta
Nota: Les recomiendo probarlo con un dispositivo movil
En resumen, con esto hemos completado nuestro sexto juego, les paso todos los recursos y codigos necesarios para poder crear el juego, espero les haya gustado sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.
Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.


Donación
Es para mantenimento del sitio, gracias!
$1.00
