blob: fce11c3efad19d66f32690b00a84e5e33badebe3 [file] [log] [blame]
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.toongame;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
/**
* This activity, launched from the ToonGame activity, takes the user between three
* different setup screens where they choose a name, choose a difficulty rating, and
* enter important financial information. All of the screens are meant to be
* simple, engaging, and fun.
*/
public class PlayerSetupActivity extends Activity {
private static final AccelerateInterpolator sAccelerator = new AccelerateInterpolator();
private static final LinearInterpolator sLinearInterpolator = new LinearInterpolator();
ViewGroup mContainer;
EditText mEditText;
private static final int NAME_STATE = 0;
private static final int DIFFICULTY_STATE = 1;
private static final int CREDIT_STATE = 2;
private int mEntryState = NAME_STATE;
SkewableTextView mNameTV, mDifficultyTV, mCreditTV;
ViewGroup mNameButtons, mDifficultyButtons, mCreditButtons1, mCreditButtons2;
Button mBobButton, mJaneButton, mPatButton;
private static final TimeInterpolator sOvershooter = new OvershootInterpolator();
private static final DecelerateInterpolator sDecelerator = new DecelerateInterpolator();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player_setup_layout);
overridePendingTransition(0, 0);
mContainer = (ViewGroup) findViewById(R.id.container);
mContainer.getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
mNameTV = (SkewableTextView) findViewById(R.id.nameTV);
mDifficultyTV = (SkewableTextView) findViewById(R.id.ageTV);
mCreditTV = (SkewableTextView) findViewById(R.id.creditTV);
mBobButton = setupButton(R.id.bobButton);
setupButton(R.id.janeButton);
setupButton(R.id.patButton);
setupButton(R.id.easyButton);
setupButton(R.id.hardButton);
setupButton(R.id.megaHardButton);
mNameButtons = (ViewGroup) findViewById(R.id.nameButtons);
mDifficultyButtons = (ViewGroup) findViewById(R.id.difficultyButtons);
mCreditButtons1 = (ViewGroup) findViewById(R.id.creditButtons1);
mCreditButtons2 = (ViewGroup) findViewById(R.id.creditButtons2);
}
@Override
public void finish() {
super.finish();
overridePendingTransition(0, 0);
}
private Button setupButton(int resourceId) {
Button button = (Button) findViewById(resourceId);
button.setOnTouchListener(mButtonPressListener);
return button;
}
private View.OnTouchListener mButtonPressListener =
new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
v.animate().setDuration(ToonGame.SHORT_DURATION).
scaleX(.8f).scaleY(.8f).setInterpolator(sDecelerator);
break;
case MotionEvent.ACTION_UP:
v.animate().setDuration(ToonGame.SHORT_DURATION).
scaleX(1).scaleY(1).setInterpolator(sAccelerator);
break;
default:
break;
}
return false;
}
};
public void buttonClick(View clickedView, int alignmentRule) {
ViewGroup parent = (ViewGroup) clickedView.getParent();
for (int i = 0; i < parent.getChildCount(); ++i) {
Button child = (Button) parent.getChildAt(i);
if (child != clickedView) {
child.animate().alpha(0);
} else {
final Button buttonCopy = new Button(this);
child.setVisibility(View.INVISIBLE);
buttonCopy.setBackground(child.getBackground());
buttonCopy.setText(((Button) child).getText());
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
params.addRule(alignmentRule);
params.setMargins(25, 50, 25, 50);
buttonCopy.setLayoutParams(params);
buttonCopy.setPadding(child.getPaddingLeft(), child.getPaddingTop(),
child.getPaddingRight(), child.getPaddingBottom());
buttonCopy.setTextSize(TypedValue.COMPLEX_UNIT_PX, child.getTextSize());
buttonCopy.setTypeface(child.getTypeface(), Typeface.BOLD);
ColorStateList colors = child.getTextColors();
buttonCopy.setTextColor(colors.getDefaultColor());
final int[] oldLocationInWindow = new int[2];
child.getLocationInWindow(oldLocationInWindow);
mContainer.addView(buttonCopy);
buttonCopy.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
buttonCopy.getViewTreeObserver().removeOnPreDrawListener(this);
int[] locationInWindow = new int[2];
buttonCopy.getLocationInWindow(locationInWindow);
float deltaX = oldLocationInWindow[0] - locationInWindow[0];
float deltaY = oldLocationInWindow[1] - locationInWindow[1];
buttonCopy.setTranslationX(deltaX);
buttonCopy.setTranslationY(deltaY);
PropertyValuesHolder pvhSX =
PropertyValuesHolder.ofFloat(View.SCALE_X, 3);
PropertyValuesHolder pvhSY =
PropertyValuesHolder.ofFloat(View.SCALE_Y, 3);
ObjectAnimator bounceAnim = ObjectAnimator.ofPropertyValuesHolder(
buttonCopy, pvhSX, pvhSY);
bounceAnim.setRepeatCount(1);
bounceAnim.setRepeatMode(ValueAnimator.REVERSE);
bounceAnim.setInterpolator(sDecelerator);
bounceAnim.setDuration(300);
PropertyValuesHolder pvhTX =
PropertyValuesHolder.ofFloat(View.TRANSLATION_X, 0);
PropertyValuesHolder pvhTY =
PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 0);
ObjectAnimator moveAnim = ObjectAnimator.ofPropertyValuesHolder(
buttonCopy, pvhTX, pvhTY);
moveAnim.setDuration(600);
bounceAnim.start();
moveAnim.start();
moveAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
switch (mEntryState) {
case (NAME_STATE) :
{
Runnable runnable = new Runnable() {
public void run() {
mDifficultyButtons.setVisibility(View.VISIBLE);
mNameButtons.setVisibility(View.GONE);
popChildrenIn(mDifficultyButtons, null);
}
};
slideToNext(mNameTV, mDifficultyTV, runnable);
mEntryState = DIFFICULTY_STATE;
break;
}
case (DIFFICULTY_STATE) :
{
mDifficultyButtons.setVisibility(View.GONE);
for (int i = 0; i < 5; ++i) {
mCreditButtons1.addView(setupNumberButton(i));
}
for (int i = 5; i < 10; ++i) {
mCreditButtons2.addView(setupNumberButton(i));
}
Runnable runnable = new Runnable() {
public void run() {
mCreditButtons1.setVisibility(View.VISIBLE);
Runnable runnable = new Runnable() {
public void run() {
mCreditButtons2.setVisibility(View.VISIBLE);
popChildrenIn(mCreditButtons2, null);
}
};
popChildrenIn(mCreditButtons1, runnable);
}
};
slideToNext(mDifficultyTV, mCreditTV, runnable);
mEntryState = CREDIT_STATE;
}
break;
}
}
});
return true;
}
});
}
}
}
public void selectDifficulty(View clickedView) {
buttonClick(clickedView, RelativeLayout.ALIGN_PARENT_RIGHT);
}
public void selectName(View clickedView) {
buttonClick(clickedView, RelativeLayout.ALIGN_PARENT_LEFT);
}
private Button setupNumberButton(int number) {
Button button = new Button(PlayerSetupActivity.this);
button.setTextSize(15);
button.setTextColor(Color.WHITE);
button.setTypeface(mBobButton.getTypeface(), Typeface.BOLD);
button.setText(Integer.toString(number));
button.setPadding(0, 0, 0, 0);
OvalShape oval = new OvalShape();
ShapeDrawable drawable = new ShapeDrawable(oval);
drawable.getPaint().setColor(0xFF << 24 | (int) (50 + 150 * Math.random()) << 16 |
(int) (50 + 150 * Math.random()) << 8 | (int) (50 + 150 * Math.random()));
button.setBackground(drawable);
button.setOnTouchListener(mButtonPressListener);
return button;
}
ViewTreeObserver.OnPreDrawListener mPreDrawListener =
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
mContainer.getViewTreeObserver().removeOnPreDrawListener(this);
mContainer.setScaleX(0);
mContainer.setScaleY(0);
mContainer.animate().scaleX(1).scaleY(1).setInterpolator(new OvershootInterpolator());
mContainer.animate().setDuration(ToonGame.LONG_DURATION).withEndAction(new Runnable() {
@Override
public void run() {
ViewGroup buttonsParent = (ViewGroup) findViewById(R.id.nameButtons);
buttonsParent.setVisibility(View.VISIBLE);
popChildrenIn(buttonsParent, null);
}
});
return false;
}
};
private void popChildrenIn(ViewGroup parent, final Runnable endAction) {
// for all children, scale in one at a time
TimeInterpolator overshooter = new OvershootInterpolator();
int childCount = parent.getChildCount();
ObjectAnimator[] childAnims = new ObjectAnimator[childCount];
for (int i = 0; i < childCount; ++i) {
View child = parent.getChildAt(i);
child.setScaleX(0);
child.setScaleY(0);
PropertyValuesHolder pvhSX = PropertyValuesHolder.ofFloat(View.SCALE_X, 1);
PropertyValuesHolder pvhSY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1);
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(child, pvhSX, pvhSY);
anim.setDuration(150);
anim.setInterpolator(overshooter);
childAnims[i] = anim;
}
AnimatorSet set = new AnimatorSet();
set.playSequentially(childAnims);
set.start();
if (endAction != null) {
set.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
endAction.run();
}
});
}
}
private void slideToNext(final SkewableTextView currentView,
final SkewableTextView nextView, final Runnable endAction) {
// skew/anticipate current view, slide off, set GONE, restore translation
ObjectAnimator currentSkewer = ObjectAnimator.ofFloat(currentView, "skewX", -.5f);
currentSkewer.setInterpolator(sDecelerator);
ObjectAnimator currentMover = ObjectAnimator.ofFloat(currentView, View.TRANSLATION_X,
-mContainer.getWidth());
currentMover.setInterpolator(sLinearInterpolator);
currentMover.setDuration(ToonGame.MEDIUM_DURATION);
// set next view visible, translate off to right, skew,
// slide on in parallel, overshoot/wobble, unskew
nextView.setVisibility(View.VISIBLE);
nextView.setSkewX(-.5f);
nextView.setTranslationX(mContainer.getWidth());
ObjectAnimator nextMover = ObjectAnimator.ofFloat(nextView, View.TRANSLATION_X, 0);
nextMover.setInterpolator(sAccelerator);
nextMover.setDuration(ToonGame.MEDIUM_DURATION);
ObjectAnimator nextSkewer = ObjectAnimator.ofFloat(nextView, "skewX", 0);
nextSkewer.setInterpolator(sOvershooter);
AnimatorSet moverSet = new AnimatorSet();
moverSet.playTogether(currentMover, nextMover);
AnimatorSet fullSet = new AnimatorSet();
fullSet.playSequentially(currentSkewer, moverSet, nextSkewer);
fullSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
currentView.setSkewX(0);
currentView.setVisibility(View.GONE);
currentView.setTranslationX(0);
if (endAction != null) {
endAction.run();
}
}
});
fullSet.start();
}
}