Our First game with AndroidStudio

Welcome ! , today we take a look to my first game with AndroidStudio.

It is a simple pong -style  game where the user must intercept the projectile. In case of intercepting it, +5 points will be added to the score, if the user fails , will be -10 points to the score.
The objective is to get 50 points, if the user gets that mark a victory message will be shown on the screen, in case of failing several times to intercept and obtain a score of -10 points, a defeat message will appear.

 

Sprite is a partially transparent 2D raster image that is usually placed over a background image. Sprites are used in video games. Normally there is more than one sprite in the screen at one time. They can represent AI (Artificial Intelligent) entities or the main character controlled by the player.

A Sprite has a (x,y) position and a (x,y) speed. It can contain its own animation and sounds. I use the next Sprites for this proyect:

Enemy Sprite                                            Background                               Main  Sprite


 

 

 

 

 

 

Bitmaps and Canvas

The Bitmap (android.graphics.Bitmap) class represents a bitmap image. You create bitmaps via the BitmapFactory (android.graphics.BitmapFactory) class.

Using a BitmapFactory, you can create bitmaps in three common ways: from a resource, a file, or an InputStream. To create a bitmap from a resource, you use the BitmapFactory method decodeResource():

 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.someImage);

Basic Sprite class :

A basic class of a Sprite must have two important methods , onDraw() and update().

The onDraw() method :

In the onDraw method  we will define the default propierties when painting the sprite with the canvas (we will invoke it in the GameView):

public void onDraw(Canvas canvas) {
        update();
        int srcX = getActualFrame() * getWidth();
        int srcY = getActualFila() * getHeight();
        Rect src = new Rect(srcX, srcY, srcX + getWidth(), srcY + getHeight());
        Rect dst = new Rect(getX(), getY(), getX() + getWidth() +50, getY() + getHeight() +50); 
        canvas.drawBitmap(getBmp(), src , dst, null);
    }

We just define the Sprite propierties.

The update() method :

We will use this method to update the properties of the sprite according to certain conditions, for example:
In this code we see that when the size of the sprite is greater than the width of the background where we painted –  its own width, it will change its speed.
That is, if our sprite reaches the right edge of the screen, its speed will be reversed and it will move towards -x.

We use a similar way to control collisions with height limit frames.

With this method and onDraw () we will update the properties of our sprite in a continuous thread

 

   private void update() {
        if (x > gameView.getWidth() - width - xSpeed) {
            setxSpeed(-getxSpeed());
            setActualFila(1);
        }
        if (x + xSpeed < 0) {
            setxSpeed(getxSpeed()*-1);
            setActualFila(1);
        }

        if (y > gameView.getHeight() - height - ySpeed) {
            setySpeed(-getySpeed());
            setActualFila(1);

        }
        if (y + ySpeed < 0) {
            setySpeed(-getySpeed()+5);
            setActualFila(1);
        }
        setX(getX() + getxSpeed());
        setY(getY() + getySpeed());
        actualFrame = ++actualFrame % BMP_COLUMNAS; 
    }

The GameView class :

In the GameView class we will control the collision mechanics through the following method:

The method will basically control when the coordinates of each sprite coincide, and if the collision occurs, the speed of both X and Y axis will be modified, +5 will be added to the score and a sound will be initiated by invoking the sp of the SoundPool class.
This method has a direct impact on the thread of the GameLoopThread class.
In short, we provoke a small animation during the movement of the sprite causing it to vary its bitmap according to its speed / orientation of the X and Y axes.

  public int colision(){
        int nivelColision=100; //Variable to control the level of collision
        int i = 1;

            if((Math.abs(sprite.getX()-enemy.getX())<150 ||
                    Math.abs(enemy.getX()-sprite.getX())<150) //Eje X
                    && (Math.abs(sprite.getY()-enemy.getY())<150 ||
                    Math.abs(enemy.getY()-sprite.getY())<0))
  {
                enemy.setxSpeed(enemy.getxSpeed()-10);
                enemy.setySpeed(enemy.getySpeed()-10);
                puntuacion = puntuacion + 5;
                sp.play(hit,1,1,1,0,1);
        return i;
            }if(enemy.getY() > this.getHeight() - enemy.getHeight() - enemy.getySpeed()) {
            puntuacion = puntuacion - 10;
        }
    return -1;
    }

The onDraw GameView method :

This is where we paint the Sprites, both the enemy and the main one.
We also select a background for the game using the method:

