i am doing an android simon says app and i am in the light up loop,
for this example i have defined it so it would light up 4 colors because the array that has the numbers that light up the according numbers is 4 cells long
unfortunately it lights up all of the colors at the same time you could not distinguish the order i am trying to figure out why that is and how do imake it light up one color at once here's the code for my main activity and java calss that helps it
this is the activity:
package com.gabie212.simonsays;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.ArrayList;
public class GameActivity extends AppCompatActivity implements View.OnClickListener {
private int i = 0;
private Thread t = new Thread();
private Button greenButton;
private Button redButton;
private Button blueButton;
private Button yellowButton;
private Button startButton;
private ArrayList<Integer> randomColors = new ArrayList<Integer>();
private ArrayList<Integer> userColors = new ArrayList<Integer>();
private GameManger gm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gm = new GameManger(this);
setContentView(R.layout.activity_game);
greenButton = (Button) findViewById(R.id.btnGreen);
redButton = (Button) findViewById(R.id.btnRed);
blueButton = (Button) findViewById(R.id.btnBlue);
yellowButton = (Button) findViewById(R.id.btnYellow);
startButton = (Button) findViewById(R.id.btnStart);
startButton.setOnClickListener(this);
greenButton.setOnClickListener(this);
redButton.setOnClickListener(this);
blueButton.setOnClickListener(this);
yellowButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int num;
for (i=0;i<3;i++) {
num = gm.getColor(4);
randomColors.add(num);
}
android.os.Handler handler = new android.os.Handler();
//TODO if the start button is pressed multiple times simultaneously it starts the lightup loop multiple times simultaneously
if (v.getId() == startButton.getId()) {
for (i = 0; i < randomColors.size(); i++) //light up loop
{
switch (randomColors.get(i)) {
case 1:
greenButton.setBackgroundResource(R.drawable.greenlightup);
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
greenButton.setBackgroundResource(R.drawable.green);
}
}, 2000);
break;
case 2:
redButton.setBackgroundResource(R.drawable.redlightup);
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
redButton.setBackgroundResource(R.drawable.red);
}
}, 2000);
break;
case 3:
blueButton.setBackgroundResource(R.drawable.bluelightup);
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
blueButton.setBackgroundResource(R.drawable.blue);
}
}, 2000);
break;
case 4:
yellowButton.setBackgroundResource(R.drawable.yellowlightup);
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
yellowButton.setBackgroundResource(R.drawable.yellow);
}
}, 2000);
break;
}
}
/*
for(i=0;i<randomColors.size();i++)
{
if(v.getId()==greenButton.getId())
{
userColors.add(1);
}
else
{
if(v.getId()==redButton.getId()){
userColors.add(2);
}
else
{
if(v.getId()==blueButton.getId())
{
userColors.add(3);
}
else
{
userColors.add(4);
}
}
}
}
for(i=0;i<randomColors.size();i++)
{
if(randomColors.get(i) != userColors.get(i))
{
Intent i = new Intent( GameActivity.this, GameOverActivity.class);
startActivity(i);
}
}
*/
}
}
}
and this is the java class:
package com.gabie212.simonsays;
import java.util.Random;
/**
* Created by Ronit on 21/02/2018.
*/
public class GameManger {
private GameActivity gActivity;
static Random rnd = new Random();
public GameManger(GameActivity mA)
{
this.gActivity =mA;
}
public int getColor(int size)
{
return rnd.nextInt(4)+1;
}
}
the part i had problems with is this part:
int num;
for (i=0;i<3;i++) {
num = gm.getColor(4);
randomColors.add(num);
}
android.os.Handler handler = new android.os.Handler();
//TODO if the start button is pressed multiple times simultaneously it starts the lightup loop multiple times simultaneously
if (v.getId() == startButton.getId()) {
for (i = 0; i < randomColors.size(); i++) //light up loop
{
switch (randomColors.get(i)) {
case 1:
greenButton.setBackgroundResource(R.drawable.greenlightup);
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
greenButton.setBackgroundResource(R.drawable.green);
}
}, 2000);
break;
case 2:
redButton.setBackgroundResource(R.drawable.redlightup);
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
redButton.setBackgroundResource(R.drawable.red);
}
}, 2000);
break;
case 3:
blueButton.setBackgroundResource(R.drawable.bluelightup);
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
blueButton.setBackgroundResource(R.drawable.blue);
}
}, 2000);
break;
case 4:
yellowButton.setBackgroundResource(R.drawable.yellowlightup);
handler.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
yellowButton.setBackgroundResource(R.drawable.yellow);
}
}, 2000);
break;
}
as i mentioned it lights up the 4 buttons at once instead of doing it in an order and i using functions such as sleep didn't work and the delay mills i used either didn't seem to work either, how do i make it light up the colors in an order (i think its using sleep functions but i am not sure).
I think the problem is that you are starting multiple coroutines all at once (inside the for loop). I guess you are not very familiar with the Runnable interface: everytime a runnable is run, it runs in parallel to your main process, which means that your code keeps going no matter what.
It runs
greenButton.setBackgroundResource(R.drawable.greenlightup);
and sets a timer to run the delayed method. But while this method is waiting the for loop goes on, and
redButton.setBackgroundResource(R.drawable.redlightup);
is executed, and so forth. This is why your buttons are all colored at (almost) the same time. Your delayed methods all fire at (almost) the same time too!
Related
I have tried searching for this topic but i didn't find anything that would help me, so here I am asking this.
I am a beginner so I don't understand a lot of terms and if you answer my question please try to use simple language so I could understand.
I have a condition in that the elements at same position of two lists are compared and if they aren't equal than it jumps to another activity:
if (randomColors.get(i) != userColors.get(i)) {
Intent i = new Intent( GameActivity.this, GameOverActivity.class);
startActivity(i);
}
and it displays an error in debugging that I cannot solve:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gabie212.simonsays/com.gabie212.simonsays.GameOverActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
Please help me, I am a beginner and I don't know what's wrong with my code because I have done exactly as they taught us in class...
Here is the complete code
I know its not the best but its a work in proggress
package com.gabie212.simonsays;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.ArrayList;
public class GameActivity extends AppCompatActivity implements
View.OnClickListener {
private int i = 0;
private Thread t = new Thread();
private Button greenButton;
private Button redButton;
private Button blueButton;
private Button yellowButton;
private Button startButton;
private ArrayList<Integer> randomColors = new ArrayList<Integer>();
private ArrayList<Integer> userColors = new ArrayList<Integer>();
private GameManger gm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gm = new GameManger(this);
setContentView(R.layout.activity_game);
greenButton = (Button) findViewById(R.id.btnGreen);
redButton = (Button) findViewById(R.id.btnRed);
blueButton = (Button) findViewById(R.id.btnBlue);
yellowButton = (Button) findViewById(R.id.btnYellow);
startButton = (Button) findViewById(R.id.btnStart);
startButton.setOnClickListener(this);
greenButton.setOnClickListener(this);
redButton.setOnClickListener(this);
blueButton.setOnClickListener(this);
yellowButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int num;
num= gm.getColor(4);
randomColors.add(num);
android.os.Handler handler = new android.os.Handler();
//TODO if the start button is pressed multiple times simultaneously it starts the lightup loop multiple times simultaneously
if (v.getId() == startButton.getId()) {
for (i = 0; i < randomColors.size(); i++) //light up loop
{
switch (randomColors.get(i)) {
case 1:
greenButton.setBackgroundResource(R.drawable.greenlightup);
handler.postDelayed(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
greenButton.setBackgroundResource(R.drawable.green);
}
}, 2000);
break;
case 2:
redButton.setBackgroundResource(R.drawable.redlightup);
handler.postDelayed(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
redButton.setBackgroundResource(R.drawable.red);
}
}, 2000);
break;
case 3:
blueButton.setBackgroundResource(R.drawable.bluelightup);
handler.postDelayed(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
blueButton.setBackgroundResource(R.drawable.blue);
}
}, 2000);
break;
case 4:
yellowButton.setBackgroundResource(R.drawable.yellowlightup);
handler.postDelayed(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
yellowButton.setBackgroundResource(R.drawable.yellow);
}
}, 2000);
break;
}
handler.postDelayed(new Runnable()
{
public void run() {
}
}, 2000);
}
for(i=0;i<randomColors.size();i++)
{
if(v.getId()==greenButton.getId())
{
userColors.add(1);
}
else
{
if(v.getId()==redButton.getId()){
userColors.add(2);
}
else
{
if(v.getId()==blueButton.getId())
{
userColors.add(3);
}
else
{
userColors.add(4);
}
}
}
}
for(i=0;i<randomColors.size();i++)
{
if(randomColors.get(i)!=userColors.get(i))
{
Intent i = new Intent( GameActivity.this, GameOverActivity.class);
startActivity(i);
}
}
}
}
}
by the its not a simple null pointer exception, at least i don't think so because there is nothing here to be null, there is only a simple intent in an if statement
here's the code for the game over activity
package com.gabie212.simonsays;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.view.View;
public class GameOverActivity extends AppCompatActivity implements View.OnClickListener {
private Button againButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_over);
againButton = (Button) findViewById(R.id.btnStart);
againButton.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Intent in = new Intent(GameOverActivity.this, GameActivity.class);
startActivity(in);
}
}
Thanks in advance.
In your GameOverActivity, on this line:
againButton = (Button) findViewById(R.id.btnStart);
Your againButton is null as you are referencing btnStart from your main activity layout (activity_game.xml). This can't be found because your GameOverActivity is using activity_game_over.xml for its layout:
setContentView(R.layout.activity_game_over);
Any views need to be defined within the activity_game_over.xml file for them to be used by the activity. You need to reference the ID of the button as defined in layout/activity_game_over.xml
againButton = (Button) findViewById(R.id.btnAgain); // Or whatver you've named it
As for your specific question as to why the Intent is not working, the Intent itself is working fine, it's just that GameOverActivity cannot start up properly due to the above issue, and therefore your app crashes.
I want to change the button color dynamically.
After writing, testing and researching, I found that the display thread should be different then the code, so I used a handler.
I am trying to change the color of a button from default to black for some time and then getting it back to default color,
but it is not happening, it just shows a default button.
Following is my code
import android.content.Intent;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
import java.util.Random;
import android.os.Handler ;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button b1;
Random r = new Random();
int random_selection;
int i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1 = (Button) findViewById(R.id.button);
b1.setOnClickListener(this);
main();
}
public void main() {
// Thread t1 = new Thread(new MainActivity());
// this wi run() function
Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
#Override
public void run() {
int count = 0;
try {
System.out.println("inside run");
for (i=0;i<4 ;i++ )
// android.widget.Toast.makeText(getBaseContext(), count,android.widget.Toast.LENGTH_SHORT).show();
Handler handler2 = new Handler();
int x = randomgen();
// android.widget.Toast.makeText(getBaseContext(), x,android.widget.Toast.LENGTH_SHORT).show();
if (x == 1) {
b1.setBackgroundColor(Color.BLACK);
handler2.postDelayed(new Runnable() {
#Override
public void run() {
b1.setBackgroundResource(android.R.drawable.btn_default);
}
}, 10000);
} else if (x == 2) {
b2.setBackgroundColor(Color.BLACK);
handler2.postDelayed(new Runnable() {
#Override
public void run() {
b2.setBackgroundResource(android.R.drawable.btn_default);
}
}, 2000);
} else if (x == 3) {
b3.setBackgroundColor(Color.BLACK);
handler2.postDelayed(new Runnable() {
#Override
public void run() {
b3.setBackgroundResource(android.R.drawable.btn_default);
}
}, 2000);
} else if (x == 4) {
b4.setBackgroundColor(Color.BLACK);
handler2.postDelayed(new Runnable() {
#Override
public void run() {
b4.setBackgroundResource(android.R.drawable.btn_default);
}
}, 2000);
}
}
}catch (Exception e) {
System.out.println("inside catch");
e.printStackTrace();
}
}
}, 1000 );
}
public int randomgen() {
random_selection = r.nextInt(4) + 1;
return random_selection;
}
The reason being is your b1.setBackgroundResource(android.R.drawable.btn_default);
is outside of the delayed handler,
Change your function main to this:
public void main() {
int count = 0;
Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
Handler handler2 = new Handler();
#Override
public void run() {
try {
System.out.println("inside run");
// android.widget.Toast.makeText(getBaseContext(), x,android.widget.Toast.LENGTH_SHORT).show();
b1.setBackgroundColor(Color.BLACK);
handler2.postDelayed(new Runnable() {
#Override
public void run() {
b1.setBackgroundResource(android.R.drawable.btn_default);
}
}, 2000);
} catch (Exception e) {
System.out.println("inside catch");
e.printStackTrace();
}
}
}, 1000);
}
Use a Thread instead:
b1.setBackgroundColor(Color.BLACK);
new Thread(new Runnable() {
#Override
public void run() {
try { System.sleep(2000) } catch(Exception e) {}
runOnUiThread(new Runnable() {
#Override
public void run() {
b1.setBackgroundResource(android.R.drawable.btn_default);
}
});
}
}).start();
I am trying to play with progress bars. I have this (below) simple activity which runs a progress bar N times one after the other, when I call Progress(N). It is working great but the problem I am facing is, if I press back button. I get into the mainActivity but the progress bars (the threads) are still running in background one after the other. As soon as they finish N loops, the intent is called and whatever I would be doing would be interrupted by this LOOP_OVER activity.
I tried solving this by my own. I tried using variable of Thread class (before I was directly doing it). And tried to interrupt() it at onDestroy() or even just before the intent is called but its not helping. How should I go about it?
public class Loop extends Activity {
private ProgressBar progressBar;
private CircleProgress circleProgress;
private int progressStatus = 0;
private Handler handler = new Handler();
private TextView myView;
private int started = 0, doneLoop=0;
private Thread th;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loop);
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
circleProgress = (CircleProgress) findViewById(R.id.circle_progress);
myView = (TextView) findViewById(R.id.instruction);
progressBar.setScaleY(3f);
// Start long running operation in a background thread
Progress(3);
}
#Override
public void onDestroy() {
// Below, everything I am just
th.interrupt();
Loop.this.finish();
Thread.currentThread().interrupt();
super.onDestroy();
}
public void Progress(final int numberOfRuns){
// QueView.setText(Que);
if(numberOfRuns == 0){
th.interrupt();
Intent myIntent = new Intent(Loop.this, LOOP_OVER.class);
startActivity(myIntent);
super.onDestroy();
finish();
}
th = new Thread(new Runnable() {
public void run() {
genNextSet();
while (progressStatus < 100) {
progressStatus += 1;
// Update the progress bar and display the
//current value in the text view
handler.post(new Runnable() {
public void run() {
circleProgress.setProgress(progressStatus);
progressBar.setProgress(progressStatus);
textView.setText(progressStatus+"/"+progressBar.getMax());
}
});
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
myView.setText(Que);
}
});
// Sleep for 200 milliseconds.
//Just to display the progress slowly
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
progressStatus = 0;
Progress(numberOfRuns - 1);
}
});
th.start();
}
private void genNextSet() {
// so some cool here!
}
}
You can think of a class variable that is shared among all threads.
Try to add something like this:
private Boolean LOOP = true;
then
while (progressStatus < 100 && LOOP) {
and
#Override
public void onBackPressed() {
LOOP = false
}
also
if(LOOP == true){
// call intent
}
finish();
Your activity does not get destroyed, if you press the "Back"-key, thus onDestroy() will not be called.I'd override onBackPressed(), if I where you.Alternatively, you could try to put it into the onPause()-method.
You haven't override the back button pressed..try this
#Override
public void onBackPressed() {
th.interrupt();
Loop.this.finish();
Thread.currentThread().interrupt();
super.onBackPressed();
// add finish() if you want to kill current activity
}
In my strings.xml I have 5 strings with text. And I want to be able to change the content of a TextView every 5 seconds.
Example:
First 5 seconds the TextView will show the content of the first string, then next five seconds it will show the second string. And after the fifth string it will show the first string again.
Sorry about this bad description, I'm new in Java.
Try this:
final TextView textView = yourTextView;
final int[] array = {R.string.text1, R.string.text2,R.string.text3,R.string.text4,R.string.text5};
textView.post(new Runnable() {
int i = 0;
#Override
public void run() {
textView.setText(array[i]);
i++;
if (i ==5)
i = 0;
textView.postDelayed(this, 5000);
}
});
new CountDownTimer(25000, 5000) {
public void onTick(long millisUntilFinished) {
mTextField.setText(//question here);
}
public void onFinish() {
mTextField.setText(//End of questions);
}
}.start();
For further Info see this -> http://developer.android.com/reference/android/os/CountDownTimer.html
You can use "Handler" in this
Create a handler in onCreate
`String[] arr = {R.string.value1, R.string.value2,R.string.value3,R.string.value4,R.string.value5};`
Handler mHandler = new Handler();
Now create one Thread and use while loop to periodically perform the task using the sleep method of the thread.
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<5;i++){
try {
Thread.sleep(5000);
mHandler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
textView.setText(arr[i])
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
}
}).start();
I'm a beginner on java and android, and now I'm trying to program the "simon says" game to learn this language, but this doesn't works fine. :-(
The first and most important problem: When I try to show the sequence of colors [number 1 to 4] stored in the array seq[] with the method seq_show().... ho call but_show(x) to change the background color of each button... But I can't see the change of the backgroud color of the corresponding linearlayout...
Also I has erased the READY? source code button because is not closed before seq_show().
I do not understand this java's way to program... is not line by line, step by step... I thing is by threads and I do not understand where the pointer of the executed code is. :-(
Can someone help me ?
Then, in the method seq_input() I catch the click's on the LinearLayout... and I thing this runs fine... but I need to solve the seq_show() problem first to continue with the program.
thanks !!
public class MainActivity extends Activity {
public LinearLayout l1, l2, l3, l4;
public GestureDetector gd1,gd2,gd3,gd4;
public static int seq[] = new int[25];
public int seq_pos = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Array pos[] amb 25 clics del joc simon
//
for (int i = 0; i < 25; i++) {
seq[i] = (int) (Math.random() * 4) + 1;
}
// declaració 4 onClickListener
//
l1 = (LinearLayout) findViewById(R.id.layout_green);
l1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
seq_input(1);
}
});
l2 = (LinearLayout) findViewById(R.id.layout_red);
l2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
seq_input(2);
}
});
l3 = (LinearLayout) findViewById(R.id.layout_yellow);
l3.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
seq_input(3);
}
});
l4 = (LinearLayout) findViewById(R.id.layout_blue);
l4.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
seq_input(4);
}
});
seq_show(0);
}
// Mostra la sequencia de botons a pulsar
//
public void seq_show(int seq_end) {
for (int i=0; i <= seq_end; i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
but_show(seq[i]);
}
}
// Espera la pulsació de la sequencia de botons
//
public void seq_input(int but_pushed){
if (seq[seq_pos] == but_pushed) {
seq_pos++;
but_show(seq[but_pushed]);
seq_show(seq_pos);
}else{
MediaPlayer sound = MediaPlayer.create(this, R.raw.wrong);
sound.start();
new Handler().postDelayed(new Runnable() {
public void run() {
}
}, 1000);
}
}
// Canvia el color i emet un so al botó but_num
//
public void but_show(int but_num) {
if (but_num == 1) {
l1.setBackgroundResource(color.green_on);
MediaPlayer sound = MediaPlayer.create(this, R.raw.tone_green);
sound.start();
new Handler().postDelayed(new Runnable() {
public void run() {
l1.setBackgroundResource(color.green_off);
}
}, 200);
} else if (but_num == 2) {
l2.setBackgroundResource(color.red_on);
MediaPlayer sound = MediaPlayer.create(this, R.raw.tone_red);
sound.start();
new Handler().postDelayed(new Runnable() {
public void run() {
l2.setBackgroundResource(color.red_off);
}
}, 200);
} else if (but_num == 3) {
l3.setBackgroundResource(color.yellow_on);
MediaPlayer sound = MediaPlayer.create(this, R.raw.tone_yellow);
sound.start();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
l3.setBackgroundResource(color.yellow_off);
}
}, 200);
} else if (but_num == 4) {
l4.setBackgroundResource(color.blue_on);
MediaPlayer sound = MediaPlayer.create(this, R.raw.tone_blue);
sound.start();
// SLEEP HERE ...
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
l4.setBackgroundResource(color.blue_off);
}
}, 200);
}
}
Bye !!