Game Space Shooter V1.1.0 – Main Menu dan Detail Record High Score

Halo teman-teman semuanya, sudah lama saya ngga update blog nih. Walaupun sudah lama ngga update blog, tapi saya tetap memantau blog ini kok. Dan dari sekian artikel yang sudah saya terbitkan, artikel tentang Buat Game Space Shooter dengan Android Studio menjadi artikel yang banyak dibaca dan banyak dikomentari. Oleh karena itu, saya memutuskan untuk mengembangkan aplikasinya dan tentunya menuliskan tutorialnya di blog ini.

Nah di tulisan kali ini, saya akan membagikan tutorial tentang membuat Main Menu dan Detail Record High Score. Main menu akan berisikan 3 button yaitu PlayHigh Score dan Exit. Sedangkan detail record high score itu artinya tidak hanya score yang disimpan, melainkan juga jumlah meteor dan pesawat yang berhasil dihancurkan.

Membuat Main Menu

Kita memerlukan1 activity baru, yaitu MainMenuActivity.

Di MainMenuActivity akan terdapat 3 button sesuai yang saya jelaskan sebelumnya, kemudian ada judul game berupa gambar dan background yang juga berupa gambar. Untuk buttonnya sendiri saya juga buat custom menggunakan gambar dari https://kenney.nl/assets/ui-pack, kemudian saya konversi ke 9-patch image. Untuk tutorial konversi gambar ke 9-patch image bisa dilihat di https://blog.andevindo.com/memahami-9-patch-image-dan-cara-menggunakannya/.

Berikut gambar untuk judul dan backgroundnya:

Tampilan akhir dari MainMenuActivity:

Kode untuk custom background buttonnya:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/blue_button01" android:state_pressed="true"/>
    <item android:drawable="@drawable/blue_button01" android:state_focused="true"/>
    <item android:drawable="@drawable/blue_button00"/>
</selector>

blue_button00 dan blue_button01 harus dibuat terlebih dahulu, tutorialnya bisa dilihat di https://blog.andevindo.com/memahami-9-patch-image-dan-cara-menggunakannya/

Kode untuk tampilan MainMenuActivity:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainMenuActivity">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/space_shooter_main_menu_background" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_marginLeft="32dp"
        android:layout_marginRight="32dp"
        android:orientation="vertical"
        android:gravity="center_horizontal">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="80dp"
            android:adjustViewBounds="true"
            android:src="@drawable/logo" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="48dp"
            android:paddingRight="48dp">

            <Button
                android:id="@+id/play"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:background="@drawable/custom_button_background"
                android:text="PLAY"
                android:textColor="@android:color/white"
                android:textSize="20sp"
                android:textStyle="bold" />

            <Button
                android:id="@+id/high_score"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:background="@drawable/custom_button_background"
                android:text="HIGH SCORE"
                android:textColor="@android:color/white"
                android:textSize="20sp"
                android:textStyle="bold" />

            <Button
                android:id="@+id/exit"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/custom_button_background"
                android:text="EXIT"
                android:textColor="@android:color/white"
                android:textSize="20sp"
                android:textStyle="bold" />

        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

Kode untuk MainMenuActivity

package com.andevindo.spaceshooter;

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;

public class MainMenuActivity extends AppCompatActivity implements View.OnClickListener {

    private Button mPlay, mHighScore, mExit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_menu);

        //Membuat tampilan menjadi full screen
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        //Membuat tampilan selalu menyala jika activity aktif
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        mPlay = findViewById(R.id.play);
        mHighScore = findViewById(R.id.high_score);
        mExit = findViewById(R.id.exit);

        mPlay.setOnClickListener(this);
        mHighScore.setOnClickListener(this);
        mExit.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.play:
                startActivity(new Intent(this, MainActivity.class));
                finish();
                break;
            case R.id. high_score:
                startActivity(new Intent(this, HighScoreActivity.class));
                break;
            case R.id.exit:
                finish();
                break;
        }
    }
}

Membuat High Score Menu

Kita perlu membuat activity baru yaitu HighScoreActivity dan berikut adalah tampilannya:

