How to initialize preference value once in LibGDX? - java

I'm using preferences to save the sound settings in my game as a boolean value. However, when I first start the game, the boolean initializes to false (sound off), because I'm not initializing it elsewhere. I could initialize it to true in the create method, but then the game would just start with sounds on every time you start the game, and that would just defeat the purpose of preferences.
Otherwise it works fine, it's just that I want the boolean to initialize to true the first time you start the game and not every time you restart it.
Is there a way to do this with preferences or do I have to use some other kind of saving method?
Note: this is a desktop application

public Preferences getPreferences() {
if (preferences == null) {
preferences = Gdx.app.getPreferences("myPrefs");
}
return preferences;
}
private void generatePreferences() {
getPreferences().clear();
getPreferences().putBoolean("soundEnabled", true).flush();
getPreferences().putBoolean("notFirstLaunch", true).flush();
}
public void loadPreferences() {
if (!getPreferences().getBoolean("notFirstLaunch")) {
generatePreferences();
} else {
//read the prefs and do your stuff
}
}

I would suggest you a slightly different approach:
Firstly, I think that the perfect place to initialize prefs is create method of the main game class (the one that extends Game):
public void create () {
Prefs.initPrefs();
....other initialization....
}
Then, initPrefs method looks like:
private static final String MUSIC_ON = "music_on";
private static final String LANG = "lang";
public static void initPrefs() {
boolean needChange = false;
if (!pref.contains(MUSIC_ON)) {
pref.putBoolean(MUSIC_ON, true);
needChange = true;
}
//if no lang - select system default
if (!pref.contains(LANG)) {
String language = Locale.getDefault().getLanguage();
pref.putString(LANG, language);
needChange = true;
}
if (needChange) {
pref.flush();
}
}
And finally to toggle the music:
public static boolean isMusicOn() {
return pref.getBoolean(MUSIC_ON);
}
public static void toggleMusic() {
pref.putBoolean(MUSIC_ON, !isMusicOn());
pref.flush();
}

I know this is a few years old now but just in case anyone else was wondering.
I think what you need to do is add a default value to your getBoolean() method without calling flush().
In my game i have a method called isSoundOn() which i call when my sound button is created. The very first time you start your game after installing it, you probably wont have saved a preference which means that the method below has to default to something. if you add true to the getBoolean method then your game should initialize to true.
public boolean isSoundOn() {
return preferences.getBoolean("soundOn", true);
}

Related

Calling a method originated from a switch case from another class

I am relatively new to java and I have been assigned a project. I need to make a rather complicated(for a newbie) battleship game.
Here, I try to call switch cases in class Player from class Tile. Since I've read that one can't directly have access to a switch case, I have made the methods caseSea(), caseShip() e.t.c.
When trying to call them in class Player I get a 'void' type not allowed here error, which I understand but have no idea how to fix!
Any help would be appreciated thanks!
Here is class Tile created to represent one block of a 2D array that will become the battleground board:
public class Tile
{
private int x,y;
static boolean hidden;
public Action tile_action;
public enum Action
{
Sea,
Ship,
Hit,
Miss
}
Action action;
public Tile(Action action)
{
this.action=action;
this.x = x;
this.y = y;
this.tile_action = action;
}
public static void caseSea()
{
System.out.println("~");
}
public static void caseShip()
{
if(hidden == true)
System.out.println("~");
else
System.out.println("s");
}
public static void caseHit()
{
System.out.println("X");
}
public static void caseMiss()
{
System.out.println("O");
}
public static void draw(Action action)
{
switch(action)
{
case Sea:
caseSea();
break;
case Ship:
caseShip();
break;
case Hit:
caseHit();
break;
case Miss:
caseMiss();
break;
}
}
}
Also here is class Player which contains the call to the switch case:
import java.util.Scanner;
public class Player
{
String username; //Variable declaration
static int shotcount;
static int misscount;
static int hitcount;
static int repeatshot;
private int HitPosition[][] = new int[10][10];
public Player(String username)
{
this.username = username;
}
private void placeAllShips()
{
//super.placeAllShips();
}
public void fire(int pos[],int board,boolean hit)
{
if(hit == true)
{
HitPosition[pos[0]][pos[1]] = Tile.draw(Tile.caseHit());
shotcount++;
hitcount++;
}
else
{
HitPosition[pos[0]][pos[1]] = Tile.draw(Tile.caseMiss());
shotcount++;
misscount++;
}
}
}
I get the error that I mention above, in Tile.draw(Tile.caseHit()) and Tile.draw(Tile.caseMiss())
Heh, since this is a relatively simple issue I wanted to stick to comments, but I feel I need to make my voice since the other answers are simply wrong.
What the other guys are suggesting is changing the return type of the methods, and that indeed can work but not with the code you have.
They would ultimately be called twice, and thats not what you want.
The call order would be
caseHit()
pass the caseHit()'s value to draw()
enter a switch inside the draw() method with the Hit enum value and ultimately call caseHit() again.
This is not what you want to do. All you wanna do is call the draw() method with the right argument, which in this case is one of the Action enum values.
So ultimately there is a very easy way to fix your code without much changes and this is changing
Tile.draw(Tile.caseHit());
to
Tile.draw(Tile.Action.Hit);
(and by analogy the other calls of this method)
With Tile.draw(Tile.caseHit()) you are trying to call the caseHit() method and sending the return value of that method as a parameter to the draw() method. The problem is that the caseHit() method isn't returning anything as it has a void return type.
You could fix this by making the caseHit() method return an Action:
public static Action caseHit() {
return Action.Hit;
}

