Now has ending, achievements calculated locally and send (have some of them now)

and Credits pimped
This commit is contained in:
Ruben 2016-09-16 18:04:01 +01:00
parent 4187be4eaf
commit dd4241c05f
28 changed files with 1346 additions and 448 deletions

View file

@ -9,8 +9,8 @@ android {
applicationId 'com.rubenvandeven.emotion_hero' applicationId 'com.rubenvandeven.emotion_hero'
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 24 targetSdkVersion 24
versionCode 2 versionCode 4
versionName '0.2' versionName '0.4'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
renderscriptTargetApi 16 renderscriptTargetApi 16

View file

@ -35,10 +35,6 @@
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name=".MenuActivity"
android:label="@string/app_name"
android:theme="@style/FullscreenTheme" />
<activity <activity
android:name=".HighscoreActivity" android:name=".HighscoreActivity"
android:label="@string/title_activity_highscore" android:label="@string/title_activity_highscore"
@ -67,7 +63,11 @@
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value="com.rubenvandeven.emotionhero.MirrorMenuActivity" /> android:value="com.rubenvandeven.emotionhero.MirrorMenuActivity" />
</activity> </activity>
<activity android:name=".IntroductionActivity"></activity> <activity android:name=".EndingActivity"
android:theme="@style/AppTheme.NoActionBar">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.rubenvandeven.emotionhero.ProgressActivity" /></activity>
</application> </application>
</manifest> </manifest>

View file

@ -1,6 +1,7 @@
package com.rubenvandeven.emotionhero; package com.rubenvandeven.emotionhero;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.widget.RelativeLayout;
/** /**
* Created by ruben on 10/09/16. * Created by ruben on 10/09/16.
@ -15,14 +16,20 @@ public class Achievement {
*/ */
public String description; public String description;
public Bitmap icon; public Bitmap icon;
public AchievementListener achievementListener;
public Achievement(String title, String description, Bitmap icon){ public Achievement(String title, Bitmap icon, AchievementListener lvlListener){
this.title = title; this.title = title;
this.description = description;
this.icon = icon; this.icon = icon;
this.achievementListener = lvlListener;
} }
public int getId() { public int getId() {
return AchievementCollection.getInstance().getId(this); return AchievementCollection.getInstance().getId(this);
} }
public interface AchievementListener {
boolean hasGotAchievement(Player player, Game game);
void setDescription(Player player, Game game, RelativeLayout layout);
}
} }

View file

@ -1,8 +1,15 @@
package com.rubenvandeven.emotionhero; package com.rubenvandeven.emotionhero;
import android.support.v4.content.res.TypedArrayUtils; import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.widget.AppCompatTextView;
import android.view.View;
import android.widget.RelativeLayout;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/** /**
* Created by ruben on 10/09/16. * Created by ruben on 10/09/16.
@ -10,12 +17,482 @@ import java.util.ArrayList;
public class AchievementCollection { public class AchievementCollection {
private ArrayList<Achievement> achievements = new ArrayList<Achievement>(){{ private ArrayList<Achievement> achievements = new ArrayList<Achievement>(){{
// fill the collection :-) // fill the collection :-)
add(new Achievement("Microexpressor", "...", null)); add(new Achievement(
add(new Achievement("\"In pursuit of happiness\"", "...", null)); "Microexpressor",
add(new Achievement("CEO", "...", null)); null,
add(new Achievement("Kuleshov", "...", null)); new Achievement.AchievementListener() {
add(new Achievement("Soap opera", "...", null)); @Override
add(new Achievement("Stock photo model", "...", null)); public boolean hasGotAchievement(Player player, Game game) {
// not showing intense enough? requested emo's only minisculy detected
//return false;
for(Hit hit: game.hits.values()) {
if(hit.target.value == 100) {
// if target was 100, but player only showed less
// then 13..s/he's playing with microexpressions ;-)
if(hit.emotions.get(hit.target.emotion) < 13) {
return true;
}
}
}
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("Do you have something to hide? You are not showing all requested emotions intense enough. A microexpression is a brief, involuntary facial expression shown on the face of humans according to emotions experienced.");
descriptionLayout.addView(textView);
}
})
);
add(new Achievement(
"Emotional leakage",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// picking up on emotions that are not requested.
// check for all hits in the level...
for(Hit hit: game.hits.values()) {
for(Emotion emotion: Emotion.values()) {
// ... whether the emotions that are NOT scored
// still have a value
if( hit.target.emotion != emotion && hit.emotions.get(emotion) > 20) {
// if so, there is emo leakage!!
return true;
}
}
}
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("There is no sign of deceit itself. There is no gesture, facial expression, nor muscle twitch that itself indicates that a person is lying. There are only clues that the person is poorly prepared and that the clues of emotions do not fit what the person is saying. These are what provide clues of leakage or deception. (Wikipedia)");
descriptionLayout.addView(textView);
}
})
);
add(new Achievement(
"A conversation with your data double",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// 2nd play is better than _PREVIOUS_ play!
Game previousGame = player.getGameOpenHelper().getPreviousGame(game);
if(previousGame == null) {
return false;
}
if(previousGame.bonus+previousGame.score < game.bonus+game.score) {
return true;
}
return false;
}
@Override
public void setDescription(Player player, Game game, final RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("You improved your performance after a retry! The 'data double' is a term coined by Mina Ruckenstein to describe how our gathered information is be figuratively reassembled for the purposes of personal reflection and interaction.");
descriptionLayout.addView(textView);
/*AppCompatTextView seeAlsoView = new AppCompatTextView(c);
seeAlsoView.setTextSize(12);
seeAlsoView.setText("See also: Ruckenstein, Mina (2014) Visualized and Interacted Life: Personal Analytics and Engagements with Data Doubles");
seeAlsoView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String url = "https://www.researchgate.net/publication/260792107_Visualized_and_Interacted_Life_Personal_Analytics_and_Engagements_with_Data_Doubles";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
descriptionLayout.getContext().startActivity(i);
}
});
descriptionLayout.addView(seeAlsoView);*/
}
})
);
add(new Achievement(
"Named emotions",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// have expressed all named emotions!
Map<Emotion, Boolean> showedEmotions = new HashMap<Emotion, Boolean>();
for(Hit hit: game.hits.values()) {
if(hit.score > 50) {
showedEmotions.put(hit.target.emotion, true);
}
}
if(showedEmotions.size() == Emotion.values().length) {
return true;
}
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("\"We do not have names for all the possible combinations of " +
"primary and background focuses. No one culture has a monopoly on emotions, and each culture may offer its own unique feelings.\" (Hochschild, 1983)");
descriptionLayout.addView(textView);
}
})
);
add(new Achievement(
"Augustine",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// all hit emotions are > 80%
boolean hasLowerItem = false;
for(Hit hit: game.hits.values()) {
if(hit.emotions.get(hit.target.emotion) <= 80) {
hasLowerItem = true;
}
}
return !hasLowerItem; // reverse
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("You are HYSTERICAL!!! Augustine is one of Jean-Martin Charcot's proofs cases for hysteria. Read 'The Invention Of Hysteria' by George Didi-Huberman on how Charcot contributed to her performance of hysteria.");
descriptionLayout.addView(textView);
AppCompatTextView seeAlsoView = new AppCompatTextView(c);
// seeAlsoView.setTextSize(12);
seeAlsoView.setText("Hysteria, in the colloquial use of the term, means ungovernable emotional excess. Generally, modern medical professionals have abandoned using the term \"hysteria\" to denote a diagnostic category, replacing it with more precisely defined categories. (Wikipedia)");
descriptionLayout.addView(seeAlsoView);
}
})
);
add(new Achievement(
"Steward(ess)", //Emotional labour
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("...");
descriptionLayout.addView(textView);
}
})
);
add(new Achievement(
"Stuff", // trouble recognising
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// have 10 times in which another emotion is expressed most pronounced then the one that is requested
int timesWrong = 0;
for(Hit hit: game.hits.values()) {
Emotion mostPronouncedEmotion = null;
for(Emotion emotion: hit.emotions.keySet()) {
if(mostPronouncedEmotion == null || hit.emotions.get(mostPronouncedEmotion) < hit.emotions.get(emotion)) {
mostPronouncedEmotion = emotion;
}
}
if(mostPronouncedEmotion != hit.target.emotion) {
timesWrong++;
}
}
return timesWrong >= 10;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("Have you been on drugs? You're making a mess of things!");
descriptionLayout.addView(textView);
AppCompatTextView seeAlsoView = new AppCompatTextView(c);
seeAlsoView.setText("\"[...] Participants were tested between 1 and 2h after treatment with oral cocaine (300mg) or placebo. Emotion recognition of low and high intensity expressions of basic emotions (fear, anger, disgust, sadness, and happiness) was tested. Findings show that cocaine impaired recognition of negative emotions; this was mediated by the intensity of the presented emotions.\" (Kuypers, 2015)");
descriptionLayout.addView(seeAlsoView);
}
})
);
add(new Achievement(
"Perfect CEO",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// you score anger, disgust, contempt on moments where it is not needed
for(Hit hit: game.hits.values()) {
if(hit.target.emotion == Emotion.ANGER || hit.target.emotion == Emotion.DISGUST|| hit.target.emotion == Emotion.FEAR){
continue;
}
if(hit.emotions.get(Emotion.ANGER) > 20 || hit.emotions.get(Emotion.DISGUST) > 20 || hit.emotions.get(Emotion.FEAR) > 20) {
return true;
}
}
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("You would be a great CEO! You'll be able to convice shareholders, even if the company is in chaos!");
descriptionLayout.addView(textView);
AppCompatTextView seeAlsoView = new AppCompatTextView(c);
seeAlsoView.setText("\"Although fear, anger, and disgust are negative emotions, Dr. Cicon found they correlated positively with financial performance. CEOs whose faces during a media interview showed disgustas evidenced by lowered eyebrows and eyes, and a closed, pursed mouthwere associated with a 9.3% boost in overall profits in the following quarter. CEOs who expressed fearraised eyebrows, widened eyes and mouth, and lips pulled in at the cornerssaw their companies stock rise .4% in the following week.\" (The Wall Street Journal, 17 Feb 2016)");
descriptionLayout.addView(seeAlsoView);
}
})
);
add(new Achievement(
"You've got the job",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// ???
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("...");
descriptionLayout.addView(textView);
}
})
);
add(new Achievement(
"Commercial",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// ???
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("...");
descriptionLayout.addView(textView);
}
})
);
add(new Achievement(
"Emotion work: suppression",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// You score good on the surpressed (<70%) targets (bonus points there!)
int suppressedTotal=0;
int suppressedGood=0;
for(Hit hit: game.hits.values()) {
if(hit.target.value > 70) {
continue;
}
suppressedTotal++;
if(hit.bonus > 10) {
suppressedGood++;
}
}
if(suppressedTotal*0.8 <= suppressedGood) {
return true;
}
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("...");
descriptionLayout.addView(textView);
}
})
);
add(new Achievement(
"Emotion work: evocation",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// You score good on the high ranked (>70%) targets (requires bonus points)
int evocedTotal=0;
int evocedGood=0;
for(Hit hit: game.hits.values()) {
if(hit.target.value <= 70) {
continue;
}
evocedTotal++;
if(hit.bonus > 10) {
evocedGood++;
}
}
if(evocedTotal*0.8 <= evocedGood) {
return true;
}
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("...");
descriptionLayout.addView(textView);
}
})
);
add(new Achievement(
"The game's on you", // ??(mixed feelings/complex emotions)
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// ????
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("...");
descriptionLayout.addView(textView);
}
})
);
add(new Achievement(
"CV dazzler",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// high lostFaceTime
if(game.lostFaceTime > 20) {
return true;
}
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("\"CV Dazzle explores how fashion can be used as camouflage from face-detection technology, the first step in automated face recognition. ");
descriptionLayout.addView(textView);
// TODO: add image
AppCompatTextView seeAlsoView = new AppCompatTextView(c);
seeAlsoView.setText("\"The name is derived from a type of World War I naval camouflage called Dazzle, which used cubist-inspired designs to break apart the visual continuity of a battleship and conceal its orientation and size. Likewise, CV Dazzle uses avant-garde hairstyling and makeup designs to break apart the continuity of a face. Since facial-recognition algorithms rely on the identification and spatial relationship of key facial features, like symmetry and tonal contours, one can block detection by creating an “anti-face”.\" (cvdazzle.com)");
descriptionLayout.addView(seeAlsoView);
// cvdazzle image (something on skincolor?
}
})
);
add(new Achievement(
"Kuleshov",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
boolean missedATarget = false;
// Add Kuleshov's target... person managers to do it
for(int target_id: game.scenario.kuleshovTargetIds) {
if(game.hits.get(target_id).bonus < 5) { // needs at least a little bonus on all
missedATarget = true;
}
}
return !missedATarget;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("In the beginning of the 20th century filmmaker Lev Kuleshov did an experiment\n" +
"for which he edited three sequences. Each sequence showed the same neutral face\n" +
"of a man, followed by the image of either a dead man, a plate of soup or a woman.\n" +
"When these sequences were shown, the audience “raved about the acting”(Pudovkin,\n" +
"1974, p. 184), believing the man who looked at either the dead man, the soup or\n" +
"the woman, was expressing grief, hunger or desire.");
// TODO: kuleshov image/video?
descriptionLayout.addView(textView);
}
})
);
add(new Achievement(
"Soap opera ",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// Confirm exactly (many bonus points?)
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("...");
descriptionLayout.addView(textView);
}
})
);
add(new Achievement(
"Stock photo model",
null,
new Achievement.AchievementListener() {
@Override
public boolean hasGotAchievement(Player player, Game game) {
// on average an overexecaration??
int niceOnes = 0;
for(Hit hit: game.hits.values()) {
if(hit.score >= 80) {
niceOnes ++;
}
}
if(niceOnes >= game.hits.size() * 0.8) {
return true;
}
return false;
}
@Override
public void setDescription(Player player, Game game, RelativeLayout descriptionLayout) {
Context c = descriptionLayout.getContext();
AppCompatTextView textView = new AppCompatTextView(c);
textView.setText("You are remarkably good at posing, just like this guy:");
// TODO: ad MS image
descriptionLayout.addView(textView);
}
})
);
}}; }};
private static AchievementCollection ourInstance = new AchievementCollection(); private static AchievementCollection ourInstance = new AchievementCollection();

