Bienvenidos sean a este post, hoy les traigo todos los codigos que usamos para crear a nuestro tercer juego, como siempre les recuerdo que este son solamente los codigos si quieren saber sobre los mismos les recomiendo revisitar estos posts:
- Nuestro tercer proyecto
- BalaceraEngine
- La clase Bala
- La verdadera balacera
- La clase Pepe
- Finalizando a Balacera
Las caracteristicas del proyectos son las siguientes:
- Dispositivos: Phone and Tablet
- Actividad: Empty Activity
- Nombre: Balacera
- Nombre de paquete: org.example.balacera
- API Minimo: API 14 (Android 4.0)
En este caso vamos a renombrar a MainActivity por BalaceraActivity, les recomiendo este post donde se explica como hacerlo, aca les dejo el enlace para descargar a nuestro jugador
Y a continuacion todos los codigos:
BalaceraActivity.java
package org.example.balacera;
import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
public class BalaceraActivity extends Activity {
private BalaceraJuego mBJuego;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager()
.getDefaultDisplay();
Point tamano = new Point();
display.getSize(tamano);
mBJuego = new BalaceraJuego(this,tamano.x,tamano.y);
setContentView(mBJuego);
}
@Override
protected void onResume(){
super.onResume();
mBJuego.retomar();
}
@Override
protected void onPause(){
super.onPause();
mBJuego.pausa();
}
}
Bala.java
package org.example.balacera;
import android.graphics.RectF;
class Bala {
private RectF mRect;
private float mVelocidadX;
private float mVelocidadY;
private float mAncho;
private float mAlto;
Bala(int screenX){
mAncho = screenX / 100;
mAlto = screenX / 100;
mRect = new RectF();
mVelocidadX = screenX / 5;
mVelocidadY = screenX / 5;
}
public RectF getRect(){
return mRect;
}
void actualizar(long fps){
mRect.left += (mVelocidadX/fps);
mRect.top += (mVelocidadY/fps);
mRect.right = mRect.left + mAncho;
mRect.bottom = mRect.top + mAlto;
}
void invertirVelocidadX(){
mVelocidadX = -mVelocidadX;
}
void invertirVelocidadY(){
mVelocidadY = -mVelocidadY;
}
void generar(int pX, int pY, int vX, int vY){
mRect.left=pX;
mRect.top=pY;
mRect.right=mRect.left + mAncho;
mRect.bottom=mRect.top + mAlto;
mVelocidadX = mVelocidadX * vX;
mVelocidadY = mVelocidadY * vY;
}
}
Pepe.java
package org.example.balacera;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.RectF;
class Pepe {
RectF mRect;
float mPepeAltura;
float mPepeAncho;
boolean mTeleporte = false;
Bitmap mBitmap;
public Pepe(Context contexto, float screenX, float screenY) {
mPepeAltura = screenY / 10;
mPepeAncho = mPepeAltura / 2;
mRect = new RectF(screenX / 2,
screenY / 2,
(screenX / 2) + mPepeAncho,
(screenY / 2) + mPepeAltura);
mBitmap = BitmapFactory.decodeResource(
contexto.getResources(), R.drawable.pepe);
}
boolean teleTransporte(float nuevoX, float nuevoY){
boolean exito = false;
if (!mTeleporte){
mRect.left = nuevoX - (mPepeAncho/2);
mRect.top = nuevoY - (mPepeAltura/2);
mRect.right = mRect.left + mPepeAncho;
mRect.bottom = mRect.top + mPepeAltura;
mTeleporte = true;
exito = true;
}
return exito;
}
void setTeleporteDisponible(){
mTeleporte = false;
}
RectF getRect(){
return mRect;
}
Bitmap getBitmap(){
return mBitmap;
}
}
BalaceraJuego.java
package org.example.balacera;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.util.Random;
class BalaceraJuego extends SurfaceView implements Runnable {
boolean mDepurando = true;
private Thread mJuegoTread=null;
private volatile boolean mJugando;
private boolean mPausado = true;
private SurfaceHolder mNuestroHolder;
private Canvas mCanvas;
private Paint mPincel;
private long mFPS;
private final int MILES_EN_SEGUNDOS = 1000;
private int mScreenX;
private int mScreenY;
private int mFontTamano;
private int mFontMargen;
private SoundPool mSP;
private int mBeepID = -1;
private int mTeleportID = -1;
private final int BALASMAXIMA = 10000;
private Bala [] mBalas = new Bala[BALASMAXIMA];
private int mNumBalas = 0;
private int mGeneracionRatio = 1;
private Random mRandomX = new Random();
private Random mRandomY = new Random();
private Pepe mPepe;
private boolean mImpacto = false;
private int mNumImpactos;
private int mEscudo = 10;
private long mTiempoInicioJuego;
private long mMejorTiempoJuego;
private long mTotalTiempoJuego;
public BalaceraJuego(Context contexto, int x, int y){
super(contexto);
mScreenX = x;
mScreenY = y;
mFontTamano = mScreenX / 20;
mFontMargen = mScreenX / 50;
mNuestroHolder = getHolder();
mPincel = new Paint();
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{
mBeepID = mSP.load(contexto,R.raw.beep,0);
mTeleportID = mSP.load(contexto,R.raw.teleport,0);
} catch (Exception e){
Log.e("Error","Ha fallado la carga de alguno de los archivos");
}
for(int a=0; a < mBalas.length; a++){
mBalas[a]=new Bala(mScreenX);
}
mPepe = new Pepe(contexto, mScreenX, mScreenY);
iniciaJuego();
}
public void iniciaJuego(){
mNumImpactos = 0;
mNumBalas = 0;
mImpacto = false;
if (mTotalTiempoJuego > mMejorTiempoJuego)
mMejorTiempoJuego = mTotalTiempoJuego;
}
private void generaBalas(){
if (mNumBalas<BALASMAXIMA)
{
int generaX;
int generaY;
int velocidadX;
int velocidadY;
if (mPepe.getRect().centerX()<(mScreenX/2)){
generaX = mRandomX.
nextInt(mScreenX/2) + mScreenX/2;
velocidadX = 1;
} else {
generaX = mRandomX.nextInt(mScreenX / 2);
velocidadX = -1;
}
if(mPepe.getRect().centerY() < (mScreenY/2)){
generaY = mRandomY.nextInt(mScreenY/2 ) + mScreenY/2;
velocidadY = 1;
} else {
generaY = mRandomY.nextInt(mScreenY/2);
velocidadY = -1;
}
mBalas[mNumBalas].generar(
generaX,
generaY,
velocidadX,
velocidadY);
mNumBalas++;
}
}
@Override
public void run(){
while(mJugando){
long frameInicioTiempo=System.currentTimeMillis();
if (!mPausado){
actualizar();
detectarColisiones();
}
dibujar();
long frameEsteTiempo=System.currentTimeMillis()
- frameInicioTiempo;
if (frameEsteTiempo>=1)
mFPS = MILES_EN_SEGUNDOS/frameEsteTiempo;
}
}
private void actualizar(){
for(int i = 0; i < mNumBalas; i++){
mBalas[i].actualizar(mFPS);
}
}
private void detectarColisiones(){
for(int i=0; i < mNumBalas; i++){
if (mBalas[i].getRect().bottom > mScreenY){
mBalas[i].invertirVelocidadY();
} else if (mBalas[i].getRect().top<0){
mBalas[i].invertirVelocidadY();
} else if (mBalas[i].getRect().left<0){
mBalas[i].invertirVelocidadX();
} else if (mBalas[i].getRect().right > mScreenX){
mBalas[i].invertirVelocidadX();
}
}
for(int i=0; i < mNumBalas; i++){
if (RectF.intersects(mBalas[i].getRect(), mPepe.getRect())){
mSP.play(mBeepID,1,1,0,0,1);
mImpacto = true;
mBalas[i].invertirVelocidadX();
mBalas[i].invertirVelocidadY();
mNumImpactos++;
if (mNumImpactos==mEscudo){
mPausado = true;
mTotalTiempoJuego = System.currentTimeMillis()
- mTiempoInicioJuego;
iniciaJuego();
}
}
}
}
private void dibujar(){
if (mNuestroHolder.getSurface().isValid()){
mCanvas = mNuestroHolder.lockCanvas();
mCanvas.drawColor(Color.argb(255,243,111,36));
mPincel.setColor(Color.argb(255,255,255,255));
for(int i=0; i<mNumBalas; i++){
mCanvas.drawRect(mBalas[i].getRect(),mPincel);
}
mCanvas.drawBitmap(mPepe.getBitmap(),
mPepe.getRect().left,mPepe.getRect().top,mPincel);
mPincel.setTextSize(mFontTamano);
mCanvas.drawText("Balas: " + mNumBalas
+ " Escudo: " + (mEscudo - mNumImpactos)
+ " Mejor tiempo: " + (mMejorTiempoJuego / MILES_EN_SEGUNDOS),
mFontMargen,mFontTamano,mPincel);
if (!mPausado){
mCanvas.drawText("Segundos de supevivencia: "
+ ((System.currentTimeMillis() - mTiempoInicioJuego) / MILES_EN_SEGUNDOS)
,mFontMargen,mFontMargen*30, mPincel);
}
if (mDepurando)
imprimirDepuracion();
mNuestroHolder.unlockCanvasAndPost(mCanvas);
}
}
@Override
public boolean onTouchEvent(MotionEvent evento){
switch (evento.getAction() & MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
if (mPausado){
mTiempoInicioJuego = System.currentTimeMillis();
mPausado = false;
}
if (mPepe.teleTransporte(evento.getX(), evento.getY())){
mSP.play(mTeleportID,1,1,0,0,1);
}
break;
case MotionEvent.ACTION_UP:
mPepe.setTeleporteDisponible();
generaBalas();
break;
}
return true;
}
public void pausa(){
mJugando = false;
try{
mJuegoTread.join();
} catch (InterruptedException e){
Log.e("Error","Joining el thread");
}
}
public void retomar(){
mJugando = true;
mJuegoTread = new Thread(this);
mJuegoTread.start();
}
private void imprimirDepuracion(){
int depuraTamano = 20;
int depuraInicio = 150;
mPincel.setTextSize(depuraTamano);
mCanvas.drawText("FPS: " + mFPS,
10,depuraInicio + depuraTamano, mPincel);
mCanvas.drawText("Pepe left: " + mPepe.getRect().left,
10,depuraInicio + (depuraTamano * 2),
mPincel);
mCanvas.drawText("Pepe top: " + mPepe.getRect().top,
10,depuraInicio + (depuraTamano * 3),
mPincel);
mCanvas.drawText("Pepe right: " + mPepe.getRect().right,
10,depuraInicio + (depuraTamano * 4),
mPincel);
mCanvas.drawText("Pepe bottom: " + mPepe.getRect().bottom,
10,depuraInicio + (depuraTamano * 5),
mPincel);
mCanvas.drawText("Pepe centerX: " + mPepe.getRect().centerX(),
10,depuraInicio + (depuraTamano * 6),
mPincel);
mCanvas.drawText("Pepe centerY: " + mPepe.getRect().centerY(),
10,depuraInicio + (depuraTamano * 7),
mPincel);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.example.balacera">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".BalaceraActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Con todo esto podran realizar un juego como se ve en el siguiente video
Esperado 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.

Tambien podes donar
Es para mantenimiento del sitio, gracias!
$1.00