Android Open Source - BarrelRace Barrel Race View






From Project

Back to project page BarrelRace.

License

The source code is released under:

MIT License

If you think the Android project BarrelRace listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.app.ui.assignment.barrelrace.views;
/*w  ww.  j a  va 2s.c  om*/
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.SystemClock;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.widget.TextView;

import com.app.ui.assignment.barrelrace.FailureActivity;
import com.app.ui.assignment.barrelrace.R;
import com.app.ui.assignment.barrelrace.SuccessActivity;
import com.app.ui.assignment.barrelrace.objects.Barrel;
import com.app.ui.assignment.barrelrace.objects.Fence;
import com.app.ui.assignment.barrelrace.objects.Horse;
import com.app.ui.assignment.barrelrace.util.TimerUtil;

/**
* @author Sudharsanan Muralidharan
* @description Barrel Race Game for Android
* @module BarrelRaceView: View for Game and GameLoop Thread
*/

/* BarrelRaceView: Main Game View extends SurfaceView, 
 * implements Runnable for Thread, SensorEvents, Callback
 * */
public class BarrelRaceView extends SurfaceView implements Runnable, SensorEventListener, Callback {

    private SensorManager sensorManager;
    
    //Main Game Thread
    Thread t = null;
    SurfaceHolder holder;
    
    /*Flag to maintain the thread state*/
    boolean isThreadRunning = true;
    
    private Context context;
    
    /*Game View Objects*/
    private Canvas canvas;
    private Fence fence1, fence2, fence3, fence4, fence5;
    private Horse horse;
    private Barrel barrel1, barrel2, barrel3;
    
    /*X and Y positions of the horse Object*/
    private float x,y;
    /*Height and Width of the Screen/Canvas*/
    private float height, width;
    /*Acceleration from the Sensor data*/
    private float accelX, accelY;
    /*X and Y positions of the three barrels*/
    private float barrel1X, barrel1Y, barrel2X, barrel2Y, barrel3X, barrel3Y;
    /*Entry point for the horse*/
    private float gateGap;
    /*Define margins and start & stop of X and Y for fence positions*/
    private float leftMargin, rightMargin, topMargin, bottomMargin;
    private float fence1StartX, fence1StartY, fence1StopX, fence1StopY;
    private float fence2StartX, fence2StartY, fence2StopX, fence2StopY;
    private float fence3StartX, fence3StartY, fence3StopX, fence3StopY;
    private float fence4StartX, fence4StartY, fence4StopX, fence4StopY;
    private float fence5StartX, fence5StartY, fence5StopX, fence5StopY;
    /*Horse and Barrel Radius*/
    private float horseRadius, barrelRadius;
    /*Start Position of the Horse*/
    private float[] horseStartPosition;
    
    /*Multiple to move the horse faster, accelX and accelY times this value*/
    private float accelRate;
    /*Various Flags to use in Game Logic*/
    private boolean hasEntered = false;
    private boolean isGameFinished = false;
    private boolean isPenaltyReduced = false;
    private boolean isTimerStarted = false;
    private boolean barrel1Circled, barrel2Circled, barrel3Circled;
    private boolean isSoundEnabled = false;
    private boolean isInterrupted = false;
    /*Game Difficulty from SharedPreferences*/
    private String gameDifficulty;
    private Paint mPaint;
    
    /*synchorized(Object) to send*/
    private Object TIMER_LOCK = new Object();
    
    /*Timer values*/
    private long startTime = 0L, timeDiffMil = 0L, tempTime = 0L;
    
    /*Initialize objects*/
    private Vibrator vibrator;
    private MediaPlayer bMedia, fMedia;
    private TextView textViewTime;
    private Handler handler;
    private TimerUtil timerUtil;
    
    private SharedPreferences sharedPreferences;
    
