Anuncios

Bienvenidos sean a este post, hoy les traigo el codigo completo de nuestro cuarto proyecto.

Anuncios

En este caso seran solamente los codigos (tal como hicimos con cada proyecto que terminamos) pero si necesitan una explicacion les dejo un listado de los posts donde explicamos cada uno de ellos:

Anuncios

Tambien les dejo los dos archivos que deben descargar, el primero sera para los sonidos:

Anuncios

Y este es el archivo que contiene las imagenes que usaremos:

Anuncios

El proyecto deberan crearlo con las siguientes caracteristicas:

  • Dispositivos: Phone and Tablet
  • Actividad: Empty Activity
  • Nombre: Snake
  • Nombre de paquete: org.example.snake
  • API Minimo: API 14 (Android 4.0)
Anuncios

Comencemos con los codigos de cada una de las clases:

SnakeActivity.java

package org.example.snake;

import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;

public class SnakeActivity extends Activity {

    SnakeJuego mSnakeJuego;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Display display = getWindowManager().getDefaultDisplay();
        Point tamano = new Point();
        display.getSize(tamano);
        mSnakeJuego = new SnakeJuego(this, tamano);
        setContentView(mSnakeJuego);
    }

    @Override
    protected void onResume(){
        super.onResume();
        mSnakeJuego.retomar();
    }

    @Override
    protected void onPause(){
        super.onPause();
        mSnakeJuego.pausar();
    }
}
Anuncios

Snake.java

package org.example.snake;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.view.MotionEvent;

import java.util.ArrayList;

class Snake {
    private ArrayList<Point> ubicacionSegmentos;
    private int mTamanoSegmento;
    private Point mRangoMov;
    private int pointMitad;
    private enum Cabeza{
        ARRIBA,
        ABAJO,
        IZQUIERDA,
        DERECHA
    };
    private Cabeza cabeza = Cabeza.DERECHA;
    private Bitmap mCabezaArr;
    private Bitmap mCabezaAbj;
    private Bitmap mCabezaDer;
    private Bitmap mCabezaIzq;
    private Bitmap mCuerpo;

    Snake(Context contexto, Point rm, int ss){
        ubicacionSegmentos = new ArrayList<>();
        mTamanoSegmento = ss;
        mRangoMov = rm;
        mCabezaIzq = BitmapFactory.decodeResource(
                contexto.getResources(),
                R.drawable.cabeza);
        mCabezaIzq = Bitmap.createScaledBitmap(mCabezaIzq,
                ss,ss,false);
        mCabezaDer = BitmapFactory.decodeResource(
                contexto.getResources(),
                R.drawable.cabeza);
        mCabezaArr = BitmapFactory.decodeResource(
                contexto.getResources(),
                R.drawable.cabeza);
        mCabezaAbj = BitmapFactory.decodeResource(
                contexto.getResources(),
                R.drawable.cabeza);
        Matrix matrix = new Matrix();
        matrix.preScale(-1,1);
        mCabezaDer = Bitmap.createBitmap(mCabezaIzq,
                0,0,ss,ss,matrix,true);
        matrix.preRotate(90);
        mCabezaArr = Bitmap.createBitmap(mCabezaIzq,
                0,0,ss,ss,matrix,true);
        matrix.preRotate(180);
        mCabezaAbj = Bitmap.createBitmap(mCabezaIzq,
                0,0,ss,ss,matrix,true);
        mCuerpo = BitmapFactory.decodeResource(
                contexto.getResources(),R.drawable.cuerpo);
        mCuerpo = Bitmap.createScaledBitmap(
                mCuerpo,ss,ss,false);
        pointMitad = rm.x * ss / 2;
    }

    void reset (int an, int al){
        cabeza = cabeza.DERECHA;
        ubicacionSegmentos.clear();
        ubicacionSegmentos.add(new Point(an/2,al/2));
    }

    void mover(){
        for(int i=ubicacionSegmentos.size()-1; i > 0; i--){
            ubicacionSegmentos.get(i).x = ubicacionSegmentos.get(i-1).x;
            ubicacionSegmentos.get(i).y = ubicacionSegmentos.get(i-1).y;
        }

        Point p = ubicacionSegmentos.get(0);

        switch (cabeza){
            case ARRIBA:
                p.y--;
                break;
            case ABAJO:
                p.y++;
                break;
            case DERECHA:
                p.x++;
                break;
            case IZQUIERDA:
                p.x--;
                break;
        }
        ubicacionSegmentos.set(0,p);
    }

