I would like to save the player's best score in the game's preferences file. Now, I know I need to call the flush() method in order for the values to get persisted, but I have other values( options) such as "music on/off" and "sound on/off" which I don't want to get saved at all.
So my question is - how can I save only the best score value without saving the other ones?
this a simple test
..//
float score = "your score player actual";
float bestScore = YourPreferences.getFloat("BestScore", -1);
if(bestScore < score){
YourPreferences.putFloat("BestScore", score).flush();
}
Related
i've made an app that implements augmented reality based on POI's and have all the functionality working for one POI but i would now like to be able to put in multiple points. Can any give me advice on how to do this ? Can i create an array of POI's ?? posted my relevant code below but don't really know where to go from here.
private void setAugmentedRealityPoint() {
homePoi = new AugmentedPOI(
"Home",
"Latitude, longitude",
28.306802, -81.601358
);
This is how its currently set and i then go on to use it in other area's as shown belown:
public double calculateAngle() {
double dX = homePoi.getPoiLatitude() - myLatitude;
double dY = homePoi.getPoiLongitude() - myLongitude;
}
and here:
private boolean isWithinDistance(double myLatitude, double myLongitude){
Location my1 = new Location("One");
my1.setLatitude(myLatitude);
my1.setLongitude(myLongitude);
Location target =new Location("Two");
target.setLatitude(homePoi.getPoiLatitude());
target.setLongitude(homePoi.getPoiLongitude());
double range =my1.distanceTo(target);
double zone = 20;
if (range < zone ) {
return true;
}
else {
return false;
}
}
Any help would be appreciated.
Using a List would be a smart idea. You could add all entries into it in code, or you could pull them in from a JSON file. When you're rendering them, you could check if they are in range.
If you have a lot of these POIs, you should divide them into smaller and smaller regions, and only load what you need. For example, structure them like this:
- CountryA
+ County 1
* POI
* POI
- CountryB
+ County 1
* POI
* POI
+ County 2
* POI
Get the country and county of the user, and only load what you really need. I assume this is a multiplayer game, so I'll share some of my code.
On the server side, I have 3 objects: Country, County and POI.
First I discover all countries on the disk, and make an object for it. Inside my country object I have a list for all counties, and inside my County object I have a list of POIs. When a player joins, they send a packet with their Country and County, and I can select the appropriate POIs for them. Storing them in smaller regions is essential, or your server will have a hard time if you go through all of the POIs for every player.
Here is my method for discovering data: Server.java#L311-L385
Code for selecting POIs for a player: Server.java#L139-L181
And how you can render it: PlayScreen.java#L209-L268
You need to port it to your own app, and I'm probably horrible at explaining, but I hope you got something out of it.
I have a score board like so :
int time = 15;
private ScoreboardManager sbManager;
private Scoreboard scoreBoard;
private Objective obj;
private Score s0;
public void init(Player player) {
sbManager = Bukkit.getScoreboardManager();
scoreBoard = sbManager.getNewScoreboard();
obj = scoreBoard.registerNewObjective("ScoreBoard", "dummy");
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
obj.setDisplayName("Test");
s0 = obj.getScore(Bukkit.getOfflinePlayer("Time = " + time));
s0.setScore(6);
player.setScoreboard(scoreBoard);
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable(){
public void run() {
time--;
updateScoreBoard(player);
System.out.println(time);
}
},20, 20);
}
And whenever I try to update it, it just dosen't work and btw my score board is a "fancy" one, so it should look like :
Time = time 6 <- the '6' is the default minecraft score.
Here's an example of my update method:
public void updateScoreBoard(Player p){
s0 = obj.getScore(Bukkit.getOfflinePlayer("Time =" + time));
s0.setScore(6);
p.setScoreboard(scoreBoard);
}
Because you're using scoreboards in an unconventional way, things are bound to get tricky. By "fancy" I assume you mean the scoreboards which display a score's name and value right next to each other on the left side, which is done by placing the actual score value inside the name String of the score (like you have already done).
The problem with your code specifically is that you are not actually changing the value of the existing score entry (since that value is set to 6 to keep the entry in the same row of the display) but creating a new score entry every time you update the display, since score entries are identified by their name and not their score value (this is required so that different score entries can have the same value, for example a player can have a "bank balance" score with a value of 2 and an "amount of deaths" score with a value of 2).
If this weren't the case for example, your new score entry with name "Time = 14" and a score value of 6 would override the previous score entry with name "Time = 15" because of the identical score value, but this is not the case.
When I tested your code snippet, more rows (score entries) were added until the display filled to maximum capacity. I can only assume this is what you meant by your code "acting weird" since you didn't elaborate on the expected and observed results of your code.
You'll want to remove the previous score entry with the outdated value. Because the API is not intended to be used this way, one cannot simply remove a score entry from an objective (resetting the score doesn't remove the entire entry).
You'll therefore need to create a new scoreboard with a new objective etc. every time you want to update a single "fancy" score entry. This also means that all scores displayed in the scoreboard need to be kept track of independently and re-added and re-set to the new scoreboard whenever any other "fancy" score is updated.
These changes to your updateScoreboard method did the trick for me:
public void updateScoreBoard(Player p) {
scoreBoard = sbManager.getNewScoreboard();
obj = scoreBoard.registerNewObjective("ScoreBoard", "dummy");
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
obj.setDisplayName("Test");
s0 = obj.getScore(Bukkit.getOfflinePlayer("Time = " + time));
s0.setScore(6);
p.setScoreboard(scoreBoard);
}
Note that this method only fixes the immediate issue of more entries being added, if you want more "fancy" and possibly even normal score entries, all of those will need to be handled respectively.
All this extra work and having meaningless numbers/values always on the right of the display seem like a large trade-off just to remove a little whitespace between a score's name and value.
Some other tips: You don't need to update the sbManager variable every time you initiate the scoreboard for a new player, the manager is always the same object, so using Bukkit.getScoreboardManager() once should suffice.
I have a double value which is in the range of 0-1. The new highscore value should be the lesser value of the two. Basically for example: if user A had a previous highscore of 0.6, and he just scored 0.4, the new highscore should be 0.4. Please be descriptive as I'm a beginner, thank you.
EDIT: Sorry I didn't make it descriptive enough, but I want the highscore to be saved and be able to be accessed again. So, if the user exits the app and revisits, it still shows the highscore.
It sounds like you'll want to use Shared Preferences to store the value for later: http://developer.android.com/training/basics/data-storage/shared-preferences.html, and then check this when you go to save it.
Here is sample code so you can call writeHighScore(score), and it will save it if it is lower than the previously saved high score:
void writeHighScore(float score)
{
if (score < getOldHighScore())
{
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putFloat("highscore", score);
editor.commit();
}
}
float getOldHighScore()
{
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
return sharedPref.getFloat("highscore", 1);
}
I used a float here instead of a double. If you want to store a double with shared preferences, you'll need to convert it to and from a Long, like here: Can't put double SharedPreferences
I am working on a map based data visualization project that scrapes data from an XML file. Locations are placed on a map based on geo location and locations are interactive with mouse clicks that will then display information about the location. I need to start filtering the results based on information about each location. Ex: lets say the i want to display information about trees and i know their location and their type. I would want to filter in and out walnut, cherry, oak using check boxes.
I am trying to plan out how to attack this problem from a design standpoint. Currently the all information is pulled directly from the XML file with very little going into new Arrays/Lists. Any recommendations as I am trying to conquer this task? If you need me to elaborate more or want any more information please let me know.
EDIT:
I'm sorry if this is vague, I'm not entirely sure how to ask the question. So right now I am taking 311 data and putting information into Array's based on the information I want to display. So lets say I want get an address. (At this point a map has been populated with all of the individual locations from the 311 data lets say 200 spots) I click one location, and that location is tied to an index in an array that has all of the addresses. So at any time I can use an index to get information from an array. There are multiple arrays holding information like address, report type, time, etc. I want the locations on the map to be sorted by the report type. I hope this makes more sense.
I hope I understand correctly, this seem like a regular data management system requirements, it will be hard to cover these kind of systems in a few words, but in a nutshell I'd say that those systems are divided into layers:
data layer, usually some database, try to install and use a database like mysql
data access layer, I understand you're using java, consider using hibernate that will let you describe and use your database using objects rather than RDBMS tables, here you would also have sql / hql queries
some business layer to have the logic on top of these dummy data objects, or maybe connect to some external service
serve this data to you client, whatever it runs on, if its a Java client or a web browser
Check out java spring http://projects.spring.io/spring-framework/ on how its done in practice.
Then, if you feel like going back and forth to the server for more data is too much on performance you may decide to cache some of the information in the client side.
Last, always remember Donald Knuth saying
about 97% of the time: premature optimization is the root of all evil.
Are you using processing tag for Processing.org right? If I understand you, isn't the case of make an object that group all data relative to one location, and when needed retrieve the info using a getter or even dot notation? I though of something like:
class Local(){
String name;
String address;
//whatever else...
float mapPosX, mapPosY;
boolean ispressedOver(){
//return if mouse over
}
}
create Locals using XML data, store in an array of Local, and when mouse pressed get it
if (localsArray[i].isPressedOver){display(localsArray[i].address);}
this would be a very simple example of the idea except for the xml parsing to an
Place[] places = new Place[4];
void setup() {
size(600, 400);
noStroke();
places[0] = new Place ("one", "That street, 12 - BR", 0.32044, 0.230098, 200, 98);
places[1] = new Place ("two", "This street, 35 - UG", 0.22222, 0.084723, 394,176);
places[2] = new Place ("three", "Other street, 132 - TY", 0.32321, 0.36388, 157, 283);
places[3] = new Place ("four", "Principal street, 672 - OP", 0.909044, 0.7828939, 276, 312);
}
void draw() {
background(75, 16, 160);
for(Place p:places){
p.display();
}
}
class Place {
String name;
String address;
float latitude;
float longitude;
float xPos;
float yPos;
float sz = 40;
Place(String n, String a, float lat, float lng, float x, float y) {
name = n;
address = a;
latitude = lat;
longitude = lng;
xPos = x;
yPos = y;
}
void display() {
fill(200, 210, 100);
rect(xPos, yPos, sz, sz);
if (isOver()) {
String quick = name + " - " + address + " - " + latitude + " - " + longitude ;
fill(0);
text(quick, xPos - textWidth(quick)/2, yPos - 10);
}
}
boolean isOver() {
return (mouseX > xPos && mouseX < xPos + sz && mouseY > yPos && mouseY < yPos + sz);
}
}
In following link I pasted a code I'm working on. It is not displaying anything. But I does get XML data and build objects based on them. For now the output is in the console. I don't know if is going to help much. Most variables names are in portuguese :P And it is not commented... But it works. You can run it. it gets the xml from an API in the web. There are two classes, don't bother with Query. It is necessary to get the xml, but not related to your question. The Prop class is the data holder. It gets an xml as parameter and parse it's fields to member vars. For now there is only one method. toString() used to display data to the console.
http://pastebin.com/8gGDsFAv
I wanted some feedback on this approach. My apologies if this is confusing or nonsensical. (thats probably why I'm asking because im unsure.)
My app auto assigns clientID's to a textview at first launch - is auto set to 100. To do this from that point forward I store an int value to sharedpreferences. At Oncreate I run a check against this specific ID in the sharedpreferences and later it either increments or assigns back to 100. The challenge was that sharedpreferences (that I know of) can only take a string value i.e. (editor.putString("CLIENTID", ID);) or editor.putInt("ID", c);
I wanted to avoid using a database for this portion to minimize overhead (could be wrong) There are validations in place that prevent this from being incremented unless certain conditions are met.
c is my persisted counter used in the shared preferences.
Here's what I did at oncreate:
public String ID; //global
int checkCount = prefs.getInt("ID", c); //get the current ID value currently set or last set.
if( checkCount > 100)
{
c = checkCount; //whatever the value of c is from its latest increment the counter c set to this
}
else if (checkCount <= 100)
{
c = 100; //base value of clientIDs //assign base value for starting clientIDs
}
ID = "" + c + ""; //sets value of the counter to a string
//Parsing integer was not passing correctly.
clientID.setText(ID);
In the onclick:
//Once all the conditions are met pass the clientID for this instance.
SharedPreferences.Editor editor = prefs.edit(); //USING EDITOR TO ADD TO THE PREFERENCES
editor.putInt("ID", c);
....// then other stuff.
Any thoughts? My apologies if this is a noob question. I just want to be sure about this approach if this app goes all the way.
Thanks