Skip to content

Instantly share code, notes, and snippets.

@glennismade
Created February 2, 2018 12:20
Show Gist options
  • Save glennismade/6c5053f046d6bde8da3737830960fb17 to your computer and use it in GitHub Desktop.
Save glennismade/6c5053f046d6bde8da3737830960fb17 to your computer and use it in GitHub Desktop.
Simple Android Based Infinite runner style racing game
//import android.graphics.Bitmap;
//import android.graphics.Canvas;
//
//import uk.ac.reading.sis05kol.mooc.MainActivity;
//
//public class Background {
//
// private Bitmap image;
// private int x, y, dx;
//
// public Background(Bitmap res)
// {
// image = res;
// }
// public void update()
// {
// x+=dx;
// if(x<-MainActivity.HEIGHT){
// x=0;
// }
// }
// public void draw(Canvas canvas)
// {
// canvas.drawBitmap(image, x, y,null);
// if(x<0)
// {
// canvas.drawBitmap(image, x+MainActivity.HEIGHT, y, null);
// }
// }
// public void setVector(int dx)
// {
// this.dx = dx;
// }
//}
//package uk.ac.reading.sis05kol.mooc;
//
//import java.util.Vector;
//
///**
// * Created by glennhealy on 17/04/2016.
// */
//public class Box {
//
// public Vector position;
// private float width;
// private float height;
// private float halfWidth;
// private float halfHeight;
// private int x = 0;
// private int y = 0;
//
//
// public Box(Vector position, float width, float height) {
// this.position = position;
// this.width = width;
// this.height = height;
// halfWidth = width/2;
// halfHeight = height/2;
//
//
// }
//
//// public boolean intersects(Box box) {
//// return (position + halfWidth() >= box.position.x = box.halfWidth() && position.y + halfHeight() >= box.position.y - box.halfHeight() ) && (box.position.x + box.halfWidth() >= position.x - halfWidth() && box.position.y + box.halfHeight() >= position.y - halfHeight() );
////
////
////
//// }
//
//
// public float getWidth() {
//
// return width;
// }
//
// public void setWidth(float width) {
// this.width = width;
// halfHeight = width /2;
// }
//
// public float getHeight() {
// return height;
// }
//
// public void setHeight(float height) {
// this.height = height;
// halfHeight = height /2;
// }
//
//
//}
//
// public boolean isIntersecting(Box box) {
// boolean test1 = false;
// boolean test2 = false;
//
// test1 = (position.x + halfWidth() >= box.position.y = box.halfHeight() )
// &&
//
// position.y + halfHeight() >= box.position.y = box.halfHeight() );
//
// test2 = (box.position.x + box.halfWidth() >= position.x - halfWidth() )
//
// &&
//
// box.position.y + box.halfHeight() >= position.y - halfHeight() );
//
// return test1 && test2;
//}
package uk.ac.reading.sis05kol.mooc;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.View;
public abstract class GameThread extends Thread {
//Different mMode states
public static final int STATE_LOSE = 1;
public static final int STATE_PAUSE = 2;
public static final int STATE_READY = 3;
public static final int STATE_RUNNING = 4;
public static final int STATE_WIN = 5;
//Control variable for the mode of the game (e.g. STATE_WIN)
protected int mMode = 1;
//Control of the actual running inside run()
private boolean mRun = false;
//The surface this thread (and only this thread) writes upon
private SurfaceHolder mSurfaceHolder;
//the message handler to the View/Activity thread
private Handler mHandler;
//Android Context - this stores almost all we need to know
private Context mContext;
//The view
public GameView mGameView;
//We might want to extend this call - therefore protected
protected int mCanvasWidth = 1;
protected int mCanvasHeight = 1;
protected int dx;
//Last time we updated the game physics
protected long mLastTime = 0;
protected Bitmap mBackgroundImage;
protected long score = 0;
//Used for time keeping
private long now;
private float elapsed;
//Rotation vectors used to calculate orientation
float[] mGravity;
float[] mGeomagnetic;
//Used to ensure appropriate threading
static final Integer monitor = 1;
public GameThread(GameView gameView) {
mGameView = gameView;
mSurfaceHolder = gameView.getHolder();
mHandler = gameView.getmHandler();
mContext = gameView.getContext();
//public Bitmap gb = mBackgroundImage;
mBackgroundImage = BitmapFactory.decodeResource
(gameView.getContext().getResources(),
R.drawable.track5);
//mBackgroundImage.setVector(-5);
}
// public void setVector(int dx){
// this.dx = dx;
// }
/*
* Called when app is destroyed, so not really that important here
* But if (later) the game involves more thread, we might need to stop a thread, and then we would need this
* Dare I say memory leak...
*/
public void cleanup() {
this.mContext = null;
this.mGameView = null;
this.mHandler = null;
this.mSurfaceHolder = null;
}
//Pre-begin a game
abstract public void setupBeginning();
//Starting up the game
public void doStart() {
synchronized(monitor) {
setupBeginning();
mLastTime = System.currentTimeMillis() + 100;
setState(STATE_RUNNING);
setScore(0);
}
}
//The thread start
@Override
public void run() {
Canvas canvasRun;
while (mRun) {
canvasRun = null;
try {
canvasRun = mSurfaceHolder.lockCanvas(null);
synchronized (monitor) {
if (mMode == STATE_RUNNING) {
updatePhysics();
}
doDraw(canvasRun);
}
}
finally {
if (canvasRun != null) {
if(mSurfaceHolder != null)
mSurfaceHolder.unlockCanvasAndPost(canvasRun);
}
}
}
}
/*
* Surfaces and drawing
*/
public void setSurfaceSize(int width, int height) {
synchronized (monitor) {
mCanvasWidth = width;
mCanvasHeight = height;
// don't forget to resize the background image
mBackgroundImage = Bitmap.createScaledBitmap(mBackgroundImage, width, height, true);
}
}
protected void doDraw(Canvas canvas) {
if(canvas == null) return;
if(mBackgroundImage != null) canvas.drawBitmap(mBackgroundImage, 0, 0, null);
}
private void updatePhysics() {
now = System.currentTimeMillis();
elapsed = (now - mLastTime) / 1000.0f;
updateGame(elapsed);
mLastTime = now;
}
abstract protected void updateGame(float secondsElapsed);
/*
* Control functions
*/
//Finger touches the screen
public boolean onTouch(MotionEvent e) {
if(e.getAction() != MotionEvent.ACTION_DOWN) return false;
if(mMode == STATE_READY || mMode == STATE_LOSE || mMode == STATE_WIN) {
doStart();
return true;
}
if(mMode == STATE_PAUSE) {
unpause();
return true;
}
synchronized (monitor) {
this.actionOnTouch(e.getRawX(), e.getRawY());
}
return false;
}
protected void actionOnTouch(float x, float y) {
//Override to do something
}
//The Orientation has changed
@SuppressWarnings("deprecation")
public void onSensorChanged(SensorEvent event) {
synchronized (monitor) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
actionWhenPhoneMoved(orientation[2],orientation[1],orientation[0]);
}
}
}
}
protected void actionWhenPhoneMoved(float xDirection, float yDirection, float zDirection) {
//Override to do something
}
/*
* Game states
*/
public void pause() {
synchronized (monitor) {
if (mMode == STATE_RUNNING) setState(STATE_PAUSE);
}
}
public void unpause() {
// Move the real time clock up to now
synchronized (monitor) {
mLastTime = System.currentTimeMillis();
}
setState(STATE_RUNNING);
}
//Send messages to View/Activity thread
public void setState(int mode) {
synchronized (monitor) {
setState(mode, null);
}
}
public void setState(int mode, CharSequence message) {
synchronized (monitor) {
mMode = mode;
if (mMode == STATE_RUNNING) {
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putString("text", "");
b.putInt("viz", View.INVISIBLE);
b.putBoolean("showAd", false);
msg.setData(b);
mHandler.sendMessage(msg);
}
else {
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
Resources res = mContext.getResources();
CharSequence str = "";
if (mMode == STATE_READY)
str = res.getText(R.string.mode_ready);
else
if (mMode == STATE_PAUSE)
str = res.getText(R.string.mode_pause);
else
if (mMode == STATE_LOSE)
str = res.getText(R.string.mode_lose);
else
if (mMode == STATE_WIN) {
str = res.getText(R.string.mode_win);
}
if (message != null) {
str = message + "\n" + str;
}
b.putString("text", str.toString());
b.putInt("viz", View.VISIBLE);
msg.setData(b);
mHandler.sendMessage(msg);
}
}
}
/*
* Getter and setter
*/
public void setSurfaceHolder(SurfaceHolder h) {
mSurfaceHolder = h;
}
public boolean isRunning() {
return mRun;
}
public void setRunning(boolean running) {
mRun = running;
}
public int getMode() {
return mMode;
}
public void setMode(int mMode) {
this.mMode = mMode;
}
/* ALL ABOUT SCORES */
//Send a score to the View to view
//Would it be better to do this inside this thread writing it manually on the screen?
public void setScore(long score) {
this.score = score;
synchronized (monitor) {
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putBoolean("score", true);
b.putString("text", getScoreString().toString());
msg.setData(b);
mHandler.sendMessage(msg);
}
}
public float getScore() {
return score;
}
public void updateScore(long score) {
this.setScore(this.score + score);
}
protected CharSequence getScoreString() {
return Long.toString(Math.round(this.score));
}
}
// This file is part of the course "Begin Programming: Build your first mobile game" from futurelearn.com
// Copyright: University of Reading and Karsten Lundqvist
// It is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// It is is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
// You should have received a copy of the GNU General Public License
// along with it. If not, see <http://www.gnu.org/licenses/>.
package uk.ac.reading.sis05kol.mooc;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.TextView;
public class GameView extends SurfaceView implements SurfaceHolder.Callback, SensorEventListener {
private volatile GameThread thread;
//private SensorEventListener sensorAccelerometer;
//Handle communication from the GameThread to the View/Activity Thread
private Handler mHandler;
//Pointers to the views
private TextView mScoreView;
private TextView mStatusView;
Sensor accelerometer;
Sensor magnetometer;
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
//Get the holder of the screen and register interest
SurfaceHolder holder = getHolder();
holder.addCallback(this);
//Set up a handler for messages from GameThread
mHandler = new Handler() {
@Override
public void handleMessage(Message m) {
if(m.getData().getBoolean("score")) {
mScoreView.setText(m.getData().getString("text"));
}
else {
//So it is a status
int i = m.getData().getInt("viz");
switch(i) {
case View.VISIBLE:
mStatusView.setVisibility(View.VISIBLE);
break;
case View.INVISIBLE:
mStatusView.setVisibility(View.INVISIBLE);
break;
case View.GONE:
mStatusView.setVisibility(View.GONE);
break;
}
mStatusView.setText(m.getData().getString("text"));
}
}
};
}
//Used to release any resources.
public void cleanup() {
this.thread.setRunning(false);
this.thread.cleanup();
this.removeCallbacks(thread);
thread = null;
this.setOnTouchListener(null);
SurfaceHolder holder = getHolder();
holder.removeCallback(this);
}
/*
* Setters and Getters
*/
public void setThread(GameThread newThread) {
thread = newThread;
setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return thread != null && thread.onTouch(event);
}
});
setClickable(true);
setFocusable(true);
}
public GameThread getThread() {
return thread;
}
public TextView getStatusView() {
return mStatusView;
}
public void setStatusView(TextView mStatusView) {
this.mStatusView = mStatusView;
}
public TextView getScoreView() {
return mScoreView;
}
public void setScoreView(TextView mScoreView) {
this.mScoreView = mScoreView;
}
public Handler getmHandler() {
return mHandler;
}
public void setmHandler(Handler mHandler) {
this.mHandler = mHandler;
}
/*
* Screen functions
*/
//ensure that we go into pause state if we go out of focus
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
if(thread!=null) {
if (!hasWindowFocus)
thread.pause();
}
}
public void surfaceCreated(SurfaceHolder holder) {
if(thread!=null) {
thread.setRunning(true);
if(thread.getState() == Thread.State.NEW){
//Just start the new thread
thread.start();
}
else {
if(thread.getState() == Thread.State.TERMINATED){
//Start a new thread
//Should be this to update screen with old game: new GameThread(this, thread);
//The method should set all fields in new thread to the value of old thread's fields
thread = new TheGame(this);
thread.setRunning(true);
thread.start();
}
}
}
}
//Always called once after surfaceCreated. Tell the GameThread the actual size
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if(thread!=null) {
thread.setSurfaceSize(width, height);
}
}
/*
* Need to stop the GameThread if the surface is destroyed
* Remember this doesn't need to happen when app is paused on even stopped.
*/
public void surfaceDestroyed(SurfaceHolder arg0) {
boolean retry = true;
if(thread!=null) {
thread.setRunning(false);
}
//join the thread with this thread
while (retry) {
try {
if(thread!=null) {
thread.join();
}
retry = false;
}
catch (InterruptedException e) {
//naugthy, ought to do something...
}
}
}
/*
* Accelerometer
*/
public void startSensor(SensorManager sm) {
accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
sm.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI);
}
public void removeSensor(SensorManager sm) {
sm.unregisterListener(this);
accelerometer = null;
magnetometer = null;
}
//A sensor has changed, let the thread take care of it
@Override
public void onSensorChanged(SensorEvent event) {
if(thread!=null) {
thread.onSensorChanged(event);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void setVisibility(Bitmap mSpeedBoost) {
mSpeedBoost.eraseColor(Color.TRANSPARENT);
}
}
// This file is part of the course "Begin Programming: Build your first mobile game" from futurelearn.com
// Copyright: University of Reading and Karsten Lundqvist
// It is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// It is is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
// You should have received a copy of the GNU General Public License
// along with it. If not, see <http://www.gnu.org/licenses/>.
package uk.ac.reading.sis05kol.mooc;
import android.app.Activity;
import android.content.Intent;
import android.content.Context;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.TranslateAnimation;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Date;
public class MainActivity extends Activity {
private static final int MENU_RESUME = 1;
private static final int MENU_START = 2;
private static final int MENU_STOP = 3;
public static final int WIDTH = 200;
public static final int HEIGHT = 300;
private GameThread mGameThread;
private GameView mGameView;
/** Called when the activity is first created. */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
mGameView = (GameView) findViewById(R.id.gamearea);
mGameView.setStatusView((TextView) findViewById(R.id.text));
mGameView.setScoreView((TextView) findViewById(R.id.score));
this.startGame(mGameView, null, savedInstanceState);
Button HomeButton = (Button) findViewById(R.id.btnHome);
HomeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
System.exit(0);
startActivity(new Intent(MainActivity.this, mainmenu.class));
}
});
// Intent menuIntent = new Intent(getApplicationContext(), mainmenu.class);
// startActivityForResult(menuIntent, 100);
//
// protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
// if(resultCode == 100){
// startActivity(menuIntent);
// }
// finish();
//
// }
// ImageView img_animation = (ImageView) findViewById(R.id.imgTrack);
//
// TranslateAnimation animation = new TranslateAnimation(0.0f, 0.0f,
// 100.0f, 100.0f);
// animation.setDuration(5000);
// animation.setRepeatCount(5);
// animation.setRepeatMode(2);
//
// img_animation.startAnimation(animation);
}
private void startGame(GameView gView, GameThread gThread, Bundle savedInstanceState) {
//Set up a new game, we don't care about previous states
mGameThread = new TheGame(mGameView);
mGameView.setThread(mGameThread);
mGameThread.setState(GameThread.STATE_READY);
mGameView.startSensor((SensorManager)getSystemService(Context.SENSOR_SERVICE));
}
// @Override
public void onRunning(View v){
//super.onRunning();
if(mGameThread.getMode() == GameThread.STATE_RUNNING) { //pause the game if its running
mGameThread.pause();
}
else if(mGameThread.getMode() == GameThread.STATE_PAUSE) { //unpause the game if its running
mGameThread.unpause();
}
}
/*
* Activity state functions
*/
@Override
protected void onPause() {
super.onPause();
if(mGameThread.getMode() == GameThread.STATE_RUNNING) {
mGameThread.setState(GameThread.STATE_PAUSE);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mGameView.cleanup();
mGameView.removeSensor((SensorManager)getSystemService(Context.SENSOR_SERVICE));
mGameThread = null;
mGameView = null;
}
/*
* UI Functions
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, MENU_START, 0, R.string.menu_start);
menu.add(0, MENU_STOP, 0, R.string.menu_stop);
menu.add(0, MENU_RESUME, 0, R.string.menu_resume);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_START:
mGameThread.doStart();
return true;
case MENU_STOP:
mGameThread.setState(GameThread.STATE_LOSE, getText(R.string.message_stopped));
return true;
case MENU_RESUME:
mGameThread.unpause();
return true;
}
return false;
}
public void onNothingSelected(AdapterView<?> arg0) {
// Do nothing if nothing is selected
}
}
package uk.ac.reading.sis05kol.mooc;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
/**
* Created by glennhealy on 03/03/2016.
*/
public class mainmenu extends Activity {
private GameThread myGameThread;
private GameView myGameView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_menu);
Button startButton = (Button) findViewById(R.id.btnGameStart); //start game button declaration
Button exitButton = (Button) findViewById(R.id.btnExit); //exit app button declaration
Button settingsButton = (Button) findViewById(R.id.btnSettings); //this is the settings button declaration
Button ScoresButton = (Button) findViewById(R.id.btnScores);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(mainmenu.this, MainActivity.class));
}
});
settingsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(mainmenu.this, SettingsActivity.class));
}
});
ScoresButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(mainmenu.this, ScoreActivity.class));
}
});
exitButton.setOnClickListener(new View.OnClickListener() { //this chunk of code exits the app completely
@Override
public void onClick(View v) {
finish();
System.exit(1);
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="uk.ac.reading.sis05kol.mooc" >
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".mainmenu"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
</activity>
<activity
android:name=".SettingsActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
</activity>
<activity
android:name=".ScoreActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
</activity>
</application>
</manifest>
package uk.ac.reading.sis05kol.mooc;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by glennhealy on 18/04/2016.
*/
public class myTimer extends Object {
Timer timer = new Timer();
int secondsPassed =0;
TimerTask mytask = new TimerTask() {
@Override
public void run() {
secondsPassed++;
}
};
public void startTimer(){
timer.scheduleAtFixedRate(mytask, 1000, 1000);
}
}
package uk.ac.reading.sis05kol.mooc;
import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.FileReader;
import uk.ac.reading.sis05kol.mooc.TheGame;
/**
* Created by glennhealy on 18/04/2016.
*/
public class ScoreActivity extends Activity {
private GameThread myGameThread;
private GameView myGameView;
// BufferedReader fileReader = new BufferedReader(new FileReader("score.txt"));
//
// StringBuilder strBuilder = new StringBuilder();
//
// public String line;
//
// while((line = fileReader.readLine()) != null)
// {
// strBuilder.append(line);
// }
//
// fileReader.close();
//
// strBuilder.trimToSize();
//
// String contentsOfFile = strBuilder.toString();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_score);
TextView Score1 = (TextView) findViewById(R.id.txtScore1);
// Score1.setText(contentsOfFile);
}
}
package uk.ac.reading.sis05kol.mooc;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import javax.xml.transform.Source;
/**
* Created by glennhealy on 09/04/2016.
*/
public class SettingsActivity extends Activity {
private GameThread myGameThread;
private GameView myGameView;
public final boolean audio = true;
MediaPlayer Music;
// public final boolean Checked = false;
// public int ON, OFF;
//this method doesnt work currenly. need to figure out how to enable sound files.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
final CheckBox Sound = (CheckBox) findViewById(R.id.chbxSound);
Sound.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Sound.isChecked()) {
// mediaplayer is already muted, so needs be to unmuted
Music.setVolume(1, 1);
} else {
// mute media player
Music.setVolume(0, 0);
}
}
});
}
}
package uk.ac.reading.sis05kol.mooc;
//Other parts of the android libraries that we use
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.Writer;
import java.util.Random;
import java.util.Timer;
public class TheGame extends GameThread{
public String ScoreFile = "scores.txt";
// public FileOutputStream files = openFileOutput();
//bitmaps for all the objects on the screen
private Bitmap mBall;
private Bitmap mEnemy;
private Bitmap mSpeedBoost;
private Bitmap mBomb;
///////////////////
public static int i;
public boolean collide = false;
public boolean collected = false;
public float BackgroundY = 0, BackgroundX = 0;
// public float globalScore = score;
// private Background bg;
private float Ewidth = 150;
private float Eheight = 300;
private float Mwidth = 128;
private float Mheight = 128;
private float Bwidth = 85;
private float Bheight = 85;
//The X and Y position of the ball on the screen (middle of ball)
private float mBallX = mCanvasWidth /2;
private float mBallY = mCanvasHeight /2;
private float mEnemyX = mCanvasWidth /2;
private float mEnemyY = mCanvasHeight /2;
private float mSpeedBoostX = mCanvasWidth /2;
private float mSpeedBoostY = mCanvasHeight /2;
private float mBombX = mCanvasWidth /2;
private float mBombY = mCanvasHeight /2;
//The speed (pixel/second) of the ball in direction X and Y
private float mBallSpeedX = 0;
private float mBallSpeedY = 0;
private float mEnemySpeedX = 0;
private float mEnemySpeedY = 1;
private float mBombSpeedX = 0;
private float mBombSpeedY = 0;
//This is run before anything else, so we can prepare things here
public TheGame(GameView gameView) {
//House keeping
super(gameView);
//Prepare the image so we can draw it on the screen (using a canvas)
mBall = BitmapFactory.decodeResource (gameView.getContext().getResources(), R.drawable.car); //player car
mEnemy = BitmapFactory.decodeResource (gameView.getContext().getResources(), R.drawable.car2); //enemy car
mSpeedBoost = BitmapFactory.decodeResource (gameView.getContext().getResources(), R.drawable.speedboost); //speed boost image
mBomb = BitmapFactory.decodeResource (gameView.getContext().getResources(), R.drawable.sad_ball); // bomb
// mBackgroundImage.setVector(-5);
}
//This is run before a new game (also after an old game)
@Override
public void setupBeginning() {
//Initialise speeds
mBallSpeedX = 0;
mBallSpeedY = 0;
mEnemySpeedY =-500;
mEnemySpeedX =1;
mBombSpeedY = 5;
mBombSpeedX = 0;
//Place the ball in the middle of the screen.
//mBall.Width() and mBall.getHeigh() gives us the height and width of the image of the ball
mBallX = mCanvasWidth / 2;
mBallY = mCanvasHeight / 2;
mEnemyX = mCanvasWidth /7;
mEnemyY = mCanvasHeight /2;
mSpeedBoostY =mCanvasHeight /5;
mSpeedBoostX = mCanvasWidth /2;
mBombX = mCanvasWidth /2;
mBombY = mCanvasHeight /5;
}
@Override
protected void doDraw(Canvas canvas) {
//If there isn't a canvas to draw on do nothing
//It is ok not understanding what is happening here
if(canvas == null) return;
super.doDraw(canvas);
canvas.drawBitmap(mBackgroundImage, BackgroundX, BackgroundY, null); //background image
//draw the image of the ball using the X and Y of the ball
//drawBitmap uses top left corner as reference, we use middle of picture
//null means that we will use the image without any extra features (called Paint)
canvas.drawBitmap(mBall, mBallX - mBall.getWidth() / 2, mBallY - mBall.getHeight() / 2, null); // drawing the car
canvas.drawBitmap(mEnemy, mEnemyX - mEnemy.getWidth() /4, mEnemyY - mEnemy.getHeight() /7, null); //drawing the AI car
canvas.drawBitmap(mBomb, mBombX - mBomb.getWidth() /6, mBombY - mBomb.getHeight() /randomPos(), null); // drawing the sad Face
//if(!collide){
canvas.drawBitmap(mSpeedBoost, mSpeedBoostX - mSpeedBoost.getWidth() /2, mSpeedBoostY - mSpeedBoost.getHeight() /6, null); //drawing the point bonus
//}
// if (mCanvasHeight <0) {
// canvas.drawBitmap(mBackgroundImage, mCanvasHeight+MainActivity.HEIGHT, mCanvasWidth, null);
// }
if(mEnemyY <-5){ //this resets the AI cars Y position to below the screen
mEnemyY = mCanvasHeight;
mEnemyX = randomEnemyX();
canvas.drawBitmap(mEnemy, mEnemyX - mEnemy.getWidth() /randomEnemyX(), mEnemyY -mEnemy.getHeight() /7, null);
}
float scrollFactor = 0.5f; //Moves the background 0.5 pixels up per call of the draw method
this.mCanvasHeight += scrollFactor; // this checks the canvas height and add the scroll factor to it.
}
//This is run whenever the phone is touched by the user
@Override
protected void actionOnTouch(float x, float y) {
//Increase/decrease the speed of the ball making the ball move towards the touch
mBallSpeedX = x - mBallX; // user car left and right controlls
//mBallSpeedY = y - mBallY; // disables to prevent user car from leavign screen
}
// This is run whenever the phone moves around its axises
// @Override
// protected void actionWhenPhoneMoved(float xDirection, float yDirection, float zDirection) {
// /*
// Increase/decrease the speed of the ball.
// If the ball moves too fast try and decrease 70f
// If the ball moves too slow try and increase 70f
// */
//
// mBallSpeedX = mBallSpeedX + 72f * xDirection;
// mBallSpeedY = mBallSpeedY - 72f * yDirection;
// }
public float randomPos(){ // random method to generate random x value for point bonus and sad face
Random r = new Random();
return r.nextInt(mCanvasWidth-1)+1;
}
public float randomEnemyX(){ // random method to generate random x value for AI car
Random r = new Random();
return r.nextInt(mCanvasWidth-2)+2;
}
public float randomSpeed(){
Random Speed = new Random();
return Speed.nextInt((int) (mEnemySpeedY-1))+1;
}
//This is run just before the game "scenario" is printed on the screen
@Override
protected void updateGame(float secondsElapsed) {
//Move the ball's X and Y using the speed (pixel/sec)
mBallX = mBallX + secondsElapsed * mBallSpeedX; //sets the user car's speed
mBallY = mBallY + secondsElapsed * mBallSpeedY; // this does the same but for Y
//mEnemyY = mEnemyY * mEnemySpeedY;
mEnemyY = mEnemyY + secondsElapsed * mEnemySpeedY; // sets the AI car speed x
mBombY = mBombY + secondsElapsed * mBombSpeedY; // sets the AI car speed Y
if (getMode() == GameThread.STATE_RUNNING) { // method to check if the game is currently in a running state (something happening) if so the following happens
mEnemyY --;//oponent car is moved up the screen towards the top
mSpeedBoostY += 5; //point bonus (bolt) is moved down the screen at 5 speed
BackgroundY += 5; // the background image is moved down the screen at +5
mBombY += 5; // the sad face is moved down the screen at +5
if (mSpeedBoostY > mCanvasHeight) { // used to check is AI cars Y pos is above screen
mSpeedBoostY = 0; // if so resets it
}
if (mBombY > mCanvasHeight) { // checks sad face's Y pos
mBombY = 0; // if below screen reset
mBombX = randomPos(); // set X pos to random value
}
for (i = 0; i < secondsElapsed; i++) {
updateScore(1); // calls the update score method to update the score every second that player is alive.
}
}
if (BackgroundY > mCanvasHeight) { // checks the backgroung images y pos (from top left of image)
BackgroundY = 0; // if below screen top (top of canvas) reset to 0
}
if (isCollide(mSpeedBoostX, mSpeedBoostY // used to check for collision, if the method isCollide == true, set collide to true, and add points
)) {
collide = true;
if (!collected) { // if true, score gets updated + 2000
updateScore(2000);
collected = true;
mSpeedBoostY = 0; //reset point bonus Y pos
mSpeedBoostX = randomPos();// reset point bonus X pos to random value
//collide = false;
}
}
if (isCollide(mBombX, mBombY)) {
setState(GameThread.STATE_LOSE); // ends the game if the player contacts sad face
setScore(score); //updates the score.
}
if (collected) { // if point bonus = colected, reprint it to defailt X&Y pos
mSpeedBoostY = mCanvasHeight;
mSpeedBoostX = mCanvasWidth;
}
if (isCollide(mEnemyX, mEnemyY)) {
setState(GameThread.STATE_LOSE); //if player and AI car collide end game
collide = false;
}
//
// if(mBallX > mCanvasWidth) {
// setState(GameThread.STATE_LOSE);
// }
// if(mBallX < mCanvasWidth) {
// setState(GameThread.STATE_LOSE);
// }
}
public void getSize() {
mSpeedBoost.getHeight();
mSpeedBoost.getWidth();
// float size = mSpeedBoost.getHeight() * mSpeedBoost.getWidth(); //doesnt work.
}
public boolean ballCollide(){
return mBallX >= mSpeedBoostX && mBallX <= mSpeedBoostX + Bwidth && mBallY >= mSpeedBoostY && mBallY <= mSpeedBoostY + Bheight;
}
public boolean bombCollide(){
return mBallX > mBombX && mBallX < mBombX + Mwidth && mBallY > mBombY && mBallY < mBombY + Mheight;
}
public boolean isCollide(float x2, float y2) {
return mBallX +64 >= x2 && mBallX +64 <= x2 + Bwidth + 64 && mBallY +64 >= y2 && mBallY +64 <= y2 + Bheight +64; //generic collision detection boolean for all objects.
}
public void setVector(int dx) {
this.dx=dx;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment