Can't get a game loop to work in Android Studio - java

So I understand the basics of java programming but when I'm trying to use my little knowledge in android studio it make everything harder having classes and different files needing to be referenced. Coming from python, when making a simple game I would define different functions, then run them in a game loop like
while running:
or something similar. I know to define something in java you go like
public void Example() {}
but when I use this in java, when I try to run the program my game either instantly crashes or doesnt load anything.
The code at the moment is
public class MainActivity extends AppCompatActivity {
//Variables
Boolean running = true;
public int years = 0;
//Setup Year Counter
TextView textView = (TextView) findViewById(R.id.year_counter);
//Advance Button
public void advance() {
ImageButton button = (ImageButton) findViewById(R.id.advance);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
years += 1;
textView.setText("" + years + "");
}
});
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Game Loop
while (running) {
advance();
}
}
}
And this results in the app not opening.
Any help at all would mean a lot to me.
Thanks in advance :)

Although I don't actually see a crash, since you didn't really upload one, I can see why you might think your app wont work.
What you are doing constantly in the while loop is that you are only setting the button's click listener over and over again.
public class MainActivity extends AppCompatActivity {
//Variables
Boolean running = true;
public int years = 0;
//Setup Year Counter
TextView textView;
ImageButton button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// you set up your views once, after the layout is inflated
setUpViews();
// you initialize your buttons functionality
initClickEvents();
//Game Loop
while (running) {
// do other stuff
}
}
private void setUpViews() {
textView = (TextView) findViewById(R.id.year_counter);
button = (ImageButton) findViewById(R.id.advance);
}
private void initClickEvents() {
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
years += 1;
textView.setText("" + years + "");
}
});
}
}

I'd recommend working with a game engine.
If you want to stick with java, libGDX is an option.
But if language (and IDE) doesn't matter, than a better option is Godot. The reason why I recommend Godot over some of the more popular game engines is because it's open source, 100% free and plus GDScript (godot's scripting language) is heavily influenced by python.
If you want to make you own game engine in java check out this: https://java-design-patterns.com/patterns/game-loop/#
Keep in mind that the while loop is calling the advance method. So every loop you are setting the view for button and then setting an OnClickListener for it. Not everything needs to be in the while loop.

You must implement (override) the render method (it is called in the game loop).
I suggest trying a complete example in the documentation.
``
#Override
public void render() {
ScreenUtils.clear(0, 0, 0.2f, 1);
advance();
...
``

Related

How to Visible/Invisible using OnClickListener?

I am working on FAQ page I don't want to use Expandable list view and stuff.
So I set 2 TextViews(1 for Question and 1 for Answer) and made one clickable.
The above image shows when the first textview mfaq is clicked it sets second one mAns to visible.
The below code works well to Set the mAns textview visible:
public class faq extends AppCompatActivity {
TextView mfaq,mAns;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_faq);
mfaq=findViewById(R.id.faq);
mAns=findViewById(R.id.ans);
mfaq.setOnClickListener(new View.OnClickListener() {
int counter=0; //setting counter to count onclick
#Override
public void onClick(View view) {
++counter; //incrementing counter first click
if(counter==1){
mAns.setVisibility(View.VISIBLE);
}
//this sets mAns visible , but when i click on it again i want it to hide the text view
counter=0; //resetting the counter
}
});
}
}
So I want to set the visibilty to gone when the textview is clicked again(Should function like Click-visible,ClickAgain-Invisible,Repeat).
Note-I am a beginner please try to explain me what the code is doing so I learn more :)
Thanks.
If I understand well you wanna hide/show your textview each time you click on the other text?
mfaq.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mAns.getVisibility() == View.VISIBLE){
mAns.setVisibility(View.GONE);
}
else
mAns.setVisibility(View.VISIBLE);
}
});

Android: App crashes on calling toast from another class [duplicate]