    /*Constructor*/
    public BarrelRaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        /*Get the Holder and addCallback on start*/
        getHolder().addCallback(this);
    }

    /*initialize(Context, int, int TextView) to initialize various objects, timer textviews, get height and width*/
    public void initialize(Context context, int width, int height, TextView textViewTime) {
        this.context = context;
        this.height = height;
        this.width = width;
        holder = getHolder();
        sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
        initalizeCoordinates(); //Initialize Object Coordinates
        initializeObjects(); //Initialize Game View Objects
        initializeMedia(); //Initialize Media and Vibrator
        initializeGamePrefs(); //Fetch Game Preferences from SharedPreferences
        this.textViewTime = textViewTime;
    }

    /*Fetch Game Preferences from SharedPreferences*/
    private void initializeGamePrefs() {
        // TODO Auto-generated method stub
        sharedPreferences = context.getSharedPreferences("GAME_PREFS", Context.MODE_PRIVATE);
        isSoundEnabled = sharedPreferences.getBoolean("sound", true);
        gameDifficulty = sharedPreferences.getString("difficulty", "normal");
        
        /*Check game difficulty from SharedPreferences to set accelRate*/ 
        if(gameDifficulty.equals("easy")) {
            accelRate = 1.45F;
        } else if(gameDifficulty.equals("hard")) {
            accelRate = 2.80F;
        } else {
            accelRate = 1.70F;
        }
    }

    /*Start Timer when start button is pressed*/
    public void startTimer() {
        // TODO Auto-generated method stub
        startTime = SystemClock.uptimeMillis(); //Get Start Time and store it
        handler = new Handler(); //Handler to update TextView
        timerUtil = new TimerUtil();
        handler.postDelayed(updateTimer, 0); //Start Handler to update timer textview
        isTimerStarted = true; //Set Timer started to true
    }

    /*Initialize Media and Vibrator*/
    private void initializeMedia() {
        // TODO Auto-generated method stub
        vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
        bMedia = MediaPlayer.create(context, R.raw.barrel_hit);
        fMedia = MediaPlayer.create(context, R.raw.fence_hit);
    }

    //Initialize Object Coordinates
    private void initalizeCoordinates() {
        // TODO Auto-generated method stub

        /*Set horseStartPosition as [x,y]*/
        horseStartPosition = new float[] { width/2, height-50 };
        
        x = horseStartPosition[0];
        y = horseStartPosition[1];
        
        /*Calculate horse and BarrelRadius using width of Screen*/
        horseRadius = width/45;
        barrelRadius = width/45; 
        
        /*Calculate gateGap based on the horseRadius*/ 
        gateGap = (float) (horseRadius * 2.5);
        
        /*Margins for the fences*/
        leftMargin = rightMargin = width/7;
        topMargin = height/10;
        bottomMargin = height/7;
        
        /*Set X and Y coordinates for barrels 1,2,3*/
        barrel1X = (width/2);
        barrel1Y = (float) (height-height/2.75);
        
        barrel2X = (3*width)/4-rightMargin/2;
        barrel2Y = height/4;
        
        barrel3X = (width/4)+leftMargin/2;
        barrel3Y = height/4;
        
        /*Set fence1 StartX, StartY, StopX and StopY*/
        fence1StartX = leftMargin;
        fence1StartY = topMargin;
        fence1StopX = width-rightMargin;
        fence1StopY = topMargin;
        
        /*Set fence2 StartX, StartY, StopX and StopY*/
        fence2StartX = leftMargin;
        fence2StartY = topMargin;
        fence2StopX = leftMargin;
        fence2StopY = height-bottomMargin;
        
        /*Set fence3 StartX, StartY, StopX and StopY*/
        fence3StartX = width-rightMargin;
        fence3StartY = topMargin;
        fence3StopX = width-rightMargin;
        fence3StopY = height-bottomMargin;
        
        /*Set fence4 StartX, StartY, StopX and StopY*/
        fence4StartX = leftMargin;
        fence4StartY = height-bottomMargin;
        fence4StopX = (width/2)-gateGap/2;
        fence4StopY = height-bottomMargin;
        
        /*Set fence5 StartX, StartY, StopX and StopY*/
        fence5StartX = width-rightMargin;
        fence5StartY = height-bottomMargin;
        fence5StopX = (width/2)+gateGap/2;
        fence5StopY = height-bottomMargin;
        
    }

    /*Initialize the various Game View objects*/
    private void initializeObjects() {
        // TODO Auto-generated method stub
        
        horse = new Horse(context);
        
        /*Draw fences based on (x1,y1) and (x2,y2) points*/
        fence1 = new Fence(context, fence1StartX, fence1StartY, fence1StopX, fence1StopY);
        fence2 = new Fence(context, fence2StartX, fence2StartY, fence2StopX, fence2StopY);
        fence3 = new Fence(context, fence3StartX, fence3StartY, fence3StopX, fence3StopY);
        fence4 = new Fence(context, fence4StartX, fence4StartY, fence4StopX, fence4StopY);
        fence5 = new Fence(context, fence5StartX, fence5StartY, fence5StopX, fence5StopY);
        
        /*Draw barrels as circles based on (x,y,r)*/
        barrel1 = new Barrel(context, barrel1X, barrel1Y, barrelRadius);
        barrel2 = new Barrel(context, barrel2X, barrel2Y, barrelRadius);
        barrel3 = new Barrel(context, barrel3X, barrel3Y, barrelRadius);
        
        mPaint = new Paint();
        mPaint.setColor(context.getResources().getColor(R.color.barrel_circled_color));
    }
    
    /*Thread run()*/ 
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(isThreadRunning) {
            /*Check if holder Surface is valid*/
            if(holder.getSurface().isValid()) {
                /*Get Lock on Canvas for drawing*/
                canvas = holder.lockCanvas();
                /*Set Canvas Background*/
                canvas.drawColor(context.getResources().getColor(R.color.bg_color));
                
                /*Draw Fences*/
                fence1.draw(canvas);
                fence2.draw(canvas);
                fence3.draw(canvas);
                fence4.draw(canvas);
                fence5.draw(canvas);
                
                /*Draw Barrels*/
                barrel1.draw(canvas);
                barrel2.draw(canvas);
                barrel3.draw(canvas);
                
                /*Change X and Y of the Horse*/
                x += accelX;
                y += accelY;
                
                /*Don't Let the horse go down the screen, Set base value*/
                if(y > horseStartPosition[1]) {
                    y = horseStartPosition[1];
                }
                
                /*Draw horse*/
                horse.draw(x, y, horseRadius-5, canvas);
                
                /*Check if the horse has entered the area*/
                if(y <= height-bottomMargin+20-horseRadius) {
                    hasEntered = true;
                } else {
                    hasEntered = false;
                }
                
                /*Check collision with the barrels*/
                if(collides()) {
                    handleCollision();
                }
                
                /*Check Collision with the Fences*/
                if(collidesFence()) {
                    handleCollisionWithFence();
                } else {
                    isPenaltyReduced = false;
                }
                
                /*Check if horse has circled barrel1*/
                if(checkCircleBarrel(barrel1)) {
                    barrel1Circled = true;
                    barrel1.setmPaint(mPaint);
                }
                
                /*Check if horse has circled barrel2*/
                if(checkCircleBarrel(barrel2)) {
                    barrel2Circled = true;
                    barrel2.setmPaint(mPaint);
                }
                
                /*Check if horse has circled barrel3*/
                if(checkCircleBarrel(barrel3)) {
                    barrel3Circled = true;
                    barrel3.setmPaint(mPaint);
                }
                
                /*If all barrels are circled, stop Thread, Go to success activity */
                if(barrel1Circled &&  
                        barrel2Circled && barrel3Circled) {
                    /*Set thread state to false*/
                    isThreadRunning = false;
                    /*Interrupt thread*/
                    t.interrupt();
                    if(!isGameFinished) {
                        /*Start SuccessActivity, send elapsed time with Intent*/
                        Intent toSuccessActivity = new Intent(context, SuccessActivity.class);
                        toSuccessActivity.putExtra("timeElapsed", timeDiffMil);
                        context.startActivity(toSuccessActivity);
                        ((Activity) context).finish();
                        //Set GameFinished to true
                        isGameFinished = true;
                    }
                }
                /*Unlock the canvas*/
                holder.unlockCanvasAndPost(canvas);
            }
        }
    }
    
    /*Handle when Horse Collides with the Fence Object*/
    private void handleCollisionWithFence() {
        // TODO Auto-generated method stub
        if(!isPenaltyReduced) {
            if(isSoundEnabled) {
                /*If Sound is Enabled in Preferences play sound on collision*/
                fMedia.start();
            }
            if(vibrator.hasVibrator()) {
                /*If device has vibrator vibrate for 100ms*/
                vibrator.vibrate(100);
            }
            
            /*Reduce startTime by 5000ms to add penalty*/
            synchronized (TIMER_LOCK) {
                startTime -= 5000;
            }
            /*Set penalty reduced to true*/
            isPenaltyReduced = true;
        }
    }

    /*Check if the horse circled the Barrel object passed*/
    private boolean checkCircleBarrel(Barrel barrel) {
        // TODO Auto-generated method stub
        
        /*Check if horse has visited the bottomRightQuadrant
        If yes then set the flag to true*/
        if(x >= (barrel.getX()+barrelRadius+10) 
                && y >= (barrel.getY()+barrelRadius+10)) {
            barrel.setRightBottomQuad(true);
        }
        
        /*Check if horse has visited the topRightQuadrant
        If yes then set the flag to true*/
        if(x >= (barrel.getX()+barrelRadius+10) 
                && y <= (barrel.getY()-barrelRadius-10)) {
            barrel.setRightTopQuad(true);
        }
        
        /*Check if horse has visited the topLeftQuadrant
        If yes then set the flag to true*/
        if(x <= (barrel.getX()-barrelRadius-10) 
                && y <= (barrel.getY()-barrelRadius-10)) {
            barrel.setLeftTopQuad(true);
        }
        
        /*Check if horse has visited the bottomLeftQuadrant
        If yes then set the flag to true*/
        if(x <= (barrel.getX()-barrelRadius-10) 
                && y >= (barrel.getY()+barrelRadius+10)) {
            barrel.setLeftBottomQuad(true);
        }
        
        /*If the horse has entered the area and all barrels are circle 
         * return true*/
        return hasEntered && barrel.isCircled();
    }

    /*Check Collision with Fences*/
    private boolean collidesFence() {
        // TODO Auto-generated method stub
        
        boolean collidesFence = false;
        
        /*Check if it collides with left Fence, 
        if true then readjust horse*/
        if(x <= (horseRadius+fence2StartX)) {
            x = fence2StartX+horseRadius;
            collidesFence = true;
        }  
        
        /*Check if it collides with right Fence, 
        if true then readjust horse*/
        if(x >= (fence3StartX-horseRadius)) {
            x = fence3StartX-horseRadius;
            collidesFence = true;
        } 
        
        /*Check if it collides with top Fence, 
        if true then readjust horse*/
        if(y <= (horseRadius+fence1StartY)) {
            y = horseRadius+fence1StartY;
            collidesFence = true;
        }  
        
        /*Check if it collides with bottom Fence,
         * Check if the horse is not within the gateGap entry point
         * Check if horse is inside the area 
        if true then readjust horse*/
        if(y >= fence4StartY-horseRadius) {
            /*Check if the horse is not within the gateGap entry point*/
            if(x >= fence4StopX+10 && x <= fence5StopX-10) {
                collidesFence = false;
            } else {
                if(hasEntered) {
                    /*Readjust horse if inside area*/
                    y = fence4StartY-horseRadius;
                    collidesFence = true;
                } else {
                    /*If outside Readjust horse to initial value*/
                    y = horseStartPosition[1];
                    collidesFence = false;
                }
            }
        } 
        
        return collidesFence;
    }

    /*Handle collision with the Barrel*/
    private void handleCollision() {
        // TODO Auto-generated method stub
        
        /*Stop the Game by setting game state to false and interrupt thread */
        isThreadRunning = false;
        t.interrupt();
        
        if(!isGameFinished) {
            if(isSoundEnabled) {
                /*Play sound if sound is enabled in preferences*/
                bMedia.start();
            }
            if(vibrator.hasVibrator()) {
                /*Vibrate if device has a vibrator*/
                vibrator.vibrate(100);
            }
            /*Go to failure activity*/
            Intent toFailureActivity = new Intent(context, FailureActivity.class);
            context.startActivity(toFailureActivity);
            ((Activity) context).finish();
            /*Set Game finished to true*/
            isGameFinished = true;
        }
    }

    /*Check if horse collides with the barrel*/
    private boolean collides() {
        // TODO Auto-generated method stub
        
        /*If horse collides readjust the position of the horse*/
        if(checkCriteria(barrel1)) {
            readjustHorse(barrel1);
        } else if(checkCriteria(barrel2)) {
            readjustHorse(barrel2);
        } else if(checkCriteria(barrel3)) {
            readjustHorse(barrel3);
        } else {
            return false;
        }
        
        return true;
    }

    /*Give a rebound to the horse on barrel collision*/
    private void readjustHorse(Barrel barrel) {
        // TODO Auto-generated method stub
        if(x > barrel.getX()) {
            x = x + 1f;
        } else {
            x = x - 1f;
        }
        
        if(y > barrel.getY()) {
            y = y + 1f;
        } else {
            y = y - 1f;
        }
        
    }

    /*Check for the criteria of two circles: horse and barrel colliding
    Condition to check:
    pow(x1-x2, 2) + pow(y1-y2, 2) <= pow(r1+r2, 2)*/
    private boolean checkCriteria(Barrel barrel) {
        return (Math.pow((x - barrel.getX()), 2) + Math.pow((y - barrel.getY()), 2)) 
                <= Math.pow((horseRadius + barrelRadius), 2);
    }
    
    /*Pause the Game Thread on Game Activity pause*/
    public void pause() {
        tempTime += SystemClock.uptimeMillis()-startTime;
        isThreadRunning = false;
        isInterrupted = true;
        while(true) {
            try {
                t.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            break;
        }
        t = null;
    }
    
    /*Resume Game Thread on Game Activity Resume*/
    public void resume() {
        if(isInterrupted) {
            startTime = SystemClock.uptimeMillis();
            handler = new Handler(); //Handler to update TextView
            timerUtil = new TimerUtil();
            handler.postDelayed(updateTimer, 0); //Start Handler to update timer textview
            isInterrupted = false;
        }
        isThreadRunning = true;
        t = new Thread(this);
        t.start();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        
    }

    /*updateTimer runnable to update the values in textview*/
    private Runnable updateTimer = new Runnable() {
        @Override
        public void run() {
            // TODO Auto-generated method stub
            if(isThreadRunning) {
                timeDiffMil = (SystemClock.uptimeMillis() - startTime) + tempTime;
                
                /*Format time and set it to textview*/
                textViewTime.setText(timerUtil.formatTime(timeDiffMil));
                
                handler.postDelayed(this, 0);
            }
        }
        
    };

    /*Check if the Motion Sensor has a change in X,Y or Z position*/
    @Override
    public void onSensorChanged(SensorEvent event) {
        // TODO Auto-generated method stub
        /*Check if the timer has been started*/
        if(isTimerStarted) {
            /*get X and Y acceleration from Sensor and multiply with accelRate*/
            accelX = (float) (event.values[1] * accelRate);
            accelY = (float) (event.values[0] * (accelRate * 1.5));
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub
        
    }
}




Java Source Code List

com.app.ui.assignment.barrelrace.FailureActivity.java
com.app.ui.assignment.barrelrace.GameActivity.java
com.app.ui.assignment.barrelrace.MainActivity.java
com.app.ui.assignment.barrelrace.SettingsActivity.java
com.app.ui.assignment.barrelrace.SuccessActivity.java
com.app.ui.assignment.barrelrace.ViewScoresActivity.java
com.app.ui.assignment.barrelrace.objects.Barrel.java
com.app.ui.assignment.barrelrace.objects.Fence.java
com.app.ui.assignment.barrelrace.objects.Horse.java
com.app.ui.assignment.barrelrace.objects.Score.java
com.app.ui.assignment.barrelrace.util.CustomAdapter.java
com.app.ui.assignment.barrelrace.util.FileUtil.java
com.app.ui.assignment.barrelrace.util.ScoreComparator.java
com.app.ui.assignment.barrelrace.util.TimerUtil.java
com.app.ui.assignment.barrelrace.views.BarrelRaceView.java