Why won't the if statement detect my game state

I am new to Java and I have come across a "bug" in my code that I am having trouble understanding/fixing. To give you some background knowledge, I set up an Enum that states all the game states (below)
public enum GameState {
IN_LOBBY(true), IN_GAME(false), POST_GAME(false), RESETTING(false);
private boolean canJoin;
private static GameState currentState;
GameState(boolean canJoin) {
this.canJoin = canJoin;
}
public boolean canJoin() {
return canJoin();
}
public static void setState(GameState state) {
GameState currentState = state;
}
public static boolean isState(GameState state) {
return GameState.currentState == state;
}
public static GameState getState() {
return currentState;
}
}
In my main.java class I specify in the onEnable method to set the GameState to IN_LOBBY.
Basically what I am trying to do is in a BlockBreakEvent Listener I want to say is
if (GameState.isState(GameState.IN_LOBBY)) {
Location bLoc = block.getLocation();
ChatUtilties.errorPlayer("You may not break blocks at this time.", player);
bLoc.getBlock().setType(Material.type);
}
In other words I am trying to detect if the GameState is IN_LOBBY and if so make it so that players can not break blocks. But currently two problems have arisen.
For some reason when the GameState is IN_LOBBY the plugin won't even take notice. It just ignores that if statement. It won't even send the message, as if the gamestate was not IN_LOBBY.
I'm not sure how to dynamically change the material based on what block the player broke.
Your setter is wrong:
public static void setState(GameState state) {
GameState currentState = state;
}
You are creating a new local variable currentState here, instead of using the existing field. This happens because you wrote the variable type in front of it, creating a new initialization statement.
Instead use:
public static void setState(GameState state) {
currentState = state;
}
(Since currentState is a static field GameState.currentState = state; would also work in this case)
Edit:
Another problem is with your canJoin method.
public boolean canJoin() {
return canJoin();
}
this method calls itself recursivly without any end condition. So you will get a StackOverflowException if you ever try to call it.
Instead you probably meant to return the canJoin field:
public boolean canJoin() {
return canJoin;
}

How to store variables values in a class i.e "settings"?