Terdapat back button, judul, keterangan kalau belum pernah main dan juga keterangan jumlah score, meteor dan pesawat musuh yang dihancurkan ketika mendapatkan high score.

Untuk gambar back button bisa didownload di https://materialdesignicons.com/

Kode untuk tampilan HighScoreActivity:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".HighScoreActivity">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/space_shooter_main_menu_background" />

    <ImageView
        android:layout_margin="16dp"
        android:id="@+id/back"
        android:src="@drawable/arrow_left_circle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_marginLeft="32dp"
        android:layout_marginRight="32dp"
        android:layout_marginTop="80dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:orientation="vertical">
        <TextView
            android:text="HIGH SCORE"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/white"
            android:fontFamily="@font/iceberg_regular"
            android:textSize="32dp"/>
        <TextView
            android:id="@+id/null_high_score"
            android:layout_marginTop="16dp"
            android:text="Belum ada high score"
            android:textColor="@android:color/white"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <LinearLayout
            android:layout_marginTop="16dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:background="@android:color/white"
            android:paddingLeft="48dp"
            android:paddingRight="48dp"
            android:paddingTop="16dp"
            android:paddingBottom="16dp"
            android:gravity="center_horizontal">
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:layout_marginBottom="16dp">
                <TextView
                    android:textStyle="bold"
                    android:text="SCORE: "
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
                <TextView
                    android:textStyle="bold"
                    android:id="@+id/score"
                    android:text="100"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
            </LinearLayout>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:gravity="center_vertical"
                android:layout_marginBottom="16dp">
                <ImageView
                    android:src="@drawable/meteor_1"
                    android:layout_width="48dp"
                    android:layout_height="wrap_content"
                    android:adjustViewBounds="true"
                    android:layout_marginRight="8dp"/>
                <TextView
                    android:textStyle="bold"
                    android:id="@+id/meteor"
                    android:text="x100"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
            </LinearLayout>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:gravity="center_vertical">
                <ImageView
                    android:src="@drawable/enemy_red_1"
                    android:layout_width="48dp"
                    android:layout_height="wrap_content"
                    android:adjustViewBounds="true"
                    android:layout_marginRight="8dp"/>
                <TextView
                    android:textStyle="bold"
                    android:id="@+id/enemy"
                    android:text="x100"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

Kode untuk HighScoreActivity

package com.andevindo.spaceshooter;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class HighScoreActivity extends AppCompatActivity implements View.OnClickListener {

    private ImageView mBack;
    private TextView mScore, mMeteor, mEnemy, mNullHighScore;
    private LinearLayout mHighScoreContainer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_high_score);

        mBack = findViewById(R.id.back);
        mScore = findViewById(R.id.score);
        mMeteor = findViewById(R.id.meteor);
        mNullHighScore = findViewById(R.id.null_high_score);
        mHighScoreContainer = findViewById(R.id.high_score_container);
        mBack.setOnClickListener(this);

        loadHighScore();
    }

    void loadHighScore(){
        SharedPreferencesManager spm = new SharedPreferencesManager(this);
        if (spm.getHighScore()!=-1){
            mNullHighScore.setVisibility(TextView.GONE);
            mHighScoreContainer.setVisibility(LinearLayout.VISIBLE);
            mScore.setText(spm.getHighScore() + "");
            mMeteor.setText(spm.getMeteorDestroyed() + "");
            mEnemy.setText(spm.getEnemyDestroyed() + "");
        }else{
            mNullHighScore.setVisibility(TextView.VISIBLE);
            mHighScoreContainer.setVisibility(LinearLayout.GONE);
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.back:
                finish();
                break;
        }
    }
}

Update Kode Sebelumnya

Karena kita ingin menambahkan data jumlah meteor dan enemy yang dihancurkan, maka ada perubahan sedikit di kodenya.

SharedPreferencesManager

package com.andevindo.spaceshooter;

import android.content.Context;
import android.content.SharedPreferences;

/**
 * Created on   : 8/12/2017
 * Developed by : Hendrawan Adi Wijaya
 * Github       : https://github.com/andevindo
 * Website      : http://www.andevindo.com
 */

