From 3d45a25895c7f357f129132a0e74f71b70572c33 Mon Sep 17 00:00:00 2001 From: Ruben Date: Sat, 20 Aug 2016 22:58:32 +0100 Subject: [PATCH] Refactor the highscore to hits, score and playerinfo. Save info it as JSON object and recover it on next run. Which means that practically local highscores are working Fix #2 Also next level now works --- .../emotionhero/GamingActivity.java | 40 +++++++------- .../rubenvandeven/emotionhero/PlayerInfo.java | 50 +++++++++++++++++ .../rubenvandeven/emotionhero/Scenario.java | 54 +++++++++---------- .../emotionhero/ScenarioView.java | 20 +++---- .../{Highscore.java => Score.java} | 8 +-- .../{Highscores.java => ScoreList.java} | 44 +++++---------- 6 files changed, 124 insertions(+), 92 deletions(-) create mode 100644 app/src/main/java/com/rubenvandeven/emotionhero/PlayerInfo.java rename app/src/main/java/com/rubenvandeven/emotionhero/{Highscore.java => Score.java} (63%) rename app/src/main/java/com/rubenvandeven/emotionhero/{Highscores.java => ScoreList.java} (56%) diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java index 6973fa9..a23e851 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java @@ -42,7 +42,7 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL public final static String INTENT_EXTRA_SCENARIO = "com.rubenvandeven.emotionhero.LEVEL"; final static String LOG_TAG = "EmotionHero"; - final static String HIGHSCORE_FILENAME = "highscores.json"; + final static String PLAYERINFO_FILENAME = "playerinfo.json"; final int PERMISSIONS_REQUEST_CAMERA = 1; @@ -148,6 +148,7 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL // currentScenario = new ScenarioAnger(this); currentScenario = new Scenario(scenarioLvlId, this); + currentScenario.init(); // "start the clock"... scenarioView = new ScenarioView(this, currentScenario); RelativeLayout.LayoutParams scenarioViewParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); @@ -221,7 +222,7 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL @Override /** - * Detector callback gives the faces found so we can match their scores to the given scenario. + * Detector callback gives the faces found so we can match their hits to the given scenario. */ public void onImageResults(List list, Frame frame, float timestamp) { // frame.getOriginalBitmapFrame() @@ -341,34 +342,34 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL sound = new SoundPool(5, AudioManager.STREAM_MUSIC,0); } - public Highscores getHighscores() { + public PlayerInfo getPlayerInfo() { try{ - FileInputStream fis = openFileInput(HIGHSCORE_FILENAME); + FileInputStream fis = openFileInput(PLAYERINFO_FILENAME ); StringBuilder builder = new StringBuilder(); int ch; while((ch = fis.read()) != -1){ builder.append((char)ch); } - return Highscores.fromJson(builder.toString()); + return PlayerInfo.fromJson(builder.toString()); } catch (IOException e) { - return new Highscores(); + return new PlayerInfo(); } } - public void addHighscore(Highscore score) { - Highscores scores = getHighscores(); - scores.add(score); - saveHighscores(scores); + public void savePlayerScore(Score score) { + PlayerInfo playerInfo = getPlayerInfo(); + playerInfo.addScore(score); + savePlayerInfo(playerInfo); } - public void saveHighscores(Highscores scores) { + public void savePlayerInfo(PlayerInfo playerInfo) { try { - FileOutputStream fos = openFileOutput(HIGHSCORE_FILENAME, Context.MODE_PRIVATE); - fos.write(scores.toJson().getBytes()); + FileOutputStream fos = openFileOutput(PLAYERINFO_FILENAME, Context.MODE_PRIVATE); + fos.write(playerInfo.toJson().getBytes()); fos.close(); } catch(IOException e) { // for now skip error - Log.e(LOG_TAG, "Could not save highscore!"); + Log.e(LOG_TAG, "Could not save player information!"); } } @@ -380,8 +381,9 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL nextLvlButton.setVisibility(View.VISIBLE); } - Highscores scores = getHighscores(); - Highscore score = currentScenario.getHighscore(); + PlayerInfo playerInfo = getPlayerInfo(); + ScoreList scores = playerInfo.getScoresForLevel(currentScenario.id); + Score score = currentScenario.getScore(); if(score.score == currentScenario.getMaxScore()) { // Maximum SCORE!! @@ -398,13 +400,13 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL // show the highscores (top 3?)... scores.add(score); - saveHighscores(scores); + savePlayerInfo(playerInfo); String highscoreText = "TOPSCORES\n"; - Highscores topscores = scores.getTopN(3); // TODO: only highscores for current lEVEL!!!!!!! + ScoreList topscores = scores.getTopN(3); // TODO: only highscores for current lEVEL!!!!!!! int i = 0; - for(Highscore topscore: topscores) { + for(Score topscore: topscores) { i++; highscoreText += String.format("%1$d. %2$.2f\n", i, topscore.score); //make line by line elements } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/PlayerInfo.java b/app/src/main/java/com/rubenvandeven/emotionhero/PlayerInfo.java new file mode 100644 index 0000000..d776738 --- /dev/null +++ b/app/src/main/java/com/rubenvandeven/emotionhero/PlayerInfo.java @@ -0,0 +1,50 @@ +package com.rubenvandeven.emotionhero; + +import android.support.annotation.NonNull; +import android.util.SparseArray; + +import com.google.gson.Gson; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Created by ruben on 20/08/16. + */ + +public class PlayerInfo { + public Map levelScores = new HashMap<>(); + + public ScoreList getScoresForLevel(int lvl_id) { + ScoreList scoreList; + if(!levelScores.containsKey(lvl_id)) { + scoreList = new ScoreList(); + levelScores.put(lvl_id, scoreList); + } else { + scoreList = levelScores.get(lvl_id); + } + return scoreList; + } + + /** + * The individual score object contains the level id, so we can fetch the corresponding + * scorelist to add this score + * @param score + */ + public void addScore(Score score) { + ScoreList scoreList = getScoresForLevel(score.lvl_id); + scoreList.add(score); + } + + public static PlayerInfo fromJson(String json) { + Gson gson = new Gson(); + return gson.fromJson(json, PlayerInfo.class); + } + + public String toJson() { + Gson gson = new Gson(); + return gson.toJson(this); + } +} diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java b/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java index 93f4984..abc41a1 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java @@ -1,15 +1,11 @@ package com.rubenvandeven.emotionhero; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.util.Log; -import com.affectiva.android.affdex.sdk.Frame; import com.affectiva.android.affdex.sdk.detector.Face; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; import java.util.Timer; import java.util.TimerTask; @@ -71,19 +67,19 @@ public class Scenario { public Emotion emotion; public float value; public float timestamp; - public Score score; + public Hit hit; } - ArrayList scores = new ArrayList<>(); + ArrayList hits = new ArrayList<>(); - class Score { + class Hit { public float value; /** * Extra bonus given */ public boolean isSpotOn = false; -// public Bitmap image; //image at time of score - public Face face; // face at time of score +// public Bitmap image; //image at time of hit + public Face face; // face at time of hit } /** @@ -99,7 +95,6 @@ public class Scenario { this.id = lvl_id; _activity = activity; createTargets(); - init(); } public void init() { @@ -137,22 +132,22 @@ public class Scenario { for (int i = targets.size() - 1; i >= 0; i--) { Target target = targets.get(i); // skip targets that are already scored - if(target.score != null) { + if(target.hit != null) { continue; } if(target.timestamp <= runningTime) { float scored_value = target.emotion.getValueFromFace(currentFace); float required_value = target.value; - Score score = new Score(); - score.value = Math.round(100 - Math.abs(scored_value-required_value)); - score.face = currentFace; - scores.add(score); + Hit hit = new Hit(); + hit.value = Math.round(100 - Math.abs(scored_value-required_value)); + hit.face = currentFace; + hits.add(hit); // _activity.sound.play(_activity.soundIds.get(_activity.SOUND_SCORE), 1, 1, - 1,0, score.value / 200f + 0.5f ); // play back the sound slower - // depending on score value - target.score = score; + 1,0, hit.value / 200f + 0.5f ); // play back the sound slower + // depending on hit value + target.hit = hit; } } @@ -209,19 +204,19 @@ public class Scenario { if(target.timestamp > timestamp - 0.2 && target.timestamp < timestamp + 0.2) { float scored_value = target.emotion.getValueFromFace(face); float required_value = target.value; - Score score = new Score(); - score.value = 100 - Math.abs(scored_value-required_value); - target.score = score; - scores.add(score); + Hit hit = new Hit(); + hit.value = 100 - Math.abs(scored_value-required_value); + target.hit = hit; + hits.add(hit); } } } - public float getTotalScore() + public float getHitTotalValue() { float value = 0; - for (Score score : scores) { - value += score.value; + for (Hit hit : hits) { + value += hit.value; } return value; } @@ -285,12 +280,12 @@ public class Scenario { return runningTime > duration; } - public Highscore getHighscore() { + public Score getScore() { if(!isFinished()) { return null; } - return new Highscore("Levelname!", getTotalScore()); + return new Score(id, getHitTotalValue()); } public int getMaxScore() { @@ -300,6 +295,9 @@ public class Scenario { public void createTargets() { switch(id) { case LVL_ANGER: + setTarget(Emotion.ANGER, 10, 1); + break; + case LVL_JOY: setTarget(Emotion.ANGER, 10, 1); setTarget(Emotion.ANGER, 20, 2); setTarget(Emotion.ANGER, 40, 3); @@ -310,8 +308,6 @@ public class Scenario { setTarget(Emotion.JOY, 100, 15); setTarget(Emotion.ANGER, 100, 20); break; - case LVL_JOY: - break; case LVL_SURPRISE: setTarget(Emotion.SURPRISE, 20, 1); setTarget(Emotion.SURPRISE, 50, 2); diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/ScenarioView.java b/app/src/main/java/com/rubenvandeven/emotionhero/ScenarioView.java index a5f95ce..13ebae6 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/ScenarioView.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/ScenarioView.java @@ -144,7 +144,7 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback float bottomline_height = height * (float) 0.8; - // draw current scores: + // draw current hits: float used_width = (float) 0.8; // 0.7: only use center float padding_left = canvas.getWidth() * (1-used_width) / 2; float step_y = (canvas.getWidth() * used_width) / Emotion.values().length; @@ -189,21 +189,21 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback float diff_y = sec_height * _scenario.getTime(); for(Scenario.Target target: _scenario.getTargets()) { -// Paint targetPaint = (target.score == null) ? emoPaints.get(target.emotion) : emoScoredPaints.get(target.emotion); +// Paint targetPaint = (target.hit == null) ? emoPaints.get(target.emotion) : emoScoredPaints.get(target.emotion); float cy = bottomline_height - (target.timestamp * sec_height) + diff_y; float cx = padding_left + (step_y * target.emotion.ordinal() + step_y / 2); canvas.drawCircle(cx, cy, max_ball_radius * target.value/100, emoPaints.get(target.emotion)); - if(target.score != null) { - canvas.drawText(Float.toString(target.score.value), cx, cy, emoPaints.get(target.emotion)); - canvas.drawCircle(cx, cy, max_ball_radius * target.score.value/100, emoScoredPaints.get(target.emotion)); + if(target.hit != null) { + canvas.drawText(Float.toString(target.hit.value), cx, cy, emoPaints.get(target.emotion)); + canvas.drawCircle(cx, cy, max_ball_radius * target.hit.value/100, emoScoredPaints.get(target.emotion)); -// TODO: Use target.score.face to set Rect src. -// if(target.score.image != null) { +// TODO: Use target.hit.face to set Rect src. +// if(target.hit.image != null) { // Rect rect = new Rect((int) cx-10, (int) cy-10, (int) cx+10, (int) cy+10); -// canvas.drawBitmap(target.score.image, null, rect, null); +// canvas.drawBitmap(target.hit.image, null, rect, null); // } } @@ -212,9 +212,9 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback // canvas.drawText(target_text, cx, y_pos + diff_y , emoPaint); } - // draw the score middle bottom; + // draw the hit middle bottom; Paint usedScorePaint = _scenario.isFinished() ? scoreFinishedPaint : scorePaint; - String scoreText = String.format("Total: %1$.0f", _scenario.getTotalScore()); + String scoreText = String.format("Total: %1$.0f", _scenario.getHitTotalValue()); Rect scoreTextBounds = new Rect(); usedScorePaint.getTextBounds(scoreText, 0, scoreText.length(), scoreTextBounds); diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/Highscore.java b/app/src/main/java/com/rubenvandeven/emotionhero/Score.java similarity index 63% rename from app/src/main/java/com/rubenvandeven/emotionhero/Highscore.java rename to app/src/main/java/com/rubenvandeven/emotionhero/Score.java index 964d272..d80d584 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/Highscore.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/Score.java @@ -6,13 +6,13 @@ import java.util.Date; * Created by ruben on 19/08/16. */ -public class Highscore { - String level; +public class Score { + int lvl_id; float score; Date time; - public Highscore(String level, float score) { - this.level = level; + public Score(int lvl_id, float score) { + this.lvl_id = lvl_id; this.score = score; this.time = new Date(); } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/Highscores.java b/app/src/main/java/com/rubenvandeven/emotionhero/ScoreList.java similarity index 56% rename from app/src/main/java/com/rubenvandeven/emotionhero/Highscores.java rename to app/src/main/java/com/rubenvandeven/emotionhero/ScoreList.java index fdad375..bd59e4e 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/Highscores.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/ScoreList.java @@ -1,38 +1,22 @@ package com.rubenvandeven.emotionhero; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - -import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.Date; /** * Created by ruben on 19/08/16. */ -public class Highscores extends ArrayList{ - - - public static Highscores fromJson(String json) { - Gson gson = new Gson(); - return gson.fromJson(json, Highscores.class); - } - - public String toJson() { - Gson gson = new Gson(); - return gson.toJson(this); - } +public class ScoreList extends ArrayList{ /** - * Check if given highscore is highest score in this set. + * Check if given highscore is highest hit in this set. * @param score * @return */ - public boolean isHighest(Highscore score) { - for(Highscore s: this) { + public boolean isHighest(Score score) { + for(Score s: this) { if(s == score) // to allow comparison of items that are already in the set continue; // skip if it wants to compare with self. @@ -44,12 +28,12 @@ public class Highscores extends ArrayList{ } /** - * Get the n highest scores + * Get the n highest hits */ - public Highscores getTopN(int n) { - Collections.sort(this, new Comparator() { + public ScoreList getTopN(int n) { + Collections.sort(this, new Comparator() { @Override - public int compare(Highscore score1, Highscore score2) + public int compare(Score score1, Score score2) { // return highest first return score1.score > score2.score ? -1 : score1.score == score2.score ? 0 : 1; @@ -59,7 +43,7 @@ public class Highscores extends ArrayList{ if(n > this.size()) n = this.size(); - Highscores scores = new Highscores(); + ScoreList scores = new ScoreList(); for (int i = 0; i < n; i++) { scores.add(this.get(i)); } @@ -67,13 +51,13 @@ public class Highscores extends ArrayList{ } /** - * Get the n highest scores + * Get the n highest hits * @todo only for current level!! */ - public Highscores getLast(Integer n) { - Collections.sort(this, new Comparator() { + public ScoreList getLast(Integer n) { + Collections.sort(this, new Comparator() { @Override - public int compare(Highscore score1, Highscore score2) + public int compare(Score score1, Score score2) { // return newest first return score1.time.before(score2.time) ? -1 : score1.time == score2.time ? 0 : 1; @@ -87,7 +71,7 @@ public class Highscores extends ArrayList{ if(n > this.size()) n = this.size(); - Highscores scores = new Highscores(); + ScoreList scores = new ScoreList(); for (int i = 0; i < n; i++) { scores.add(this.get(i)); }