com.google.cloud.solutions.griddler.android.ui.game.GameActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.google.cloud.solutions.griddler.android.ui.game.GameActivity.java

Source

/*
 * Copyright 2013 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.cloud.solutions.griddler.android.ui.game;

import com.google.cloud.solutions.griddler.android.GameApplication;
import com.google.cloud.solutions.griddler.android.R;
import com.google.cloud.solutions.griddler.android.helpers.CountDownTimerPausable;
import com.google.cloud.solutions.griddler.android.helpers.Location;
import com.google.cloud.solutions.griddler.android.models.GameModel;
import com.google.cloud.solutions.griddler.android.ui.RequestCodes;
import com.google.cloud.solutions.griddler.android.ui.game.models.BoardRenderModel;
import com.google.cloud.solutions.griddler.android.ui.summary.GameSummaryActivity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.view.MotionEvent;

import java.util.ArrayList;
import java.util.List;

/**
 * Represents the Game Workflow and View Controllers. The game transitions between a GameStateType
 * status during playback/feedback.
 */
public class GameActivity extends FragmentActivity implements IGameManager {

    BoardRenderModel board;
    GameStateType gameState = GameStateType.GENERATING;
    CountDownTimerPausable countdownTimer;
    GameModel gameModel;
    long currentTimeLeft = 0;