View file

@ -212,6 +212,7 @@ public class ApiRestClient {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
df.setTimeZone(tz); df.setTimeZone(tz);
j.put("time", df.format(game.time)); j.put("time", df.format(game.time));
j.put("lost_face_time", game.lostFaceTime);
JSONArray jHits = new JSONArray(); JSONArray jHits = new JSONArray();
j.put("hits", jHits); j.put("hits", jHits);
@ -251,6 +252,13 @@ public class ApiRestClient {
jHits.put(jHit); jHits.put(jHit);
} }
JSONArray jAchievements = new JSONArray();
j.put("achievements", jAchievements);
for(Achievement achievement: game.achievements) {
jAchievements.put(achievement.getId());
}
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -278,7 +286,8 @@ public class ApiRestClient {
hit.remoteId = hits.getString(Long.toString(hit.id)); hit.remoteId = hits.getString(Long.toString(hit.id));
gameHelper.saveRemoteId(hit); gameHelper.saveRemoteId(hit);
} }
JSONArray jAchievements = response.getJSONArray("achievements"); // Achievement checking now in-game.
/*JSONArray jAchievements = response.getJSONArray("achievements");
if(jAchievements.length() > 0){ if(jAchievements.length() > 0){
ArrayList<Achievement> achievements = new ArrayList<Achievement>(jAchievements.length()); ArrayList<Achievement> achievements = new ArrayList<Achievement>(jAchievements.length());
for (int ai = 0; ai < jAchievements .length(); ai++) { for (int ai = 0; ai < jAchievements .length(); ai++) {
@ -286,7 +295,7 @@ public class ApiRestClient {
} }
game.achievements = achievements; game.achievements = achievements;
gameHelper.saveAchievementsForGame(game); gameHelper.saveAchievementsForGame(game);
} }*/
} catch (JSONException e) { } catch (JSONException e) {
Log.e("API","Invalid data: " + response.toString()); Log.e("API","Invalid data: " + response.toString());

View file

@ -1,8 +1,14 @@
package com.rubenvandeven.emotionhero; package com.rubenvandeven.emotionhero;
import android.content.Intent;
import android.graphics.Typeface;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
public class CreditsActivity extends AppCompatActivity { public class CreditsActivity extends AppCompatActivity {
@ -14,5 +20,64 @@ public class CreditsActivity extends AppCompatActivity {
getSupportActionBar().hide(); getSupportActionBar().hide();
} }
setContentView(R.layout.activity_credits); setContentView(R.layout.activity_credits);
Typeface font = Typeface.createFromAsset(getAssets(), "unifont-9.0.02.ttf");
TextView textView = (TextView) findViewById(R.id.textView);
TextView affectivaPower = (TextView) findViewById(R.id.affectivaPower);
TextView fontInfo = (TextView) findViewById(R.id.fontInfo);
TextView moreInfo = (TextView) findViewById(R.id.moreInfo);
TextView mySite = (TextView) findViewById(R.id.mySite);
textView.setTypeface(font);
affectivaPower.setTypeface(font);
fontInfo.setTypeface(font);
moreInfo.setTypeface(font);
mySite.setTypeface(font);
findViewById(R.id.logoArquivo).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String url = "http://www.arquivo237.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
findViewById(R.id.logoV2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String url = "http://www.v2.nl";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
findViewById(R.id.logoAffectiva).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String url = "http://www.affectiva.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
moreInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String url = "http://www.emotionhero.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
mySite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String url = "http://www.rubenvandeven.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
} }
} }

View file