This question already has answers here:
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Closed 2 years ago.
I am a novice Android Developer.
I have created a package-private class which extends Application, and contains the required code for specific functions. I basically want to display if the user-selected button is the correct choice or not, via a toast. Since I have to call this code for many activities, I just created a package-private class for it. However, on clicking the button, the app crashes. Please see the code given below for reference.
I cannot change the onClick method to non-static because if I do that, Android Studio shows an error, and if I change it to static, I am unable to use the method getApplicationContext(), because it is not accessible inside static blocks.
I think that using view.getContext() is causing the crash.
Is there any workaround, or a solution?
Your help would be greatly appreciated. Thanks :)
Here is the code for your reference.
activity.java:
public class activity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(functions.select);
functions.makeLayout(expression, buttons);
}
}
Here is the code which crashes the app.
functions.java:
class functions extends Application {
private static int idx;
public static View.OnClickListener select=new View.OnClickListener() {
#Override
public void onClick(View view) {
int selected_index=(int) view.getTag();
if(selected_index==idx)
{
Toast.makeText(view.getContext(), "Correct.", Toast.LENGTH_LONG).show();
((Button) view).setTextColor(Color.GREEN);
}
else
{
Toast.makeText(view.getContext(), "Wrong.", Toast.LENGTH_LONG).show();
((Button) view).setTextColor(Color.RED);
}
}
};
Okay, I figured out that it was not view.getContext() but the line int selected_index=(int) view.getTag(); which was causing the crash. I solved it first making it into a string and then int by using the following code:
String selected_index=view.getTag.toString();
int sidx=Integer.parseInt(selected_index);

SavedIntanceState.getBoolean() is making my app crash (i think)

My Goal:
So I need help putting a boolean primitives into a bundle and retrieving it from the bundle when there is a screen orientation change in Android. I am using that boolean value in a conditional statement that helps decide if 2 Button views (mTrueButton, mFalseButton) should be enabled or not. What i have so far is causing the app to shut down (aka crash) when there is a screen rotation. I think I am not retrieving or writing my boolean from my bundle or into my bundle correctly, and it is causing the app to crash.
How The App Should Works:
When a user touches the mTrueButton or mFalseButton button to answer a question, both buttons become disabled so the user is not allowed to answer again. I want those buttons to keep being disabled when the user answers and then rotates the screen.**
I know that when a user rotates their Android device, onDestroy() is called because runtime configuration changes take place, causing the app to be relaunched without having knowledge of it's previous state, (unless store my necessary data onto a bundle and pass it onto my onCreate method).
These are SOME global variables in my activity class
private int index = 0;
priavate Button mTrueButton,mFalseButton;
private static final String KEY_INDEX = "index";
private static final String BTTN_ENABLED = "bttnEnabled";
private boolean trueFalseButtonsEnabled = true;
These are SOME statements in my onCreate() method of the same activity class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate(Bundle) called");
setContentView(R.layout.activity_quiz);
if(savedInstanceState != null) {
index = savedInstanceState.getInt(KEY_INDEX, 0);
changeButtonEnableStatus(savedInstanceState.getBoolean(BTTN_ENABLED,true));
}
mTrueButton = (Button)findViewById(R.id.true_button);
mFalseButton = (Button)findViewById(R.id.false_button);
mTrueButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
checkAnswer(true);
changeButtonEnableStatus(false);
}
});
mFalseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkAnswer(false);
changeButtonEnableStatus(false);
}
});
}
These are SOME methods in the same activity class but not in my onCreate()
private void changeButtonEnableStatus(boolean bool){
trueFalseButtonsEnabled = bool;
mTrueButton.setEnabled(bool);
mFalseButton.setEnabled(bool);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
Log.d(TAG,"onSavedInstanceState() called");
savedInstanceState.putInt(KEY_INDEX,index);
savedInstanceState.putBoolean(BTTN_ENABLED, trueFalseButtonsEnabled);
}
Note that:
index = savedInstanceState.getInt(KEY_INDEX, 0);
works properly. It is setting global variable "index" to equal to the int primitive what was stored in into keywork "KEY_INDEX".
However I don't think: changeButtonEnableStatus(savedInstanceState.getBoolean(BTTN_ENABLED,true)); is working properly. My app seems to crash when I include that statement and run the app, and then rotate the device.

