Anuncios

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:

Anuncios

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)
Anuncios

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

Anuncios

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();
    }
}
Anuncios

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;
    }
}
Anuncios

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;
    }

}
Anuncios

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);
    }
}
Anuncios

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>
Anuncios

Con todo esto podran realizar un juego como se ve en el siguiente video

Anuncios

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.

Anuncios

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