diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 03b6a6a..4ab3f1d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,30 +3,42 @@ xmlns:tools="http://schemas.android.com/tools" package="com.rubenvandeven.emotionhero"> - - - + - + tools:replace="android:allowBackup,android:label"> + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java index a23e851..f3a40df 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/GamingActivity.java @@ -42,7 +42,6 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL public final static String INTENT_EXTRA_SCENARIO = "com.rubenvandeven.emotionhero.LEVEL"; final static String LOG_TAG = "EmotionHero"; - final static String PLAYERINFO_FILENAME = "playerinfo.json"; final int PERMISSIONS_REQUEST_CAMERA = 1; @@ -68,6 +67,7 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL final static int SOUND_SCORE = 1; + protected Player player; @Override protected void onCreate(Bundle savedInstanceState) { @@ -77,6 +77,8 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL setContentView(R.layout.activity_gaming); + player = Player.getInstance(getApplicationContext()); + Intent intent = getIntent(); // first level is the default to load, if none is given to intent int scenarioLvlId = intent.getIntExtra(INTENT_EXTRA_SCENARIO, Scenario.SCENARIOS.get(0)); @@ -148,6 +150,7 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL // currentScenario = new ScenarioAnger(this); currentScenario = new Scenario(scenarioLvlId, this); + currentScenario.init(); // "start the clock"... scenarioView = new ScenarioView(this, currentScenario); @@ -178,10 +181,10 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL String permission = "android.permission.CAMERA"; int res = getApplicationContext().checkCallingOrSelfPermission(permission); if (res == PackageManager.PERMISSION_GRANTED) { - Log.e(LOG_TAG, "HAS PERM"); + Log.i(LOG_TAG, "Has camera permission"); has_camera_permission = true; } else { - Log.e(LOG_TAG, "NO PERM"); + Log.i(LOG_TAG, "No camera permission"); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSIONS_REQUEST_CAMERA); @@ -242,11 +245,6 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL Face face = list.get(0); currentScenario.setCurrentFace(face); scenarioView.setCurrentAttributeScoresForFace(face); - -// if(frame instanceof Frame.ByteArrayFrame) -// { -// Frame.ByteArrayFrame byteArrayFrame = (Frame.ByteArrayFrame) frame; -// } } } @@ -342,37 +340,6 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL sound = new SoundPool(5, AudioManager.STREAM_MUSIC,0); } - public PlayerInfo getPlayerInfo() { - try{ - FileInputStream fis = openFileInput(PLAYERINFO_FILENAME ); - StringBuilder builder = new StringBuilder(); - int ch; - while((ch = fis.read()) != -1){ - builder.append((char)ch); - } - return PlayerInfo.fromJson(builder.toString()); - } catch (IOException e) { - return new PlayerInfo(); - } - } - - public void savePlayerScore(Score score) { - PlayerInfo playerInfo = getPlayerInfo(); - playerInfo.addScore(score); - savePlayerInfo(playerInfo); - } - - public void savePlayerInfo(PlayerInfo playerInfo) { - try { - FileOutputStream fos = openFileOutput(PLAYERINFO_FILENAME, Context.MODE_PRIVATE); - fos.write(playerInfo.toJson().getBytes()); - fos.close(); - } catch(IOException e) { - // for now skip error - Log.e(LOG_TAG, "Could not save player information!"); - } - } - public void finishLevel() { setText("LEVEL ENDED"); stopDetector(); @@ -381,7 +348,7 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL nextLvlButton.setVisibility(View.VISIBLE); } - PlayerInfo playerInfo = getPlayerInfo(); + PlayerInfo playerInfo = player.getPlayerInfo(); ScoreList scores = playerInfo.getScoresForLevel(currentScenario.id); Score score = currentScenario.getScore(); @@ -399,8 +366,15 @@ public class GamingActivity extends AppCompatActivity implements Detector.ImageL // show the highscores (top 3?)... + // check whether this is the highest reached level by the player + // ... used by 'continue' button in main menu + Scenario nextScenario = new Scenario(currentScenario.getNextLevelId(), this); + if(nextScenario.isHigherThen(playerInfo.reachedLevelId)) { + playerInfo.reachedLevelId = currentScenario.id; + } + scores.add(score); - savePlayerInfo(playerInfo); + player.savePlayerInfo(playerInfo); String highscoreText = "TOPSCORES\n"; diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/IntroActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/IntroActivity.java new file mode 100644 index 0000000..cbeb45b --- /dev/null +++ b/app/src/main/java/com/rubenvandeven/emotionhero/IntroActivity.java @@ -0,0 +1,75 @@ +package com.rubenvandeven.emotionhero; + +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.content.Intent; +import android.os.Handler; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.Toast; + +public class IntroActivity extends AppCompatActivity { + + protected Player player; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + getSupportActionBar().hide(); + setContentView(R.layout.activity_intro); + + player = Player.getInstance(getApplicationContext()); + + int extraLogoDelay; + if(player.isNew()) { + extraLogoDelay = 1500; + } else { + extraLogoDelay = 0; + } + + final ImageView logoV2 = (ImageView) findViewById(R.id.logoV2); + final ImageView logoArquivo = (ImageView) findViewById(R.id.logoArquivo); + final ImageView logoAffectiva = (ImageView) findViewById(R.id.logoAffectiva); + + ObjectAnimator fadeOutV2 = ObjectAnimator.ofFloat(logoV2, "alpha", 0f); + fadeOutV2.setDuration(1000); + fadeOutV2.setStartDelay(0 + extraLogoDelay); + ObjectAnimator fadeInV2 = ObjectAnimator.ofFloat(logoV2, "alpha", 0f, 1f); + fadeInV2.setDuration(1000); + + ObjectAnimator fadeOutArquivo = ObjectAnimator.ofFloat(logoArquivo, "alpha", 0f); + fadeOutArquivo.setDuration(1000); + fadeOutArquivo.setStartDelay(0 + extraLogoDelay); + ObjectAnimator fadeInArquivo = ObjectAnimator.ofFloat(logoArquivo, "alpha", 0f, 1f); + fadeInArquivo.setDuration(1000); + + ObjectAnimator fadeOutAffectiva = ObjectAnimator.ofFloat(logoAffectiva, "alpha", 0f); + fadeOutAffectiva.setDuration(1000); + fadeOutAffectiva.setStartDelay(1000 + extraLogoDelay); + ObjectAnimator fadeInAffectiva = ObjectAnimator.ofFloat(logoAffectiva, "alpha", 0f, 1f); + fadeInAffectiva.setDuration(1000); + + + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.playSequentially(fadeInV2, fadeOutV2, + fadeInArquivo, fadeOutArquivo, + fadeInAffectiva, fadeOutAffectiva); + animatorSet.start(); + + + final Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + Intent intent = new Intent(IntroActivity.this, MenuActivity.class); + finish(); + startActivity(intent); + + } + }, 7000 + (3*extraLogoDelay)); + } +} diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/MenuActivity.java b/app/src/main/java/com/rubenvandeven/emotionhero/MenuActivity.java new file mode 100644 index 0000000..9976f76 --- /dev/null +++ b/app/src/main/java/com/rubenvandeven/emotionhero/MenuActivity.java @@ -0,0 +1,117 @@ +package com.rubenvandeven.emotionhero; + +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +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; + +public class MenuActivity extends AppCompatActivity { + + Player player; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + 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 quitButton = (Button) findViewById(R.id.quitButton); + + + 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); + quitButton.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 fadeInQuitButton = ObjectAnimator.ofFloat(quitButton, "alpha", 0f, 1f); + fadeInQuitButton.setDuration(1000); + fadeInQuitButton.setStartDelay(900); + + + 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, + fadeInQuitButton); + buttonAnimatorSet.start(); + +// AnimatorSet animatorSet = new AnimatorSet(); +// animatorSet.playSequentially(fadeInEmotionHero, buttonAnimatorSet); +// animatorSet.start(); + + + startButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(MenuActivity.this, GamingActivity.class); + startActivity(intent); + } + }); + + continueButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + 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) { + Toast toast = Toast.makeText(getApplicationContext(), "Not implemented yet", Toast.LENGTH_LONG); + toast.show(); + } + }); + + quitButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + + + } +} diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/Player.java b/app/src/main/java/com/rubenvandeven/emotionhero/Player.java new file mode 100644 index 0000000..dcbc175 --- /dev/null +++ b/app/src/main/java/com/rubenvandeven/emotionhero/Player.java @@ -0,0 +1,77 @@ +package com.rubenvandeven.emotionhero; + +import android.content.Context; +import android.util.Log; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * The current player of the game (for this device) + * Created by ruben on 22/08/16. + */ +public class Player { + + final static String PLAYERINFO_FILENAME = "playerinfo.json"; + + private static Player ourInstance; + + private Context c; + + PlayerInfo info; + + public static Player getInstance(Context c) { + if(ourInstance == null) { + ourInstance = new Player(c); + } + return ourInstance; + } + + private Player(Context c) { + this.c = c; + this.info = loadPlayerInfo(); + } + + public PlayerInfo getPlayerInfo() { + return this.info; + } + + public PlayerInfo loadPlayerInfo() { + try{ + FileInputStream fis = c.openFileInput(PLAYERINFO_FILENAME ); + StringBuilder builder = new StringBuilder(); + int ch; + while((ch = fis.read()) != -1){ + builder.append((char)ch); + } + return PlayerInfo.fromJson(builder.toString()); + } catch (IOException e) { + return new PlayerInfo(); + } + } + + public boolean isNew() { + if(this.info.reachedLevelId < 0) { + return true; + } + return false; + } + + + public void savePlayerScore(Score score) { + info.addScore(score); + savePlayerInfo(info); + } + + public void savePlayerInfo(PlayerInfo playerInfo) { + try { + FileOutputStream fos = c.openFileOutput(PLAYERINFO_FILENAME, Context.MODE_PRIVATE); + fos.write(playerInfo.toJson().getBytes()); + fos.close(); + } catch(IOException e) { + // for now skip error + Log.e("PlayerInfo", "Could not save player information!"); + } + } +} diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/PlayerInfo.java b/app/src/main/java/com/rubenvandeven/emotionhero/PlayerInfo.java index d776738..42f5020 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/PlayerInfo.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/PlayerInfo.java @@ -1,6 +1,7 @@ package com.rubenvandeven.emotionhero; import android.support.annotation.NonNull; +import android.util.Log; import android.util.SparseArray; import com.google.gson.Gson; @@ -16,6 +17,7 @@ import java.util.Set; public class PlayerInfo { public Map levelScores = new HashMap<>(); + public int reachedLevelId = -1; public ScoreList getScoresForLevel(int lvl_id) { ScoreList scoreList; @@ -45,6 +47,24 @@ public class PlayerInfo { public String toJson() { Gson gson = new Gson(); - return gson.toJson(this); + String json = gson.toJson(this); + Log.i("PlayerInfo", "Generated: "+json); + return json; + } + + /** + * Whether the reachedLevelId is higher than the first level + * used to show 'continue' button in menu + * @return + */ + public boolean canContinueLevel() { + if(reachedLevelId < 0) + return false; + + if(Scenario.SCENARIOS.indexOf(reachedLevelId) > 0) { + return true; + } + + return false; } } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java b/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java index abc41a1..697f0d3 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/Scenario.java @@ -6,6 +6,8 @@ import android.util.Log; import com.affectiva.android.affdex.sdk.detector.Face; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import java.util.Timer; import java.util.TimerTask; @@ -285,7 +287,9 @@ public class Scenario { return null; } - return new Score(id, getHitTotalValue()); + Score score = new Score(id, getHitTotalValue()); + score.setTargets(targets); + return score; } public int getMaxScore() { @@ -332,4 +336,16 @@ public class Scenario { return false; } + public boolean isHigherThen(int lvl_id) { + return isHigherLevel(id, lvl_id); + } + + public static boolean isHigherLevel(int lvl_id, int then_lvl_id) { + if(lvl_id == then_lvl_id) { + return false; + } + + return SCENARIOS.indexOf(lvl_id) > SCENARIOS.indexOf(then_lvl_id); + } + } diff --git a/app/src/main/java/com/rubenvandeven/emotionhero/Score.java b/app/src/main/java/com/rubenvandeven/emotionhero/Score.java index d80d584..d37f3c0 100644 --- a/app/src/main/java/com/rubenvandeven/emotionhero/Score.java +++ b/app/src/main/java/com/rubenvandeven/emotionhero/Score.java @@ -1,5 +1,6 @@ package com.rubenvandeven.emotionhero; +import java.util.ArrayList; import java.util.Date; /** @@ -11,9 +12,15 @@ public class Score { float score; Date time; + ArrayList targets = new ArrayList<>(); + public Score(int lvl_id, float score) { this.lvl_id = lvl_id; this.score = score; this.time = new Date(); } + + public void setTargets(ArrayList targets) { + this.targets = targets; + } } diff --git a/app/src/main/res/drawable/affectiva_logo.png b/app/src/main/res/drawable/affectiva_logo.png new file mode 100644 index 0000000..298f182 Binary files /dev/null and b/app/src/main/res/drawable/affectiva_logo.png differ diff --git a/app/src/main/res/drawable/arquivo237_logo.png b/app/src/main/res/drawable/arquivo237_logo.png new file mode 100644 index 0000000..518693e Binary files /dev/null and b/app/src/main/res/drawable/arquivo237_logo.png differ diff --git a/app/src/main/res/drawable/emotionhero_logo.png b/app/src/main/res/drawable/emotionhero_logo.png new file mode 100644 index 0000000..e6d4b79 Binary files /dev/null and b/app/src/main/res/drawable/emotionhero_logo.png differ diff --git a/app/src/main/res/drawable/v2_logo.png b/app/src/main/res/drawable/v2_logo.png new file mode 100644 index 0000000..09fe05f Binary files /dev/null and b/app/src/main/res/drawable/v2_logo.png differ diff --git a/app/src/main/res/layout/activity_intro.xml b/app/src/main/res/layout/activity_intro.xml new file mode 100644 index 0000000..6e2756e --- /dev/null +++ b/app/src/main/res/layout/activity_intro.xml @@ -0,0 +1,47 @@ + + + + + + + + diff --git a/app/src/main/res/layout/activity_menu.xml b/app/src/main/res/layout/activity_menu.xml new file mode 100644 index 0000000..02c1210 --- /dev/null +++ b/app/src/main/res/layout/activity_menu.xml @@ -0,0 +1,63 @@ + + + + + + +