public class SharedPreferencesManager {

    private String mName = "SpaceShooter";
    private Context mContext;

    public SharedPreferencesManager(Context context) {
        mContext = context;
    }

    public void saveHighScore(int score, int meteorDestroyed, int enemyDestroyed){
        SharedPreferences sp = mContext.getSharedPreferences(mName, Context.MODE_PRIVATE);
        SharedPreferences.Editor e = sp.edit();
        e.putInt("high_score", score);
        e.putInt("meteor", meteorDestroyed);
        e.putInt("enemy", enemyDestroyed);
        e.commit();
    }

    public int getHighScore(){
        SharedPreferences sp = mContext.getSharedPreferences(mName, Context.MODE_PRIVATE);
        return sp.getInt("high_score", 0);
    }

    public int getMeteorDestroyed(){
        SharedPreferences sp = mContext.getSharedPreferences(mName, Context.MODE_PRIVATE);
        return sp.getInt("meteor", 0);
    }

    public int getEnemyDestroyed(){
        SharedPreferences sp = mContext.getSharedPreferences(mName, Context.MODE_PRIVATE);
        return sp.getInt("enemy", 0);
    }
}

Dari kode di atas, ketika menyimpan highScore, juga sekalian menyimpan data jumlah meteor dan enemy.

GameView

package com.andevindo.spaceshooter;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.util.ArrayList;
import java.util.Random;

/**
 * Created on   : 8/11/2017
 * Developed by : Hendrawan Adi Wijaya
 * Github       : https://github.com/andevindo
 * Website      : http://www.andevindo.com
 */

public class GameView extends SurfaceView implements Runnable {

    private Thread mGameThread;
    private volatile boolean mIsPlaying;
    private Player mPlayer;
    private Paint mPaint;
    private Canvas mCanvas;
    private SurfaceHolder mSurfaceHolder;
    private ArrayList<Laser> mLasers;
    private ArrayList<Meteor> mMeteors;
    private ArrayList<Enemy> mEnemies;
    private ArrayList<Star> mStars;
    private int mScreenSizeX, mScreenSizeY;
    private int mCounter = 0;
    private SoundPlayer mSoundPlayer;
    private SharedPreferencesManager mSP;
    public static int SCORE = 0;
    public static int METEOR_DESTROYED = 0;
    public static int ENEMY_DESTROYED = 0;
    private volatile boolean mIsGameOver;
    private volatile boolean mNewHighScore;

    public GameView(Context context, int screenSizeX, int screenSizeY) {
        super(context);

        mScreenSizeX = screenSizeX;
        mScreenSizeY = screenSizeY;
        mSP = new SharedPreferencesManager(context);

        mSoundPlayer = new SoundPlayer(context);
        mPaint = new Paint();
        mSurfaceHolder = getHolder();

        reset();
    }