Bitmap bmpFondo = BitmapFactory.decodeResource(getResources(), R.drawable.fondojuego);

 protected void onDraw(Canvas canvas) {
        Bitmap bmpFondo = BitmapFactory.decodeResource(getResources(),
               R.drawable.fondojuego);
        Rect src = new Rect(0, 0, bmpFondo.getWidth(), bmpFondo.getHeight());
        Rect dst = new Rect(0, 0, canvas.getWidth(), canvas.getHeight());
        canvas.drawBitmap(bmpFondo, src, dst, null);

        enemy.onDraw(canvas);
        sprite.onDraw(canvas);

GameLoopThread :

In this class we create the run () method that will act as a thread checking the properties and movements of the Sprites

public void run() {
        while (isRunning()) { //running un "flag" para parar el "game loop"
            Canvas c = null;
  try {
                c = getView().getHolder().lockCanvas();
                //Sincroniza para impedir que se pueda usar varias veces a la vez
                synchronized (getView().getHolder()) {
                    getView().onDraw(c);
                    detectarColision();
  }
            } finally {
                if (c != null) {
                    getView().getHolder().unlockCanvasAndPost(c);
                } } }  }

    public void detectarColision(){
        int i= view.colision();
 if(i>=0){
        Log.e("Colision ", String.valueOf(i));
    }
}

Sound System :

An object of the MediaPlayer class that we will use for background music.
An object of the SoundPool class that we will use to make a reusable stream of sounds for the conditions of: collision, victory and defeat.

MediaPlayer mp;
    SoundPool sp = null ;
    int win = null ;
    int hit = null ;
    int lose = null ;

In the constructor of the GameView class we initialize the object of the MediaPlayer class, select the volume, the option to play it in a loop (setLooping (true)) and start it with its .start () method.

  mp=new MediaPlayer().create(context,R.raw.soundtrack);
        mp.setVolume(0.50F,0.50F);
        mp.setLooping(true);
        mp.start();

For the sounds effect , we initialize the effects using the sp object of the SoundPool class:

sp = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
hit=sp.load(context,R.raw.hit,1);
win = sp.load(context,R.raw.win,1);
lose = sp.load(context,R.raw.lose,1);

We will invoke the play () method of the sp object in case the player loses, and a defeat message will be shown on the screen:

if(puntuacion <=-10) {
    mp.stop();
    Paint o = new Paint();
    o.setStrokeWidth(8);
    o.setColor(Color.BLUE);
    o.setTextSize(100F);
    o.setTypeface(Typeface.DEFAULT_BOLD);
    canvas.drawText(" ¡ YOU LOSE  !  ",250,500,p);
    sp.play(lose,1,1,1,0,1);

    gameLoopThread.setRunning(false);
}

In case the player wins another different sound effect will be invoked:

if(puntuacion >=50) {
    Paint o = new Paint();
    o.setStrokeWidth(8);
    o.setColor(Color.BLUE);
    o.setTextSize(100F);
    o.setTypeface(Typeface.DEFAULT_BOLD);
    canvas.drawText(" ¡ YOU WIN  !  ",250,500,p);
    sp.play(win,1,1,1,0,1);
    mp.stop();

    gameLoopThread.setRunning(false);
}

Each time the two sprites collide a sound effect will be initiated, initialized from the collision () method:

sp.play(hit,1,1,1,0,1);

Controlls :

For the input subsystem, a KeyEvent method has been implemented.
The player can move his sprite by the X axis to intercept the trajectory of the enemy projectile:
The method basically works in the following way:
“A” or “<-” key of the numPad: The main sprite will move to the left increasing the speed of the -X axis.
“D” or “->” key of the numPad: The main sprite will move to the right, increasing the speed of the + X axis.

public boolean onKey(View v, int keyCode, KeyEvent keyEvent) {
        boolean hecho = false;
        if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
            switch (keyCode) {
    //Left
 case KeyEvent.KEYCODE_A:
     sprite.setX(sprite.getX()-70);
            case KeyEvent.KEYCODE_DPAD_LEFT:
            sprite.setxSpeed(-sprite.getSpeed());
 //Paramos la velocidad del eje Y
            hecho = true;
                sprite.setX(sprite.getX()-70);
 break;
    //Rigth
 case KeyEvent.KEYCODE_D:
     sprite.setxSpeed(sprite.getSpeed());
            case KeyEvent.KEYCODE_DPAD_RIGHT:
            sprite.setxSpeed(sprite.getSpeed());
            hecho = true;
                sprite.setX(sprite.getX()+70);
 break;
}
 }
         return hecho;
         }

 

This is just my first game, so I’m still working on it and improving it . Feel free to download , modify and improve it as much you want :

GitHub :    https://github.com/RayRT/SpaceDefender

Tutorials :  http://www.edu4java.com/en/androidgame/androidgame1.html

Youtube Video guides : https://www.youtube.com/watch?v=OojQitoAEXs

 

Acerca del autor: Start2Develop

Dejar una contestacion

Tu dirección de correo electrónico no será publicada.