    boolean detectarMuerte(){
        boolean muerto = false;

        if (ubicacionSegmentos.get(0).x==-1 ||
                ubicacionSegmentos.get(0).x >= mRangoMov.x ||
                ubicacionSegmentos.get(0).y == -1 ||
                ubicacionSegmentos.get(0).y >= mRangoMov.y){
            muerto = true;
        }

        for(int i=ubicacionSegmentos.size()-1; i > 0; i--){
            if (ubicacionSegmentos.get(0).x ==
                    ubicacionSegmentos.get(i).x &&
                    ubicacionSegmentos.get(0).y ==
                            ubicacionSegmentos.get(i).y){
                muerto = true;
            }
        }

        return muerto;
    }

    boolean chekaCena(Point l){
        if (ubicacionSegmentos.get(0).x == l.x &&
                ubicacionSegmentos.get(0).y == l.y){
            ubicacionSegmentos.add(new Point(-10,-10));
            return true;
        }
        return false;
    }

    void dibujar(Canvas canvas, Paint pincel){
        if (!ubicacionSegmentos.isEmpty()){
            switch (cabeza){
                case DERECHA:
                    canvas.drawBitmap(mCabezaDer,
                            ubicacionSegmentos.get(0).x * mTamanoSegmento,
                            ubicacionSegmentos.get(0).y * mTamanoSegmento,
                            pincel);
                    break;
                case IZQUIERDA:
                    canvas.drawBitmap(mCabezaIzq,
                            ubicacionSegmentos.get(0).x * mTamanoSegmento,
                            ubicacionSegmentos.get(0).y * mTamanoSegmento,
                            pincel);
                    break;
                case ABAJO:
                    canvas.drawBitmap(mCabezaAbj,
                            ubicacionSegmentos.get(0).x * mTamanoSegmento,
                            ubicacionSegmentos.get(0).y * mTamanoSegmento,
                            pincel);
                    break;
                case ARRIBA:
                    canvas.drawBitmap(mCabezaArr,
                            ubicacionSegmentos.get(0).x * mTamanoSegmento,
                            ubicacionSegmentos.get(0).y * mTamanoSegmento,
                            pincel);
                    break;
            }
            for(int i=1; i < ubicacionSegmentos.size(); i++){
                canvas.drawBitmap(mCuerpo,
                        ubicacionSegmentos.get(i).x * mTamanoSegmento,
                        ubicacionSegmentos.get(i).y * mTamanoSegmento,
                        pincel);
            }
        }
    }

    void cambiarDireccion(MotionEvent evento){
        if (evento.getX() >= pointMitad){
            switch (cabeza){
                case ARRIBA:
                    cabeza = cabeza.DERECHA;
                    break;
                case ABAJO:
                    cabeza = cabeza.IZQUIERDA;
                    break;
                case IZQUIERDA:
                    cabeza = cabeza.ARRIBA;
                    break;
                case DERECHA:
                    cabeza = cabeza.ABAJO;
                    break;
            }
        } else {
            switch (cabeza){
                case ARRIBA:
                    cabeza = cabeza.IZQUIERDA;
                    break;
                case ABAJO:
                    cabeza = cabeza.DERECHA;
                    break;
                case IZQUIERDA:
                    cabeza = cabeza.ABAJO;
                    break;
                case DERECHA:
                    cabeza = cabeza.ARRIBA;
                    break;
            }
        }
    }
}
Anuncios

Manzana.java

package org.example.snake;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;

import java.util.Random;

class Manzana {
    private Point mUbicacion = new Point();
    private Point mRangoCreacion;
    private int mTamano;
    private Bitmap mBitmapManzana;

    Manzana(Context contexto, Point rc, int t){
        mRangoCreacion = rc;
        mTamano = t;
        mUbicacion.x = -10;
        mBitmapManzana = BitmapFactory
                .decodeResource(contexto.getResources()
                        ,R.drawable.manzana);
        mBitmapManzana = Bitmap
                .createScaledBitmap(mBitmapManzana,t,t,false);
    }

    void generar(){
        Random random = new Random();
        mUbicacion.x = random.nextInt(mRangoCreacion.x) + 1;
        mUbicacion.y = random.nextInt(mRangoCreacion.y - 1) + 1;
    }

    Point getUbicacion(){
        return mUbicacion;
    }

    void dibujar(Canvas canvas, Paint pincel){
        canvas.drawBitmap(mBitmapManzana,
                mUbicacion.x * mTamano,mUbicacion.y * mTamano,pincel);
    }
}
Anuncios

SnakeJuego.java

package org.example.snake;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
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.io.IOException;

class SnakeJuego extends SurfaceView implements Runnable {