@ -0,0 +1,91 @@
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.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.loopj.android.http.JsonHttpResponseHandler;
import org.json.JSONException;
import org.json.JSONObject;
import cz.msebera.android.httpclient.Header;
public class EndingActivity extends AppCompatActivity {
Player player;
TextView textLoading;
TextView textFailure;
TextView textSuccess;
TextView textRank;
TextView rank;
ImageView logoEmotionHero;
ProgressBar scoreProgressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_ending);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("The End?");
textLoading = (TextView) findViewById(R.id.textLoading);
textFailure = (TextView) findViewById(R.id.textFailure);
textSuccess = (TextView) findViewById(R.id.textSuccess);
textRank = (TextView) findViewById(R.id.textRank);
rank = (TextView) findViewById(R.id.rank);
logoEmotionHero = (ImageView) findViewById(R.id.logoEmotionHero);
scoreProgressBar = (ProgressBar) findViewById(R.id.scoreProgressBar);
player = Player.getInstance(this);
player.api.get("/me", null, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
try {
int rank = response.getInt("rank");
setRank(rank);
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int statusCode, Header[] headers, String response, Throwable throwable) {
throwable.printStackTrace();
ApiRestClient.handleOnFailure(statusCode, headers, response, throwable);
// Log.e("API", response == null ? "NULL" : response);
Toast.makeText(getApplicationContext(), "Something went wrong when loading results", Toast.LENGTH_LONG).show();
scoreProgressBar.setVisibility(View.GONE);
}
});
}
public void setRank(int rank) {
textLoading.setVisibility(View.GONE);
scoreProgressBar.setVisibility(View.GONE);
if(rank == 1) {
textSuccess.setVisibility(View.VISIBLE);
logoEmotionHero.setVisibility(View.VISIBLE);
} else {
textFailure.setVisibility(View.VISIBLE);
}
this.rank.setText(""+rank);
this.rank.setVisibility(View.VISIBLE);
this.textRank.setVisibility(View.VISIBLE);
}
}

View file

@ -1,9 +1,5 @@
package com.rubenvandeven.emotionhero; 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.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@ -24,6 +20,11 @@ public class Game {
public String remoteId; public String remoteId;
public Map<Integer, Hit> hits = new HashMap<>(); public Map<Integer, Hit> hits = new HashMap<>();
public ArrayList<Achievement> achievements = new ArrayList<>(); public ArrayList<Achievement> achievements = new ArrayList<>();
/**
* How long the face has been 'lost' during playing the level
*/
public float lostFaceTime;
public Game(Long id, int lvl_id, float score, float bonus, Date time, String remoteId) { 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); this(id, new Scenario(lvl_id, null), score, bonus, time, remoteId);
@ -59,4 +60,15 @@ public class Game {
} }
return s; return s;
} }
/**
* Calculate which achievements fit the game
*/
public void checkAchievements(Player player) {
for(Achievement achievement: scenario.achievements) {
if(achievement.achievementListener.hasGotAchievement(player, this) && !achievements.contains(achievement)) {
achievements.add(achievement);
}
}
}
} }

View file

@ -23,7 +23,7 @@ import java.util.Date;
* adb pull /sdcard/emotionhero.db * adb pull /sdcard/emotionhero.db
*/ */
public class GameOpenHelper extends SQLiteOpenHelper { public class GameOpenHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 5; private static final int DATABASE_VERSION = 6;
private static final String GAME_TABLE_NAME = "games"; private static final String GAME_TABLE_NAME = "games";
private static final String GAME_TABLE_CREATE = private static final String GAME_TABLE_CREATE =
"CREATE TABLE " + GAME_TABLE_NAME + " (" + "CREATE TABLE " + GAME_TABLE_NAME + " (" +
@ -32,6 +32,7 @@ public class GameOpenHelper extends SQLiteOpenHelper {
"score VARCHAR(255) NOT NULL," + "score VARCHAR(255) NOT NULL," +
"bonus VARCHAR(255) NOT NULL," + "bonus VARCHAR(255) NOT NULL," +
"time INTEGER NOT NULL," + "time INTEGER NOT NULL," +
"lost_face_time VARCHAR(255) NOT NULL," +
"remoteId VARCHAR(255) DEFAULT NULL, " + "remoteId VARCHAR(255) DEFAULT NULL, " +
"PRIMARY KEY(id));"; "PRIMARY KEY(id));";
private static final String[] GAME_PROJECTION = { private static final String[] GAME_PROJECTION = {
@ -40,6 +41,7 @@ public class GameOpenHelper extends SQLiteOpenHelper {
"score", "score",
"bonus", "bonus",
"time", "time",
"lost_face_time",
"remoteId" "remoteId"
}; };
@ -206,6 +208,9 @@ public class GameOpenHelper extends SQLiteOpenHelper {
if(oldVersion == 4 && newVersion == 5) { if(oldVersion == 4 && newVersion == 5) {
db.execSQL(GAME_ACH_TABLE_CREATE); db.execSQL(GAME_ACH_TABLE_CREATE);
} }
if(oldVersion == 5 && newVersion == 6) {
db.execSQL("ALTER TABLE games ADD lost_face_time VARCHAR(255);");
}
} }
@ -236,6 +241,7 @@ public class GameOpenHelper extends SQLiteOpenHelper {
values.put("score", game.score); values.put("score", game.score);
values.put("bonus", game.bonus); values.put("bonus", game.bonus);
values.put("time", game.time.getTime()); values.put("time", game.time.getTime());
values.put("lost_face_time", game.lostFaceTime);
if(game.remoteId == null) { if(game.remoteId == null) {
values.putNull("remoteId"); values.putNull("remoteId");
} else { } else {
@ -249,6 +255,8 @@ public class GameOpenHelper extends SQLiteOpenHelper {
for(Hit hit: game.hits.values()) { for(Hit hit: game.hits.values()) {
insertHit(hit); insertHit(hit);
} }
saveAchievementsForGame(game);
} }
public Game[] getGamesForLevel(int lvl_id) { public Game[] getGamesForLevel(int lvl_id) {
@ -277,6 +285,37 @@ public class GameOpenHelper extends SQLiteOpenHelper {
return cursorToGames(c, s); return cursorToGames(c, s);
} }
/**
* Get the game that was played before this game
* @param game
* @return Game
*/
public Game getPreviousGame(Game game) {
SQLiteDatabase db = getReadableDatabase();
String selection = "lvl_id = ? AND time < ?";
String[] selectionArgs = { Integer.toString(game.scenario.id), Long.toString(game.time.getTime()) };
String sortOrder = "time 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
"1" // only last item
);
if(c.getCount() < 1)
return null;
Game[] games = cursorToGames(c, game.scenario);
return games[0];
}
public Game[] cursorToGames(Cursor c, Scenario s) { public Game[] cursorToGames(Cursor c, Scenario s) {
Game[] games = new Game[c.getCount()]; Game[] games = new Game[c.getCount()];
int i = 0; int i = 0;
@ -292,6 +331,7 @@ public class GameOpenHelper extends SQLiteOpenHelper {
new Date(c.getLong(c.getColumnIndex("time"))), new Date(c.getLong(c.getColumnIndex("time"))),
c.getString(c.getColumnIndex("remoteId")) c.getString(c.getColumnIndex("remoteId"))
); );
game.lostFaceTime = c.getFloat(c.getColumnIndex("lost_face_time"));
games[i] = game; games[i] = game;
this.getHitsForGame(game); // hits are appended to game object this.getHitsForGame(game); // hits are appended to game object
game.achievements = getAchievementsOfGame(game); game.achievements = getAchievementsOfGame(game);

View file

@ -307,6 +307,7 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL
public void onFaceDetectionStarted() public void onFaceDetectionStarted()
{ {
setText("START!"); setText("START!");
currentScenario.lostFace = false;
if(isStarted) if(isStarted)
currentScenario.start(); currentScenario.start();
@ -316,6 +317,7 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL
public void onFaceDetectionStopped() public void onFaceDetectionStopped()
{ {
currentScenario.pause(); currentScenario.pause();
currentScenario.lostFace = true;
} }
public void setText(String text) public void setText(String text)
@ -380,7 +382,9 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL
// check whether this is the highest reached level by the player // check whether this is the highest reached level by the player
// ... used by 'continue' button in main menu // ... used by 'continue' button in main menu
if(currentScenario.minimumScore < currentScenario.game.score) { currentScenario.game.checkAchievements(player);
if(currentScenario.minimumScore < currentScenario.game.score + currentScenario.game.bonus) {
if(currentScenario.isFinalLevel()) { if(currentScenario.isFinalLevel()) {
playerInfo.completedAll = true; playerInfo.completedAll = true;
} else { } else {

View file

@ -1,58 +0,0 @@
package com.rubenvandeven.emotionhero;
import android.content.Intent;
import android.graphics.Typeface;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
/**
* Not to be confused with IntroActivity:
* this is the first game introduction (explaining the procedure etc.)
*/
public class IntroductionActivity extends AppCompatActivity {
TextView nextButton;
TextView readyButton;
TextView text1;
TextView text2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_introduction);
nextButton = (TextView) findViewById(R.id.nextButton);
readyButton = (TextView) findViewById(R.id.readyButton);
text1 = (TextView) findViewById(R.id.introText1);
text2 = (TextView) findViewById(R.id.introText2);
Typeface font = Typeface.createFromAsset(getAssets(), "unifont-9.0.02.ttf");
nextButton.setTypeface(font);
readyButton.setTypeface(font);
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nextButton.setVisibility(View.GONE);
readyButton.setVisibility(View.VISIBLE);
text1.setVisibility(View.GONE);
text2.setVisibility(View.VISIBLE);
}
});
readyButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(IntroductionActivity.this, ProgressActivity.class);
finish();
startActivity(intent);
}
});
}
}

View file

@ -1,137 +0,0 @@
package com.rubenvandeven.emotionhero;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.ProgressDialog;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
/**
* @deprecated Now done using MirrorMenuActivity
*/
public class MenuActivity extends AppCompatActivity {
Player player;
ProgressDialog loadGameDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
if(getSupportActionBar() != null) {
getSupportActionBar().hide();
}
setContentView(R.layout.activity_menu);
player = Player.getInstance(getApplicationContext());
Button startButton = (Button) findViewById(R.id.startButton);
Button continueButton = (Button) findViewById(R.id.continueButton);
Button highscoreButton = (Button) findViewById(R.id.highscoresButton);
Button creditsButton = (Button) findViewById(R.id.creditsButton);
final ImageView logoEmotionHero = (ImageView) findViewById(R.id.logoEmotionHero);
if(!player.getPlayerInfo().canContinueLevel()) {
continueButton.setVisibility(View.GONE);
}
// prepare for animation
startButton.setAlpha(0f);
continueButton.setAlpha(0f);
highscoreButton.setAlpha(0f);
creditsButton.setAlpha(0f);
ObjectAnimator fadeInEmotionHero = ObjectAnimator.ofFloat(logoEmotionHero, "alpha", 0f, 1f);
fadeInEmotionHero.setDuration(1000);
ObjectAnimator fadeInstartButton = ObjectAnimator.ofFloat(startButton, "alpha", 0f, 1f);
fadeInstartButton.setDuration(1000);
ObjectAnimator fadeInContinueButton = ObjectAnimator.ofFloat(continueButton, "alpha", 0f, 1f);
fadeInContinueButton.setDuration(1000);
fadeInContinueButton.setStartDelay(300);
ObjectAnimator fadeInHighscoreButton = ObjectAnimator.ofFloat(highscoreButton, "alpha", 0f, 1f);
fadeInHighscoreButton.setDuration(1000);
fadeInHighscoreButton.setStartDelay(600);
ObjectAnimator fadeInCreditsButton = ObjectAnimator.ofFloat(creditsButton, "alpha", 0f, 1f);
fadeInCreditsButton.setDuration(1000);
fadeInCreditsButton.setStartDelay(1000);
Animation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(1000); //You can manage the blinking time with this parameter
anim.setStartOffset(20);
anim.setRepeatMode(Animation.REVERSE);
anim.setRepeatCount(Animation.INFINITE);
logoEmotionHero.startAnimation(anim);
AnimatorSet buttonAnimatorSet = new AnimatorSet();
buttonAnimatorSet.playTogether(fadeInstartButton,
fadeInContinueButton,
fadeInHighscoreButton,
fadeInCreditsButton);
buttonAnimatorSet.start();
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loadGameDialog = ProgressDialog.show(MenuActivity.this, "",
MenuActivity.this.getResources().getString(R.string.load_game_activity), true);
Intent intent = new Intent(MenuActivity.this, MirrorMenuActivity.class);
startActivity(intent);
}
});
continueButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loadGameDialog= ProgressDialog.show(MenuActivity.this, "",
MenuActivity.this.getResources().getString(R.string.load_game_activity), true);
Intent intent = new Intent(MenuActivity.this, GamingActivity.class);
intent.putExtra(GamingActivity.INTENT_EXTRA_SCENARIO, player.getPlayerInfo().reachedLevelId);
startActivity(intent);
}
});
highscoreButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MenuActivity.this, HighscoreActivity.class);
// intent.putExtra(HighscoreActivity.INTENT_EXTRA_LEVEL, player.getPlayerInfo().reachedLevelId);
startActivity(intent);
}
});
creditsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MenuActivity.this, CreditsActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onResume() {
super.onResume();
if(loadGameDialog != null)
loadGameDialog.dismiss();
}
}

