Highlight buttons one at a time - android

I am making an Android game modeled after the old Simon game. It is a little different in the layout as it is using a 3x3 layout of buttons. I am trying to get the buttons to light up one at a time inside the loop that randomly selects a button. The trouble I have is that all of the buttons light up at once and only the last (or first, not sure) changes back to the original color. I have tried very thoroughly to find an appropriate answer to my situation but have had no luck here or elsewhere. The button id(s) are in the butts[]. butts[0] is button 1, butts[2] ... Below is my attempt.
public void play()
{
for(int x = 0; x <= numButtons; ++x)
{
spot = randomGenerator.nextInt(9);
playMe[x] = spot;
//butts[spot].setBackgroundColor(Color.parseColor("#540115"));
handler.postDelayed(new Runna(spot), (x+1)*1000);
}
}
class Runna implements Runnable
{
public Runna(int j2)
{
butts[j2].setBackgroundColor(Color.parseColor("#540115"));
}
public void run()
{
butts[spot].setBackgroundColor(Color.LTGRAY);
}
}

I think it has to do with the value of spot. It is global to the functions and you change it every time. It runs, but at the end there is still only one spot and EVERY runnable is trying to change that same spot.
Perhaps save spot in your runnable?
class Runna implements Runnable
{
int s;
public Runna(int j2)
{
s = j2;
butts[s].setBackgroundColor(Color.parseColor("#540115"));
}
public void run()
{
butts[s].setBackgroundColor(Color.LTGRAY);
}
}

Have you tried to invalidate the button each time?
public Runna(int j2)
{
butts[j2].setBackgroundColor(Color.parseColor("#540115"));
butts[j2].invalidate();
}

Related

How to obtain the expected order of actions in my game loop?

