Scores are now saved in SQLite and can be send to the /me/games API endpoint
This commit is contained in:
parent
5bdda26f30
commit
f5fa4ead2f
12 changed files with 852 additions and 70 deletions
|
@ -1,20 +1,27 @@
|
||||||
package com.rubenvandeven.emotionhero;
|
package com.rubenvandeven.emotionhero;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.PointF;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
import com.loopj.android.http.AsyncHttpClient;
|
import com.loopj.android.http.AsyncHttpClient;
|
||||||
import com.loopj.android.http.AsyncHttpResponseHandler;
|
import com.loopj.android.http.AsyncHttpResponseHandler;
|
||||||
import com.loopj.android.http.JsonHttpResponseHandler;
|
import com.loopj.android.http.JsonHttpResponseHandler;
|
||||||
|
import com.loopj.android.http.RequestHandle;
|
||||||
import com.loopj.android.http.RequestParams;
|
import com.loopj.android.http.RequestParams;
|
||||||
import com.loopj.android.http.SyncHttpClient;
|
import com.loopj.android.http.SyncHttpClient;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import cz.msebera.android.httpclient.Header;
|
import cz.msebera.android.httpclient.Header;
|
||||||
import cz.msebera.android.httpclient.HeaderElement;
|
import cz.msebera.android.httpclient.HeaderElement;
|
||||||
import cz.msebera.android.httpclient.ParseException;
|
import cz.msebera.android.httpclient.ParseException;
|
||||||
|
import cz.msebera.android.httpclient.entity.StringEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ruben on 01/09/16.
|
* Created by ruben on 01/09/16.
|
||||||
|
@ -26,7 +33,7 @@ public class ApiRestClient {
|
||||||
private static final String BASE_URL = "http://api.emotionhero.com"; // TODO: https!
|
private static final String BASE_URL = "http://api.emotionhero.com"; // TODO: https!
|
||||||
|
|
||||||
private static AsyncHttpClient client = new AsyncHttpClient();
|
private static AsyncHttpClient client = new AsyncHttpClient();
|
||||||
private static SyncHttpClient syncClient = new SyncHttpClient();
|
// private static SyncHttpClient syncClient = new SyncHttpClient();
|
||||||
|
|
||||||
private String jwt;
|
private String jwt;
|
||||||
|
|
||||||
|
@ -38,7 +45,7 @@ public class ApiRestClient {
|
||||||
|
|
||||||
public void registerIfNeeded() {
|
public void registerIfNeeded() {
|
||||||
if(player.getJWT() == null) {
|
if(player.getJWT() == null) {
|
||||||
requestWithJWT(null, null, null, null);
|
requestWithJWT(null, null, null, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,10 +54,11 @@ public class ApiRestClient {
|
||||||
* @todo However, custom token endpoint should be used eventually
|
* @todo However, custom token endpoint should be used eventually
|
||||||
* @param method
|
* @param method
|
||||||
* @param url
|
* @param url
|
||||||
* @param params
|
* @param postBody
|
||||||
|
* @param getParams
|
||||||
* @param responseHandler
|
* @param responseHandler
|
||||||
*/
|
*/
|
||||||
public void requestWithJWT(final String method, final String url, final RequestParams params, final AsyncHttpResponseHandler responseHandler) {
|
public void requestWithJWT(final String method, final String url, final StringEntity postBody, final RequestParams getParams, final AsyncHttpResponseHandler responseHandler) {
|
||||||
// sync call, so we can return a value!
|
// sync call, so we can return a value!
|
||||||
client.post(BASE_URL + "/api/register", null, new JsonHttpResponseHandler() {
|
client.post(BASE_URL + "/api/register", null, new JsonHttpResponseHandler() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -65,7 +73,7 @@ public class ApiRestClient {
|
||||||
getPlayer().setRemoteId(remoteId);
|
getPlayer().setRemoteId(remoteId);
|
||||||
|
|
||||||
if(method != null) {
|
if(method != null) {
|
||||||
ApiRestClient.this.request( method, url, params, responseHandler);
|
ApiRestClient.this.request( method, url, postBody, getParams, responseHandler);
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
// responseHandler.sendFailureMessage(500, null, null);
|
// responseHandler.sendFailureMessage(500, null, null);
|
||||||
|
@ -115,35 +123,136 @@ public class ApiRestClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void request(String method, String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
|
public void request(String method, String url, StringEntity postBody, RequestParams getParams, AsyncHttpResponseHandler responseHandler) {
|
||||||
Header[] headers = new Header[]{new TokenHeader()};
|
Header[] headers = new Header[]{new TokenHeader()};
|
||||||
Log.d("API", "Do request to: " + url);
|
Log.d("API", "Do request to: " + url);
|
||||||
if(method == "post") {
|
if(method == "post") {
|
||||||
client.post(player.getContext(), url, headers,params,"application/json", responseHandler);
|
client.post(player.getContext(), url, headers, postBody,"application/json", responseHandler);
|
||||||
} else {
|
} else {
|
||||||
client.get(player.getContext(), url, headers, params, responseHandler);
|
client.get(player.getContext(), url, headers, getParams, responseHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
|
public void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
|
||||||
String jwt = player.getJWT();
|
String jwt = player.getJWT();
|
||||||
if(jwt != null) {
|
if(jwt != null) {
|
||||||
request("get", getAbsoluteUrl(url), params, responseHandler);
|
request("get", getAbsoluteUrl(url), null, params, responseHandler);
|
||||||
} else {
|
} else {
|
||||||
requestWithJWT("get", getAbsoluteUrl(url), params, responseHandler);
|
requestWithJWT("get", getAbsoluteUrl(url), null, params, responseHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
|
public void post(String url, StringEntity postBody, AsyncHttpResponseHandler responseHandler) {
|
||||||
String jwt = player.getJWT();
|
String jwt = player.getJWT();
|
||||||
if(jwt != null) {
|
if(jwt != null) {
|
||||||
request("post", getAbsoluteUrl(url), params, responseHandler);
|
request("post", getAbsoluteUrl(url), postBody, null, responseHandler);
|
||||||
} else {
|
} else {
|
||||||
requestWithJWT("post", getAbsoluteUrl(url), params, responseHandler);
|
requestWithJWT("post", getAbsoluteUrl(url), postBody, null, responseHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getAbsoluteUrl(String relativeUrl) {
|
private static String getAbsoluteUrl(String relativeUrl) {
|
||||||
return BASE_URL + relativeUrl;
|
return BASE_URL + relativeUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void syncGame(final Game game) {
|
||||||
|
if(game.remoteId != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RequestParams params = new RequestParams();
|
||||||
|
|
||||||
|
JSONObject j = new JSONObject();
|
||||||
|
try {
|
||||||
|
j.put("lvl_id", game.scenario.id);
|
||||||
|
j.put("score", game.score);
|
||||||
|
j.put("time", game.time);
|
||||||
|
|
||||||
|
JSONArray jHits = new JSONArray();
|
||||||
|
j.put("hits", jHits);
|
||||||
|
|
||||||
|
for(Hit hit: game.hits.values()) {
|
||||||
|
JSONObject jHit = new JSONObject();
|
||||||
|
jHit.put("target_index", hit.target.index);
|
||||||
|
jHit.put("score", hit.score);
|
||||||
|
jHit.put("glasses", hit.glasses);
|
||||||
|
jHit.put("ethnicity", hit.ethnicity);
|
||||||
|
jHit.put("age", hit.age);
|
||||||
|
jHit.put("gender", hit.gender);
|
||||||
|
|
||||||
|
JSONObject jExpressions = new JSONObject();
|
||||||
|
jHit.put("expressions", jExpressions);
|
||||||
|
JSONObject jEmotions = new JSONObject();
|
||||||
|
jHit.put("emotions", jEmotions);
|
||||||
|
JSONObject jPoints = new JSONObject();
|
||||||
|
jHit.put("points", jPoints);
|
||||||
|
|
||||||
|
for(Expression e: Expression.values()) {
|
||||||
|
jExpressions.put(e.getDbName(), hit.expressions.get(e));
|
||||||
|
}
|
||||||
|
for(Emotion e: Emotion.values()) {
|
||||||
|
jEmotions.put(e.getDbName(), hit.emotions.get(e));
|
||||||
|
}
|
||||||
|
int i=0;
|
||||||
|
for(PointF p: hit.points) {
|
||||||
|
JSONObject jPoint = new JSONObject();
|
||||||
|
jPoint.put("x", p.x);
|
||||||
|
jPoint.put("y", p.y);
|
||||||
|
jPoints.put(""+i, jPoint);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
jHits.put(jHit);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringEntity postBody = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
postBody = new StringEntity(j.toString());
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.post("/me/games", postBody, new JsonHttpResponseHandler(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
||||||
|
Log.d("API",response.toString());
|
||||||
|
GameOpenHelper gameHelper = new GameOpenHelper(player.getContext());
|
||||||
|
// set remote ids on hits and game.
|
||||||
|
try {
|
||||||
|
game.remoteId = response.getString("id");
|
||||||
|
JSONObject hits = response.getJSONObject("hits");
|
||||||
|
gameHelper.saveRemoteId(game);
|
||||||
|
for(Hit hit: game.hits.values()) {
|
||||||
|
hit.remoteId = hits.getString(Long.toString(hit.id));
|
||||||
|
gameHelper.saveRemoteId(hit);
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e("API","Invalid data: " + response.toString());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
|
||||||
|
handleOnFailure(statusCode, headers, responseString, throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handleOnFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
|
||||||
|
Log.e("API", "FAILURE ON REQUEST!");
|
||||||
|
Log.e("API", throwable.getMessage());
|
||||||
|
Log.e("API", "Status: "+statusCode);
|
||||||
|
Log.e("API", "Headers:");
|
||||||
|
for(Header header: headers) {
|
||||||
|
Log.e("API", "\t" + header.getName() + ": " + header.getValue());
|
||||||
|
}
|
||||||
|
Log.e("API", "Response:");
|
||||||
|
Log.e("API", responseString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,4 +62,9 @@ public enum Emotion {
|
||||||
|
|
||||||
return Color.BLACK;
|
return Color.BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getDbName() {
|
||||||
|
return this.name().toLowerCase();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
package com.rubenvandeven.emotionhero;
|
||||||
|
|
||||||
|
import com.affectiva.android.affdex.sdk.detector.Face;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruben on 02/09/16.
|
||||||
|
*
|
||||||
|
* Strictly not all expression variables, but they all are floats...
|
||||||
|
*/
|
||||||
|
|
||||||
|
public enum Expression {
|
||||||
|
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;
|
||||||
|
|
||||||
|
public float getValueFromFace(Face face)
|
||||||
|
{
|
||||||
|
if(face == null)
|
||||||
|
return 0f;
|
||||||
|
|
||||||
|
switch (this) {
|
||||||
|
case ROLL:
|
||||||
|
return face.measurements.orientation.getRoll();
|
||||||
|
case PITCH:
|
||||||
|
return face.measurements.orientation.getPitch();
|
||||||
|
case YAW:
|
||||||
|
return face.measurements.orientation.getYaw();
|
||||||
|
case INTER_OCULAR_DISTANCE:
|
||||||
|
return face.measurements.getInterocularDistance();
|
||||||
|
case MOUTH_OPEN:
|
||||||
|
return face.expressions.getMouthOpen();
|
||||||
|
case LIP_PRESS:
|
||||||
|
return face.expressions.getLipPress();
|
||||||
|
case BROW_RAISE:
|
||||||
|
return face.expressions.getBrowRaise();
|
||||||
|
case NOSE_WRINKLER:
|
||||||
|
return face.expressions.getNoseWrinkle();
|
||||||
|
case LIP_DEPRESSOR:
|
||||||
|
return face.expressions.getLipCornerDepressor();
|
||||||
|
case BROW_FURROW:
|
||||||
|
return face.expressions.getBrowFurrow();
|
||||||
|
case ATTENTION:
|
||||||
|
return face.expressions.getAttention();
|
||||||
|
case SMILE:
|
||||||
|
return face.expressions.getSmile();
|
||||||
|
case INNER_BROW_RAISER:
|
||||||
|
return face.expressions.getBrowRaise();
|
||||||
|
case CHIN_RAISER:
|
||||||
|
return face.expressions.getChinRaise();
|
||||||
|
case SMIRK:
|
||||||
|
return face.expressions.getSmirk();
|
||||||
|
case LIP_SUCK:
|
||||||
|
return face.expressions.getLipSuck();
|
||||||
|
case UPPER_LIP_RAISER:
|
||||||
|
return face.expressions.getUpperLipRaise();
|
||||||
|
case LIP_PUCKER:
|
||||||
|
return face.expressions.getLipPucker();
|
||||||
|
case EYE_CLOSURE:
|
||||||
|
return face.expressions.getEyeClosure();
|
||||||
|
case ENGAGEMENT:
|
||||||
|
return face.emotions.getEngagement();
|
||||||
|
case VALENCE:
|
||||||
|
return face.emotions.getValence();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDbName() {
|
||||||
|
return this.name().toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
49
app/src/main/java/com/rubenvandeven/emotionhero/Game.java
Normal file
49
app/src/main/java/com/rubenvandeven/emotionhero/Game.java
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package com.rubenvandeven.emotionhero;
|
||||||
|
|
||||||
|
import com.loopj.android.http.JsonHttpResponseHandler;
|
||||||
|
import com.loopj.android.http.RequestParams;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruben on 02/09/16.
|
||||||
|
*
|
||||||
|
* A play of a level by current user at a specific time
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Game {
|
||||||
|
public Long id;
|
||||||
|
public Scenario scenario;
|
||||||
|
public float score;
|
||||||
|
public Date time;
|
||||||
|
public String remoteId;
|
||||||
|
public Map<Integer, Hit> hits = new HashMap<>();
|
||||||
|
|
||||||
|
public Game(Long id, int lvl_id, float score, Date time, String remoteId) {
|
||||||
|
this(id, new Scenario(lvl_id, null), score, time, remoteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Game(Long id, Scenario scenario, float score, Date time, String remoteId) {
|
||||||
|
this.id = id;
|
||||||
|
this.scenario= scenario;
|
||||||
|
this.score = score;
|
||||||
|
this.time = time == null ? new Date() : time;
|
||||||
|
this.remoteId = remoteId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHit(Hit hit) {
|
||||||
|
hits.put(hit.target.index, hit);
|
||||||
|
score = calculateScore();
|
||||||
|
}
|
||||||
|
|
||||||
|
private float calculateScore() {
|
||||||
|
float s = 0;
|
||||||
|
for(Hit hit: hits.values()) {
|
||||||
|
s += hit.score;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,401 @@
|
||||||
|
package com.rubenvandeven.emotionhero;
|
||||||
|
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
|
import android.graphics.PointF;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruben on 02/09/16.
|
||||||
|
*
|
||||||
|
* To test data:
|
||||||
|
* adb -d shell "run-as com.rubenvandeven.emotionhero ls /data/data/com.rubenvandeven.emotionhero/databases/"
|
||||||
|
* adb -d shell "run-as com.rubenvandeven.emotionhero cp /data/data/com.rubenvandeven.emotionhero/databases/emotionhero.db /sdcard/emotionhero.db"
|
||||||
|
* adb pull /sdcard/emotionhero.db
|
||||||
|
*/
|
||||||
|
public class GameOpenHelper extends SQLiteOpenHelper {
|
||||||
|
private static final int DATABASE_VERSION = 2;
|
||||||
|
private static final String GAME_TABLE_NAME = "games";
|
||||||
|
private static final String GAME_TABLE_CREATE =
|
||||||
|
"CREATE TABLE " + GAME_TABLE_NAME + " (" +
|
||||||
|
"id INTEGER NOT NULL," +
|
||||||
|
"lvl_id INTEGER NOT NULL," +
|
||||||
|
"score VARCHAR(255) NOT NULL," +
|
||||||
|
"time INTEGER NOT NULL," +
|
||||||
|
"remoteId VARCHAR(255) DEFAULT NULL, " +
|
||||||
|
"PRIMARY KEY(id));";
|
||||||
|
private static final String[] GAME_PROJECTION = {
|
||||||
|
"id",
|
||||||
|
"lvl_id",
|
||||||
|
"score",
|
||||||
|
"time",
|
||||||
|
"remoteId"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final String HIT_TABLE_NAME = "hits";
|
||||||
|
public static final String HIT_TABLE_CREATE =
|
||||||
|
"CREATE TABLE hits (" +
|
||||||
|
"id INTEGER NOT NULL," +
|
||||||
|
"game_id INTEGER NOT NULL," +
|
||||||
|
"target_index INTEGER NOT_NULL," +
|
||||||
|
"score VARCHAR(20)," +
|
||||||
|
"remoteId VARCHAR(20)," +
|
||||||
|
"glasses VARCHAR(20)," +
|
||||||
|
"ethnicity VARCHAR(20)," +
|
||||||
|
"age VARCHAR(20)," +
|
||||||
|
"gender VARCHAR(1)," +
|
||||||
|
"anger VARCHAR(20)," +
|
||||||
|
"contempt VARCHAR(20)," +
|
||||||
|
"disgust VARCHAR(20)," +
|
||||||
|
"fear VARCHAR(20)," +
|
||||||
|
"joy VARCHAR(20)," +
|
||||||
|
"sadness VARCHAR(20)," +
|
||||||
|
"surprise VARCHAR(20)," +
|
||||||
|
"roll VARCHAR(20)," +
|
||||||
|
"pitch VARCHAR(20)," +
|
||||||
|
"yaw VARCHAR(20)," +
|
||||||
|
"inter_ocular_distance VARCHAR(20)," +
|
||||||
|
"mouth_open VARCHAR(20)," +
|
||||||
|
"lip_press VARCHAR(20)," +
|
||||||
|
"brow_raise VARCHAR(20)," +
|
||||||
|
"nose_wrinkler VARCHAR(20)," +
|
||||||
|
"lip_depressor VARCHAR(20)," +
|
||||||
|
"brow_furrow VARCHAR(20)," +
|
||||||
|
"attention VARCHAR(20)," +
|
||||||
|
"smile VARCHAR(20)," +
|
||||||
|
"inner_brow_raiser VARCHAR(20)," +
|
||||||
|
"chin_raiser VARCHAR(20)," +
|
||||||
|
"smirk VARCHAR(20)," +
|
||||||
|
"lip_suck VARCHAR(20)," +
|
||||||
|
"upper_lip_raiser VARCHAR(20)," +
|
||||||
|
"lip_pucker VARCHAR(20)," +
|
||||||
|
"eye_closure VARCHAR(20)," +
|
||||||
|
"engagement VARCHAR(20)," +
|
||||||
|
"valence VARCHAR(20)," +
|
||||||
|
"point_0x VARCHAR(20)," +
|
||||||
|
"point_0y VARCHAR(20)," +
|
||||||
|
"point_1x VARCHAR(20)," +
|
||||||
|
"point_1y VARCHAR(20)," +
|
||||||
|
"point_2x VARCHAR(20)," +
|
||||||
|
"point_2y VARCHAR(20)," +
|
||||||
|
"point_3x VARCHAR(20)," +
|
||||||
|
"point_3y VARCHAR(20)," +
|
||||||
|
"point_4x VARCHAR(20)," +
|
||||||
|
"point_4y VARCHAR(20)," +
|
||||||
|
"point_5x VARCHAR(20)," +
|
||||||
|
"point_5y VARCHAR(20)," +
|
||||||
|
"point_6x VARCHAR(20)," +
|
||||||
|
"point_6y VARCHAR(20)," +
|
||||||
|
"point_7x VARCHAR(20)," +
|
||||||
|
"point_7y VARCHAR(20)," +
|
||||||
|
"point_8x VARCHAR(20)," +
|
||||||
|
"point_8y VARCHAR(20)," +
|
||||||
|
"point_9x VARCHAR(20)," +
|
||||||
|
"point_9y VARCHAR(20)," +
|
||||||
|
"point_10x VARCHAR(20)," +
|
||||||
|
"point_10y VARCHAR(20)," +
|
||||||
|
"point_11x VARCHAR(20)," +
|
||||||
|
"point_11y VARCHAR(20)," +
|
||||||
|
"point_12x VARCHAR(20)," +
|
||||||
|
"point_12y VARCHAR(20)," +
|
||||||
|
"point_13x VARCHAR(20)," +
|
||||||
|
"point_13y VARCHAR(20)," +
|
||||||
|
"point_14x VARCHAR(20)," +
|
||||||
|
"point_14y VARCHAR(20)," +
|
||||||
|
"point_15x VARCHAR(20)," +
|
||||||
|
"point_15y VARCHAR(20)," +
|
||||||
|
"point_16x VARCHAR(20)," +
|
||||||
|
"point_16y VARCHAR(20)," +
|
||||||
|
"point_17x VARCHAR(20)," +
|
||||||
|
"point_17y VARCHAR(20)," +
|
||||||
|
"point_18x VARCHAR(20)," +
|
||||||
|
"point_18y VARCHAR(20)," +
|
||||||
|
"point_19x VARCHAR(20)," +
|
||||||
|
"point_19y VARCHAR(20)," +
|
||||||
|
"point_20x VARCHAR(20)," +
|
||||||
|
"point_20y VARCHAR(20)," +
|
||||||
|
"point_21x VARCHAR(20)," +
|
||||||
|
"point_21y VARCHAR(20)," +
|
||||||
|
"point_22x VARCHAR(20)," +
|
||||||
|
"point_22y VARCHAR(20)," +
|
||||||
|
"point_23x VARCHAR(20)," +
|
||||||
|
"point_23y VARCHAR(20)," +
|
||||||
|
"point_24x VARCHAR(20)," +
|
||||||
|
"point_24y VARCHAR(20)," +
|
||||||
|
"point_25x VARCHAR(20)," +
|
||||||
|
"point_25y VARCHAR(20)," +
|
||||||
|
"point_26x VARCHAR(20)," +
|
||||||
|
"point_26y VARCHAR(20)," +
|
||||||
|
"point_27x VARCHAR(20)," +
|
||||||
|
"point_27y VARCHAR(20)," +
|
||||||
|
"point_28x VARCHAR(20)," +
|
||||||
|
"point_28y VARCHAR(20)," +
|
||||||
|
"point_29x VARCHAR(20)," +
|
||||||
|
"point_29y VARCHAR(20)," +
|
||||||
|
"point_30x VARCHAR(20)," +
|
||||||
|
"point_30y VARCHAR(20)," +
|
||||||
|
"point_31x VARCHAR(20)," +
|
||||||
|
"point_31y VARCHAR(20)," +
|
||||||
|
"point_32x VARCHAR(20)," +
|
||||||
|
"point_32y VARCHAR(20)," +
|
||||||
|
"point_33x VARCHAR(20)," +
|
||||||
|
"point_33y VARCHAR(20)," +
|
||||||
|
"PRIMARY KEY (id));" ;
|
||||||
|
private static final String[] HIT_PROJECTION = {
|
||||||
|
"id","game_id", "target_index","score","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"
|
||||||
|
};
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
GameOpenHelper(Context context) {
|
||||||
|
super(context, "emotionhero.db", null, DATABASE_VERSION);
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(SQLiteDatabase db) {
|
||||||
|
db.execSQL(GAME_TABLE_CREATE);
|
||||||
|
db.execSQL(HIT_TABLE_CREATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
|
||||||
|
{
|
||||||
|
// until now there is only 1 database version.. so no alter table statements
|
||||||
|
if(oldVersion == 1 && newVersion == 2) {
|
||||||
|
// run alter statements
|
||||||
|
db.execSQL("DROP TABLE hits");
|
||||||
|
db.execSQL("DROP TABLE games");
|
||||||
|
db.execSQL(GAME_TABLE_CREATE);
|
||||||
|
db.execSQL(HIT_TABLE_CREATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertGame(Game game) {
|
||||||
|
// Gets the data repository in write mode
|
||||||
|
SQLiteDatabase db = getWritableDatabase();
|
||||||
|
|
||||||
|
// Create a new map of values, where column names are the keys
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put("lvl_id", game.scenario.id);
|
||||||
|
values.put("score", game.score);
|
||||||
|
values.put("time", game.time.getTime());
|
||||||
|
if(game.remoteId == null) {
|
||||||
|
values.putNull("remoteId");
|
||||||
|
} else {
|
||||||
|
values.put("remoteId", game.remoteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the new row, returning the primary key value of the new row
|
||||||
|
long newRowId = db.insert(GAME_TABLE_NAME, null, values);
|
||||||
|
game.id = newRowId;
|
||||||
|
|
||||||
|
for(Hit hit: game.hits.values()) {
|
||||||
|
insertHit(hit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Game[] getGamesForLevel(int lvl_id) {
|
||||||
|
SQLiteDatabase db = getReadableDatabase();
|
||||||
|
|
||||||
|
String selection = "lvl_id = ?";
|
||||||
|
String[] selectionArgs = { Integer.toString(lvl_id) };
|
||||||
|
|
||||||
|
String sortOrder = "score DESC";
|
||||||
|
|
||||||
|
Cursor c = db.query(
|
||||||
|
GAME_TABLE_NAME, // The table to query
|
||||||
|
GAME_PROJECTION, // The columns to return
|
||||||
|
selection, // The columns for the WHERE clause
|
||||||
|
selectionArgs, // The values for the WHERE clause
|
||||||
|
null, // don't group the rows
|
||||||
|
null, // don't filter by row groups
|
||||||
|
sortOrder, // The sort order
|
||||||
|
null // no limit!
|
||||||
|
);
|
||||||
|
return cursorToGames(c, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Game[] getGamesForScenario(Scenario s) {
|
||||||
|
SQLiteDatabase db = getReadableDatabase();
|
||||||
|
|
||||||
|
String selection = "lvl_id = ?";
|
||||||
|
String[] selectionArgs = { Integer.toString(s.id) };
|
||||||
|
|
||||||
|
String sortOrder = "score DESC";
|
||||||
|
|
||||||
|
Cursor c = db.query(
|
||||||
|
GAME_TABLE_NAME, // The table to query
|
||||||
|
GAME_PROJECTION, // The columns to return
|
||||||
|
selection, // The columns for the WHERE clause
|
||||||
|
selectionArgs, // The values for the WHERE clause
|
||||||
|
null, // don't group the rows
|
||||||
|
null, // don't filter by row groups
|
||||||
|
sortOrder, // The sort order
|
||||||
|
null // no limit!
|
||||||
|
);
|
||||||
|
return cursorToGames(c, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Game[] cursorToGames(Cursor c, Scenario s) {
|
||||||
|
Game[] games = new Game[c.getCount()];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
c.moveToFirst();
|
||||||
|
while (!c.isAfterLast()) {
|
||||||
|
Scenario scenario = s == null ? new Scenario(c.getInt(1), null) : s;
|
||||||
|
Game game = new Game(c.getLong(0), scenario, c.getFloat(2), new Date(c.getInt(3)), c.getString(4));
|
||||||
|
games[i] = game;
|
||||||
|
this.getHitsForGame(game); // hits are appended to game object
|
||||||
|
i++;
|
||||||
|
c.moveToNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
return games;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveRemoteId(Game game) {
|
||||||
|
SQLiteDatabase db = getWritableDatabase();
|
||||||
|
|
||||||
|
// New value for one column
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put("remoteId", game.remoteId);
|
||||||
|
|
||||||
|
// Which row to update, based on the title
|
||||||
|
String selection = "id = ?";
|
||||||
|
String[] selectionArgs = { Long.toString(game.id) };
|
||||||
|
|
||||||
|
int count = db.update(
|
||||||
|
GAME_TABLE_NAME,
|
||||||
|
values,
|
||||||
|
selection,
|
||||||
|
selectionArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void insertHit(Hit hit) {
|
||||||
|
// Gets the data repository in write mode
|
||||||
|
SQLiteDatabase db = getWritableDatabase();
|
||||||
|
|
||||||
|
// Create a new map of values, where column names are the keys
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
|
||||||
|
values.put("game_id", hit.game.id);
|
||||||
|
values.put("target_index", hit.target.index);
|
||||||
|
values.put("score", hit.score);
|
||||||
|
|
||||||
|
values.put("glasses", hit.glasses);
|
||||||
|
values.put("ethnicity", hit.ethnicity);
|
||||||
|
values.put("age", hit.age);
|
||||||
|
values.put("gender", hit.gender);
|
||||||
|
|
||||||
|
for(Emotion emotion: Emotion.values()) {
|
||||||
|
values.put(emotion.name().toLowerCase(), hit.emotions.get(emotion));
|
||||||
|
}
|
||||||
|
for(Expression exp: Expression.values()) {
|
||||||
|
values.put(exp.getDbName(), hit.expressions.get(exp));
|
||||||
|
}
|
||||||
|
|
||||||
|
int i=0;
|
||||||
|
for(PointF point: hit.points) {
|
||||||
|
values.put("point_"+i+"x", point.x);
|
||||||
|
values.put("point_"+i+"y", point.y);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hit.remoteId == null) {
|
||||||
|
values.putNull("remoteId");
|
||||||
|
} else {
|
||||||
|
values.put("remoteId", hit.remoteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the new row, returning the primary key value of the new row
|
||||||
|
long newRowId = db.insert(HIT_TABLE_NAME, null, values);
|
||||||
|
hit.id = newRowId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Hit> getHitsForGame(Game game) {
|
||||||
|
SQLiteDatabase db = getReadableDatabase();
|
||||||
|
|
||||||
|
String selection = "game_id = ?";
|
||||||
|
String[] selectionArgs = { Long.toString(game.id) };
|
||||||
|
|
||||||
|
String sortOrder = "target_index ASC";
|
||||||
|
|
||||||
|
Cursor c = db.query(
|
||||||
|
HIT_TABLE_NAME, // The table to query
|
||||||
|
HIT_PROJECTION, // The columns to return
|
||||||
|
selection, // The columns for the WHERE clause
|
||||||
|
selectionArgs, // The values for the WHERE clause
|
||||||
|
null, // don't group the rows
|
||||||
|
null, // don't filter by row groups
|
||||||
|
sortOrder, // The sort order
|
||||||
|
null // no limit!
|
||||||
|
);
|
||||||
|
return cursorToHits(game, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Hit> cursorToHits(Game game, Cursor c) {
|
||||||
|
ArrayList<Hit> hits = new ArrayList<Hit>(c.getCount());
|
||||||
|
c.moveToFirst();
|
||||||
|
while (!c.isAfterLast()) {
|
||||||
|
hits.add(new Hit(game, c));
|
||||||
|
c.moveToNext();
|
||||||
|
}
|
||||||
|
return hits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void saveRemoteId(Hit hit) {
|
||||||
|
SQLiteDatabase db = getWritableDatabase();
|
||||||
|
|
||||||
|
// New value for one column
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put("remoteId", hit.remoteId);
|
||||||
|
|
||||||
|
// Which row to update, based on the title
|
||||||
|
String selection = "id = ?";
|
||||||
|
String[] selectionArgs = { Long.toString(hit.id) };
|
||||||
|
|
||||||
|
int count = db.update(
|
||||||
|
HIT_TABLE_NAME,
|
||||||
|
values,
|
||||||
|
selection,
|
||||||
|
selectionArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Game getGameByid(long id) {
|
||||||
|
SQLiteDatabase db = getReadableDatabase();
|
||||||
|
|
||||||
|
String selection = "id = ?";
|
||||||
|
String[] selectionArgs = { Long.toString(id) };
|
||||||
|
|
||||||
|
Cursor c = db.query(
|
||||||
|
GAME_TABLE_NAME, // The table to query
|
||||||
|
GAME_PROJECTION, // The columns to return
|
||||||
|
selection, // The columns for the WHERE clause
|
||||||
|
selectionArgs, // The values for the WHERE clause
|
||||||
|
null, // don't group the rows
|
||||||
|
null, // don't filter by row groups
|
||||||
|
null, // The sort order
|
||||||
|
null // no limit!
|
||||||
|
);
|
||||||
|
|
||||||
|
Game[] games = cursorToGames(c, null);
|
||||||
|
return games[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLocalRankOfGame(Game game) {
|
||||||
|
String[] params = { Long.toString(game.scenario.id), Float.toString(game.score) };
|
||||||
|
Cursor c = getReadableDatabase().rawQuery("SELECT COUNT(id)+1 FROM games WHERE lvl_id = ? AND score > ?", params);
|
||||||
|
c.moveToFirst();
|
||||||
|
return c.getInt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -205,7 +205,7 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL
|
||||||
detector.setDetectAllEmotions(true);
|
detector.setDetectAllEmotions(true);
|
||||||
detector.setDetectAllAppearances(false);
|
detector.setDetectAllAppearances(false);
|
||||||
detector.setDetectAllEmojis(false);
|
detector.setDetectAllEmojis(false);
|
||||||
detector.setDetectAllExpressions(false);
|
detector.setDetectAllExpressions(true);
|
||||||
detector.setMaxProcessRate(20);
|
detector.setMaxProcessRate(20);
|
||||||
|
|
||||||
detector.setImageListener(this);
|
detector.setImageListener(this);
|
||||||
|
@ -393,8 +393,12 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL
|
||||||
// highscoreView.setVisibility(View.VISIBLE);
|
// highscoreView.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
finish();
|
finish();
|
||||||
|
GameOpenHelper gameHelper = new GameOpenHelper(getApplicationContext());
|
||||||
|
gameHelper.insertGame(currentScenario.game);
|
||||||
|
|
||||||
Intent intent = new Intent(this, HighscoreActivity.class);
|
Intent intent = new Intent(this, HighscoreActivity.class);
|
||||||
intent.putExtra(HighscoreActivity.INTENT_EXTRA_SCORE_ID, score.id.toString());
|
intent.putExtra(HighscoreActivity.INTENT_EXTRA_SCORE_ID, score.id.toString());
|
||||||
|
intent.putExtra(HighscoreActivity.INTENT_EXTRA_GAME_ID, currentScenario.game.id.toString());
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ public class HighscoreActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
|
||||||
public final static String INTENT_EXTRA_SCORE_ID = "com.rubenvandeven.emotionhero.SCORE_ID";
|
public final static String INTENT_EXTRA_SCORE_ID = "com.rubenvandeven.emotionhero.SCORE_ID";
|
||||||
|
public final static String INTENT_EXTRA_GAME_ID = "com.rubenvandeven.emotionhero.GAME_ID";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link android.support.v4.view.PagerAdapter} that will provide
|
* The {@link android.support.v4.view.PagerAdapter} that will provide
|
||||||
|
@ -67,6 +68,7 @@ public class HighscoreActivity extends AppCompatActivity {
|
||||||
player = Player.getInstance(getApplicationContext());
|
player = Player.getInstance(getApplicationContext());
|
||||||
|
|
||||||
String scoreIdString = getIntent().getStringExtra(INTENT_EXTRA_SCORE_ID);
|
String scoreIdString = getIntent().getStringExtra(INTENT_EXTRA_SCORE_ID);
|
||||||
|
String gameIdString = getIntent().getStringExtra(INTENT_EXTRA_GAME_ID);
|
||||||
if(scoreIdString != null) {
|
if(scoreIdString != null) {
|
||||||
UUID score_id = UUID.fromString(scoreIdString);
|
UUID score_id = UUID.fromString(scoreIdString);
|
||||||
score = player.getPlayerInfo().getScore(score_id);
|
score = player.getPlayerInfo().getScore(score_id);
|
||||||
|
@ -74,10 +76,20 @@ public class HighscoreActivity extends AppCompatActivity {
|
||||||
Log.e("Highscore", "CANNOT FIND SCORE!! " + scoreIdString);
|
Log.e("Highscore", "CANNOT FIND SCORE!! " + scoreIdString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(gameIdString != null) {
|
||||||
|
long gameId = Long.valueOf(gameIdString);
|
||||||
|
Game game = player.getGameOpenHelper().getGameByid(gameId);
|
||||||
|
if(game == null) {
|
||||||
|
Log.e("Highscore", "CANNOT FIND GAME!! " + gameIdString);
|
||||||
|
} else {
|
||||||
|
Log.i("Highscore", "FOUND GAME" + game.id + " " + game.score);
|
||||||
|
Log.i("Highscore", "RANK " + player.getGameOpenHelper().getLocalRankOfGame(game));
|
||||||
|
player.api.syncGame(game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Log.i("Highscore", ""+player.getPlayerInfo().reachedLevelId);
|
Log.i("Highscore", ""+player.getPlayerInfo().reachedLevelId);
|
||||||
|
|
||||||
|
|
||||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
|
130
app/src/main/java/com/rubenvandeven/emotionhero/Hit.java
Normal file
130
app/src/main/java/com/rubenvandeven/emotionhero/Hit.java
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
package com.rubenvandeven.emotionhero;
|
||||||
|
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.graphics.PointF;
|
||||||
|
|
||||||
|
import com.affectiva.android.affdex.sdk.detector.Face;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruben on 02/09/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Hit {
|
||||||
|
|
||||||
|
public long id;
|
||||||
|
|
||||||
|
public Scenario.Target target;
|
||||||
|
|
||||||
|
@Expose(serialize = false, deserialize = false)
|
||||||
|
public Game game;
|
||||||
|
|
||||||
|
public float score;
|
||||||
|
|
||||||
|
public Map<Emotion, Float> emotions = new HashMap<>(7);
|
||||||
|
|
||||||
|
public boolean glasses;
|
||||||
|
public String ethnicity;
|
||||||
|
public String age;
|
||||||
|
public String gender;
|
||||||
|
|
||||||
|
public Map<Expression, Float> expressions = new HashMap<>(21); // also includes measurements
|
||||||
|
|
||||||
|
public PointF[] points = new PointF[34];
|
||||||
|
|
||||||
|
public String remoteId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for game moment
|
||||||
|
*/
|
||||||
|
public Hit(Scenario.Target target, Game game, Face face, float score) {
|
||||||
|
this.score = score;
|
||||||
|
this.target = target;
|
||||||
|
this.game = game;
|
||||||
|
for(Emotion emotion: Emotion.values()) {
|
||||||
|
emotions.put(emotion,emotion.getValueFromFace(face));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.gender = face.appearance.getGender() == Face.GENDER.UNKNOWN ? "U" : (face.appearance.getGender() == Face.GENDER.MALE ? "M" : "F");
|
||||||
|
this.glasses = face.appearance.getGlasses() == Face.GLASSES.YES ? true : false;
|
||||||
|
this.ethnicity = face.appearance.getEthnicity().name();
|
||||||
|
this.age = face.appearance.getAge().name();
|
||||||
|
|
||||||
|
for(Expression exp: Expression.values()) {
|
||||||
|
this.expressions.put(exp, exp.getValueFromFace(face));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.points = face.getFacePoints().clone();
|
||||||
|
|
||||||
|
game.addHit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor from database entity
|
||||||
|
*/
|
||||||
|
public Hit(Game game, Cursor c) {
|
||||||
|
this.id = c.getLong(c.getColumnIndex("id"));
|
||||||
|
this.score = c.getFloat(c.getColumnIndex("score"));
|
||||||
|
String rId = c.getString(c.getColumnIndex("remoteId"));
|
||||||
|
this.remoteId = (rId == null || rId.length() == 0) ? null : c.getString(c.getColumnIndex("remoteId"));
|
||||||
|
this.target = game.scenario.getTargetByIndex(c.getInt(c.getColumnIndex("target_index")));
|
||||||
|
|
||||||
|
this.glasses = c.getInt(c.getColumnIndex("glasses")) == 1;
|
||||||
|
this.ethnicity = c.getString(c.getColumnIndex("ethnicity"));
|
||||||
|
this.age = c.getString(c.getColumnIndex("age"));
|
||||||
|
this.gender = c.getString(c.getColumnIndex("gender"));
|
||||||
|
|
||||||
|
this.emotions.put(Emotion.ANGER, c.getFloat(c.getColumnIndex("anger")));
|
||||||
|
this.emotions.put(Emotion.CONTEMPT, c.getFloat(c.getColumnIndex("contempt")));
|
||||||
|
this.emotions.put(Emotion.DISGUST, c.getFloat(c.getColumnIndex("disgust")));
|
||||||
|
this.emotions.put(Emotion.FEAR, c.getFloat(c.getColumnIndex("fear")));
|
||||||
|
this.emotions.put(Emotion.JOY, c.getFloat(c.getColumnIndex("joy")));
|
||||||
|
this.emotions.put(Emotion.SADNESS, c.getFloat(c.getColumnIndex("sadness")));
|
||||||
|
this.emotions.put(Emotion.SURPRISE, c.getFloat(c.getColumnIndex("surprise")));
|
||||||
|
|
||||||
|
for(Expression exp: Expression.values()) {
|
||||||
|
this.expressions.put(exp, c.getFloat( c.getColumnIndex( exp.getDbName() )));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.points[0] = new PointF(c.getFloat(c.getColumnIndex("point_0x")), c.getFloat(c.getColumnIndex("point_0y")));
|
||||||
|
this.points[1] = new PointF(c.getFloat(c.getColumnIndex("point_1x")), c.getFloat(c.getColumnIndex("point_1y")));
|
||||||
|
this.points[2] = new PointF(c.getFloat(c.getColumnIndex("point_2x")), c.getFloat(c.getColumnIndex("point_2y")));
|
||||||
|
this.points[3] = new PointF(c.getFloat(c.getColumnIndex("point_3x")), c.getFloat(c.getColumnIndex("point_3y")));
|
||||||
|
this.points[4] = new PointF(c.getFloat(c.getColumnIndex("point_4x")), c.getFloat(c.getColumnIndex("point_4y")));
|
||||||
|
this.points[5] = new PointF(c.getFloat(c.getColumnIndex("point_5x")), c.getFloat(c.getColumnIndex("point_5y")));
|
||||||
|
this.points[6] = new PointF(c.getFloat(c.getColumnIndex("point_6x")), c.getFloat(c.getColumnIndex("point_6y")));
|
||||||
|
this.points[7] = new PointF(c.getFloat(c.getColumnIndex("point_7x")), c.getFloat(c.getColumnIndex("point_7y")));
|
||||||
|
this.points[8] = new PointF(c.getFloat(c.getColumnIndex("point_8x")), c.getFloat(c.getColumnIndex("point_8y")));
|
||||||
|
this.points[9] = new PointF(c.getFloat(c.getColumnIndex("point_9x")), c.getFloat(c.getColumnIndex("point_9y")));
|
||||||
|
this.points[10] = new PointF(c.getFloat(c.getColumnIndex("point_10x")), c.getFloat(c.getColumnIndex("point_10y")));
|
||||||
|
this.points[11] = new PointF(c.getFloat(c.getColumnIndex("point_11x")), c.getFloat(c.getColumnIndex("point_11y")));
|
||||||
|
this.points[12] = new PointF(c.getFloat(c.getColumnIndex("point_12x")), c.getFloat(c.getColumnIndex("point_12y")));
|
||||||
|
this.points[13] = new PointF(c.getFloat(c.getColumnIndex("point_13x")), c.getFloat(c.getColumnIndex("point_13y")));
|
||||||
|
this.points[14] = new PointF(c.getFloat(c.getColumnIndex("point_14x")), c.getFloat(c.getColumnIndex("point_14y")));
|
||||||
|
this.points[15] = new PointF(c.getFloat(c.getColumnIndex("point_15x")), c.getFloat(c.getColumnIndex("point_15y")));
|
||||||
|
this.points[16] = new PointF(c.getFloat(c.getColumnIndex("point_16x")), c.getFloat(c.getColumnIndex("point_16y")));
|
||||||
|
this.points[17] = new PointF(c.getFloat(c.getColumnIndex("point_17x")), c.getFloat(c.getColumnIndex("point_17y")));
|
||||||
|
this.points[18] = new PointF(c.getFloat(c.getColumnIndex("point_18x")), c.getFloat(c.getColumnIndex("point_18y")));
|
||||||
|
this.points[19] = new PointF(c.getFloat(c.getColumnIndex("point_19x")), c.getFloat(c.getColumnIndex("point_19y")));
|
||||||
|
this.points[20] = new PointF(c.getFloat(c.getColumnIndex("point_20x")), c.getFloat(c.getColumnIndex("point_20y")));
|
||||||
|
this.points[21] = new PointF(c.getFloat(c.getColumnIndex("point_21x")), c.getFloat(c.getColumnIndex("point_21y")));
|
||||||
|
this.points[22] = new PointF(c.getFloat(c.getColumnIndex("point_22x")), c.getFloat(c.getColumnIndex("point_22y")));
|
||||||
|
this.points[23] = new PointF(c.getFloat(c.getColumnIndex("point_23x")), c.getFloat(c.getColumnIndex("point_23y")));
|
||||||
|
this.points[24] = new PointF(c.getFloat(c.getColumnIndex("point_24x")), c.getFloat(c.getColumnIndex("point_24y")));
|
||||||
|
this.points[25] = new PointF(c.getFloat(c.getColumnIndex("point_25x")), c.getFloat(c.getColumnIndex("point_25y")));
|
||||||
|
this.points[26] = new PointF(c.getFloat(c.getColumnIndex("point_26x")), c.getFloat(c.getColumnIndex("point_26y")));
|
||||||
|
this.points[27] = new PointF(c.getFloat(c.getColumnIndex("point_27x")), c.getFloat(c.getColumnIndex("point_27y")));
|
||||||
|
this.points[28] = new PointF(c.getFloat(c.getColumnIndex("point_28x")), c.getFloat(c.getColumnIndex("point_28y")));
|
||||||
|
this.points[29] = new PointF(c.getFloat(c.getColumnIndex("point_29x")), c.getFloat(c.getColumnIndex("point_29y")));
|
||||||
|
this.points[30] = new PointF(c.getFloat(c.getColumnIndex("point_30x")), c.getFloat(c.getColumnIndex("point_30y")));
|
||||||
|
this.points[31] = new PointF(c.getFloat(c.getColumnIndex("point_31x")), c.getFloat(c.getColumnIndex("point_31y")));
|
||||||
|
this.points[32] = new PointF(c.getFloat(c.getColumnIndex("point_32x")), c.getFloat(c.getColumnIndex("point_32y")));
|
||||||
|
this.points[33] = new PointF(c.getFloat(c.getColumnIndex("point_33x")), c.getFloat(c.getColumnIndex("point_33y")));
|
||||||
|
|
||||||
|
game.addHit(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -91,6 +91,7 @@ public class Player {
|
||||||
while((ch = fis.read()) != -1){
|
while((ch = fis.read()) != -1){
|
||||||
builder.append((char)ch);
|
builder.append((char)ch);
|
||||||
}
|
}
|
||||||
|
Log.d("PLAYER", builder.toString());
|
||||||
return PlayerInfo.fromJson(builder.toString());
|
return PlayerInfo.fromJson(builder.toString());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return new PlayerInfo();
|
return new PlayerInfo();
|
||||||
|
@ -120,4 +121,12 @@ public class Player {
|
||||||
Log.e("PlayerInfo", "Could not save player information!");
|
Log.e("PlayerInfo", "Could not save player information!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GameOpenHelper gameOpenHelper;
|
||||||
|
public GameOpenHelper getGameOpenHelper() {
|
||||||
|
if(gameOpenHelper == null) {
|
||||||
|
gameOpenHelper = new GameOpenHelper(getContext());
|
||||||
|
}
|
||||||
|
return gameOpenHelper;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,13 @@
|
||||||
package com.rubenvandeven.emotionhero;
|
package com.rubenvandeven.emotionhero;
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseArray;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static com.google.gson.internal.bind.TypeAdapters.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ruben on 20/08/16.
|
* Created by ruben on 20/08/16.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.util.Log;
|
||||||
import com.affectiva.android.affdex.sdk.detector.Face;
|
import com.affectiva.android.affdex.sdk.detector.Face;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
|
@ -39,6 +40,11 @@ public class Scenario {
|
||||||
|
|
||||||
float duration = 0;
|
float duration = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a game is beign played.
|
||||||
|
*/
|
||||||
|
Game game;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
|
@ -68,22 +74,11 @@ public class Scenario {
|
||||||
ArrayList<Target> targets = new ArrayList<>();
|
ArrayList<Target> targets = new ArrayList<>();
|
||||||
|
|
||||||
class Target {
|
class Target {
|
||||||
|
public int index;
|
||||||
public Emotion emotion;
|
public Emotion emotion;
|
||||||
public float value;
|
public float value;
|
||||||
public float timestamp;
|
public float timestamp;
|
||||||
public Hit hit;
|
public boolean isHit = false;
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<Hit> hits = new ArrayList<>();
|
|
||||||
|
|
||||||
class Hit {
|
|
||||||
public float value;
|
|
||||||
/**
|
|
||||||
* Extra bonus given
|
|
||||||
*/
|
|
||||||
public boolean isSpotOn = false;
|
|
||||||
// public Bitmap image; //image at time of hit
|
|
||||||
public Face face; // face at time of hit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,7 +110,7 @@ public class Scenario {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
timer.schedule(tickTask, 0, 1000/DESIRED_FPS);
|
timer.schedule(tickTask, 0, 1000/DESIRED_FPS);
|
||||||
|
this.game = new Game(null, this, 0, new Date(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,30 +128,30 @@ public class Scenario {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = targets.size() - 1; i >= 0; i--) {
|
for(Target target: targets) {
|
||||||
Target target = targets.get(i);
|
|
||||||
// skip targets that are already scored
|
// skip targets that are already scored
|
||||||
if(target.hit != null) {
|
if(target.isHit == true) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(target.timestamp <= runningTime) {
|
if(target.timestamp <= runningTime) {
|
||||||
float scored_value = target.emotion.getValueFromFace(currentFace);
|
float scored_value = target.emotion.getValueFromFace(currentFace);
|
||||||
float required_value = target.value;
|
float required_value = target.value;
|
||||||
Hit hit = new Hit();
|
float score = Math.round(100 - Math.abs(scored_value-required_value));
|
||||||
hit.value = Math.round(100 - Math.abs(scored_value-required_value));
|
Hit hit = new Hit(target, game, currentFace, score);
|
||||||
hit.face = currentFace;
|
|
||||||
hits.add(hit);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
_activity.sound.play(_activity.soundIds.get(_activity.SOUND_SCORE), 1, 1,
|
_activity.sound.play(_activity.soundIds.get(_activity.SOUND_SCORE), 1, 1,
|
||||||
1,0, hit.value / 200f + 0.5f ); // play back the sound slower
|
1,0, hit.score / 200f + 0.5f ); // play back the sound slower
|
||||||
// depending on hit value
|
// depending on hit value
|
||||||
target.hit = hit;
|
target.isHit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Target getTargetByIndex(int target_index) {
|
||||||
|
return targets.get(target_index-1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a target on given timestamp
|
* Add a target on given timestamp
|
||||||
|
@ -175,6 +170,7 @@ public class Scenario {
|
||||||
target.timestamp = timestamp;
|
target.timestamp = timestamp;
|
||||||
target.value = value;
|
target.value = value;
|
||||||
target.emotion = emotion;
|
target.emotion = emotion;
|
||||||
|
target.index = targets.size() + 1;
|
||||||
targets.add(target);
|
targets.add(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,32 +191,11 @@ public class Scenario {
|
||||||
setTarget(emotion, value, timestamp);
|
setTarget(emotion, value, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated use @see tick()
|
|
||||||
* @param face
|
|
||||||
* @param timestamp
|
|
||||||
*/
|
|
||||||
public void validateFaceOnTime(Face face, float timestamp)
|
|
||||||
{
|
|
||||||
// TODO: interpolation of time
|
|
||||||
for (int i = targets.size() - 1; i >= 0; i--) {
|
|
||||||
Target target = targets.get(i);
|
|
||||||
if(target.timestamp > timestamp - 0.2 && target.timestamp < timestamp + 0.2) {
|
|
||||||
float scored_value = target.emotion.getValueFromFace(face);
|
|
||||||
float required_value = target.value;
|
|
||||||
Hit hit = new Hit();
|
|
||||||
hit.value = 100 - Math.abs(scored_value-required_value);
|
|
||||||
target.hit = hit;
|
|
||||||
hits.add(hit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getHitTotalValue()
|
public float getHitTotalValue()
|
||||||
{
|
{
|
||||||
float value = 0;
|
float value = 0;
|
||||||
for (Hit hit : hits) {
|
for (Hit hit : game.hits.values()) {
|
||||||
value += hit.value;
|
value += hit.score;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -385,4 +360,8 @@ public class Scenario {
|
||||||
return "...";
|
return "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Hit getHitForTarget(Target target) {
|
||||||
|
return game.hits.get(target.index);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,9 +196,10 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback
|
||||||
|
|
||||||
canvas.drawCircle(cx, cy, max_ball_radius * target.value/100, emoPaints.get(target.emotion));
|
canvas.drawCircle(cx, cy, max_ball_radius * target.value/100, emoPaints.get(target.emotion));
|
||||||
|
|
||||||
if(target.hit != null) {
|
if(target.isHit) {
|
||||||
canvas.drawText(Float.toString(target.hit.value), cx, cy, emoPaints.get(target.emotion));
|
Hit hit = _scenario.getHitForTarget(target);
|
||||||
canvas.drawCircle(cx, cy, max_ball_radius * target.hit.value/100, emoScoredPaints.get(target.emotion));
|
canvas.drawText(Float.toString(hit.score), cx, cy, emoPaints.get(target.emotion));
|
||||||
|
canvas.drawCircle(cx, cy, max_ball_radius * hit.score/100, emoScoredPaints.get(target.emotion));
|
||||||
|
|
||||||
// TODO: Use target.hit.face to set Rect src.
|
// TODO: Use target.hit.face to set Rect src.
|
||||||
// if(target.hit.image != null) {
|
// if(target.hit.image != null) {
|
||||||
|
|
Loading…
Reference in a new issue