diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c66d819..3c1ed71 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -42,11 +42,11 @@
+ android:value="com.rubenvandeven.emotionhero.MirrorMenuActivity" />
-
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/Achievement.java b/app/src/main/java/com/rubenvandeven/emotionhero/Achievement.java
new file mode 100644
index 0000000..4ff29c6
--- /dev/null
+++ b/app/src/main/java/com/rubenvandeven/emotionhero/Achievement.java
@@ -0,0 +1,28 @@
+package com.rubenvandeven.emotionhero;
+
+import android.graphics.Bitmap;
+
+/**
+ * Created by ruben on 10/09/16.
+ *
+ * Achievements made in a specific game (as provided by the API)
+ */
+
+public class Achievement {
+ public String title;
+ /**
+ * Html string
+ */
+ public String description;
+ public Bitmap icon;
+
+ public Achievement(String title, String description, Bitmap icon){
+ this.title = title;
+ this.description = description;
+ this.icon = icon;
+ }
+
+ public int getId() {
+ return AchievementCollection.getInstance().getId(this);
+ }
+}
diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/AchievementCollection.java b/app/src/main/java/com/rubenvandeven/emotionhero/AchievementCollection.java
new file mode 100644
index 0000000..0754357
--- /dev/null
+++ b/app/src/main/java/com/rubenvandeven/emotionhero/AchievementCollection.java
@@ -0,0 +1,38 @@
+package com.rubenvandeven.emotionhero;
+
+import android.support.v4.content.res.TypedArrayUtils;
+
+import java.util.ArrayList;
+
+/**
+ * Created by ruben on 10/09/16.
+ */
+public class AchievementCollection {
+ private ArrayList achievements = new ArrayList(){{
+ // fill the collection :-)
+ add(new Achievement("Microexpressor", null, null));
+ add(new Achievement("\"In pursuit of happiness\"", null, null));
+ add(new Achievement("CEO", null, null));
+ add(new Achievement("Kuleshov", null, null));
+ add(new Achievement("Soap opera", null, null));
+ add(new Achievement("Stock photo model", null, null));
+ }};
+
+ private static AchievementCollection ourInstance = new AchievementCollection();
+
+ public static AchievementCollection getInstance() {
+ return ourInstance;
+ }
+
+ private AchievementCollection() {
+ }
+
+ // ids start at one
+ public Achievement get(int id) {
+ return achievements.get(id-1);
+ }
+
+ public int getId(Achievement a){
+ return achievements.indexOf(a) + 1;
+ }
+}
diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/ApiRestClient.java b/app/src/main/java/com/rubenvandeven/emotionhero/ApiRestClient.java
index ef1c4cb..d0cb408 100644
--- a/app/src/main/java/com/rubenvandeven/emotionhero/ApiRestClient.java
+++ b/app/src/main/java/com/rubenvandeven/emotionhero/ApiRestClient.java
@@ -19,6 +19,7 @@ import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Locale;
import java.util.TimeZone;
@@ -245,6 +246,15 @@ public class ApiRestClient {
hit.remoteId = hits.getString(Long.toString(hit.id));
gameHelper.saveRemoteId(hit);
}
+ JSONArray jAchievements = response.getJSONArray("achievements");
+ if(jAchievements.length() > 0){
+ ArrayList achievements = new ArrayList(jAchievements.length());
+ for (int ai = 0; ai < jAchievements .length(); ai++) {
+ achievements.add(AchievementCollection.getInstance().get(jAchievements.getInt(ai)));
+ }
+ game.achievements = achievements;
+ gameHelper.saveAchievementsForGame(game);
+ }
} catch (JSONException e) {
Log.e("API","Invalid data: " + response.toString());
e.printStackTrace();
diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/Game.java b/app/src/main/java/com/rubenvandeven/emotionhero/Game.java
index 1e59208..60ec414 100644
--- a/app/src/main/java/com/rubenvandeven/emotionhero/Game.java
+++ b/app/src/main/java/com/rubenvandeven/emotionhero/Game.java
@@ -3,6 +3,7 @@ package com.rubenvandeven.emotionhero;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;
+import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
@@ -22,6 +23,7 @@ public class Game {
public Date time;
public String remoteId;
public Map hits = new HashMap<>();
+ public ArrayList achievements = new ArrayList<>();
public Game(Long id, int lvl_id, float score, float bonus, Date time, String remoteId) {
this(id, new Scenario(lvl_id, null), score, bonus, time, remoteId);
diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/GameOpenHelper.java b/app/src/main/java/com/rubenvandeven/emotionhero/GameOpenHelper.java
index eaf680a..66163dc 100644
--- a/app/src/main/java/com/rubenvandeven/emotionhero/GameOpenHelper.java
+++ b/app/src/main/java/com/rubenvandeven/emotionhero/GameOpenHelper.java
@@ -20,7 +20,7 @@ import java.util.Date;
* adb pull /sdcard/emotionhero.db
*/
public class GameOpenHelper extends SQLiteOpenHelper {
- private static final int DATABASE_VERSION = 4;
+ private static final int DATABASE_VERSION = 5;
private static final String GAME_TABLE_NAME = "games";
private static final String GAME_TABLE_CREATE =
"CREATE TABLE " + GAME_TABLE_NAME + " (" +
@@ -155,6 +155,19 @@ public class GameOpenHelper extends SQLiteOpenHelper {
"id","game_id", "target_index","score","bonus","remoteId","glasses","ethnicity","age","gender","anger","contempt","disgust","fear","joy","sadness","surprise","roll","pitch","yaw","inter_ocular_distance","mouth_open","lip_press","brow_raise","nose_wrinkler","lip_depressor","brow_furrow","attention","smile","inner_brow_raiser","chin_raiser","smirk","lip_suck","upper_lip_raiser","lip_pucker","eye_closure","engagement","valence","point_0x","point_0y","point_1x","point_1y","point_2x","point_2y","point_3x","point_3y","point_4x","point_4y","point_5x","point_5y","point_6x","point_6y","point_7x","point_7y","point_8x","point_8y","point_9x","point_9y","point_10x","point_10y","point_11x","point_11y","point_12x","point_12y","point_13x","point_13y","point_14x","point_14y","point_15x","point_15y","point_16x","point_16y","point_17x","point_17y","point_18x","point_18y","point_19x","point_19y","point_20x","point_20y","point_21x","point_21y","point_22x","point_22y","point_23x","point_23y","point_24x","point_24y","point_25x","point_25y","point_26x","point_26y","point_27x","point_27y","point_28x","point_28y","point_29x","point_29y","point_30x","point_30y","point_31x","point_31y","point_32x","point_32y","point_33x","point_33y", "image"
};
+ private static final String GAME_ACH_TABLE_NAME = "game_achievements";
+ private static final String GAME_ACH_TABLE_CREATE =
+ "CREATE TABLE " + GAME_ACH_TABLE_NAME + " (" +
+ "id INTEGER NOT NULL," +
+ "game_id INTEGER NOT NULL," +
+ "achievement_id INTEGER NOT NULL," +
+ "PRIMARY KEY(id));";
+ private static final String[] GAME_ACH_PROJECTION = {
+ "id",
+ "game_id",
+ "achievement_id",
+ };
+
private Context context;
GameOpenHelper(Context context) {
@@ -166,6 +179,7 @@ public class GameOpenHelper extends SQLiteOpenHelper {
public void onCreate(SQLiteDatabase db) {
db.execSQL(GAME_TABLE_CREATE);
db.execSQL(HIT_TABLE_CREATE);
+ db.execSQL(GAME_ACH_TABLE_CREATE);
}
@Override
@@ -186,6 +200,10 @@ public class GameOpenHelper extends SQLiteOpenHelper {
db.execSQL("ALTER TABLE hits ADD bonus VARCHAR(20);");
db.execSQL("ALTER TABLE games ADD bonus VARCHAR(255);");
}
+ if(oldVersion == 4 && newVersion == 5) {
+ db.execSQL(GAME_ACH_TABLE_CREATE);
+ }
+
}
public void insertGame(Game game) {
@@ -256,6 +274,7 @@ public class GameOpenHelper extends SQLiteOpenHelper {
);
games[i] = game;
this.getHitsForGame(game); // hits are appended to game object
+ game.achievements = getAchievementsOfGame(game);
i++;
c.moveToNext();
}
@@ -281,6 +300,24 @@ public class GameOpenHelper extends SQLiteOpenHelper {
selectionArgs);
}
+ public void saveAchievementsForGame(Game game) {
+ SQLiteDatabase db = getWritableDatabase();
+
+ if(game.achievements.size() < 1) {
+ return;
+ }
+
+ // New value for one column
+ for(Achievement achievement: game.achievements) {
+ ContentValues values = new ContentValues();
+ values.put("game_id", game.id);
+ values.put("achievement_id", achievement.getId());
+
+ db.insert(GAME_ACH_TABLE_NAME, null, values);
+ }
+
+ }
+
public void insertHit(Hit hit) {
// Gets the data repository in write mode
@@ -413,4 +450,27 @@ public class GameOpenHelper extends SQLiteOpenHelper {
return c.getInt(0);
}
+ public int countAchievementsForLevel(int lvl_id) {
+ String[] params = { Long.toString(lvl_id) };
+ Cursor c = getReadableDatabase().rawQuery("SELECT COUNT(DISTINCT achievement_id) FROM games g INNER JOIN game_achievements ga ON ga.game_id = g.id WHERE g.lvl_id = ?", params);
+ c.moveToFirst();
+ return c.getInt(0);
+ }
+
+ public ArrayList getAchievementsOfGame(Game game) {
+ String[] params = { Long.toString(game.id) };
+ Cursor c = getReadableDatabase().rawQuery("SELECT achievement_id FROM games g INNER JOIN game_achievements ga ON ga.game_id = g.id WHERE g.id = ?", params);
+ int count = c.getCount();
+ if(count < 1)
+ return null;
+
+ ArrayList achievements = new ArrayList<>(count);
+ c.moveToFirst();
+ while (!c.isAfterLast()) {
+ achievements.add(AchievementCollection.getInstance().get(c.getInt(0)));
+ c.moveToNext();
+ }
+ return achievements;
+ }
+
}
diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/ReviewAchievementsActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/ReviewAchievementsActivity.java
new file mode 100644
index 0000000..d558e7e
--- /dev/null
+++ b/app/src/main/java/com/rubenvandeven/emotionhero/ReviewAchievementsActivity.java
@@ -0,0 +1,83 @@
+package com.rubenvandeven.emotionhero;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class ReviewAchievementsActivity extends AppCompatActivity {
+
+ public final static String INTENT_EXTRA_GAME_ID = "com.rubenvandeven.emotionhero.GAME_ID";
+
+ Player player;
+
+ Game game;
+
+ LinearLayout achievementsLayout;
+ TextView toDiscoverText;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ setContentView(R.layout.activity_review_achievements);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setTitle("Achievements");
+
+ achievementsLayout = (LinearLayout) findViewById(R.id.achievementsLayout);
+ toDiscoverText = (TextView) findViewById(R.id.toDiscoverText);
+
+ player = Player.getInstance(getApplicationContext());
+
+ // get game from Intent
+ long gameId = getIntent().getLongExtra(INTENT_EXTRA_GAME_ID, 0);
+ Log.d("Review", "gameid:" + gameId);
+ if(gameId != 0) {
+ game = player.getGameOpenHelper().getGameByid(gameId);
+ if(game == null) {
+ Log.e("Highscore", "CANNOT FIND GAME!! " + gameId);
+ throw new RuntimeException("Cannot find specified game");
+ } else {
+ Log.i("Highscore", "FOUND GAME" + game.id + " " + game.score);
+ }
+ } else {
+ // no game specified??? SHould not be possible so finish
+ finish();
+ }
+
+ for(Achievement achievement: game.achievements) {
+ addAchievement(achievement);
+ }
+
+ int toDiscover = game.scenario.achievements.size() - game.achievements.size();
+
+ if(toDiscover > 0) {
+ toDiscoverText.setText(String.format("There are %1$d other achievements for this level.", toDiscover));
+ } else {
+ toDiscoverText.setText("Wow, you obtained all achievements in one run!!");
+ }
+ }
+
+ public void addAchievement(Achievement achievement) {
+ TextView titleText = new TextView(this);
+ TextView descriptionText = new TextView(this);
+// ImageView imageView = new ImageView(this);
+
+ titleText.setText(achievement.title);
+ titleText.setTextColor(getResources().getColor(R.color.textHighlight));
+ titleText.setTextSize(R.dimen.highscore_textsize);
+
+ descriptionText.setText(achievement.description);
+ descriptionText.setTextColor(getResources().getColor(R.color.textPrimary));
+
+ achievementsLayout.addView(titleText);
+ achievementsLayout.addView(descriptionText);
+ }
+}
diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/ReviewActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/ReviewActivity.java
index 865903c..9f02781 100644
--- a/app/src/main/java/com/rubenvandeven/emotionhero/ReviewActivity.java
+++ b/app/src/main/java/com/rubenvandeven/emotionhero/ReviewActivity.java
@@ -45,6 +45,11 @@ public class ReviewActivity extends AppCompatActivity {
TextView overallScorePercText;
TextView overallScoreText;
+
+ TextView achievementTitle;
+ RelativeLayout achievementLayout;
+ TextView achievementArrow;
+ TextView achievementText;
TextView improveArrow;
TextView hintText;
RelativeLayout retryLayout;
@@ -81,6 +86,8 @@ public class ReviewActivity extends AppCompatActivity {
position.getInt("position");
scoreProgressBar.setVisibility(View.GONE);
+
+ checkAchievements();
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Something went wrong when loading results", Toast.LENGTH_LONG).show();
@@ -137,6 +144,11 @@ public class ReviewActivity extends AppCompatActivity {
overallScorePercText= (TextView) findViewById(R.id.overallScorePercText);
overallScoreText= (TextView) findViewById(R.id.overallScoreText);
+ achievementTitle = (TextView) findViewById(R.id.achievementTitle);
+ achievementLayout = (RelativeLayout) findViewById(R.id.achievementLayout);
+ achievementArrow = (TextView) findViewById(R.id.achievementArrow);
+ achievementText = (TextView) findViewById(R.id.achievementText);
+
improveArrow = (TextView) findViewById(R.id.improveArrow);
hintText = (TextView) findViewById(R.id.hintText);
retryLayout = (RelativeLayout) findViewById(R.id.retryLayout);
@@ -149,10 +161,12 @@ public class ReviewActivity extends AppCompatActivity {
scoreProgressBar = (ProgressBar) findViewById(R.id.scoreProgressBar);
+ checkAchievements();
Typeface font = Typeface.createFromAsset(getAssets(), "unifont-9.0.02.ttf");
lvlNameText.setTypeface(font);
overallScorePercText.setTypeface(font);
+ achievementArrow.setTypeface(font);
retryArrow.setTypeface(font);
improveArrow.setTypeface(font);
nextLvlArrow.setTypeface(font);
@@ -201,6 +215,33 @@ public class ReviewActivity extends AppCompatActivity {
retryText.setText(retryString);
}
+ public void checkAchievements() {
+ if(game.achievements.size() > 0) {
+ achievementTitle.setVisibility(View.VISIBLE);
+ achievementLayout.setVisibility(View.VISIBLE);
+
+ String achievementString = "";
+ for(Achievement achievement: game.achievements) {
+ if(achievementString.length() > 0) {
+ achievementString += "\n";
+ }
+ achievementString += String.format("%2$s", achievement.title);
+ }
+ achievementText.setText(achievementString);
+ achievementLayout.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(getApplicationContext(), ReviewAchievementsActivity.class);
+ intent.putExtra(ReviewAchievementsActivity.INTENT_EXTRA_GAME_ID, game.id);
+ startActivity(intent);
+ }
+ });
+ } else {
+ achievementTitle.setVisibility(View.GONE);
+ achievementLayout.setVisibility(View.GONE);
+ }
+ }
+
/**
* Translate 1 => 1st, 2 => 2nd etc.
* Thanks to http://stackoverflow.com/a/23182005
diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java b/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java
index bcee462..99c80b8 100644
--- a/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java
+++ b/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java
@@ -60,6 +60,11 @@ public class Scenario {
*/
float minimumAchievements= 0;
+ /**
+ * Achievements one get obtain in this level
+ */
+ ArrayList achievements = new ArrayList<>();
+
/**
* If a game is beign played.
*/
@@ -357,6 +362,7 @@ public class Scenario {
}
public void createTargets() {
+ AchievementCollection achievementCollection = AchievementCollection.getInstance();
switch(id) {
case LVL_ANGER:
setTarget(Emotion.ANGER, 100, 1);
@@ -366,6 +372,13 @@ public class Scenario {
setTarget(Emotion.ANGER, 40, 5);
setTarget(Emotion.ANGER, 70, 6);
setTarget(Emotion.ANGER, 100, 7);
+
+ setMinimumScoreFromPercentage(10);
+ minimumAchievements = 2;
+
+ achievements.add(achievementCollection.get(1));
+ achievements.add(achievementCollection.get(3));
+
break;
case LVL_JOY:
setTarget(Emotion.JOY, 100, 1);
@@ -385,23 +398,46 @@ public class Scenario {
setTarget(Emotion.JOY, 100, 18);
setTarget(Emotion.JOY, 100, 19);
setTarget(Emotion.JOY, 100, 20);
+
+
+ setMinimumScoreFromPercentage(10);
+ minimumAchievements = 2;
+
+
+ achievements.add(achievementCollection.get(2));
+ achievements.add(achievementCollection.get(4));
+
break;
case LVL_SURPRISE:
setTarget(Emotion.SURPRISE, 20, 1);
setTarget(Emotion.SURPRISE, 50, 2);
setTarget(Emotion.SURPRISE, 80, 3);
setTarget(Emotion.SURPRISE, 100, 4);
+
+ setMinimumScoreFromPercentage(10);
+ minimumAchievements = 2;
+
+ achievements.add(achievementCollection.get(5));
+ achievements.add(achievementCollection.get(6));
+
break;
case LVL_SADDNESS:
setTarget(Emotion.SADNESS, 20, 1);
setTarget(Emotion.SADNESS, 50, 2);
setTarget(Emotion.SADNESS, 80, 3);
setTarget(Emotion.SADNESS, 100, 4);
+
+ setMinimumScoreFromPercentage(10);
+ minimumAchievements = 2;
break;
}
}
+ public void setMinimumScoreFromPercentage(float percentage) {
+ this.minimumScore = maxScore * (percentage / 100f);
+ }
+
public int getNextLevelId() {
int nextIdx = SCENARIOS.indexOf(id) + 1;
if(SCENARIOS.size() <= nextIdx) {
diff --git a/app/src/main/res/layout/activity_review.xml b/app/src/main/res/layout/activity_review.xml
index 2685440..f6bcfae 100644
--- a/app/src/main/res/layout/activity_review.xml
+++ b/app/src/main/res/layout/activity_review.xml
@@ -127,7 +127,53 @@
android:textAlignment="center"
android:textColor="@color/textSecondary" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+