I don't fully understand what is going on behind the scene, and therefore, what I can do to correctly code this issue. I'm looking for an explanation that will lead me to figure it out myself. This is just a fun home based project(I'm not a student), where I'm coding a turn based app. However, the battle scenes are randomly calculated durations, rather than turn based, so my desire is as follows:
Present initial battle count on screen for 2 seconds
Calculate first skirmish
Present updated battle count on screen for 2 seconds
Calculate 2nd skirmish
...
...
Present Victory or Defeat on screen
The problem I'm having is that the app is performing as follows currently:
Present initial battle count on screen
Calculate all skirmishes
Page displays null for the number, since it's apparently already returned?
Code looks like this:
void fightBattle(){
setContentView(R.layout.brigands);
boolean winnerDetermined = false;
while(!winnerDetermined) {
boolean brigandsWon = brigandsWon(player, brigandCount);
if(brigandsWon) {
player.removeWarriors(2);
}
displayWarriors(player);
if(brigandsWon){
if(player.getWarriors() < 2){
winnerDetermined = true;
}
}
if(!brigandsWon) {
brigandCount = brigandCount / 2;
}
displayBrigands();
if(brigandCount == 0){
winnerDetermined = true;
}
}
}
private void displayWarriors(Player player){
final Player currentPlayer = player;
new CountDownTimer(2000, 2000) {
public void onTick(long millisUntilFinished) { }
public void onFinish() {
setContentView(R.layout.warriors);
TextView warrior_count_tv = findViewById(R.id.warrior_count_tv);
warrior_count_tv.setText(currentPlayer.getWarriors());
}
}.start();
}
private void displayBrigands(Player player){
new CountDownTimer(2000, 2000) {
public void onTick(long millisUntilFinished) { }
public void onFinish() {
setContentView(R.layout.brigands);
TextView brigand_count_tv = findViewById(R.id.brigand_count_tv);
brigand_count_tv.setText(Integer.toString(brigandCount));
}
}.start();
}
Ultimately, what I want to see is something like the below sudo-code:
displayPage1For2Seconds;
while(somethingIsTrue){
calculateNumber;
displayPage2For2Seconds;
displayPage3for2Seconds;
}
displayPage4For2Seconds;
Calculate all skirmishes
Your current code does this because the while loop doesn't actually stops to wait. The flow will be like this:
enter while loop -> call displayWarriors() -> create CountDownTimer() to do something after 2 seconds -> return to while loop -> call displayBrigands() -> create CountDownTimer() to do something after 2 seconds -> return to while loop -> do the same until you exit while
With this code you'll end up with a bunch of CountDownTimers that are created and executed at the same(almost) time so after two seconds they all try to set a view to some value(with an indefinite behavior like you mention it happens).
There are several ways to do what you want. You could use a Thread for example:
void fightBattle(){
setContentView(R.layout.brigands);
new Thread(new Runnable() {
public void run() {
// I assume R.layout.brigands is the initial screen that you want to show for 2 seconds?!? In this case wait 2 seconds
TimeUnit.Seconds.sleep(2);
boolean winnerDetermined = false;
while(!winnerDetermined) {
// ...
// from your code it seems you want to show this for 2 seconds?
displayWarriors(player);
TimeUnit.Seconds.sleep(2);
//...
displayBrigands();
// also show this for 2 seconds
TimeUnit.Seconds.sleep(2);
// ...
}
}
}).start();
}
Then your display methods will be something like this:
private void displayWarriors(Player player){
// you need to wrap this code in a runOnUiThread() method(from the activity)
// because we are on a background thread and we are changing views!
final Player currentPlayer = player;
setContentView(R.layout.warriors);
TextView warrior_count_tv = findViewById(R.id.warrior_count_tv);
warrior_count_tv.setText(currentPlayer.getWarriors());
}
Another approach would be to use a Handler and break your code in Runnables that you then schedule at appropriate times.

Attaching a Rect to imageview so it follows it through infinite animation loop

I cant seem to figure out how to move my rects along with an imageview I am animating to use as a hit box. I have it detecting collisions with intersects but it just stays at the starting position of the image.
The first way I cracked at it was by using the getOnScreenLocation() and storing that in a variable to use .offsetTo() on the rect to move it with the image but that only moved the hitbox to the end of the animation and that was it. I have my hitbox movements and checking for collisions inside a seprate thread updating the UI frequently.
So my question is how can I get the rect hitbox to just stay attached to the imageview as it is animated across the screen? Any and all advice helps even if its just a method i should look into thank you.
Here is the latest version of my moveHitbox(), still it's not functioning correctly.
public void hitBox()
{
//declaration of rectangles around each image
getHits();
moveHitBox();
//see if rectangle around rocket intersects enemy ships rectangle
if (Rect.intersects(myViewRect, otherViewRect1)||Rect.intersects(myViewRect,
otherViewRect2) ||Rect.intersects(myViewRect, otherViewRect3)) {
check();
//immunity();
}
}
public void moveHitBox()
{
int YYY = (int)enemy_ship.getTranslationY();
int XXX = (int)enemy_ship.getTranslationX();
enemy_ship.setTranslationY(YYY);
enemy_ship.setTranslationX(XXX);
enemy_ship.getLocationOnScreen(thisLocation);
enemy_ship2.getLocationOnScreen(thisLocationA);
enemy_ship3.getLocationOnScreen(thisLocationB);
x.getLocationOnScreen(thisShipLocation);
otherViewRect1.union(thisLocation[0],thisLocation[1]);
otherViewRect2.union(thisLocationA[0], thisLocationA[1]);
otherViewRect3.union(thisLocationB[0],thisLocationB[1]);
}
// Separate thread that updates the ui thread
Runnable myRunnable = new Runnable() {
#Override
public void run() {
while (testByte == 0) {
try {
Thread.sleep(3); // Waits for 1 second (1000 milliseconds)
}catch(InterruptedException e)
{
finish();
}
enemy_ship.post(new Runnable() {
#Override
public void run() {
hitBox();
}
});
}
}
};

Android use thread to draw every 4 seconds

I am quite new to Android and want to create a simple game.
Therefor i need a thread which is drawing a transparent Rectangle on different positions every 4 seconds with a 2 second break (without drawing).
I got it working with a "recursive" thread calling a new instance of itself with handler.postdelayed.
My feeling about threads tells me, that this isn't a very nice way...
While searching here for similar topics, i found out about the Timer construct. Can i use this for my problem?
Is there a better way to do this?
(edit) The thread is meant for highlighting part of the gameboard, but only for 4 seconds. After that there should be 2 seconds without highlighting. Then 4 seconds highlighting the next part of the board etc.
(edit2) I couldn't use sleep, because it froze my UI. If anyone has a similar situation, here is how i solved it:
public class myRunnable implements Runnable {
private int duration;
private int counter;
private boolean highlight;
public myRunnable(int duration, boolean highlight) {
this.duration = duration;
this.highlight = !highlight;
}
#Override
public void run() {
if (highlight) {
// highlight 4s long
highlight();
invalidate();
myThread = new myRunnable(duration, highlight);
postDelayed(myThread, duration);
} else {
// pause (2s)
resetHighlight();
invalidate();
myThread = new myRunnable(duration, highlight);
postDelayed(myThread, noHighlightDuration);
}
}
}
The Best way to do this is use to use invalidate() to call the onDraw() function and a method to update the position. Something like this-
int x,y;
protected void onDraw(Canvas canvas) {
x=10;
y=10;
canvas.drawRect(___);
update();
invalidate();
}
private void update()
{/*Change the x and y/*}
Here everytime inavlidate() is called from anywhere the onDraw() is called again with the new x and y.

Simultaneous, linked threads in android

I'm working on a math game which presents the player with a simple math problem of the sort 4 + 3 = ? or 6 / 2 = ?. The player is offered 4 possible answers and clicks one. The screen has two buttons, one with an arrow, and one with a square.
The player selects the answer they think is correct. If the answer is correct they get a message. If the answer is incorrect, that choice is grayed out, and they can keep choosing until they get it right.
I want two modes of play: practice and timed.
In practice mode, the player clicks the arrow button and gets a new question. This works fine.
I also want a timed play mode. When the player presses the arrow button, a timer starts and the first problem comes up. If they get it right, they are immediately asked a new question. Again, if they are incorrect, they keep asking until they get it right. Meanwhile, there should be a timer counting down. Play stops when the timer ends or the player presses the square button.
I don't know how to do the timed play where there are two simultaneous activities: playing the game, and the timer.
I'm including pseudo-code instead of code -- the code is long. But if necessary, I can post the entire code.
Update:
This was my naive attempt. The problem is that I can't figure out how to wait in the while loop for until the player to ask the question before askQuestion() is called again. Perhaps it needs to be in a separate thread and have the while loop wait for that thread to return. Would the timer keep going? I want the timer to run simultaneously to a separate task in which a question is posed --> Player answers the question --> a new question is posed .....
public void playTimed()
{
// Toast.makeText(getApplicationContext(), "in playPractice", Toast.LENGTH_SHORT).show();
go_button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
go_button.setEnabled(false);
new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished)
{
timer.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish()
{
timer.setText("done!");
go_button.setEnabled(true);
timer_done = true;
}
}.start();
while(!timer_done)
{
askQuestion();
}
}
});
}
onCreate()
{
-For all four answer buttons:
answer_button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
correct = checkAnswer(answer_button_id);
}
});
-get intent extras to know which game
-swith-case to play selected game
}
checkAnswer()
{
if (correct)
{
// feedback
handleRightAnswer();
}
else
{
// feedback
handleWrongAnswer();
}
}
askQuestion()
{
-choose type of problem (+,-,*,/)
-generate arguments and answer
-create random answer list
where one choice is correct
-display problem
-display answer choices
}
playTimed()
{
-When player presses go_button,
timer starts and first question
appears. When correct answer is
selected a new question immediately
appears. Continues until timer runs
out or player presses stop_button.
Seconds left is displayed during play.
}
playPractice()
{
//When player presses go_button
// a new question appears.
go_button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
askQuestion();
}
});
}
As Gabe Sechan stated, you can do this using a timer to update a counter, then when the counter hits 0, do something. You can also use the timer to update a TextView (to display the time remaining).
Here is a class that I have used in the past, originally found here:
public class UIUpdater{
private Handler mHandler = new Handler(Looper.getMainLooper());
private Runnable mStatusChecker;
private int UPDATE_INTERVAL = 1000; //updates every second
public UIUpdater(final Runnable uiUpdater) {
mStatusChecker = new Runnable() {
#Override
public void run() {
// Run the passed runnable
uiUpdater.run();
// Re-run it after the update interval
mHandler.postDelayed(this, UPDATE_INTERVAL);
}
};
}
public UIUpdater(Runnable uiUpdater, int interval){
this(uiUpdater);
UPDATE_INTERVAL = interval;
}
public synchronized void startUpdates(){
mStatusChecker.run();
}
public synchronized void stopUpdates(){
mHandler.removeCallbacks(mStatusChecker);
}
}
Then, in your method where you want to update your counter, you would put:
UIUpdater mUIUpdater = new UIUpdater(new Runnable() {
#Override
public void run() {
//method to update counter
}
});
//to start the method:
mUIUpdater.startUpdates();
//to stop the method, ie, when counter == 0
mUIUpdater.stopUpdates();

Simple flip card game in Android using layouts instead of a surfaceview?

My project is to create a flip card game in Android like http://partyhatmy.blogspot.kr/2012/08/angry-bird-matching-card-game.html. The differences are that there will be 3 x 4 total 12 cards on the screen, and the game will have a timer. So if the timer expires or if the user finds all pairs, the new stage begins.
My problem is that I do know how to implement this using SurfaceView, but since all cards are at fixed positions, I think it might be possible to implement the game using layouts in xml, but I don't know how. Is there any starting point resource available on the web?
Edition 1
My Code is like this: I just first want to print the remaining time to one TextView to the screen. The problem is that the screen is all black (without runOnUiThread() invocation, the activity draws the given layout activity_game flawlessly.
public class GameActivity extends Activity {
private TextView mTimerTextView;
private int mRemainingTime = 30;
#Override
protected void onCreate(Bundled savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_game);
mTimerTextView = (TextView)findViewById(R.id.remaining_time);
this.runOnUiThread(new Runnable() {
public void run() {
long lastSystemTime = 0;
mTimeTextView.setText(String.valueOf(mRemainingTime));
while (mRemainingTime > 0) {
if (lastSystemTime == 0) { // initial run
lastSystemTime = System.currentTimeMillis();
continue;
}
long currentTime = System.currentTimeMillis();
long elapsedTime = currentTime - lastSystemTime;
lastSystemTime = currentTime;
if (elapsedTime > 1000) {
mRemainingTime--;
mTimeTextView.setText(String.valueOf(mRemainingTime));
}
// To avoid excessive loop
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
}
see this link it will help you with flip animation
Displaying card flip animation on old android
or
http://www.techrepublic.com/blog/software-engineer/use-androids-scale-animation-to-simulate-a-3d-flip/
use this coode to do changes in ui thread
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
//do ui changes here
}
});

Categories

Resources