    void reset() {
        SCORE = 0;
        mPlayer = new Player(getContext(), mScreenSizeX, mScreenSizeY, mSoundPlayer);
        mLasers = new ArrayList<>();
        mMeteors = new ArrayList<>();
        mEnemies = new ArrayList<>();
        mStars = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            mStars.add(new Star(getContext(), mScreenSizeX, mScreenSizeY, true));
        }
        mIsGameOver = false;
        mNewHighScore = false;
    }

    @Override
    public void run() {
        while (mIsPlaying) {
            if (!mIsGameOver) {
                update();
                draw();
                control();
            }
        }
        Log.d("GameThread", "Run stopped");
    }

    public void update() {
        mPlayer.update();
        if (mCounter % 200 == 0) {
            mPlayer.fire();
        }

        for (Meteor m : mMeteors) {
            m.update();

            if (Rect.intersects(m.getCollision(), mPlayer.getCollision())) {
                m.destroy();
                mIsGameOver = true;
                if (SCORE>mSP.getHighScore()){
                    mNewHighScore = true;
                    mSP.saveHighScore(SCORE, METEOR_DESTROYED, ENEMY_DESTROYED);
                }
            }

            for (Laser l : mPlayer.getLasers()) {
                if (Rect.intersects(m.getCollision(), l.getCollision())) {
                    m.hit();
                    l.destroy();
                }
            }
        }

        boolean deleting = true;
        while (deleting) {
            if (mMeteors.size() != 0) {
                if (mMeteors.get(0).getY() > mScreenSizeY) {
                    mMeteors.remove(0);
                }
            }

            if (mMeteors.size() == 0 || mMeteors.get(0).getY() <= mScreenSizeY) {
                deleting = false;
            }
        }
        if (mCounter % 1000 == 0) {
            mMeteors.add(new Meteor(getContext(), mScreenSizeX, mScreenSizeY, mSoundPlayer));
        }

        for (Enemy e : mEnemies) {
            e.update();
            if (Rect.intersects(e.getCollision(), mPlayer.getCollision())) {
                e.destroy();
                mIsGameOver = true;
                if (SCORE>=mSP.getHighScore()){
                    mSP.saveHighScore(SCORE, METEOR_DESTROYED, ENEMY_DESTROYED);
                }
            }

            for (Laser l : mPlayer.getLasers()) {
                if (Rect.intersects(e.getCollision(), l.getCollision())) {
                    e.hit();
                    l.destroy();
                }
            }
        }
        deleting = true;
        while (deleting) {
            if (mEnemies.size() != 0) {
                if (mEnemies.get(0).getY() > mScreenSizeY) {
                    mEnemies.remove(0);
                }
            }

            if (mEnemies.size() == 0 || mEnemies.get(0).getY() <= mScreenSizeY) {
                deleting = false;
            }
        }
        if (mCounter % 2000 == 0) {
            mEnemies.add(new Enemy(getContext(), mScreenSizeX, mScreenSizeY, mSoundPlayer));
        }

        for (Star s : mStars) {
            s.update();
        }
        deleting = true;
        while (deleting) {
            if (mStars.size() != 0) {
                if (mStars.get(0).getY() > mScreenSizeY) {
                    mStars.remove(0);
                }
            }

            if (mStars.size() == 0 || mStars.get(0).getY() <= mScreenSizeY) {
                deleting = false;
            }
        }

        if (mCounter % 250 == 0) {
            Random random = new Random();
            for (int i = 0; i < random.nextInt(3) + 1; i++) {
                mStars.add(new Star(getContext(), mScreenSizeX, mScreenSizeY, false));
            }

        }


    }

    public void draw() {
        if (mSurfaceHolder.getSurface().isValid()) {
            mCanvas = mSurfaceHolder.lockCanvas();
            mCanvas.drawColor(Color.BLACK);
            mCanvas.drawBitmap(mPlayer.getBitmap(), mPlayer.getX(), mPlayer.getY(), mPaint);
            for (Star s : mStars) {
                mCanvas.drawBitmap(s.getBitmap(), s.getX(), s.getY(), mPaint);
            }
            for (Laser l : mPlayer.getLasers()) {
                mCanvas.drawBitmap(l.getBitmap(), l.getX(), l.getY(), mPaint);
            }
            for (Meteor m : mMeteors) {
                mCanvas.drawBitmap(m.getBitmap(), m.getX(), m.getY(), mPaint);
            }
            for (Enemy e : mEnemies) {
                mCanvas.drawBitmap(e.getBitmap(), e.getX(), e.getY(), mPaint);
            }
            drawScore();
            if (mIsGameOver) {
                drawGameOver();
            }
            mSurfaceHolder.unlockCanvasAndPost(mCanvas);
        }
    }

    void drawScore() {
        Paint score = new Paint();
        score.setTextSize(30);
        score.setColor(Color.WHITE);
        mCanvas.drawText("Score : " + SCORE, 100, 50, score);
    }

    void drawGameOver() {
        Paint gameOver = new Paint();
        gameOver.setTextSize(100);
        gameOver.setTextAlign(Paint.Align.CENTER);
        gameOver.setColor(Color.WHITE);
        mCanvas.drawText("GAME OVER", mScreenSizeX / 2, mScreenSizeY / 2, gameOver);
        Paint highScore = new Paint();
        highScore.setTextSize(50);
        highScore.setTextAlign(Paint.Align.CENTER);
        highScore.setColor(Color.WHITE);
        if (mNewHighScore){
            mCanvas.drawText("New High Score : " + mSP.getHighScore(), mScreenSizeX / 2, (mScreenSizeY / 2) + 60, highScore);
            Paint enemyDestroyed = new Paint();
            enemyDestroyed.setTextSize(50);
            enemyDestroyed.setTextAlign(Paint.Align.CENTER);
            enemyDestroyed.setColor(Color.WHITE);
            mCanvas.drawText("Enemy Destroyed : " + mSP.getEnemyDestroyed(), mScreenSizeX / 2, (mScreenSizeY / 2) + 120, enemyDestroyed);
            Paint meteorDestroyed = new Paint();
            meteorDestroyed.setTextSize(50);
            meteorDestroyed.setTextAlign(Paint.Align.CENTER);
            meteorDestroyed.setColor(Color.WHITE);
            mCanvas.drawText("Meteor Destroyed : " + mSP.getMeteorDestroyed(), mScreenSizeX / 2, (mScreenSizeY / 2) + 180, meteorDestroyed);
        }

    }

    public void steerLeft(float speed) {
        mPlayer.steerLeft(speed);
    }

    public void steerRight(float speed) {
        mPlayer.steerRight(speed);
    }

    public void stay() {
        mPlayer.stay();
    }

    public void control() {
        try {
            if (mCounter == 10000) {
                mCounter = 0;
            }
            mGameThread.sleep(20);
            mCounter += 20;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void pause() {
        Log.d("GameThread", "Main");
        mIsPlaying = false;
        try {
            mGameThread.join();
            mSoundPlayer.pause();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void resume() {
        mIsPlaying = true;
        mSoundPlayer.resume();
        mGameThread = new Thread(this);
        mGameThread.start();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (mIsGameOver){
                    ((Activity) getContext()).finish();
                    getContext().startActivity(new Intent(getContext(), MainMenuActivity.class));
                }
                break;
        }
        return super.onTouchEvent(event);
    }
}

Beberapa kode baru dari kode di atas adalah:

  1. mNewHighScore digunakan sebagai kondisi ketika game over, jika ada high score baru, maka tampilkan tulisan NewHighScore dan beberapa data lainnya.
  2. Beberapa drawText baru untuk menampilkan jumlah enemy dan meteor yang berhasil dihancurkan.
  3. Ketika game over dan user menekan layar, maka akan berpindah ke MainMenuActivity.

Enemy

...
public void hit(){
    if (--mHP ==0){
        SCORE += 50;
        ENEMY_DESTROYED++;
        destroy();
    }else{
        mSoundPlayer.playExplode();
    }
}
...

Tambahkan kode ENEMY_DESTROYED++; pada class Enemy.

Meteor

...
public void hit(){
    if (--mHP ==0){
        SCORE += 20;
        METEOR_DESTROYED++;
        destroy();
    }else{
        mSoundPlayer.playExplode();
    }
}
...

Tambahkan kode METEOR_DESTROYED++; pada class Meteor.

Setelah itu jangan lupa pindahkan intent filter Launcher dari MainActivity ke MainMenuActivity agar MainMenuActivity dipanggil pertama kali saat aplikasi dibuka. Dan juga tambahkan screenOrientation=”portrait” untuk semua activity agar semua activity tidak berubah orientasinya dan tetap portrait.

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

    <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=".MainActivity"
            android:theme="@style/AppTheme.NoActionBar"
            android:screenOrientation="portrait"></activity>
        <activity
            android:name=".MainMenuActivity"
            android:label="@string/title_activity_main_menu"
            android:theme="@style/AppTheme.NoActionBar"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".HighScoreActivity"
            android:theme="@style/AppTheme.NoActionBar"
            android:screenOrientation="portrait"></activity>
    </application>

</manifest>

Itulah beberapa update dari game Space Shooter ini. Kode terbaru dari tutorial ini bisa dilihat di https://github.com/andevindo/space-shooter-as/tree/v1.1.0