Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am making a space shooter for my final year project and thought it will be cool to include a local score/ High score screen. I don't know how to go about this and would really appreciate if someone can point me in the right direction, all the examples I found online look very complex to me. Also I want the score to be displayed on the game screen which is rendered with opengl es.
Thanks.
I have just finished creating a high score board for my OpenGL ES game that I'm currently working on. As it's for your final year project I won't be using this as a pastebin, but instead give you some pointers. In my application the scores are sent to my PHP script which stores values in MySQL.
What I used:
new class which handles everything to do with high scores
AlertDialog "alertName" - to ask for player name
EditText "input" added to the dialog with alertName.setView(input);
submitting the score to the server using an AsyncTask
this could be replaced with other Data Storage options, either internal, external, or SQLlite db
When the game is over (all lives gone, timer up, etc) I use a line of code, not too de-similar to this:
HighScore hs = new HighScore(context, score, level);
The context is required so AlertDialogs and Toasts can be created. The constructor calls the function submit() which shows the AlertDialog asking for the player name, then sends the data to the server.
My class contains this line of code to let the player know if they reached the top 100 after a response was received from the server:
Toast.makeText(mContext, "You didn't make the score board",
Toast.LENGTH_SHORT).show();
The high score list is stored in an ArrayList
private ArrayList<String> highscores = new ArrayList<String>();
And the data is padded using String.format in a similar fashion to this:
highscore_headers = String.format("%7s","rank") +
String.format("%11s","name") +
String.format("%10s","score") +
String.format("%5s","lvl");
And Then:
within your Renderer's onDrawFrame you could build the highscore class so you could call something like the one liner below, which would contain your translations, scales pushMatrix and popMatrix calls to draw the highscore data to the screen.
hs.draw(gl);
Which contains a loop, not too dissimilar to this:
for(int i=0; i<highscores.size(); i++){
text.drawText(gl, highscore.get(i).toString());
gl.glTranslatef(0f, -0.8f, 0f);
}
Note: Text is a class I wrote to draw various textures on the screen
depending on the char value of each character, which is then
translated to a set of x,y coordinates which relate to my
character map image file.
Hope this helps to push you in the right direction, and best of luck with your project
A screenshot of my android app's high score state rendered using OpenGL ES
EDIT: Sending Scores to PHP
This won't be an exact copy and paste of my source, but hopefully there will be enough information here to give you the general idea of it all. My final code also gives the device a uniqid, which users can track all of their scores that have been stored in the database - but that's something else.
php file:
I did mess around with signing requests, hashing scores, but for the purpose of my beta and getting the game published quicker I opted for just plain text entries. The code below, also does not detail highlighting the players submitted score, or getting rank based on time.
if(isset($_POST['name']) && isset($_POST['score'])){
$sql = "INSERT INTO highscores(name, score) VALUES (:name, :score)";
$data = array(":name"=>$_POST['name'], ":score"=>$_POST['score']);
$db->run($sql, $data);
echo display();
}
function display(){
$sql = "SELECT name, score FROM highscores ORDER BY score DESC";
$result = $db->run($sql, array());
return json_encode($result);
}
It should be noted that the $db object is a small class I made to wrap PDO methods prepare and execute, which return results as associative arrays
HighScore Android Class:
again, i won't copy/paste but this will illustrate how to post data to a server, receive a JSON string, then pad the string and add it to the highscores ArrayList. The code below is the constructor for the HighScore class, it asks for the users input.
List<NameValuePair>nameValuePairs = new ArraList<NameValuePair>(2);
AlertDialog alertName;
DefaultHttpClient client = new DefaultHttpClient();
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String response = "";
HighScore(Context context, int score){
nameValuePairs.add(new BasicNameValuePair("score", + score.toString()));
alertName = new AlertDialog(context).create();
EditText input = new EditText(context);
alertName.setTitle('Enter Your Name');
alertName.setButton(AlertDialog.BUTTON_POSITIVE, "OK",
new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int which){
nameValuePairs.add(
new BasicNameValuePair("name", input.getText().toString())
);
SubmitAsync sa = new SubmitAsync();
sa.execute();
}
});
alertName.show();
}
The SubmitAsync class is a subclass of the HighScore class, it will setup the http client to send data, and add the received data. The data is digested as JSON and strings are padded as mentioned previously, then added to the highscore ArrayList
class SubmitAsync extends AsyncTask<String, Void, Void>{
#Override
protected Void doInBackground(String... params){
HttpPost postMethod = new HttpPost("http://address-of-script.php");
postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs));
response = client.execute(postMethod, responseHandler);
JSONArray jsonArray = new JSONArray(response);
for(int i=0; i<jsonArray.length(); i++){
JSONObject j = jsonArray.getJSONObject(i);
String name = String.format("%11s", j.get("name"));
String score = String.format("%10s", j.get("score"));
highscores.add(name + score);
}
}
}
That's the very basics and alot more code than I would have liked to have entered onto here at any one time, and most definitely my longest post ever. I would seriously consider the comments of #Dan, and research local storage over my server based approach to a highscore board
These code snippets will likely not work if copied and pasted. So please try to understand them and code yourself :)
Well, write a file with the high-scores in whatever format u want (like Name, score, date etc.) easier for u to parse later. And then, keep on editing it every time u want to write a new score. Blindly read it and display it.
I alerady do that in a same kind project, I do a list of object. This object represent one high score. If I need to store the list of High Scoren, I serialize the list and if I need to display it, I deserialize this file.
Related
Good afternoon everyone.
I work in a chemistry lab at a university. I'm trying to create an app where the user puts in some sample data and the app performs some statistical calculations.
I would like some help with the following:
Create a method that takes the amount of samples as a parameter and creates a TextView and an EditText for each sample, one below the other.
Below is what I've done so far, but I know it's incomplete. can anybody help me?
'''
private void createBoxToAddBlankSamples(int numberOfBlanks){
List <TextView> blankSampleTitles = new ArrayList<>(numberOfBlanks);
List <EditText> blankSampleNumbers = new ArrayList<>(numberOfBlanks);
for (int i=0; i<=numberOfBlanks; i++) {
blankSampleTitles.add((TextView) findViewById(R.id.blank_title_1 + i));
blankSampleNumbers.add((EditText) findViewById(R.id.blank_value_1 + i));
}
}
Been searching the whole world wide web and haven't been able to find a solution to get this to work.
There is 15 questions in total.
Each question include an audio clip, and you get 4 buttons choices.
3 wrong choices which will give you + 0 score.
1 right choice which give you + 1 score.
after you finished all 15 questions you can click "Show score"
And here I want to make a TextView which shows you how many questions out of 15 you got right.
It sounds pretty simple to make this to work,
But I've tried multiple codes with SharedPreferences, Editors, Arrays etc...
First sample code is from pressing the right answer on the first question.
Second sample code is for the show score after finishing the quiz.
final Button answerC = (Button) findViewById(R.id.answerC);
answerC.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences prefs = getSharedPreferences("mresult", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("result", + 1);
editor.apply();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_easy_result);
SharedPreferences prefs = getSharedPreferences("mResult", Context.MODE_PRIVATE);
int myResult = prefs.getInt("result", 0);
In order to send data from one Activity to another Activity you have a few options depending on your circumstances. Although, for my answer - I'm going to assume that it's easy for you to navigate to another activity at a moments notice.
With what you're doing, you must understand that data in activities are completely mutable and can be voided by androids garbage collection at any time - you must develop your applications with this in mind and not rely on data constantly being available within your classes.
With the little information you've provided it seems as if you have a main activity in which you're storing data about the user's score and you want to change the user's activity and display that on the other screen.
I would advise that you create a Score object of some sort and allow it to implement the interface Serializable
You can then simply write the following to start the other activity
Intent toShowScoreActivity = new Intent(currentActivity, ShowScoreActivity.class);
Bundle bundle = new Bundle();
Score score = new Score(1);
bundle.putSerializable("score", scoreSerialized);
toShowScoreActivity.putExtras(bundle);
activity.startActivity(toShowScoreActivity);
then, when the other activity is started, you can reference the Serialized Score object by doing the following:
Score score = (Score) getIntent().getExtras().getSerializable("score")
Here's the mock up, over simplified, Score.java
package Testing;
import java.io.Serializable;
public class Score implements Serializable {
private final int score;
public Score(int score) {
this.score = score;
}
public int getScore() {
return score;
}
}
I would definitely recommend reading up more about android's guide to app architecture and conventional management of the Activity life cycle over at the following links
- https://developer.android.com/jetpack/docs/guide
- https://developer.android.com/guide/components/activities/activity-lifecycle
- https://www.programcreek.com/java-api-examples/?class=android.app.Activity&method=getIntent
I have a Swing form where I want to detect edited field data so I can update the data via a web service. There doesn't seem to be a simple way to do this as there are a plethora of medium to complex code examples for this, most of which are over my head! However, I think I found a simple solution that will fit my needs and I wanted to run it by the group for input / suggestions. FYI: it may not matter but know that I am using NetBeans so things like listeners are auto-coded by the app.
Step 1: When I load the form, I am saving all the data to a Class array so I know the starting point of the each field. Here is the code for that load:
public void coSetSearchDetail(String coDetail){
String[] text;
System.out.println("SingleCO Result: "+ coDetail);
text = coDetail.split("\\|");
txtName_CoDetail.setText(text[1]);
txtAddr_CoDetail.setText(text[2]);
txtAddr2_CoDetail.setText(text[3]);
txtCity_CoDetail.setText(text[4]);
txtState_CoDetail.setText(text[5]);
txtZip_CoDetail.setText(text[6]);
stringarrayCoDetails[0] = text[0];
stringarrayCoDetails[1] = text[1];
stringarrayCoDetails[2] = text[2];
stringarrayCoDetails[3] = text[3];
stringarrayCoDetails[4] = text[4];
stringarrayCoDetails[5] = text[5];
stringarrayCoDetails[6] = text[6];
java.awt.CardLayout card = (java.awt.CardLayout)pnlMain.getLayout();
card.show(pnlMain, "pnlCoDetail");
}
Step 2: I created a Lost Focus event listener for one field and am testing the current value of the field against the array:
private void txtName_CoDetailFocusLost(java.awt.event.FocusEvent evt) {
if (!(txtName_CoDetail.getText().equals(stringarrayCoDetails[1]))){
createEditBorder();
}
}
private void createEditBorder (){
Border border = BorderFactory.createLineBorder(Color.RED, 2);
txtName_CoDetail.setBorder(border);
}
Besides the general question of "is this an OK approach?", I would like to be able to pass the field name to the createEditBorder method so the listener for each data field can call it and I have one method for "edited text" formatting.
I am making a simple sequence from randomly generated numbers. Each number will show an image linked to it.
for example,
the value 1 will show a picture of a cat.
value 2 a dog
and value 3 a mouse.
Each image has it's own dedicated imageview, the layout looks like this by default, i.e image views that store black until it's number is called:
Each time the sequence increments. so on the second run two images will show, on the third 3 will show and so on.
The problem I am having is that all the images show at once. So for sequence one just the one image flashes (which is what I want). but on the second run both images show at once together instead of showing the first image then the second.
So to clarify let's say on the four runs the stored array is 1,2,3,3 I would want
image 1 to show, and disappear.then
image 2 show and disappear. then
image 3 show and disappear
and then image 3 to show and disappear.
But what I actually get is on the fourth run 1,2&3 will show at once and disappear at the same time together. How can I break this up to achieve what I want. I have tried many methods and the same result happens. I can't get my head around this problem.
Here is my code:
ArrayList<Integer> stored_vals = new ArrayList<Integer>();
public void Gen() {
int i=0 ;
Random rand = new Random();
int rndInt = rand.nextInt(3)+ 1 ;
list.add(rndInt);
int totalElements = list.size();
Log.d("LOOK", Integer.toString(rndInt));
Log.i("VALUE LIST ", list.toString()+" <<<<LIST HERE");
while(i < totalElements) {
retval =list.get(i);
Log.d("RETVAL", Integer.toString(retval));
String imgName = "flash" + retval;
int id = getResources().getIdentifier(imgName, "drawable", getPackageName());
if (retval==1){
Cat.setImageResource(id);
Reset_View();
}
else if (retval==2){
Dog.setImageResource(id);
Reset_View();
}
else if (retval==3){
Mouse.setImageResource(id);
Reset_View();
}
i++;
}
}
To try and delay the images showing at one at a time and to reset to it's default after showing for a few seconds I call Reset_View(); which is the following code:
CountDownTimer Reset_View = new CountDownTimer(1000 , 0010){
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
Centre.setImageResource(R.drawable.i1);
upperRight.setImageResource(R.drawable.i2);
lowerRight.setImageResource(R.drawable.i3);
lowerLeft.setImageResource(R.drawable.i4);
upperLeft.setImageResource(R.drawable.i5);
}
};
So how can I achieve what I want. I have been stuck on this idea for weeks.
This is a high level idea of what you could do.
Put all the showing and hiding in the countdowntimer. So basically you would need to handle the 'onTick' and hide or show the images when needed. Something like 'time > 0 and < 1000' hide all but the first image. 1000 to 2000, show only second image. 2000 to 3000, show only third image. On finish, hide all.
When you instantiate the timer after the for loop, if retval is 1 - then 1000 would be how long to run, retval = 2, then 2000, retval = 3, then 3000.
There is probably a better way to do it but this is the first thing that comes to my mind.
One problem might be that Reset_View(); is not a method. The line even states public CLASS Reset_View(); extends CountDownTimer. ( I don't know ho that can be a valid class name but whatever) Therefore, calling Reset_View(); will not actually do anything.
You need to change the name of the class to something else, I suggest ResetTimer. Then to reset the Views you must create an instance of ResetTimer and use its start() method like this:
new ResetTimer(1000, 1000).start();
Note: the first number in the constructor is the total time (in milliseconds) until the timers onFinish() is called. The second one it the time between the onTick()s. Since you don't use this method, the number you put in there doesn't matter.
I want the ability to allow the user to choose an image from the gallery,
but only images were taken, for example, 10 minutes ago (maybe using Time Created Metadata?).
There are examples of how to open gallery and choose an image:
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
However, I only need images which were taken 10 minutes ago.
Does anyone have an idea?
I might be wrong but I don't think you can achieve this directly by using the Intent.ACTION_PICK into the Gallery. I think, there is a possible way with MediaStore.Images.ImageColumns.DATE_TAKEN and a Cursor as you can see in this answer. However, I did not find the right way to do it.
Then, you can do a workaround: create your own Gallery into your app. Select all the pictures from the Camera folder, filter them, and display only which are taken x min ago into your own Gallery - a simple GridView. I think this might be easy to do:
Init the vars:
// FileArray
private File[] aFile;
// ArrayList
private ArrayList<String> aImagePath = new ArrayList<String>();
Get the DCIM Camera folder:
File fPath = new File(Environment
.getExternalStorageDirectory().toString() + "/DCIM/Camera");
Create a FileArray and list the files in this folder:
// use a FilenameFilter to have only the pictures in JPG
aFile = fPath.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".jpg");
}
});
For each file, get the last modified date and populate an ArrayList<String>:
for(int i=0; i < aFile.length; i++) {
long lastDate = aFile[i].lastModified(); // get last modified date
long nowTime = nDate.getTime(); // get the current time to compare
if(nowTime - lastDate < 600*1000) { // if less than 10 min
String pathFile = aFile[i].getPath();
aImagePath.add(pathFile); // populate the Array
}
}
Finally, reverse the Array to have the most recent pictures at the first place and display them:
if(aImagePath.size() != 0) {
Collections.reverse(aImagePath); // reverse the Array
// Call an AsyncTask to create and retrieve each Bitmap
// then, in onPostExecute(), populate the Adapter of the GridView
} else {
// No pictures taken 10 min ago!
}
Actually, in the AsyncTask, you will have to deal with the Bitmap options to save memory... I tested this in a GridView into a Fragment and it worked well. You can find the references I used above:
Using File.listFiles with FileNameExtensionFilter
How to get a file's creation date?
Get File Creation Time
How to display selected image gallery in ImageView?
Maybe someone has a better solution, but this above does the trick and displays only the images taken 10 min ago with the Camera's device. I hope this will help you.