    // Subviews of the game
    List<IGameView> views;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_game);

        // Register all IGameViews
        views = new ArrayList<IGameView>();
        views.add((HeaderView) this.findViewById(R.id.gameactivity_fragment_header));
        views.add((BoardView) this.findViewById(R.id.gameactivity_fragment_boardview));
        views.add((QuestionAnswerPagerView) this.findViewById(R.id.gameactivity_fragment_questionanswerpager));
        views.add((BoardLoadingView) this.findViewById(R.id.gameactivity_fragment_boardloadingview));

        // Register game manager with views
        for (IGameView view : views) {
            view.setGameManager(this);
            view.setFragmentManager(this.getSupportFragmentManager());
        }

        goToGameState(GameStateType.GENERATING);

        gameModel = (GameModel) getIntent().getSerializableExtra(GameModel.TAG);
        board = GameModelAdapter.adapt(gameModel);

        bindSimulationEvents();

        goToGameState(GameStateType.PLAYING);
        countdownTimer.start();

        for (IGameView view : views) {
            view.onGameModelLoaded(board);
        }
    }

    private void bindSimulationEvents() {
        countdownTimer = new CountDownTimerPausable(board.getTotalTime(), 1000) {
            @SuppressLint("DefaultLocale")
            @Override
            public void onTick(long millisUntilFinished) {

                currentTimeLeft = millisUntilFinished;
                board.setRemainingTime(millisUntilFinished);

                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        // Register game manager with views
                        for (IGameView view : views) {
                            view.onTick();
                        }
                    }
                });
            }

            @Override
            public void onFinish() {
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        // since the time ran out assign the time left to zero
                        currentTimeLeft = 0;
                        // change the game state to finished
                        goToGameState(GameStateType.FINISHED);
                    }
                });
            }
        };
    }

    /**
     * Got to the game state specified
     */
    @Override
    public void goToGameState(GameStateType stateType) {
        switch (stateType) {
        case PLAYING:
            if (countdownTimer.isPaused()) {
                countdownTimer.start();
            }
            break;
        case FINISHED:
            navigateToSummary();
            break;
        case GENERATING:
            break;
        case QUESTION_TRANSITIONING:
            countdownTimer.pause();
            break;
        case PAUSED:
            break;
        }

        gameState = stateType;

        for (IGameView gameView : this.views) {
            gameView.onGameManagerStateChange(this.gameState);
        }
    }

    private void navigateToSummary() {

        // cancel the timer
        countdownTimer.cancel();

        // assign the time left
        gameModel.getCurrentPlayer().setTimeLeft(currentTimeLeft);

        // navigate to the summary
        Intent intent = new Intent(GameActivity.this, GameSummaryActivity.class);
        intent.putExtra(GameModel.TAG, gameModel);
        startActivityForResult(intent, RequestCodes.REQUEST_GAME_RESULT);
    }

    /**
     * Gets the current game state
     */
    @Override
    public GameStateType getState() {
        return this.gameState;
    }

    /**
     * Get the board renderer model
     */
    @Override
    public BoardRenderModel getBoardRenderModel() {
        return board;
    }

    /**
     * Returns true if the board renderer model has loaded
     */
    @Override
    public Boolean isBoardRenderModelLoaded() {
        return board != null;
    }

    /**
     * Occurs when a question is skipped. Updates UI appropriately such as the current question etc.
     */
    @Override
    public void onQuestionSkipped() {

        if (board.getAllQuestionsCompleted()) {
            this.goToGameState(GameStateType.FINISHED);
        } else {
            board.setCurrentWordIndex(board.getIndexOfNextUnansweredQuestion());
        }

        board.getGridLayout().clearSelectedLetters();

        for (IGameView view : views) {
            view.onQuestionSkipped();
        }
    }

    /**
     * Occurs when a letter is selected. Updates the UI based upon the connectedness of the letter
     * selected
     */
    @Override
    public void onLetterSelected(Location letterLocation) {

        if (!board.getGridLayout().validateConnectedness()) {
            board.getGridLayout().clearSelectedLetters();
            for (IGameView view : views) {
                view.updateUI();
                view.onLetterReset();
            }

        }

        if (!board.getGridLayout().getBoard().get(letterLocation).getIsSelected()) {
            board.getGridLayout().toggleLetterSelection(letterLocation);

            for (IGameView view : views) {
                view.updateUI();
                view.onLetterAdded();
            }
        }
    }

    /**
     * Updates the UI after checking if the selected letters have correctly spelled the word
     */
    @Override
    public void simulate() {
        // check for completion
        if (board.isCurrentQuestionAnsweredBySelection()) {
            onQuestionAnswered();
        } else {
            board.getGridLayout().clearSelectedLetters();
            for (IGameView view : views) {
                view.updateUI();
                view.onLetterReset();
            }
        }
    }

    /**
     * Occurs when the game surface has been touched
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.gameState == GameStateType.PLAYING) {
            float x = event.getRawX();
            float y = event.getRawY();
            switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                for (IGameView gameView : this.views) {
                    gameView.onTouchMove((int) x, (int) y);
                }
                break;
            case MotionEvent.ACTION_UP:
                simulate();
                break;
            }
        }
        return false;
    }

    /**
     * Updates the UI appropriately when a question has been answered correctly
     */
    @Override
    public void onQuestionAnswered() {
        board.getWords().get(board.getCurrentQuestionIndex()).setCompleted(true);
        gameModel.getCurrentPlayer().addAnswerIndex(board.getCurrentQuestionIndex());

        // advance to next available question
        if (board.getAllQuestionsCompleted()) {
            goToGameState(GameStateType.FINISHED);
        } else {
            goToGameState(GameStateType.QUESTION_TRANSITIONING);

            // clear letters
            board.getGridLayout().clearSelectedLetters();

            board.setCurrentWordIndex(board.getIndexOfNextUnansweredQuestion());
            for (IGameView view : views) {
                view.onQuestionAnswered();
            }

            Handler h = new Handler();
            h.postDelayed(new Runnable() {
                @Override
                public void run() {
                    for (IGameView view : views) {
                        view.updateUI();
                    }
                    goToGameState(GameStateType.PLAYING);
                }
            }, 1000);
        }
    }

    /**
     * Cancel the timer
     */
    @Override
    public void onBackPressed() {

        if (countdownTimer != null) {
            countdownTimer.cancel();
        }

        super.onBackPressed();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
        case RequestCodes.REQUEST_GAME_RESULT:
            setResult(resultCode, data);
            finish();
            break;
        }
    }

    /**
     * Marks the application as not playing a game
     */
    @Override
    protected void onPause() {
        super.onPause();
        ((GameApplication) getApplication()).setIsCurrentlyPlayingGame(false);
    }

    /**
     * Marks the application as currently playing a game
     */
    @Override
    protected void onResume() {
        super.onResume();
        ((GameApplication) getApplication()).setIsCurrentlyPlayingGame(true);
    }
}