    private Thread mThread = null;
    private long mProxTiempoCuadro;
    private volatile boolean mPausado = true;
    private volatile boolean mJugando = false;
    private SoundPool mSP;
    private int mComer_ID = -1;
    private int mMordida_ID = -1;
    private final int ANCHO_NUM_BLOQUES = 30;
    private int mNumeroBloquesAlto;
    private int mPuntaje;
    private Canvas mCanvas;
    private SurfaceHolder mSurfaceHolder;
    private Paint mPincel;
    private Snake mSnake;
    private Manzana mManzana;

    public SnakeJuego(Context contexto, Point tamano) {
        super(contexto);

        int tamanoBloque = tamano.x / ANCHO_NUM_BLOQUES;
        mNumeroBloquesAlto = tamano.y / tamanoBloque;

        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()
                    .setAudioAttributes(atributos)
                    .setMaxStreams(5)
                    .build();
        } else {
            mSP = new SoundPool(5, AudioManager.STREAM_MUSIC,0);
        }
        try {
            mComer_ID = mSP.load(contexto,R.raw.apple,0);
            mMordida_ID = mSP.load(contexto,R.raw.bitten,0);
        } catch (Exception e){
            Log.e("Error","Ha ocurrido un error con la carga de los archivos");
        }
        mSurfaceHolder=getHolder();
        mPincel = new Paint();

        mManzana = new Manzana(contexto,
                new Point(ANCHO_NUM_BLOQUES,
                        mNumeroBloquesAlto),
                tamanoBloque);
        mSnake = new Snake(contexto,
                new Point(ANCHO_NUM_BLOQUES,
                        mNumeroBloquesAlto),
                tamanoBloque);
    }

    @Override
    public void run(){
        while(mJugando){
            if(!mPausado){
                if(requiereActualizar()){
                    actualizar();
                }
            }
            dibujar();
        }
    }

    public boolean requiereActualizar(){
        final long BLANCO_FPS = 10;
        final long MILES_POR_SEGUNDO = 1000;
        if(mProxTiempoCuadro<=System.currentTimeMillis()){
            mProxTiempoCuadro=System.currentTimeMillis()
                    + MILES_POR_SEGUNDO / BLANCO_FPS;
            return true;
        }
        return false;
    }

    public void actualizar(){
        mSnake.mover();
        if (mSnake.chekaCena(mManzana.getUbicacion())){
            mManzana.generar();
            mPuntaje++;
            mSP.play(mComer_ID,1,1,0,0,1);
        }
        if (mSnake.detectarMuerte()){
            mSP.play(mMordida_ID,1,1,0,0,1);
            mPausado = true;
        }
    }

    public void dibujar(){
        if(mSurfaceHolder.getSurface().isValid()){
            mCanvas = mSurfaceHolder.lockCanvas();
            mCanvas.drawColor(Color.argb(255,26,128,182));
            mPincel.setColor(Color.argb(255,255,255,255));
            mPincel.setTextSize(120);
            mCanvas.drawText("" + mPuntaje,20,120,mPincel);
            mManzana.dibujar(mCanvas,mPincel);
            mSnake.dibujar(mCanvas,mPincel);
            if (mPausado){
                mPincel.setColor(Color.argb(255,255,255,255));
                mPincel.setTextSize(100);
                mCanvas.drawText(getResources().getString(R.string.inicioTexto),
                        20,300,mPincel);
            }
            mSurfaceHolder.unlockCanvasAndPost(mCanvas);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent evento){
        switch (evento.getAction() & MotionEvent.ACTION_MASK){
            case MotionEvent.ACTION_UP:
                if (mPausado){
                    mPausado = false;
                    nuevoJuego();
                    return true;
                }
                mSnake.cambiarDireccion(evento);
                break;
            default:
                break;
        }
        return true;
    }

    public void nuevoJuego(){
        mSnake.reset(ANCHO_NUM_BLOQUES,mNumeroBloquesAlto);
        mManzana.generar();
        mPuntaje = 0;
        mProxTiempoCuadro = System.currentTimeMillis();
    }

    public void pausar(){
        mJugando=false;
        try{
            mThread.join();
        } catch (InterruptedException e){
            Log.e("Error", "no se pudo detener el thread.");
        }
    }

    public void retomar(){
        mJugando=true;
        mThread = new Thread(this);
        mThread.start();
    }
}
Anuncios

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.example.snake">

    <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=".SnakeActivity"
            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 esto ya tenemos completo nuestro juego deberan tener un resultado similar a este:

Anuncios

En resumen, hemos hecho nuestro cuarto proyecto y con un clasico como es el juego snake, hemos logrado como manejar varios elementos para nuestro cuerpo, hemos trabajado algunos elementos de manera muy avanzada pero para el proximo proyecto haremos una genialidad unica, espero les haya gustado o sido util 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