OK. After spending literally a few hours trying to get things working I give up.
Basically I am creating a program in which user inputs some values, then after hitting button a new scene is created and depending on the values it was given, different things take place.
My problem - I created "Settings.class" with a few variables with getters and setters. My assumption was to store the values input in there and whenever needed I have easy access to them using getters.
For some reason it doesn't work.
Keep in mind I simplified it as much as I can because It'd look very messy and would be very long if I pasted my original code. I made sure that the core of the problem is the same.
Settings class:
public class Settings {
private boolean diamonds;
public boolean getDiamonds() {
return diamonds;
}
public void setDiamonds(boolean diamonds) {
this.diamonds = diamonds;
}
}
Controller class:
public class Controller implements Initializable {
private Settings settings = new Settings();
private ProblematicOne prob = new ProblematicOne();
public void handleGoAction() throws IOException {
settings.setDiamonds(true);
prob.editText("This shall be set");
/* ..creating new stage and scene here no reason to paste it here, no probs with that.. */
#Override
public void initialize(URL location, ResourceBundle resources) {
}
}
}
And crème de la crème, problematic class:
public class ProblematicOne{
private Setting settings = new Settings();
String toBeEdited = ""; //
public void editText(String text){
if(settings.getDiamonds){ // for some reason it doesn't work; The getter returns false.
toBeEdited = text;
}else if(!settings.getDiamonds){
toBeEdited = "getDiamonds is false";
}
}
}
Alright, first off, what you are trying to do can be achieved by serializing the object (i.e Settings) and storing it. Or, simpler, just write to a file with values and load from there when you want to instantiate the class.
Look at this line in your "ProblematicOne"
private Setting settings = new Settings();
You just created a new instance of Settings. This instance does not have any idea of your Settings instance in your Controller.
Another way is to make your Settings class a singleton and then just reuse it. Example:
Settings.java
public class Settings {
private static Settings instance = null;
private boolean diamonds;
public boolean getDiamonds() {
return diamonds;
}
public void setDiamonds(boolean diamonds) {
this.diamonds = diamonds;
}
private Settings() {}
public static Settings getInstance(){
return instance == null ? new Settings() : instance;
}
}
Then in your Controller class just get the instance using the getInstance() method;
private Settings settings = Settings.getInstance();
Similarly, when you use it again in your ProblematicOne class, use the getInstance() method
Your issue is that ProblematicClass creates a new instance of settings, so the value is not accessible. You need to pass the same instance into the other class, or make your variables in settings class static, so you can access them without instance:
public class Settings {
private static boolean diamonds;
public static boolean getDiamonds() {
return diamonds;
}
public static void setDiamonds(boolean diamonds) {
this.diamonds = diamonds;
}
}
And use it without instance:
Settings.setDiamonds(true);
Settings.getDiamonds();
in the following class with out setting value to settings object, you are trying to use get, which will return default value.
public class ProblematicOne{
private Setting settings = new Settings();
String toBeEdited = ""; //
public void editText(String text){
if(settings.getDiamonds){ // for some reason it doesn't work; The getter returns false.
toBeEdited = text;
}else if(!settings.getDiamonds){
toBeEdited = "getDiamonds is false";
}
}
}
if you want to use the settings object which you created in the controller then pass settings object to editText method in the ProblematicOne class.
The problem is you are instantiating Setting class twice. You set the
settings.setDiamonds(true); //in one instance
and you expect to retrive this value in second instance in class ProblematicOne.
Try to solve this by instantiating Settings only once in Controller class and pass the same to ProblematicOne. Frame your code such that you instantiate
private Setting settings = new Settings();
only once in your whole application. Consider making this class singleton. Read about singleton instantiation here
http://www.javaworld.com/article/2073352/core-java/simply-singleton.html

Check if a boolean is true from another java class