View file

@ -179,7 +179,9 @@ public class ProgressActivity extends AppCompatActivity {
outroText.setOnClickListener(new View.OnClickListener() { outroText.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
// TODO: .. handle onclick!! Intent intent = new Intent(getApplicationContext(), EndingActivity.class);
finish();
startActivity(intent);
} }
}); });
} }

View file

@ -8,6 +8,7 @@ import android.util.Log;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
public class ReviewAchievementsActivity extends AppCompatActivity { public class ReviewAchievementsActivity extends AppCompatActivity {
@ -72,6 +73,7 @@ public class ReviewAchievementsActivity extends AppCompatActivity {
public void addAchievement(Achievement achievement) { public void addAchievement(Achievement achievement) {
AppCompatTextView titleText = new AppCompatTextView(this); AppCompatTextView titleText = new AppCompatTextView(this);
AppCompatTextView descriptionText = new AppCompatTextView(this); AppCompatTextView descriptionText = new AppCompatTextView(this);
RelativeLayout descriptionLayout = new RelativeLayout(this);
// ImageView imageView = new ImageView(this); // ImageView imageView = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
@ -82,13 +84,13 @@ public class ReviewAchievementsActivity extends AppCompatActivity {
titleText.setTextSize(getResources().getDimensionPixelSize(R.dimen.highscore_textsize)); titleText.setTextSize(getResources().getDimensionPixelSize(R.dimen.highscore_textsize));
titleText.setLayoutParams(params); titleText.setLayoutParams(params);
descriptionLayout.setLayoutParams(params);
descriptionLayout.setPadding(0,0,0, 20);
achievement.achievementListener.setDescription(player, game, descriptionLayout);
descriptionText.setText(achievement.description);
descriptionText.setTextColor(getResources().getColor(R.color.textPrimary));
descriptionText.setLayoutParams(params);
achievementsLayout.addView(titleText); achievementsLayout.addView(titleText);
achievementsLayout.addView(descriptionText); achievementsLayout.addView(descriptionLayout);
} }
} }

View file

@ -51,6 +51,7 @@ public class ReviewActivity extends AppCompatActivity {
TextView achievementArrow; TextView achievementArrow;
TextView achievementText; TextView achievementText;
TextView improveArrow; TextView improveArrow;
RelativeLayout improveLayout;
TextView hintText; TextView hintText;
RelativeLayout retryLayout; RelativeLayout retryLayout;
TextView retryArrow; TextView retryArrow;
@ -89,7 +90,7 @@ public class ReviewActivity extends AppCompatActivity {
// TODO: pass the game to checkAchievements() to avoid crash on null error // TODO: pass the game to checkAchievements() to avoid crash on null error
// means we have to load Player.getInstance form here and load the game // means we have to load Player.getInstance form here and load the game
// from given id to be save. // from given id to be save.
checkAchievements(); // checkAchievements();
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();
Toast.makeText(getApplicationContext(), "Something went wrong when loading results", Toast.LENGTH_LONG).show(); Toast.makeText(getApplicationContext(), "Something went wrong when loading results", Toast.LENGTH_LONG).show();
@ -139,7 +140,9 @@ public class ReviewActivity extends AppCompatActivity {
} }
} else { } else {
// no game specified??? SHould not be possible so finish // no game specified??? SHould not be possible so finish
finish(); // This happens when comming back.
// apparently back button does not acknowledge intent??
// finish(); // doesn't work?
} }
lvlNameText = (TextView) findViewById(R.id.lvlNameText); lvlNameText = (TextView) findViewById(R.id.lvlNameText);
@ -153,7 +156,8 @@ public class ReviewActivity extends AppCompatActivity {
achievementArrow = (TextView) findViewById(R.id.achievementArrow); achievementArrow = (TextView) findViewById(R.id.achievementArrow);
achievementText = (TextView) findViewById(R.id.achievementText); achievementText = (TextView) findViewById(R.id.achievementText);
improveArrow = (TextView) findViewById(R.id.improveArrow); // improveLayout = (RelativeLayout) findViewById(R.id.improveLayout);
// improveArrow = (TextView) findViewById(R.id.improveArrow);
hintText = (TextView) findViewById(R.id.hintText); hintText = (TextView) findViewById(R.id.hintText);
retryLayout = (RelativeLayout) findViewById(R.id.retryLayout); retryLayout = (RelativeLayout) findViewById(R.id.retryLayout);
retryArrow = (TextView) findViewById(R.id.retryArrow); retryArrow = (TextView) findViewById(R.id.retryArrow);
@ -165,6 +169,9 @@ public class ReviewActivity extends AppCompatActivity {
scoreProgressBar = (ProgressBar) findViewById(R.id.scoreProgressBar); scoreProgressBar = (ProgressBar) findViewById(R.id.scoreProgressBar);
nextLvlText.setVisibility(View.GONE);
nextLvlLayout.setVisibility(View.GONE);
checkAchievements(); checkAchievements();
Typeface font = Typeface.createFromAsset(getAssets(), "unifont-9.0.02.ttf"); Typeface font = Typeface.createFromAsset(getAssets(), "unifont-9.0.02.ttf");
@ -173,7 +180,7 @@ public class ReviewActivity extends AppCompatActivity {
achievementArrow.setTypeface(font); achievementArrow.setTypeface(font);
achievementText.setTypeface(font); achievementText.setTypeface(font);
retryArrow.setTypeface(font); retryArrow.setTypeface(font);
improveArrow.setTypeface(font); // improveArrow.setTypeface(font);
nextLvlArrow.setTypeface(font); nextLvlArrow.setTypeface(font);
lvlNameText.setText("\""+game.scenario.toString()+"\""); lvlNameText.setText("\""+game.scenario.toString()+"\"");
@ -196,23 +203,6 @@ public class ReviewActivity extends AppCompatActivity {
} }
}); });
if(player.getPlayerInfo().hasAccessToLevel(game.scenario.getNextLevelId())) {
nextLvlLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), GamingActivity.class);
intent.putExtra(GamingActivity.INTENT_EXTRA_SCENARIO, game.scenario.getNextLevelId());
ProgressDialog dialog = ProgressDialog.show(ReviewActivity.this, "",
getApplicationContext().getResources().getString(R.string.load_game_activity), true);
finish();
startActivity(intent);
}
});
} else {
nextLvlText.setVisibility(View.GONE);
nextLvlLayout.setVisibility(View.GONE);
}
int rank = player.getGameOpenHelper().getLocalRankOfGame(game); int rank = player.getGameOpenHelper().getLocalRankOfGame(game);
String personalScoreJudgement = rank < 7 ? "nice work!" : "you can do better."; String personalScoreJudgement = rank < 7 ? "nice work!" : "you can do better.";
@ -220,18 +210,51 @@ public class ReviewActivity extends AppCompatActivity {
retryText.setText(retryString); retryText.setText(retryString);
} }
public void setNextLvlMessage(boolean hasAccess) {
nextLvlText.setVisibility(View.VISIBLE);
nextLvlLayout.setVisibility(View.VISIBLE);
if(hasAccess) {
if(game.scenario.isFinalLevel()) {
nextLvlText.setText("This was the final level! Let's see what the ending brings...");
nextLvlLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), EndingActivity.class);
finish();
startActivity(intent);
}
});
} else {
nextLvlLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), GamingActivity.class);
intent.putExtra(GamingActivity.INTENT_EXTRA_SCENARIO, game.scenario.getNextLevelId());
ProgressDialog dialog = ProgressDialog.show(ReviewActivity.this, "",
getApplicationContext().getResources().getString(R.string.load_game_activity), true);
finish();
startActivity(intent);
}
});
}
} else {
nextLvlText.setText(String.format("You need at least %1$.0f points, or unlock %2$d achievements to get to the next level.", game.scenario.minimumScore, game.scenario.minimumAchievements));
nextLvlArrow.setVisibility(View.GONE);
}
}
public void checkAchievements() { public void checkAchievements() {
if(game.achievements != null && game.achievements.size() > 0) { if(game.achievements != null && game.achievements.size() > 0) {
achievementTitle.setVisibility(View.VISIBLE); achievementTitle.setVisibility(View.VISIBLE);
achievementLayout.setVisibility(View.VISIBLE); achievementLayout.setVisibility(View.VISIBLE);
String achievementString = game.achievements.size() > 1 ? "You've obtained special achievements!\n" : "You've obtained the special achievement "; String achievementString = game.achievements.size() > 1 ? "You've obtained special achievements!\n - " : "You've obtained the special achievement ";
boolean firstAchievement = true; boolean firstAchievement = true;
for(Achievement achievement: game.achievements) { for(Achievement achievement: game.achievements) {
if(firstAchievement ) { if(firstAchievement ) {
firstAchievement = false; firstAchievement = false;
} else { } else {
achievementString += "\n"; achievementString += "\n - ";
} }
achievementString += String.format("%1$s", achievement.title); achievementString += String.format("%1$s", achievement.title);
} }
@ -248,6 +271,31 @@ public class ReviewActivity extends AppCompatActivity {
achievementTitle.setVisibility(View.GONE); achievementTitle.setVisibility(View.GONE);
achievementLayout.setVisibility(View.GONE); achievementLayout.setVisibility(View.GONE);
} }
// only check after sync has been done (so achievements is [] rather than null))
if(game.achievements != null) {
// check next level access, based on achievements:
int nextLevelId = game.scenario.getNextLevelId();
PlayerInfo playerInfo = player.getPlayerInfo();
// if s/he has access, there is nothing to check.. if not.. go ahead
if(!playerInfo.hasAccessToLevel(nextLevelId)) {
int lvlAchievementCount = player.getGameOpenHelper().countAchievementsForLevel(game.scenario.id);
if(lvlAchievementCount >= game.scenario.minimumAchievements) {
playerInfo.reachedLevelId = nextLevelId;
player.savePlayerInfo(playerInfo);
} else {
// only reveal message if there is results
setNextLvlMessage(false);
return;
}
} else {
if(game.scenario.isFinalLevel() && !playerInfo.completedAll) {
setNextLvlMessage(false);
} else{
setNextLvlMessage(true);
}
}
}
} }
/** /**

View file

@ -37,12 +37,22 @@ public class Scenario {
public static final int LVL_SURPRISE = 3; public static final int LVL_SURPRISE = 3;
public static final int LVL_SADDNESS= 4; public static final int LVL_SADDNESS= 4;
public static final int LVL_THESEVEN = 5;
public static final int LVL_SMILE = 6;
public static final int LVL_BUSINESS = 7;
public static final int LVL_REALLY = 8;
public static final int LVL_ACTNORMAL = 9;
// used for the kuleshov targets
public int[] kuleshovTargetIds;
// the levels in the right order. // the levels in the right order.
public static final ArrayList<Integer> SCENARIOS = new ArrayList<Integer>() {{ public static final ArrayList<Integer> SCENARIOS = new ArrayList<Integer>() {{
add(LVL_JOY); add(LVL_THESEVEN);
add(LVL_ANGER); add(LVL_SMILE);
add(LVL_SADDNESS); add(LVL_BUSINESS);
add(LVL_SURPRISE); add(LVL_REALLY);
add(LVL_ACTNORMAL);
}}; }};
static int DESIRED_FPS = 25; static int DESIRED_FPS = 25;
@ -59,7 +69,7 @@ public class Scenario {
* Number of achievements required to have, before being able to go to next level * Number of achievements required to have, before being able to go to next level
* (check minimumScore || minimumAchievements) * (check minimumScore || minimumAchievements)
*/ */
float minimumAchievements= 0; int minimumAchievements= 0;
/** /**
* Achievements one get obtain in this level * Achievements one get obtain in this level
@ -97,6 +107,14 @@ public class Scenario {
protected Paint squarePaint; protected Paint squarePaint;
protected int bitmapCount = 0;
/**
* LostFace starts false, stays false when face is found, the becomes
* true when losing the face
*/
protected boolean lostFace = false;
/** /**
* The scorres in this moment, as to draw them on the screen. * The scorres in this moment, as to draw them on the screen.
* Indexes are Emotion ordinals * Indexes are Emotion ordinals
@ -154,8 +172,12 @@ public class Scenario {
*/ */
public void tick() public void tick()
{ {
if(!isRunning) if(!isRunning){
if(lostFace) {
game.lostFaceTime += 1.0f/DESIRED_FPS;
}
return; return;
}
runningTime += 1.0f/DESIRED_FPS; runningTime += 1.0f/DESIRED_FPS;
@ -186,10 +208,11 @@ public class Scenario {
Bitmap outputBitmap = null; Bitmap outputBitmap = null;
if(currentFrame != null) { if(currentFrame != null && bitmapCount < 5) {
// convert NV21 byteArrayFrame from camera to RGB bitmap. // convert NV21 byteArrayFrame from camera to RGB bitmap.
Frame.ByteArrayFrame byteArrayFrame = (Frame.ByteArrayFrame) currentFrame; Frame.ByteArrayFrame byteArrayFrame = (Frame.ByteArrayFrame) currentFrame;
outputBitmap = Nv21Image.nv21ToBitmap(rs, byteArrayFrame.getByteArray(), byteArrayFrame.getWidth(), byteArrayFrame.getHeight()); outputBitmap = Nv21Image.nv21ToBitmap(rs, byteArrayFrame.getByteArray(), byteArrayFrame.getWidth(), byteArrayFrame.getHeight());
bitmapCount++;
Frame.ROTATE rotation = byteArrayFrame.getTargetRotation(); Frame.ROTATE rotation = byteArrayFrame.getTargetRotation();
// ie BY_90_CCW -90.0 // ie BY_90_CCW -90.0
Log.v("Scenario", "frame rotation: " + rotation.toString() + " " + rotation.toDouble()); Log.v("Scenario", "frame rotation: " + rotation.toString() + " " + rotation.toDouble());
@ -199,6 +222,7 @@ public class Scenario {
matrix.postRotate((int) rotation.toDouble()); matrix.postRotate((int) rotation.toDouble());
// int width = rotation == Frame.ROTATE.BY_180 ? outputBitmap.getWidth() : outputBitmap.getHeight(); // int width = rotation == Frame.ROTATE.BY_180 ? outputBitmap.getWidth() : outputBitmap.getHeight();
// int height = rotation == Frame.ROTATE.BY_180 ? outputBitmap.getHeight() : outputBitmap.getWidth(); // int height = rotation == Frame.ROTATE.BY_180 ? outputBitmap.getHeight() : outputBitmap.getWidth();
// TODO: max 5 bitmaps
outputBitmap = Bitmap.createBitmap(outputBitmap , 0, 0, outputBitmap .getWidth(), outputBitmap .getHeight(), matrix, true); outputBitmap = Bitmap.createBitmap(outputBitmap , 0, 0, outputBitmap .getWidth(), outputBitmap .getHeight(), matrix, true);
} }
@ -236,7 +260,7 @@ public class Scenario {
* @param value * @param value
* @param timestamp * @param timestamp
*/ */
public void setTarget(Emotion emotion, float value, float timestamp) public int setTarget(Emotion emotion, float value, float timestamp)
{ {
// Log.e(GamingActivity.LOG_TAG, "Set target:" + Float.toString(timestamp) + " " + Float.toString(duration)); // Log.e(GamingActivity.LOG_TAG, "Set target:" + Float.toString(timestamp) + " " + Float.toString(duration));
if((timestamp + 1) > duration) if((timestamp + 1) > duration)
@ -250,6 +274,8 @@ public class Scenario {
target.index = targets.size() + 1; target.index = targets.size() + 1;
targets.add(target); targets.add(target);
maxScore = getMaxScore(); maxScore = getMaxScore();
return targets.indexOf(target);
} }
/** /**
@ -449,6 +475,270 @@ public class Scenario {
setMinimumScoreFromPercentage(10); setMinimumScoreFromPercentage(10);
minimumAchievements = 2; minimumAchievements = 2;
break; break;
////////////////// new levels:
case LVL_THESEVEN:
int i = 2;
setTarget(Emotion.JOY, 100, i++);
setTarget(Emotion.JOY, 100, i++);
setTarget(Emotion.JOY, 100, i++);
i++;
i++;
setTarget(Emotion.SADNESS, 100, i++);
setTarget(Emotion.SADNESS, 100, i++);
setTarget(Emotion.SADNESS, 100, i++);
i++;
i++;
setTarget(Emotion.ANGER, 100, i++);
setTarget(Emotion.ANGER, 100, i++);
setTarget(Emotion.ANGER, 100, i++);
i++;
i++;
setTarget(Emotion.SURPRISE, 100, i++);
setTarget(Emotion.SURPRISE, 100, i++);
setTarget(Emotion.SURPRISE, 100, i++);
i++;
i++;
setTarget(Emotion.DISGUST, 100, i++);
setTarget(Emotion.DISGUST, 100, i++);
setTarget(Emotion.DISGUST, 100, i++);
i++;
i++;
setTarget(Emotion.CONTEMPT, 100, i++);
setTarget(Emotion.CONTEMPT, 100, i++);
setTarget(Emotion.CONTEMPT, 100, i++);
i++;
i++;
setTarget(Emotion.FEAR, 100, i++);
setTarget(Emotion.FEAR, 100, i++);
setTarget(Emotion.FEAR, 100, i++);
setMinimumScoreFromPercentage(40);
minimumAchievements = 2;
achievements.add(achievementCollection.get(1));
achievements.add(achievementCollection.get(2));
achievements.add(achievementCollection.get(3));
achievements.add(achievementCollection.get(4));
break;
case LVL_SMILE:
int s = 2;
setTarget(Emotion.JOY, 100, s++);
setTarget(Emotion.JOY, 100, s++);
setTarget(Emotion.JOY, 50, s++);
setTarget(Emotion.JOY, 50, s++);
setTarget(Emotion.JOY, 30, s++);
setTarget(Emotion.JOY, 30, s++);
setTarget(Emotion.JOY, 50, s++);
setTarget(Emotion.JOY, 50, s++);
setTarget(Emotion.JOY, 100, s++);
setTarget(Emotion.JOY, 100, s++);
s++;
s++;
setTarget(Emotion.SURPRISE, 100, s++);
setTarget(Emotion.SURPRISE, 100, s++);
setTarget(Emotion.SURPRISE, 50, s++);
setTarget(Emotion.SURPRISE, 50, s++);
setTarget(Emotion.SURPRISE, 100, s++);
setTarget(Emotion.SURPRISE, 100, s++);
s++;
s++;
s++;
setTarget(Emotion.JOY, 100, s++);
setTarget(Emotion.SURPRISE, 100, s);
setTarget(Emotion.JOY, 100, s++);
setTarget(Emotion.SURPRISE, 100, s);
setTarget(Emotion.JOY, 100, s++);
setTarget(Emotion.SURPRISE, 50, s);
setTarget(Emotion.SURPRISE, 30, s);
s++;
s++;
setTarget(Emotion.JOY, 100, s++);
setTarget(Emotion.ANGER, 1, s);
setTarget(Emotion.CONTEMPT, 1, s);
setTarget(Emotion.DISGUST, 1, s);
s++;
s++;
setTarget(Emotion.DISGUST, 1, s++);
setTarget(Emotion.ANGER, 1, s);
setTarget(Emotion.SURPRISE, 100, s);
setMinimumScoreFromPercentage(40);
minimumAchievements = 2;
achievements.add(achievementCollection.get(5));
achievements.add(achievementCollection.get(6));
achievements.add(achievementCollection.get(7));
break;
case LVL_BUSINESS:
int b = 2;
setTarget(Emotion.ANGER, 100, b++);
setTarget(Emotion.ANGER, 100, b++);
setTarget(Emotion.ANGER, 50, b++);
setTarget(Emotion.ANGER, 50, b++);
setTarget(Emotion.ANGER, 30, b++);
setTarget(Emotion.ANGER, 30, b++);
b++;
setTarget(Emotion.DISGUST, 100, b++);
setTarget(Emotion.DISGUST, 50, b++);
setTarget(Emotion.DISGUST, 50, b++);
setTarget(Emotion.DISGUST, 30, b++);
b++;
setTarget(Emotion.CONTEMPT, 100, b++);
setTarget(Emotion.CONTEMPT, 50, b++);
setTarget(Emotion.CONTEMPT, 50, b++);
setTarget(Emotion.CONTEMPT, 30, b++);
b++;
setTarget(Emotion.SURPRISE, 100, b++);
setTarget(Emotion.SURPRISE, 100, b++);
setTarget(Emotion.SADNESS, 50, b);
setTarget(Emotion.JOY, 50, b++);
setTarget(Emotion.DISGUST, 50, b++);
setTarget(Emotion.CONTEMPT, 30, b++);
setTarget(Emotion.CONTEMPT, 100, b++);
setTarget(Emotion.JOY, 100, b++);
setTarget(Emotion.SURPRISE, 100, b++);
b++;
setTarget(Emotion.SADNESS, 100, b++);
setTarget(Emotion.ANGER, 10, b++);
setTarget(Emotion.SADNESS, 100, b++);
setTarget(Emotion.ANGER, 10, b++);
setTarget(Emotion.SADNESS, 100, b++);
setTarget(Emotion.ANGER, 10, b++);
setMinimumScoreFromPercentage(40);
minimumAchievements = 2;
achievements.add(achievementCollection.get(8));
achievements.add(achievementCollection.get(9));
achievements.add(achievementCollection.get(10));
break;
case LVL_REALLY:
int r = 2;
setTarget(Emotion.FEAR, 100, r++);
setTarget(Emotion.FEAR, 50, r++);
setTarget(Emotion.FEAR, 30, r++);
r++;
setTarget(Emotion.SADNESS, 100, r++);
setTarget(Emotion.SADNESS, 50, r++);
setTarget(Emotion.SADNESS, 100, r++);
r++;
setTarget(Emotion.DISGUST, 100, r++);
setTarget(Emotion.DISGUST, 100, r++);
setTarget(Emotion.DISGUST, 50, r++);
r++;
setTarget(Emotion.DISGUST, 100, r++);
setTarget(Emotion.CONTEMPT, 30, r);
setTarget(Emotion.DISGUST, 50, r++);
setTarget(Emotion.CONTEMPT, 50, r);
setTarget(Emotion.DISGUST, 30, r++);
setTarget(Emotion.CONTEMPT, 100, r);
r++;
r++;
setTarget(Emotion.SADNESS, 100, r++);
setTarget(Emotion.JOY, 50, r++);
setTarget(Emotion.SADNESS, 100, r++);
setTarget(Emotion.JOY, 50, r++);
setTarget(Emotion.SADNESS, 50, r++);
setTarget(Emotion.JOY, 100, r++);
setTarget(Emotion.SADNESS, 50, r++);
setTarget(Emotion.JOY, 100, r);
setTarget(Emotion.SADNESS, 100, r++);
setTarget(Emotion.JOY, 50, r);
setMinimumScoreFromPercentage(40);
minimumAchievements = 2;
achievements.add(achievementCollection.get(8));
achievements.add(achievementCollection.get(9));
achievements.add(achievementCollection.get(10));
achievements.add(achievementCollection.get(11));
break;
case LVL_ACTNORMAL:
float a = 2;
setTarget(Emotion.ANGER, 100, a++);
setTarget(Emotion.DISGUST, 100, a++);
setTarget(Emotion.FEAR, 100, a++);
setTarget(Emotion.JOY, 100, a++);
setTarget(Emotion.SADNESS, 100, a++);
setTarget(Emotion.SURPRISE, 100, a++);
a++;
setTarget(Emotion.ANGER, 30, a++);
setTarget(Emotion.DISGUST, 30, a+=0.5);
setTarget(Emotion.FEAR, 30, a+=0.5);
setTarget(Emotion.JOY, 30, a+=0.5);
setTarget(Emotion.SADNESS, 30, a+=0.5);
setTarget(Emotion.SURPRISE, 30, a+=0.5);
a++;
setTarget(Emotion.ANGER, 30, a++);
setTarget(Emotion.DISGUST, 30, a);
setTarget(Emotion.ANGER, 30, a++);
setTarget(Emotion.DISGUST, 30, a);
setTarget(Emotion.FEAR, 30, a++);
setTarget(Emotion.JOY, 30, a);
setTarget(Emotion.FEAR, 30, a++);
setTarget(Emotion.JOY, 30, a);
setTarget(Emotion.SADNESS, 30, a++);
setTarget(Emotion.SURPRISE, 30, a);
setTarget(Emotion.SADNESS, 30, a++);
setTarget(Emotion.SURPRISE, 30, a);
a++;
a++;
setTarget(Emotion.DISGUST, 20, a++);
setTarget(Emotion.CONTEMPT, 20, a);
setTarget(Emotion.SURPRISE, 20, a);
setTarget(Emotion.DISGUST, 10, a++);
setTarget(Emotion.CONTEMPT, 10, a);
setTarget(Emotion.SURPRISE, 10, a);
setTarget(Emotion.DISGUST, 5, a++);
setTarget(Emotion.CONTEMPT, 5, a);
setTarget(Emotion.SURPRISE, 5, a);
// Kuleshov's target:
kuleshovTargetIds = new int[3];
kuleshovTargetIds[0] = setTarget(Emotion.DISGUST, 1, a++);
kuleshovTargetIds[1] = setTarget(Emotion.CONTEMPT, 1, a);
kuleshovTargetIds[2] = setTarget(Emotion.SURPRISE, 1, a);
// END OF KULESHOV
setTarget(Emotion.DISGUST, 1, a++);
setTarget(Emotion.CONTEMPT, 1, a);
setTarget(Emotion.SURPRISE, 1, a);
setTarget(Emotion.ANGER, 1, a++);
setTarget(Emotion.CONTEMPT, 1, a);
setTarget(Emotion.DISGUST, 1, a);
setTarget(Emotion.FEAR, 1, a);
setTarget(Emotion.JOY, 1, a);
setTarget(Emotion.SADNESS, 1, a);
setTarget(Emotion.SURPRISE, 1, a);
setMinimumScoreFromPercentage(40);
minimumAchievements = 2;
achievements.add(achievementCollection.get(12));
achievements.add(achievementCollection.get(13));
achievements.add(achievementCollection.get(14));
break;
} }
} }
@ -494,6 +784,17 @@ public class Scenario {
return "\"Let's talk business\""; return "\"Let's talk business\"";
case LVL_SADDNESS: case LVL_SADDNESS:
return "A sad sad situation"; return "A sad sad situation";
// new:
case LVL_THESEVEN:
return "Welcome to the seven";
case LVL_SMILE:
return "\"Smile like you mean it\"";
case LVL_BUSINESS:
return "\"Let's talk business\"";
case LVL_REALLY:
return "Show me what you really feel";
case LVL_ACTNORMAL:
return "Please act normally";
} }
return "..."; return "...";
} }

View file

@ -43,6 +43,7 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback
private Paint attrScorePaint = new Paint(); private Paint attrScorePaint = new Paint();
private Paint attrScoreLinePaint = new Paint(); private Paint attrScoreLinePaint = new Paint();
private Paint linePaint = new Paint(); private Paint linePaint = new Paint();
private Paint missedPaint = new Paint();
private Paint scorePaint = new Paint(); private Paint scorePaint = new Paint();
private Paint bonusScorePaint = new Paint(); private Paint bonusScorePaint = new Paint();
private Paint scoreFinishedPaint = new Paint(); private Paint scoreFinishedPaint = new Paint();
@ -103,6 +104,8 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback
getHolder().addCallback(this); getHolder().addCallback(this);
_scenario = s; _scenario = s;
Typeface font = Typeface.createFromAsset(context.getAssets(), "unifont-9.0.02.ttf");
scorePaint.setColor(Color.YELLOW); scorePaint.setColor(Color.YELLOW);
scorePaint.setTextSize(40); scorePaint.setTextSize(40);
scorePaint.setTypeface(Typeface.DEFAULT_BOLD); scorePaint.setTypeface(Typeface.DEFAULT_BOLD);
@ -124,6 +127,7 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback
linePaint.setColor(Color.GRAY); linePaint.setColor(Color.GRAY);
linePaint.setStrokeWidth(5); linePaint.setStrokeWidth(5);
attrScorePaint.setColor(Color.GRAY); attrScorePaint.setColor(Color.GRAY);
missedPaint.setColor(Color.DKGRAY);
attrScoreLinePaint.setColor(Color.DKGRAY); attrScoreLinePaint.setColor(Color.DKGRAY);
attrScoreLinePaint.setStrokeWidth(2); attrScoreLinePaint.setStrokeWidth(2);
@ -131,6 +135,7 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback
for(Emotion emotion: Emotion.values()) { for(Emotion emotion: Emotion.values()) {
Paint emoPaint = new Paint(); Paint emoPaint = new Paint();
emoPaint.setTextSize(22); emoPaint.setTextSize(22);
// emoPaint.setTypeface(font);//gets ugly when transformed
emoPaint.setColor(emotion.getColor()); emoPaint.setColor(emotion.getColor());
// emoPaint.setShadowLayer(10,0,0,Color.BLACK); // emoPaint.setShadowLayer(10,0,0,Color.BLACK);
emoPaints.put(emotion, emoPaint); emoPaints.put(emotion, emoPaint);
@ -138,7 +143,7 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback
Paint emoPaintOutline = new Paint(); Paint emoPaintOutline = new Paint();
emoPaintOutline.setColor(emotion.getColor()); emoPaintOutline.setColor(emotion.getColor());
emoPaintOutline.setStyle(Paint.Style.STROKE); emoPaintOutline.setStyle(Paint.Style.STROKE);
emoPaintOutline.setStrokeWidth(3); emoPaintOutline.setStrokeWidth(5);
// emoPaintOutline.setShadowLayer(10,0,0,Color.BLACK); // emoPaintOutline.setShadowLayer(10,0,0,Color.BLACK);
emoOutlinePaints.put(emotion, emoPaintOutline); emoOutlinePaints.put(emotion, emoPaintOutline);
@ -241,7 +246,6 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback
continue; continue;
} }
// Paint targetPaint = (target.hit == null) ? emoPaints.get(target.emotion) : emoScoredPaints.get(target.emotion);
float cy = bottomline_height - (target.timestamp * sec_height) + diff_y; float cy = bottomline_height - (target.timestamp * sec_height) + diff_y;
if(cy < (-1 * canvas.getHeight()) ) { if(cy < (-1 * canvas.getHeight()) ) {
@ -258,19 +262,8 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback
canvas.drawCircle(cx, cy, max_ball_radius * hit.score/100, emoScoredPaints.get(target.emotion)); canvas.drawCircle(cx, cy, max_ball_radius * hit.score/100, emoScoredPaints.get(target.emotion));
} }
// String target_text = target.emotion.toString() + " " + target.value + "%";
// canvas.drawText(target_text, cx, y_pos + diff_y , emoPaint);
} }
// draw the hit middle bottom;
// Paint usedScorePaint = _scenario.isFinished() ? scoreFinishedPaint : scorePaint;
// String scoreText = String.format("Total: %1$.0f", _scenario.getHitTotalValue());
// Rect scoreTextBounds = new Rect();
// usedScorePaint.getTextBounds(scoreText, 0, scoreText.length(), scoreTextBounds);
// canvas.drawText(scoreText, (width - scoreTextBounds.width()) / 2, height - 10, usedScorePaint);
canvas.restore(); canvas.restore();
float hitWidth = width*(_scenario.getHitPercentage()/100); float hitWidth = width*(_scenario.getHitPercentage()/100);
@ -297,7 +290,7 @@ public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback
canvas.drawLine(stepSize*i, height*0.95f, stepSize*i, height, attrScoreLinePaint); canvas.drawLine(stepSize*i, height*0.95f, stepSize*i, height, attrScoreLinePaint);
} }
canvas.drawRect(0, height*0.95f, hitWidth, height, emoPaints.get(Emotion.JOY)); // paint: yellow canvas.drawRect(0, height*0.95f, hitWidth, height, emoPaints.get(Emotion.JOY)); // paint: yellow
canvas.drawRect(hitWidth, height*0.95f, hitWidth+misWidth, height, attrScorePaint); canvas.drawRect(hitWidth, height*0.95f, hitWidth+misWidth, height, missedPaint);
canvas.drawRect(0, height*0.95f, bonusWidth, height*0.975f, bonusBarPaint); canvas.drawRect(0, height*0.95f, bonusWidth, height*0.975f, bonusBarPaint);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -5,12 +5,99 @@
android:id="@+id/activity_credits" android:id="@+id/activity_credits"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.rubenvandeven.emotionhero.CreditsActivity"> tools:context="com.rubenvandeven.emotionhero.CreditsActivity">
<ScrollView
android:id="@+id/creditsLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_marginTop="240dp"
android:text="Emotion Hero is a project by Ruben van de Ven which is produced as part of the Summer Sessions Network for Talent Development in a co-production of Arquivo 237 and V2_ Institute for the Unstable Media."
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srcCompat="@drawable/v2_logo"
android:id="@+id/logoV2"
android:layout_centerHorizontal="true"
android:cropToPadding="true"
android:layout_weight="1" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/arquivo237_logo"
android:id="@+id/logoArquivo"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_weight="1"
android:layout_marginLeft="@dimen/fab_margin" />
</LinearLayout>
<TextView
android:text="Emotional intelligence powered by Affectiva."
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/affectivaPower"
android:textAlignment="center"
android:layout_marginBottom="@dimen/fab_margin"
android:layout_marginTop="@dimen/fab_margin" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/affectiva_logo"
android:id="@+id/logoAffectiva"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:adjustViewBounds="true"
android:cropToPadding="true"
android:layout_marginBottom="@dimen/fab_margin" />
<TextView
android:text="Font used: Unifont CSUR - GPL."
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fontInfo"
android:textAlignment="center"
android:layout_marginBottom="@dimen/fab_margin"
android:layout_marginTop="@dimen/fab_margin" />
<TextView
android:text="For more information see\nwww.emotionhero.com"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/moreInfo"
android:textAlignment="center" />
<TextView
android:text="www.rubenvandeven.com"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/mySite"
android:textAlignment="center"
android:layout_marginBottom="@dimen/fab_margin"
android:layout_marginTop="@dimen/fab_margin" />
</LinearLayout>
</ScrollView>
<ImageView <ImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -24,54 +111,5 @@
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:contentDescription="@string/app_name" /> android:contentDescription="@string/app_name" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_below="@+id/logoEmotionHero"
android:layout_marginTop="@dimen/activity_vertical_margin">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:text="Emotion Hero is a project by Ruben van de Ven.\n
\n\nThis project is produced as part of the Summer Sessions Network for Talent Development in a co-production of Arquivo 237 and V2_ Institute for the Unstable Media.\n
\n\nEmotional intelligence powered by Affectiva.
\n\n Font used:\n - Unifont CSUR - GPL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/v2_logo"
android:id="@+id/logoV2"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/arquivo237_logo"
android:id="@+id/logoArquivo"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/affectiva_logo"
android:id="@+id/logoAffectiva"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
/>
</LinearLayout>
</ScrollView>
</RelativeLayout> </RelativeLayout>

View file

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_ending"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.rubenvandeven.emotionhero.EndingActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/AppTheme.AppBarOverlay"
android:layout_marginBottom="10dp"
>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:titleTextColor="@color/textHighlight">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/appbar"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
>
<TextView
android:text="Loading your position in the general rank list..."
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textLoading"
android:textSize="30sp"
android:textColor="@color/textPrimary" />
<TextView
android:text="You seek desperately to become the Emotion Hero. However, you are not yet there. \nDespite finishing all steps in the training, your peers have done the same. They are better at employing this technology for their own benefit, so you are still one step behind.\nKeep on training young padawan, and eventually, you might become the one and only..."
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textFailure"
android:textSize="30sp"
android:textColor="@color/textPrimary"
android:visibility="gone"/>
<TextView
android:text="You are the one and only Emotion Hero. As number one in the general ranklist, you are the 'Master of the face'."
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textSuccess"
android:textSize="30sp"
android:textColor="@color/textPrimary"
android:visibility="gone" />
<TextView
android:text="Your position"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/fab_margin"
android:id="@+id/textRank"
android:textSize="30sp"
android:textColor="@color/textHighlight"
android:textAlignment="center"
android:visibility="gone" />
<TextView
android:text="23"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/rank"
android:textSize="45sp"
android:textColor="@color/textHighlight"
android:textAlignment="center"
android:visibility="gone" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/emotionhero_logo"
android:id="@+id/logoEmotionHero"
android:cropToPadding="false"
android:adjustViewBounds="true"
android:layout_marginTop="20dp"
android:contentDescription="@string/app_name"
android:visibility="gone" />
<ProgressBar
style="?android:attr/progressBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/scoreProgressBar"
android:indeterminate="true"
android:indeterminateTint="@color/textHighlight"
android:layout_marginTop="20dp" />
</LinearLayout>
</ScrollView>
</RelativeLayout>

View file

@ -35,6 +35,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/titleText" android:id="@+id/titleText"
tools:text='"A spectacular level"' tools:text='"A spectacular level"'
android:layout_margin="@dimen/fab_margin" /> android:layout_margin="@dimen/fab_margin"
android:textSize="24sp" />
</FrameLayout> </FrameLayout>

View file

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_introduction"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.rubenvandeven.emotionhero.IntroductionActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/introText1"
android:text="@string/game_intro_text"
android:textColor="@color/textPrimary"
android:textSize="30sp" />
<TextView
android:text="Yes!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:id="@+id/nextButton"
android:textSize="40sp"
android:textColor="@color/textHighlight"
android:layout_marginBottom="20dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/introText2"
android:text="@string/game_intro_text2"
android:textColor="@color/textPrimary"
android:textSize="30sp"
android:visibility="gone"/>
<TextView
android:text="I'm ready!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:id="@+id/readyButton"
android:textSize="40sp"
android:textColor="@color/textHighlight"
android:layout_marginBottom="20dp"
android:visibility="gone" />
</RelativeLayout>

View file

@ -1,66 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.rubenvandeven.emotionhero.MenuActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/logoEmotionHero"
android:layout_above="@+id/creditsButton"
android:layout_centerHorizontal="true"
android:layout_marginTop="19dp">
<Button
android:text="@string/start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/startButton"
android:fontFamily="sans-serif" />
<Button
android:text="@string/continueBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/continueButton"
android:fontFamily="sans-serif" />
<Button
android:text="@string/highscores"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/highscoresButton"
android:fontFamily="sans-serif" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/emotionhero_logo"
android:id="@+id/logoEmotionHero"
android:cropToPadding="false"
android:adjustViewBounds="true"
android:layout_marginTop="58dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:contentDescription="@string/app_name" />
<Button
android:text="@string/credits"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/creditsButton"
android:layout_alignParentBottom="true"
android:fontFamily="sans-serif" />
</RelativeLayout>

View file

@ -208,7 +208,8 @@
android:layout_below="@+id/hintText" android:layout_below="@+id/hintText"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:id="@+id/improveLayout"> android:id="@+id/improveLayout"
android:visibility="gone">
<TextView <TextView
android:text="Compare scores to get even better!" android:text="Compare scores to get even better!"

View file

@ -43,7 +43,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:id="@+id/achievementsLayout" > android:id="@+id/achievementsLayout"
android:layout_margin="@dimen/fab_margin">
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View file

@ -16,4 +16,8 @@
<string name="load_game_activity">Loading training...</string> <string name="load_game_activity">Loading training...</string>
<string name="game_intro_text">Are you ready to become the next <b>Emotion Hero</b>? With this program you train for the right emotional response in <i>every</i> situation.</string> <string name="game_intro_text">Are you ready to become the next <b>Emotion Hero</b>? With this program you train for the right emotional response in <i>every</i> situation.</string>
<string name="game_intro_text2">The bar belows shows your current feelings.\nFeel the emotions as they are given by the dots on screen. If <i>you</i> feel them, <i>we</i> detect them!</string> <string name="game_intro_text2">The bar belows shows your current feelings.\nFeel the emotions as they are given by the dots on screen. If <i>you</i> feel them, <i>we</i> detect them!</string>
<string name="permission_description">When you play this game, it can collect fragments of your face which are contributed to a shared artwork. See the example image below, emotionhero.com.\nAre you ok with this?</string>
<string name="permission_no">Rather not</string>
<string name="permission_yes">Sure!</string>
</resources> </resources>