Simon game is an electric memory game. The device creates a series of tones and lights and requires a user to
repeat the sequence. If the user succeeds, the series becomes
progressively longer and more complex. Once the user fails or the time
limit runs out, the game is over. Read in wikipedia.
This android game is a simulation of that.
The buttons on the screen glow in some order with their notes. The user must reproduce these button clicks in the same order.It is a very good game for memory with the added benefit of audio feature.
The source code of the game is available in my github page Simon
The android game with Simon and 3 more memory games by Hegdeapps can be downloaded from google play
Basically in our layout file, we have four SimonCell custom widgets which are extended classes of image views. These are the four colored buttons you see in the image above.
<com.hegdeapps.simonsays.SimonCell
android:id="@+id/cell1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="@drawable/green" />
Now this SimonCell has on and off states. When it is in On state, the glowing button is set as drawable. Here is the SimonCell.java
public class SimonCell extends androidx.appcompat.widget.AppCompatImageView
{
private final Context mContext;
final static int ON = 1;
final static int OFF = 2;
public final static int CELL_TYPE_RED = 1;
public final static int CELL_TYPE_BLUE = 2;
public final static int CELL_TYPE_GREEN = 3;
public final static int CELL_TYPE_YELLOW = 4;
public int onDrawable;
public int offDrawable;
int onColor;
int offColor;
int color;
int state;
int cellType;
int soundRawFile;
void setOn()
{
this.setImageDrawable(getResources().getDrawable(onDrawable));
this.refreshDrawableState();
}
public SimonCell(Context ctx,AttributeSet attr){
super(ctx,attr);
mContext =ctx;
}
public SimonCell(Context ctx){
super(ctx);
mContext =ctx;
}
void onCellClicked()
{
if(getState()!=ON) {
setOn();
}
}
public int getState() {
return state;
}
void setOff() {
state = OFF;
this.setImageDrawable(getResources().getDrawable(offDrawable));
this.refreshDrawableState();
}
public void setCellType(int cellType) {
this.cellType = cellType;
switch (this.cellType) {
case CELL_TYPE_BLUE:
this.onDrawable = R.drawable.blueon;
offDrawable = R.drawable.blue;
break;
case CELL_TYPE_GREEN:
onDrawable = R.drawable.greenon;
offDrawable = R.drawable.green;
break;
case CELL_TYPE_RED:
onDrawable = R.drawable.redon;
offDrawable = R.drawable.red;
break;
case CELL_TYPE_YELLOW:
onDrawable = R.drawable.yellowon;
offDrawable = R.drawable.yellow;
break;
}
}
}
In the activity file, we store the four buttons as an array. In the start game function, we generate a random number between 0 to 3, and add this random number to the CellOnList and glow the buttons of this list accompanied by their music notes. This is taken care by a timer task - at the end of timer, if the index is less than array length, the glowonecell function is called for the next list element.
fun glowCells2() {
mInstancesSaved = false
mCurrentCellIndex = 0
// int duration = 1000 * mCellOnList.size();
if (mTimer != null) {
mTimer!!.cancel()
}
mTimer = Timer()
mTimerTask = object : TimerTask() {
override fun run() {
runOnUiThread {
mTimerTaskCompleted = false
if (mCurrentCellIndex < mCellOnList!!.size) {
glowOneCell(mCellOnList!![mCurrentCellIndex++])
} else {
mTimerTaskCompleted = true
}
}
}
}
mTimer!!.schedule(mTimerTask, 0, 700)
}
Glowonecell will display ondrawable, play the note of the cell and starts the timer. At the end of the timer, the cell will display the normal off drawable.
private fun glowOneCell(celIndex: Int) {
val cell = mImgView[celIndex]
if (mPrevSoundStreamID != 0) {
soundPool!!.stop(mPrevSoundStreamID)
}
if (mSoundOn) {
mPrevSoundStreamID =
soundPool!!.play(mSoundID[celIndex], mSndVolume, mSndVolume, 1, 0, 1f)
}
cell!!.setOn()
startTimer(cell)
}
private fun startTimer(cell: SimonCell?) {
val timer: CountDownTimer = object : CountDownTimer(300, 400) {
override fun onTick(l: Long) {}
override fun onFinish() {
cell!!.setOff()
}
}
timer.start()
}
Now so far, we see how the game displays buttons in order. Next let us see, how do we check if the user has pressed the buttons in correct order.
So the buttons have onclicklisteners
for (i in 0..3) {
mImgView[i]!!.setOnClickListener(this)
mImgView[i]!!.setOff()
}
And onclick method will call processcellclicked
override fun onClick(view: View) {
val id = view.id
when (id) {
R.id.cell1 -> processCellClicked(0, view as SimonCell)
R.id.cell2 -> processCellClicked(1, view as SimonCell)
R.id.cell3 -> processCellClicked(2, view as SimonCell)
R.id.cell4 -> processCellClicked(3, view as SimonCell)
}
}
private fun processCellClicked(cellNum: Int, cell: SimonCell) {
if (mTimerForClick != null) {
mTimerForClick!!.cancel()
}
cell.setOn()
if (mPrevSoundStreamID != 0) {
soundPool!!.stop(mPrevSoundStreamID)
}
if (mSoundOn) {
mPrevSoundStreamID =
soundPool!!.play(mSoundID[cellNum], mSndVolume, mSndVolume, 1, 0, 1f)
}
startTimer(cell)
if (mCellOnList!![count] != cellNum) {
showAlert("Game Over\n\nScore $mScore", GAME_OVER)
return
}
count++
if (count == mLevel) {
mLevel++
count = 0
mScore += 1000
showScore()
saveScoreInPref()
showAlert(
"LEVEL " + (mLevel - 1).toString() + " COMPLETED\n\nSCORE " + mScore,
LEVEL_COMPLETED
)
}
}
ProcessCellClicked method glows the cell using setcellon method. If the previous note is playing, it is stopped and and then the note is played. If the button pressed in not in the correct order then the Game over message is displayed and game stops. And if the end of list is reached and all buttons are in correct order, then level is incremented and next level is started.
Note : The button color and note playing can be added as properties of the cell. And of course UI can be improved :)
Comments
Post a Comment