emotionhero/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java

173 lines
4.5 KiB
Java

package com.rubenvandeven.emotionhero;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import com.affectiva.android.affdex.sdk.detector.Face;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* Created by ruben on 16/08/16.
*/
abstract public class Scenario {
float duration = 0;
long startTime = 0;
ArrayList<Target> targets = new ArrayList<>();
abstract void createScenario();
class Target {
public Emotion emotion;
public float value;
public float timestamp;
}
ArrayList<Score> scores = new ArrayList<>();
class Score {
public float value;
/**
* Extra bonus given
*/
public boolean isSpotOn = false;
/**
* The target the score is awarded for
*/
public Target target;
}
/**
* Constructor
*/
public Scenario()
{
createScenario();
}
/**
* Add a target on given timestamp
* @param emotion
* @param value
* @param timestamp
*/
public void setTarget(Emotion emotion, float value, float timestamp)
{
// Log.e(GamingActivity.LOG_TAG, "Set target:" + Float.toString(timestamp) + " " + Float.toString(duration));
if(timestamp > duration)
{
duration = timestamp;
}
Target target = new Target();
target.timestamp = timestamp;
target.value = value;
target.emotion = emotion;
targets.add(target);
}
/**
* Add target after existing targets, give delta with last item instead of absolute time.
* @param emotion
* @param value
* @param interval
*/
public void addTarget(Emotion emotion, float value, float interval)
{
float timestamp;
if(targets.isEmpty()) {
timestamp = interval;
} else {
timestamp = targets.get(targets.size() - 1).timestamp + interval;
}
setTarget(emotion, value, 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;
Score score = new Score();
score.value = 100 - Math.abs(scored_value-required_value);
score.target = target;
scores.add(score);
}
}
}
public float getTotalScore()
{
float value = 0;
for (Score score : scores) {
value += score.value;
}
return value;
}
/**
* Check whether given timestamp is within duration of the scenario
* @param timestamp
* @return
*/
public boolean isWithinTime(float timestamp)
{
return timestamp <= duration;
}
public ArrayList<Target> getTargets() {
return targets;
}
/**
* Get the time within the scenario (so since start() has been called)
*/
public float getTime() {
// if not started, don't move the labels, if started, move them by diff_y
if(startTime == 0) {
return 0;
} else {
float diff_t = ((System.currentTimeMillis() - startTime)) / (float) 1000;
if(diff_t > duration) { // never larger than scenario duration
return duration;
}
return diff_t;
}
}
public void start()
{
startTime = System.currentTimeMillis();
}
// TODO: create a 'tick' that checks all current values with requirements and increases the timer etc
// TODO: ... if scenario is running. This internal times makes it easier to pause etc.
}
class ScenarioAnger extends Scenario{
void createScenario()
{
Log.d(GamingActivity.LOG_TAG, "CREATE SCENARIO: anger");
setTarget(Emotion.ANGER, 10, 1);
setTarget(Emotion.ANGER, 20, 2);
setTarget(Emotion.ANGER, 40, 3);
setTarget(Emotion.ANGER, 70, 4);
setTarget(Emotion.ANGER, 100, 5);
setTarget(Emotion.JOY, 100, 8);
setTarget(Emotion.ANGER, 100, 10);
setTarget(Emotion.JOY, 100, 15);
setTarget(Emotion.ANGER, 100, 20);
}
}