ImageView size valid only in onGlobalLayout()

I have a problem with getting the size of ImageView in an android app I'm making. I've read several solutions to this problem and none of them seem to solve my problem. I just want to get the size once at the beginning of the application like in onCreate() before loading anything to the ImageView (When it's empty.) and use it for the rest of my app.
The solution that almost works is the one with getViewTreeObserver().addOnGlobalLayoutListener.
I did that and it is getting me the right size and everything but only in the onGlobalLayout() method. All I want to do is to save that size in some class global variable but everything that happens in onGlobalLayout() stays there. It's like it has no effect on the rest of the class. I can't really write my whole application in that method it's ridiculous. Why is it happening and how can I fix that?
Also I tried the OnFocusChangeListener solution and it gives me the size only if I try to exit the app. As expected the focus is changed but this is not what I need.
Here is the code:
public class Fractaler extends Activity {
int finalWidth;
int finalHeight;
TextView txt;
ImageView fractal;
Fractal mandelbrot;
boolean viewIsMeasured = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initialize();
}
private void initialize() {
txt = (TextView) findViewById(R.id.txt);
fractal = (ImageView) findViewById(R.id.mainImage);
fractal.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (!viewIsMeasured) {
finalWidth=fractal.getWidth();
finalHeight=fractal.getHeight();
viewIsMeasured = true;
mandelbrot=new Fractal("Mandelbrot",finalWidth,finalHeight);
fractal.setImageBitmap(mandelbrot.create());
}
}
});
txt.setTextColor(Color.CYAN);
//txt.setText(String.valueOf(mandelbrot.getWidth())+" "+String.valueOf(mandelbrot.getHeight()));
}
#Override
protected void onStart() {
super.onStart();
}
}

Update Textview from function Android

someone can tell me how to update a control Textview Android from a function? I have searched deep into the internet and see many people who ask the same question, I tested threads but could not work, someone has a simple working example of doing this? for example to call a function (which runs several times in a loop) and the function writes in the TextView, but the problem is that until the function is not finished running, it shows me the text.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
while(condition) //here freezes the UI and the text in textview only shows when the loop ends
{
HardWork();
}
}
public void HardWork() {
txtProgreso.append("Test Line" + "\n\n");
};
Thanks in advance.
If i understood you correctly
Use AsyncTask here, So you can update textview in onProgressUpdate method
private class SomeTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
while(condition) {
//do more
publishProgress("Some text value to you textview");
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
txtProgreso.append(values[0]);
}
}
I think what you're trying to ask is "how do I force my TextView to show its updated contents without returning control to the runloop?" (ie, returning out of your function).
If so, I'm afraid you're out of luck, such a thing is impossible to do with Android's UI model. The nearest thing to this that is possible is to keep track of your loop state, and set a timer that will call a function for you to update the TextView.
Here's an example. Suppose you want to put the text "this is a test" into a TextView, one character at a time:
private Handler mHandler = new Handler();
private String desiredText = new String("This is a test");
private Runnable mUpdateTextView = new Runnable() {
public void run() {
TextView textView = (TextView)findViewById(R.id.myTextView);
int lengthSoFar = textView.getText().length();
if (lengthSoFar < desiredText.length()) {
mTextView.setText(desiredText.substring(0, lengthSoFar + 1));
mHandler.postDelayed(100, mUpdateTextView);
}
}
};
protected void onStart() {
mHandler.postDelayed(100, mUpdateTextView);
}
I think some of my object visibility is incorrect here, and I don't have an Android environment handy to test on, but you get the general idea. Rather than a Handler you could also use a Timer, but it's a bit more heavyweight so it depends how often you want to be updating the UI.
You get the textview by doing the following.
TextView myTextView = (TextView)findViewById(R.id.textViewsId);
Then afterwards, you can change the TextView using the functions. For example, you can set the text using the following code.
myTextView.setText("New text example");
Are there any other updates to the control you are trying to do?

Categories

Resources