How can I check whether a boolean is true or false from another java class?
menu.class
public class menu extends AppCompatActivity {
TextView textPoints;
Button button2;
public boolean easy;
public void Click(View v) {
if (button2.getText().equals("Svårighetsgrad: Svårt")) {
easy = true;
button2.setText("Svårighetsgrad: Lätt");
}
else {
easy = false;
button2.setText("Svårighetsgrad: Svårt");
GameActivity.class
menu m = new menu();
if (m.easy == true) {
myImageView.setVisibility(View.VISIBLE);
newAndroid();
points = getPoints() - 1;
text1.setText("Poäng: " + points);
}
else {
myImageView.setVisibility(View.VISIBLE);
newAndroid();
points = getPoints() - 5;
text1.setText("Poäng: " + points);
you are developing for Android right?
you should probably use SharedPreference in this case (it would be easier).
use this code to save value:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean("EASY", easy);
editor.commit();
and this code to get the value:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
boolean score = sharedPref.getBoolean("EASY", defaultValue);
If you're just trying to get whether or not a value is true or false, you could either make your boolean public or you could make a getter method.
public boolean getBooleanValue(){
return booleanYouWant;
}
You need a reference on that class in order to do that. The common way of communicating would be the observer pattern for java. Delegation is also a possibility - which will create a double reference, but in Java you usually want to take observer pattern, as it is implemented by default.
You can also have some kind of singleton pattern, to have a global reference of an instance.

Developing Persisent Store in Blackberry Java

I currently have code to share a variable between two entry points in my application. The variable is the iconCount variable used to indicate how many notices the user has which is displayed on the home screen beside the icon. The way I've managed to do this is with a singleton and it (seems) to work fine at the moment. The issue is now that I do not want those notices to reset to zero when I completely turn off and turn on the phone. Should there be 7 notifications, I want there to be 7 notifications even after a device restart. For this I apparently need a persistent store integration which I've researched for a while.
So far my code for the bare singleton is:
public class MyAppIndicator{
public ApplicationIndicator _indicator;
public static MyAppIndicator _instance;
MyAppIndicator () {
setupIndicator();
}
public static MyAppIndicator getInstance() {
if (_instance == null) {
_instance = new MyAppIndicator ();
}
return(_instance);
}
public void setupIndicator() {
//Setup notification
if (_indicator == null) {
ApplicationIndicatorRegistry reg = ApplicationIndicatorRegistry.getInstance();
_indicator = reg.getApplicationIndicator();
if(_indicator == null) {
ApplicationIcon icon = new ApplicationIcon(EncodedImage.getEncodedImageResource ("notificationsdemo_jde.png"));
_indicator = reg.register(icon, false, true);
_indicator.setValue(0);
_indicator.setVisible(false);
}
}
}
public void setVisible1(boolean visible, int count) {
if (_indicator != null) {
if (visible) {
_indicator.setVisible(true);
_indicator.setValue(count); //UserInterface.incrementCount()
} else {
_indicator.setVisible(false);
}
}
}
}
I have been using the blackberry tutorial to figure out how to implement the persistable storage: http://supportforums.blackberry.com/t5/Java-Development/Storing-persistent-data/ta-p/442747
Now before I go any further I must stress I'm very new to java development so my coding might be completely wrong, but here is what I've tried to do:
public void setVisible1(boolean visible, int count) {
if (_indicator != null) {
if (visible) {
_indicator.setVisible(true);
_indicator.setValue(count); //UserInterface.incrementCount()
StoreInfo info = new StoreInfo();
info.incElement();
synchronized (persistentCount) {
//persistentCount.setContents(_data);
persistentCount.commit();
}
} else {
_indicator.setVisible(false);
}
}
}
static {
persistentCount = PersistentStore.getPersistentObject(0xdec6a67096f833cL);
synchronized (persistentCount) {
if (persistentCount.getContents() == null) {
persistentCount.setContents(new Vector()); //don't know what to do with this?
persistentCount.commit();
}
}
}
private static final class StoreInfo implements Persistable{
private int iconCount;
public StoreInfo(){}
public int getElement(){
return (int)iconCount;
}
public void incElement(){
iconCount++; //persistently increment icon variable
}
public void resetElement(){
iconCount=0; //when user checks application
}
}
The code above doesn't work which I'd expect somehow because I'm having trouble implementing the persistent portion. If anyone has any idea or input on how to accomplish this any assistance would be helpful. And of course thanks in advance.
In the example they have a variable called _data that holds the StoreInfo class, so first of all you should be keeping the StoreInfo in some variable. To do this have something like the following in your static initializer:
persistentCount = PersistentStore.getPersistentObject(0xdec6a67096f833cL);
synchronized (persistentCount) {
if (persistentCount.getContents() == null) {
persistentCount.setContents(new StoreInfo());
persistentCount.commit();
}
}
_data = (StoreInfo)persistentCount.getContents();
Now when you want to update it and save to the PersistentStore you can have something like:
_data.incElement();
synchronized(persistentCount) {
persistentCount.setContents(_data);
persistentCount.commit();
}
Assuming you're going to only ever have one instance of StoreInfo it could be better to put the commit code into the modifier methods so you don't forget to save the new values to the PersistentStore.

Categories