Add original project.
42
.gitignore
vendored
@ -33,3 +33,45 @@ google-services.json
|
|||||||
# Android Profiling
|
# Android Profiling
|
||||||
*.hprof
|
*.hprof
|
||||||
|
|
||||||
|
## Suggested ^^
|
||||||
|
|
||||||
|
## From TicTacToe project for good measure. vv
|
||||||
|
|
||||||
|
# Gradle files
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Local configuration file (sdk path, etc)
|
||||||
|
local.properties
|
||||||
|
|
||||||
|
# Log/OS Files
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Android Studio generated files and folders
|
||||||
|
captures/
|
||||||
|
.externalNativeBuild/
|
||||||
|
.cxx/
|
||||||
|
*.apk
|
||||||
|
output.json
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
*.iml
|
||||||
|
.idea/
|
||||||
|
misc.xml
|
||||||
|
deploymentTargetDropDown.xml
|
||||||
|
render.experimental.xml
|
||||||
|
|
||||||
|
# Keystore files
|
||||||
|
*.jks
|
||||||
|
*.keystore
|
||||||
|
|
||||||
|
# Google Services (e.g. APIs or Firebase)
|
||||||
|
google-services.json
|
||||||
|
|
||||||
|
# Android Profiling
|
||||||
|
*.hprof
|
||||||
|
/app/debug/output-metadata.json
|
||||||
|
|
||||||
|
# Ha!
|
||||||
|
keystore/*
|
||||||
|
release
|
||||||
|
1
app/.gitignore
vendored
Executable file
@ -0,0 +1 @@
|
|||||||
|
/build
|
30
app/build.gradle
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 24
|
||||||
|
buildToolsVersion "24.0.2"
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "apps.hyperling.com.platformer"
|
||||||
|
minSdkVersion 15
|
||||||
|
targetSdkVersion 24
|
||||||
|
versionCode 10
|
||||||
|
versionName "0.9"
|
||||||
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||||
|
exclude group: 'com.android.support', module: 'support-annotations'
|
||||||
|
})
|
||||||
|
compile 'com.android.support:appcompat-v7:24.2.1'
|
||||||
|
compile 'com.google.android.gms:play-services-ads:9.8.0'
|
||||||
|
testCompile 'junit:junit:4.12'
|
||||||
|
}
|
17
app/proguard-rules.pro
vendored
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in /home/ling/Android/Sdk/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumentation test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
public void useAppContext() throws Exception {
|
||||||
|
// Context of the app under test.
|
||||||
|
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||||
|
|
||||||
|
assertEquals("apps.hyperling.com.platformer", appContext.getPackageName());
|
||||||
|
}
|
||||||
|
}
|
41
app/src/main/AndroidManifest.xml
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.hyperling.apps.games">
|
||||||
|
|
||||||
|
<!-- Include required permissions for Google Mobile Ads to run. -->
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@drawable/icon"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/AppTheme"
|
||||||
|
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize">
|
||||||
|
<!-- android:configChanges="orientation|keyboardHidden|screenSize" -->
|
||||||
|
|
||||||
|
<!-- This meta-data tag is required to use Google Play Services. -->
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.android.gms.version"
|
||||||
|
android:value="@integer/google_play_services_version" />
|
||||||
|
|
||||||
|
<activity android:name="com.hyperling.apps.games.MainActivity">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.hyperling.apps.games.GameActivity"
|
||||||
|
android:screenOrientation="landscape"
|
||||||
|
android:theme="@style/Theme.AppCompat.NoActionBar"/>
|
||||||
|
|
||||||
|
<activity android:name="com.hyperling.apps.games.OptionsActivity"/>
|
||||||
|
|
||||||
|
<activity android:name="com.hyperling.apps.games.HighScoreActivity"/>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
36
app/src/main/java/com/hyperling/apps/games/AdsHelper.java
Executable file
@ -0,0 +1,36 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.google.android.gms.ads.AdRequest;
|
||||||
|
import com.google.android.gms.ads.AdView;
|
||||||
|
import com.google.android.gms.ads.MobileAds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/26/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AdsHelper {
|
||||||
|
|
||||||
|
// To be called in onResume in Activities
|
||||||
|
public static void toggleAds(SharedPreferences sharedPreferences, String adsKey, Context applicationContext, AdView mAdView){
|
||||||
|
// Enable ads?
|
||||||
|
boolean adsEnabled = sharedPreferences.getBoolean(adsKey, false);
|
||||||
|
if (adsEnabled) {
|
||||||
|
mAdView.setVisibility(View.VISIBLE);
|
||||||
|
MobileAds.initialize(applicationContext, "ca-app-pub-3940256099942544~3347511713");
|
||||||
|
AdRequest adRequest = new AdRequest.Builder()
|
||||||
|
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
|
||||||
|
.addTestDevice("C6A494DC6E7C9AC29102694D48487084") // Nexus 7
|
||||||
|
.addTestDevice("6545BCC9B60A394005546783687339B7") // Moto G
|
||||||
|
.build();
|
||||||
|
mAdView.loadAd(adRequest);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
mAdView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
54
app/src/main/java/com/hyperling/apps/games/Animation.java
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/22/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Animation {
|
||||||
|
|
||||||
|
private Bitmap[] frames;
|
||||||
|
private int currentFrame;
|
||||||
|
private long startTime;
|
||||||
|
private long delay;
|
||||||
|
private boolean playedOnce;
|
||||||
|
|
||||||
|
public void setFrames(Bitmap[] f) {
|
||||||
|
frames = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDelay(long d) {
|
||||||
|
delay = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentFrame(int cf) {
|
||||||
|
currentFrame = cf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap getImage(){
|
||||||
|
return frames[currentFrame];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurrentFrame(){
|
||||||
|
return currentFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getPlayedOnce(){
|
||||||
|
return playedOnce;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(){
|
||||||
|
long elapsed = System.currentTimeMillis() - startTime;
|
||||||
|
if (elapsed > delay){
|
||||||
|
currentFrame++;
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentFrame == frames.length){
|
||||||
|
currentFrame = 0;
|
||||||
|
playedOnce = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
76
app/src/main/java/com/hyperling/apps/games/Bird.java
Executable file
@ -0,0 +1,76 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/23/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Bird extends Player {
|
||||||
|
|
||||||
|
private boolean flapping = false;
|
||||||
|
|
||||||
|
private int lives = 0;
|
||||||
|
|
||||||
|
public Bird(Bitmap b, int w, int h, int numFrames){
|
||||||
|
super(b, w, h, numFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFlapping() {
|
||||||
|
return flapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlapping(boolean flapping) {
|
||||||
|
this.flapping = flapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLives() {
|
||||||
|
return lives;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLives(int lives) {
|
||||||
|
this.lives += lives;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void subtractLives(int lives) {
|
||||||
|
this.lives -= lives;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
// Go up!
|
||||||
|
if (flapping){
|
||||||
|
dy += -1;
|
||||||
|
}
|
||||||
|
// Otherwise fall
|
||||||
|
else{
|
||||||
|
dy += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not fly up faster than this
|
||||||
|
if (dy < -5){
|
||||||
|
dy = -5;
|
||||||
|
}
|
||||||
|
// Do not fall faster than this
|
||||||
|
if (dy > 7){
|
||||||
|
dy = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Map limits *****/
|
||||||
|
if (y < GameView.HEIGHT - getHeight() || dy < 0) {
|
||||||
|
y += dy;
|
||||||
|
}
|
||||||
|
// Do not leave bottom of map
|
||||||
|
else{
|
||||||
|
y = GameView.HEIGHT - getHeight();
|
||||||
|
dy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not leave top of map
|
||||||
|
if (y < 0){
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.update();
|
||||||
|
}
|
||||||
|
}
|
71
app/src/main/java/com/hyperling/apps/games/BirdEnemy.java
Executable file
@ -0,0 +1,71 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/26/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class BirdEnemy extends GameObject {
|
||||||
|
|
||||||
|
protected Bitmap image;
|
||||||
|
|
||||||
|
private Animation animation;
|
||||||
|
|
||||||
|
private int speed, damage;
|
||||||
|
|
||||||
|
public BirdEnemy(Bitmap b, int w, int h, int numFrames, int x, int y, int speed, int damage){
|
||||||
|
image = b;
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.speed = speed;
|
||||||
|
this.damage = damage;
|
||||||
|
|
||||||
|
if (speed > -1){
|
||||||
|
speed = -1;
|
||||||
|
}
|
||||||
|
if (this.y >= GameView.HEIGHT - this.height){
|
||||||
|
this.y = GameView.HEIGHT - this.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create animation
|
||||||
|
Bitmap[] image = new Bitmap[numFrames];
|
||||||
|
animation = new Animation();
|
||||||
|
|
||||||
|
for (int i = 0; i < numFrames; i++){
|
||||||
|
image[i] = Bitmap.createBitmap(b, width * i, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
animation.setFrames(image);
|
||||||
|
|
||||||
|
//animation.setDelay(100);
|
||||||
|
int delay = 25 * Math.abs(speed);
|
||||||
|
if (delay > 125){
|
||||||
|
delay = 125;
|
||||||
|
}
|
||||||
|
else if (delay < 75){
|
||||||
|
delay = 75;
|
||||||
|
}
|
||||||
|
animation.setDelay(delay);
|
||||||
|
animation.setCurrentFrame((int)(Math.random() * numFrames));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(){
|
||||||
|
animation.update();
|
||||||
|
|
||||||
|
// Move the object
|
||||||
|
x += speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
// Draw the object
|
||||||
|
canvas.drawBitmap(animation.getImage(), getX(), getY(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDamage() {
|
||||||
|
return damage;
|
||||||
|
}
|
||||||
|
}
|
290
app/src/main/java/com/hyperling/apps/games/BirdGameView.java
Executable file
@ -0,0 +1,290 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/28/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class BirdGameView extends GameView {
|
||||||
|
private final String birdScoreKey;
|
||||||
|
|
||||||
|
private final int birdGameSpeed = -8;
|
||||||
|
private final int birdEnemySpeedVariance = 5;
|
||||||
|
private final int birdEnemySpeedConstant = 2;
|
||||||
|
private final int cloudsSpeed = birdGameSpeed/2;
|
||||||
|
|
||||||
|
private Bird bird;
|
||||||
|
private Bitmap birdBitmap;
|
||||||
|
|
||||||
|
private ArrayList<BirdEnemy> birdEnemies;
|
||||||
|
private Bitmap birdEnemyBitmap;
|
||||||
|
|
||||||
|
private final int birdWidth = 30;
|
||||||
|
private final int birdHeight = 20;
|
||||||
|
private final int birdFrames = 4;
|
||||||
|
|
||||||
|
private ArrayList<ExtraLife> birdExtraLives;
|
||||||
|
private Bitmap birdExtraLifeBitmap;
|
||||||
|
|
||||||
|
private final int birdExtraLifeWidth = 20;
|
||||||
|
private final int birdExtraLifeHeight = 30;
|
||||||
|
|
||||||
|
private final int birdMaxNumEnemyRows = HEIGHT / birdHeight;
|
||||||
|
private final int birdEnemySpawnRate = 25;
|
||||||
|
|
||||||
|
private Bitmap backgroundBitmap, cloudsBitmap;
|
||||||
|
|
||||||
|
public BirdGameView(Context context){
|
||||||
|
super(context);
|
||||||
|
|
||||||
|
// Keys
|
||||||
|
birdScoreKey = resources.getString(R.string.birdScoreKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayScore(Canvas canvas){
|
||||||
|
int highScore = sharedPreferences.getInt(birdScoreKey, 0);
|
||||||
|
textPaint.setColor(Color.parseColor("#330066"));
|
||||||
|
canvas.drawText("High: " + highScore, 0, textPaint.getTextSize(), textPaint);
|
||||||
|
canvas.drawText("Current: " + bird.getScore(), 0, textPaint.getTextSize() * 2, textPaint);
|
||||||
|
|
||||||
|
if (bird.getLives() > 0) {
|
||||||
|
canvas.drawText("Lives: " + bird.getLives(), 0, textPaint.getTextSize() * 3, textPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fpsEnabled){
|
||||||
|
canvas.drawText("FPS: " + thread.averageFPS, 0, HEIGHT - 1, textPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bird.isPlaying()) {
|
||||||
|
textPaint.setColor(Color.parseColor("#330066"));
|
||||||
|
canvas.drawText("You are the Purple Bird", WIDTH / 4, HEIGHT / 4 - textPaint.getTextSize(), textPaint);
|
||||||
|
|
||||||
|
textPaint.setColor(Color.parseColor("#FF9900"));
|
||||||
|
canvas.drawText("Tap the Screen to Start", WIDTH / 4, HEIGHT / 4, textPaint);
|
||||||
|
canvas.drawText("Hold the Screen to Fly Higher", WIDTH / 4, HEIGHT / 4 + textPaint.getTextSize(), textPaint);
|
||||||
|
|
||||||
|
textPaint.setColor(Color.parseColor("#FF0000"));
|
||||||
|
canvas.drawText("Dodge the Enemy Birds", WIDTH / 4, HEIGHT * 3 / 4, textPaint);
|
||||||
|
|
||||||
|
textPaint.setColor(Color.parseColor("#FFFF00"));
|
||||||
|
textPaint.setFakeBoldText(true);
|
||||||
|
canvas.drawText("Collect the Bird Coins for Extra Lives", WIDTH / 4, HEIGHT * 3 / 4 + textPaint.getTextSize(), textPaint);
|
||||||
|
textPaint.setFakeBoldText(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
|
|
||||||
|
// Base Object Initializations
|
||||||
|
if (higherQualityEnabled) {
|
||||||
|
backgroundBitmap = BitmapFactory.decodeResource(resources, R.drawable.background_forest_without_clouds);
|
||||||
|
cloudsBitmap = BitmapFactory.decodeResource(resources, R.drawable.clouds);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
backgroundBitmap = BitmapFactory.decodeResource(resources, R.drawable.background_forest);
|
||||||
|
}
|
||||||
|
birdBitmap = BitmapFactory.decodeResource(resources, R.drawable.bird);
|
||||||
|
birdEnemyBitmap = BitmapFactory.decodeResource(resources, R.drawable.bird_enemy);
|
||||||
|
birdExtraLifeBitmap = BitmapFactory.decodeResource(resources, R.drawable.bird_extra_life);
|
||||||
|
|
||||||
|
// Game Object Initializations
|
||||||
|
background = new GameBackground(backgroundBitmap);
|
||||||
|
if (higherQualityEnabled) {
|
||||||
|
clouds = new GameBackground(cloudsBitmap);
|
||||||
|
}
|
||||||
|
bird = new Bird(birdBitmap, birdWidth, birdHeight, birdFrames);
|
||||||
|
birdEnemies = new ArrayList<>();
|
||||||
|
birdExtraLives = new ArrayList<>();
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
setGameSpeed(birdGameSpeed);
|
||||||
|
|
||||||
|
super.surfaceCreated(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
|
if (!bird.isPlaying()) {
|
||||||
|
bird.setPlaying(true);
|
||||||
|
|
||||||
|
int lifeMiddleOfScreen = HEIGHT/2 - birdExtraLifeHeight/2;
|
||||||
|
birdExtraLives.add(new ExtraLife(birdExtraLifeBitmap, birdExtraLifeWidth, birdExtraLifeHeight, WIDTH, lifeMiddleOfScreen, 1));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
bird.setFlapping(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_UP){
|
||||||
|
bird.setFlapping(false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseGame() {
|
||||||
|
super.pauseGame(birdScoreKey, bird.getScore());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
super.update();
|
||||||
|
|
||||||
|
|
||||||
|
if (bird.isPlaying()) {
|
||||||
|
background.update(gameSpeed);
|
||||||
|
if (higherQualityEnabled) {
|
||||||
|
clouds.update(cloudsSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
int birdLevel = bird.getScore() / (birdEnemySpawnRate * birdMaxNumEnemyRows);
|
||||||
|
|
||||||
|
// Update extra lives before enemies :)
|
||||||
|
for (int i = 0; i < birdExtraLives.size(); i++) {
|
||||||
|
ExtraLife birdExtraLife = birdExtraLives.get(i);
|
||||||
|
boolean removeLife = false;
|
||||||
|
|
||||||
|
// Check if we've hit any extra lives
|
||||||
|
if (bird.getRect().intersect(birdExtraLife.getRect())){
|
||||||
|
bird.addLives(birdExtraLife.getNumLives());
|
||||||
|
removeLife = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removeLife || birdExtraLife.x + birdExtraLifeWidth < 0){
|
||||||
|
birdExtraLives.remove(birdExtraLife);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
birdExtraLife.update(birdGameSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Add new lives *****/
|
||||||
|
// Only < so that lives don't appear until more than 1 bird can be on a row
|
||||||
|
if (birdExtraLives.size() < birdLevel){
|
||||||
|
int birdExtraLifeX = WIDTH + birdExtraLifeWidth;
|
||||||
|
int birdExtraLifeY = ((int)(Math.random() * HEIGHT));;
|
||||||
|
birdExtraLives.add(new ExtraLife(birdExtraLifeBitmap, birdExtraLifeWidth, birdExtraLifeHeight, birdExtraLifeX, birdExtraLifeY, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update enemies
|
||||||
|
for (int i = 0; i < birdEnemies.size(); i++){
|
||||||
|
BirdEnemy birdEnemy = birdEnemies.get(i);
|
||||||
|
boolean birdEnemyRemove = false;
|
||||||
|
|
||||||
|
// Check if we've hit any enemies
|
||||||
|
if (bird.getRect().intersect(birdEnemy.getRect())){
|
||||||
|
|
||||||
|
bird.subtractLives(birdEnemy.getDamage());
|
||||||
|
birdEnemyRemove = true;
|
||||||
|
|
||||||
|
if (bird.getLives() < 0) {
|
||||||
|
/***** Stop the game, save the score, and reset the player and all objects *****/
|
||||||
|
bird.setPlaying(false);
|
||||||
|
saveScore(birdScoreKey, bird.getScore());
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
bird = new Bird(birdBitmap, birdWidth, birdHeight, birdFrames);
|
||||||
|
birdEnemies = new ArrayList<>();
|
||||||
|
birdExtraLives = new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
birdEnemy.update();
|
||||||
|
|
||||||
|
// Check if any enemies can be removed yet
|
||||||
|
if (birdEnemyRemove || birdEnemy.x + birdEnemy.width < 0){
|
||||||
|
birdEnemies.remove(birdEnemy);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we can add new enemies
|
||||||
|
if (birdEnemies.size() < bird.getScore() / 25 && !thread.markerFrame){
|
||||||
|
//int enemyX = WIDTH + (int)(WIDTH * Math.random());
|
||||||
|
int enemyX = WIDTH + birdWidth;
|
||||||
|
int enemyY = ((int)(Math.random() * HEIGHT));
|
||||||
|
// Add constant so that the bird is always slower than the background
|
||||||
|
// Prevents birds from looking frozen or like they're going backwards
|
||||||
|
int enemySpeed = gameSpeed + ((int)(Math.random() * birdEnemySpeedVariance) + birdEnemySpeedConstant);
|
||||||
|
int numBirdEnemiesInRow = 0;
|
||||||
|
for (BirdEnemy birdEnemy : birdEnemies){
|
||||||
|
Log.d(TAG, "GameView.update(): enemyY=" + enemyY + ", birdEnemy.y=" + birdEnemy.y);
|
||||||
|
if (birdEnemy.getRect().intersect(new Rect(birdEnemy.x, enemyY, birdEnemy.x + birdWidth, enemyY + birdHeight))){
|
||||||
|
numBirdEnemiesInRow++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.d(TAG, "GameView.update(): birdLevel=" + birdLevel);
|
||||||
|
Log.d(TAG, "GameView.update(): numBirdEnemiesInRow=" + numBirdEnemiesInRow);
|
||||||
|
|
||||||
|
// Just for a little chaos, 1/100 chance for extra enemies
|
||||||
|
boolean addExtraEnemies = ((int) (Math.random() * 100)) == 69;
|
||||||
|
|
||||||
|
// <= so that the game can start
|
||||||
|
if (numBirdEnemiesInRow <= birdLevel || addExtraEnemies){
|
||||||
|
Log.d(TAG, "GameView.update(): Adding birdEnemy!");
|
||||||
|
birdEnemies.add(new BirdEnemy(birdEnemyBitmap, birdWidth, birdHeight, birdFrames, enemyX, enemyY, enemySpeed, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bird.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
|
||||||
|
if (canvas != null) {
|
||||||
|
super.draw(canvas);
|
||||||
|
|
||||||
|
final float scaleX = (float) getWidth()/WIDTH;
|
||||||
|
final float scaleY = (float) getHeight()/HEIGHT;
|
||||||
|
|
||||||
|
Log.d(TAG, "GameView.draw(): Canvas not null, scaling! scaleX=" + scaleX + ", scaleY=" + scaleY);
|
||||||
|
Log.d(TAG, "GameView.draw(): Canvas not null, scaling! getScaleX()=" + getScaleX() + ", getScaleY()=" + getScaleY());
|
||||||
|
|
||||||
|
final int savedState = canvas.save();
|
||||||
|
canvas.scale(scaleX, scaleY);
|
||||||
|
|
||||||
|
// Draw all the game's objects
|
||||||
|
if (higherQualityEnabled) {
|
||||||
|
clouds.draw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
background.draw(canvas);
|
||||||
|
|
||||||
|
for (ExtraLife birdExtraLife : birdExtraLives) {
|
||||||
|
birdExtraLife.draw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (BirdEnemy birdEnemy : birdEnemies) {
|
||||||
|
birdEnemy.draw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
displayScore(canvas);
|
||||||
|
|
||||||
|
bird.draw(canvas);
|
||||||
|
|
||||||
|
// Prevent canvas from infinite scaling
|
||||||
|
canvas.restoreToCount(savedState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
103
app/src/main/java/com/hyperling/apps/games/Chicken.java
Executable file
@ -0,0 +1,103 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/23/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Chicken extends Player {
|
||||||
|
|
||||||
|
private boolean jumping, flapping;
|
||||||
|
private int lastY, lastDY;
|
||||||
|
private int leftFootX, rightFootX;
|
||||||
|
|
||||||
|
public Chicken(Bitmap b, int w, int h, int numFrames){
|
||||||
|
super(b, w, h, numFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isJumping() {
|
||||||
|
return jumping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJumping(boolean jumping) {
|
||||||
|
this.jumping = jumping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFlapping() {
|
||||||
|
return flapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlapping(boolean flapping) {
|
||||||
|
this.flapping = flapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jump(){
|
||||||
|
// If we are already jumping then we should flap instead
|
||||||
|
if (jumping){
|
||||||
|
flap();
|
||||||
|
}
|
||||||
|
// Jumps are more powerful than flaps
|
||||||
|
else{
|
||||||
|
jumping = true;
|
||||||
|
dy -= 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flap(){
|
||||||
|
// Only allow a flap after we start falling
|
||||||
|
if (!flapping){
|
||||||
|
flapping = true;
|
||||||
|
dy -= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(int platformY) {
|
||||||
|
// If we are in the same Y position and are not flapping, we are on solid ground.
|
||||||
|
if (lastY == y && !flapping){
|
||||||
|
jumping = false;
|
||||||
|
}
|
||||||
|
// Allow flapping once the last flap wears off.
|
||||||
|
if (dy > 0){
|
||||||
|
flapping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply gravity
|
||||||
|
dy += 1;
|
||||||
|
|
||||||
|
// Do not allow super flapping
|
||||||
|
if (dy < -5){
|
||||||
|
dy = -5;
|
||||||
|
}
|
||||||
|
// Fall slower if we have jumped
|
||||||
|
else if (dy > 5 && jumping){
|
||||||
|
dy = 5;
|
||||||
|
}
|
||||||
|
// Otherwise cap gravity
|
||||||
|
else if (dy > 15 && !jumping){
|
||||||
|
dy = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not fall through platforms
|
||||||
|
if (y + dy > platformY - getHeight()){
|
||||||
|
setY(platformY - getHeight());
|
||||||
|
setDy(0);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
y += dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not leave top of map
|
||||||
|
if (y < 0){
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember where we used to be
|
||||||
|
lastY = y;
|
||||||
|
lastDY = dy;
|
||||||
|
|
||||||
|
super.update();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
320
app/src/main/java/com/hyperling/apps/games/ChickenGameView.java
Executable file
@ -0,0 +1,320 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/28/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ChickenGameView extends GameView {
|
||||||
|
|
||||||
|
private Chicken chicken;
|
||||||
|
private Bitmap chickenBitmap;
|
||||||
|
private final int chickenWidth = 20;
|
||||||
|
private final int chickenHeight = 20;
|
||||||
|
private final int chickenFrames = 2;
|
||||||
|
|
||||||
|
private final int lavaHeight = 30;
|
||||||
|
|
||||||
|
private ArrayList<Platform> platforms;
|
||||||
|
private Bitmap platformBitmap;
|
||||||
|
private final int platformWidth = 32;
|
||||||
|
private final int platformHeight = 400;
|
||||||
|
private final int platformDefaultY = HEIGHT - lavaHeight;
|
||||||
|
|
||||||
|
private Bitmap backgroundBitmap, lavaBitmap, cloudsBitmap;
|
||||||
|
|
||||||
|
private int chickenGameSpeed = -4;
|
||||||
|
private int cloudsSpeed = chickenGameSpeed / 2;
|
||||||
|
private int lavaSpeed = chickenGameSpeed - 1;
|
||||||
|
|
||||||
|
private ArrayList<Enemy> enemies;
|
||||||
|
private Bitmap enemyBitmap;
|
||||||
|
private final int enemyWidth = 32;
|
||||||
|
private final int enemyHeight = 32;
|
||||||
|
private final int enemyFrames = 1;
|
||||||
|
private final int enemySpeed = chickenGameSpeed * 2;
|
||||||
|
|
||||||
|
private String chickenScoreKey;
|
||||||
|
|
||||||
|
private int maxGapSize = 200;
|
||||||
|
|
||||||
|
public ChickenGameView(Context context) {
|
||||||
|
super(context);
|
||||||
|
|
||||||
|
// Keys
|
||||||
|
chickenScoreKey = resources.getString(R.string.chickenScoreKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
|
setGameSpeed(chickenGameSpeed);
|
||||||
|
|
||||||
|
// Create global Bitmaps
|
||||||
|
if (higherQualityEnabled) {
|
||||||
|
backgroundBitmap = BitmapFactory.decodeResource(resources, R.drawable.background_forest_without_clouds);
|
||||||
|
lavaBitmap = BitmapFactory.decodeResource(resources, R.drawable.lava);
|
||||||
|
cloudsBitmap = BitmapFactory.decodeResource(resources, R.drawable.clouds);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
backgroundBitmap = BitmapFactory.decodeResource(resources, R.drawable.background_forest_with_lava);
|
||||||
|
}
|
||||||
|
chickenBitmap = BitmapFactory.decodeResource(resources, R.drawable.chicken);
|
||||||
|
platformBitmap = BitmapFactory.decodeResource(resources, R.drawable.normal_platform);
|
||||||
|
enemyBitmap = BitmapFactory.decodeResource(resources, R.drawable.enemy);
|
||||||
|
|
||||||
|
// Initialize Background(s)
|
||||||
|
background = new GameBackground(backgroundBitmap);
|
||||||
|
if (higherQualityEnabled) {
|
||||||
|
clouds = new GameBackground(cloudsBitmap);
|
||||||
|
lava = new GameBackground(lavaBitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
resetPlatforms();
|
||||||
|
|
||||||
|
enemies = new ArrayList<>();
|
||||||
|
|
||||||
|
chicken = new Chicken(chickenBitmap, chickenWidth, chickenHeight, chickenFrames);
|
||||||
|
|
||||||
|
super.surfaceCreated(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseGame() {
|
||||||
|
super.pauseGame(chickenScoreKey, chicken.getScore());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
|
if (!chicken.isPlaying()) {
|
||||||
|
chicken.setPlaying(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Accelerate when moving higher in the air
|
||||||
|
/*
|
||||||
|
if (chicken.isJumping()) {
|
||||||
|
boost(2, 250);
|
||||||
|
}
|
||||||
|
// Boost harder on the a jump than a flap
|
||||||
|
else{
|
||||||
|
boost(2, 500);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
chicken.jump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetPlatforms(){
|
||||||
|
platforms = new ArrayList<>();
|
||||||
|
|
||||||
|
// Create initial platform layer
|
||||||
|
int platformEndX = 0;
|
||||||
|
while (platformEndX < WIDTH){
|
||||||
|
Platform platform = new Platform(platformBitmap, platformWidth, platformHeight, platformEndX, platformDefaultY);
|
||||||
|
platformEndX = platform.x + platform.width;
|
||||||
|
|
||||||
|
platforms.add(platform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayScore(Canvas canvas){
|
||||||
|
int highScore = sharedPreferences.getInt(chickenScoreKey, 0);
|
||||||
|
textPaint.setColor(Color.parseColor("#330066"));
|
||||||
|
canvas.drawText("High: " + highScore, 0, textPaint.getTextSize(), textPaint);
|
||||||
|
canvas.drawText("Current: " + chicken.getScore(), 0, textPaint.getTextSize() * 2, textPaint);
|
||||||
|
|
||||||
|
if (fpsEnabled){
|
||||||
|
canvas.drawText("FPS: " + thread.averageFPS, 0, HEIGHT - 1, textPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chicken.isPlaying()) {
|
||||||
|
textPaint.setColor(Color.parseColor("#330066"));
|
||||||
|
canvas.drawText("You are the Purple and White Chicken", WIDTH / 4, HEIGHT / 4 - textPaint.getTextSize(), textPaint);
|
||||||
|
|
||||||
|
textPaint.setColor(Color.parseColor("#FF9900"));
|
||||||
|
canvas.drawText("Tap the Screen to Start", WIDTH / 4, HEIGHT / 4, textPaint);
|
||||||
|
canvas.drawText("Tap the Screen to Jump and Flap", WIDTH / 4, HEIGHT / 4 + textPaint.getTextSize(), textPaint);
|
||||||
|
|
||||||
|
textPaint.setColor(Color.parseColor("#FF0000"));
|
||||||
|
canvas.drawText("Don't fall into the lava!", WIDTH / 4, HEIGHT * 3 / 4, textPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endGame(){
|
||||||
|
// Stop the game, save, then reset the game
|
||||||
|
chicken.setPlaying(false);
|
||||||
|
saveScore(chickenScoreKey, chicken.getScore());
|
||||||
|
|
||||||
|
resetPlatforms();
|
||||||
|
enemies = new ArrayList<>();
|
||||||
|
chicken = new Chicken(chickenBitmap, chickenWidth, chickenHeight, chickenFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
super.update();
|
||||||
|
|
||||||
|
if (chicken.isPlaying()) {
|
||||||
|
background.update(gameSpeed);
|
||||||
|
if (higherQualityEnabled) {
|
||||||
|
clouds.update(cloudsSpeed);
|
||||||
|
lava.update(lavaSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove old platforms
|
||||||
|
for (int i = 0; i < platforms.size(); i++) {
|
||||||
|
Platform platform = platforms.get(i);
|
||||||
|
|
||||||
|
platform.update(gameSpeed);
|
||||||
|
|
||||||
|
if (platform.x + platform.width < 0) {
|
||||||
|
platforms.remove(platform);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add new platform(s) if the last platform is already being displayed
|
||||||
|
// Check where the last platform left off
|
||||||
|
boolean createPlatforms = true;
|
||||||
|
int lastPlatformEndX = 0;
|
||||||
|
for (Platform platform : platforms) {
|
||||||
|
if (platform.x > WIDTH) {
|
||||||
|
createPlatforms = false;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
lastPlatformEndX = platform.x + platform.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (createPlatforms && !thread.markerFrame) {
|
||||||
|
// Get X
|
||||||
|
int newPlatformX;
|
||||||
|
// Chance of a gap
|
||||||
|
boolean createGap = ((int) (Math.random() * 100) > 69);
|
||||||
|
if (createGap) {
|
||||||
|
newPlatformX = lastPlatformEndX + (int) (Math.random() * maxGapSize);
|
||||||
|
} else {
|
||||||
|
newPlatformX = lastPlatformEndX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Y
|
||||||
|
int newPlatformY = platformDefaultY - ((int) (platformHeight * Math.random())) / (chickenHeight * 2);
|
||||||
|
|
||||||
|
// Add the platform
|
||||||
|
platforms.add(new Platform(platformBitmap, platformWidth, platformHeight, newPlatformX, newPlatformY));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we fell in a hole
|
||||||
|
if (chicken.y > HEIGHT) {
|
||||||
|
endGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh enemies array
|
||||||
|
boolean enemyOnTop = false;
|
||||||
|
for (int i = 0; i < enemies.size() && i >= 0; i++) {
|
||||||
|
Enemy enemy = enemies.get(i);
|
||||||
|
|
||||||
|
Log.d(TAG, "ChickenGameView.update(): enemy.getBottomY()=" + enemy.getBottomY());
|
||||||
|
// Check if we hit an enemy
|
||||||
|
if (chicken.getRect().intersect(enemy.getRect())) {
|
||||||
|
endGame();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Check if enemy is off the screen
|
||||||
|
else if (enemy.getEndX() <= 0) {
|
||||||
|
enemies.remove(enemy);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
// Verify there is still an enemy on top
|
||||||
|
else {
|
||||||
|
if (enemy.y < chickenHeight) {
|
||||||
|
enemyOnTop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.d(TAG, "ChickenGameView.update(): enemyOnTop=" + enemyOnTop);
|
||||||
|
|
||||||
|
// Always prioritize an enemy on the top, else create normal enemies above all the platforms
|
||||||
|
if (!thread.markerFrame) {
|
||||||
|
if (!enemyOnTop) {
|
||||||
|
int enemyY = (int) (chickenHeight * Math.random());
|
||||||
|
enemies.add(new Enemy(enemyBitmap, enemyWidth, enemyHeight, enemyFrames, WIDTH, enemyY, enemySpeed, 1));
|
||||||
|
}
|
||||||
|
else if ((chicken.getScore() / 25) > enemies.size()) {
|
||||||
|
int newEnemyHeight = HEIGHT;
|
||||||
|
|
||||||
|
// Make sure the enemy is always above the platforms
|
||||||
|
for (Platform platform : platforms) {
|
||||||
|
if (platform.y < newEnemyHeight) {
|
||||||
|
newEnemyHeight = platform.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newEnemyHeight -= enemyHeight * 2;
|
||||||
|
newEnemyHeight = (int) (newEnemyHeight * Math.random());
|
||||||
|
enemies.add(new Enemy(enemyBitmap, enemyWidth, enemyHeight, enemyFrames, WIDTH, newEnemyHeight, enemySpeed, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Enemy enemy : enemies){
|
||||||
|
enemy.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
chicken.update(findPlatformY(chicken, platforms));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
|
||||||
|
if (canvas != null) {
|
||||||
|
super.draw(canvas);
|
||||||
|
final float scaleX = (float) getWidth() / WIDTH;
|
||||||
|
final float scaleY = (float) getHeight() / HEIGHT;
|
||||||
|
|
||||||
|
Log.d(TAG, "GameView.draw(): Canvas not null, scaling! scaleX=" + scaleX + ", scaleY=" + scaleY);
|
||||||
|
Log.d(TAG, "GameView.draw(): Canvas not null, scaling! getScaleX()=" + getScaleX() + ", getScaleY()=" + getScaleY());
|
||||||
|
|
||||||
|
final int savedState = canvas.save();
|
||||||
|
canvas.scale(scaleX, scaleY);
|
||||||
|
|
||||||
|
// Draw all the game's objects
|
||||||
|
if (higherQualityEnabled) {
|
||||||
|
clouds.draw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
background.draw(canvas);
|
||||||
|
|
||||||
|
if (higherQualityEnabled) {
|
||||||
|
lava.draw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Platform platform : platforms) {
|
||||||
|
platform.draw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Enemy enemy : enemies){
|
||||||
|
enemy.draw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
displayScore(canvas);
|
||||||
|
|
||||||
|
chicken.draw(canvas);
|
||||||
|
|
||||||
|
// Prevent canvas from infinite scaling
|
||||||
|
canvas.restoreToCount(savedState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
72
app/src/main/java/com/hyperling/apps/games/Enemy.java
Executable file
@ -0,0 +1,72 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/26/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Enemy extends GameObject {
|
||||||
|
|
||||||
|
protected Bitmap image;
|
||||||
|
|
||||||
|
private Animation animation;
|
||||||
|
|
||||||
|
private int speed, damage;
|
||||||
|
|
||||||
|
public Enemy(Bitmap b, int w, int h, int numFrames, int x, int y, int speed, int damage){
|
||||||
|
image = b;
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.speed = speed;
|
||||||
|
this.damage = damage;
|
||||||
|
|
||||||
|
if (speed > -1){
|
||||||
|
speed = -1;
|
||||||
|
}
|
||||||
|
if (this.y >= GameView.HEIGHT - this.height){
|
||||||
|
this.y = GameView.HEIGHT - this.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create animation
|
||||||
|
Bitmap[] image = new Bitmap[numFrames];
|
||||||
|
animation = new Animation();
|
||||||
|
|
||||||
|
for (int i = 0; i < numFrames; i++){
|
||||||
|
image[i] = Bitmap.createBitmap(b, width * i, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
animation.setFrames(image);
|
||||||
|
|
||||||
|
//animation.setDelay(100);
|
||||||
|
int delay = 25 * Math.abs(speed);
|
||||||
|
if (delay > 125){
|
||||||
|
delay = 125;
|
||||||
|
}
|
||||||
|
else if (delay < 75){
|
||||||
|
delay = 75;
|
||||||
|
}
|
||||||
|
animation.setDelay(delay);
|
||||||
|
animation.setCurrentFrame((int)(Math.random() * numFrames));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(){
|
||||||
|
animation.update();
|
||||||
|
|
||||||
|
// Move the object
|
||||||
|
x += speed;
|
||||||
|
super.updateEdgeLocations();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
// Draw the object
|
||||||
|
canvas.drawBitmap(animation.getImage(), getX(), getY(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDamage() {
|
||||||
|
return damage;
|
||||||
|
}
|
||||||
|
}
|
34
app/src/main/java/com/hyperling/apps/games/EnvironmentObject.java
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/23/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class EnvironmentObject extends GameObject {
|
||||||
|
|
||||||
|
protected Bitmap image;
|
||||||
|
|
||||||
|
public EnvironmentObject(Bitmap i, int w, int h, int x, int y){
|
||||||
|
image = i;
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(int gameSpeed){
|
||||||
|
// Move the object
|
||||||
|
x += gameSpeed;
|
||||||
|
|
||||||
|
setEndX(getX() + getWidth());
|
||||||
|
setCenterX((getX() + getEndX()) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
// Draw the object
|
||||||
|
canvas.drawBitmap(image, x, y, null);
|
||||||
|
}
|
||||||
|
}
|
25
app/src/main/java/com/hyperling/apps/games/ExtraLife.java
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/26/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ExtraLife extends EnvironmentObject {
|
||||||
|
|
||||||
|
private int numLives;
|
||||||
|
|
||||||
|
public ExtraLife(Bitmap b, int w, int h, int x, int y, int numLives){
|
||||||
|
super(b, w, h, x, y);
|
||||||
|
this.numLives = numLives;
|
||||||
|
|
||||||
|
if (this.y >= GameView.HEIGHT - this.height){
|
||||||
|
this.y = GameView.HEIGHT - this.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumLives() {
|
||||||
|
return numLives;
|
||||||
|
}
|
||||||
|
}
|
56
app/src/main/java/com/hyperling/apps/games/GameActivity.java
Executable file
@ -0,0 +1,56 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/17/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class GameActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
BirdGameView birdGameView;
|
||||||
|
ChickenGameView chickenGameView;
|
||||||
|
|
||||||
|
private String gameType, birdGame, cowGame, pigGame, chickenGame, catGame;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|
||||||
|
gameType = GameActivity.this.getIntent().getAction();
|
||||||
|
|
||||||
|
// Game types
|
||||||
|
birdGame = getString(R.string.btnGameBird);
|
||||||
|
cowGame = getString(R.string.btnGameCow);
|
||||||
|
pigGame = getString(R.string.btnGamePig);
|
||||||
|
chickenGame = getString(R.string.btnGameChicken);
|
||||||
|
catGame = getString(R.string.btnGameCat);
|
||||||
|
|
||||||
|
if (gameType.equals(birdGame)) {
|
||||||
|
birdGameView = new BirdGameView(GameActivity.this);
|
||||||
|
setContentView(birdGameView);
|
||||||
|
}
|
||||||
|
else if (gameType.equals(chickenGame)) {
|
||||||
|
chickenGameView = new ChickenGameView(GameActivity.this);
|
||||||
|
setContentView(chickenGameView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
|
||||||
|
if (gameType.equals(birdGame)) {
|
||||||
|
birdGameView.pauseGame();
|
||||||
|
}
|
||||||
|
else if (gameType.equals(chickenGame)) {
|
||||||
|
chickenGameView.pauseGame();
|
||||||
|
}
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
}
|
44
app/src/main/java/com/hyperling/apps/games/GameBackground.java
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/17/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class GameBackground {
|
||||||
|
|
||||||
|
private Bitmap image;
|
||||||
|
private int x, y;
|
||||||
|
|
||||||
|
public GameBackground(Bitmap i){
|
||||||
|
image = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(int gameSpeed){
|
||||||
|
// Move the background
|
||||||
|
x += gameSpeed;
|
||||||
|
|
||||||
|
// If the image is completely off the screen, put it back to the middle.
|
||||||
|
if (x <= -GameView.WIDTH || x >= GameView.WIDTH){
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Canvas canvas){
|
||||||
|
// Draw the current image
|
||||||
|
canvas.drawBitmap(image, x, y, null);
|
||||||
|
|
||||||
|
// Place two more to the right since we are to the left
|
||||||
|
if (x < 0){
|
||||||
|
canvas.drawBitmap(image, x + GameView.WIDTH, y, null);
|
||||||
|
//canvas.drawBitmap(image, x + (2 * GameView.WIDTH), y, null);
|
||||||
|
}
|
||||||
|
// Place two more to the left since we are to the right
|
||||||
|
else if (x > 0){
|
||||||
|
canvas.drawBitmap(image, x - GameView.WIDTH, y, null);
|
||||||
|
//canvas.drawBitmap(image, x - (2 * GameView.WIDTH), y, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
101
app/src/main/java/com/hyperling/apps/games/GameLoopThread.java
Executable file
@ -0,0 +1,101 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/17/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class GameLoopThread extends Thread {
|
||||||
|
private final int FPS = 30;
|
||||||
|
protected double averageFPS;
|
||||||
|
private SurfaceHolder surfaceHolder;
|
||||||
|
private GameView gameView;
|
||||||
|
private boolean running;
|
||||||
|
public static Canvas canvas;
|
||||||
|
|
||||||
|
public boolean markerFrame;
|
||||||
|
|
||||||
|
private String TAG;
|
||||||
|
|
||||||
|
public GameLoopThread(SurfaceHolder sh, GameView gv){
|
||||||
|
super();
|
||||||
|
surfaceHolder = sh;
|
||||||
|
gameView = gv;
|
||||||
|
|
||||||
|
TAG = gameView.getResources().getString(R.string.TAG);
|
||||||
|
|
||||||
|
markerFrame = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
super.run();
|
||||||
|
|
||||||
|
long timeStart, timeRun, timeWait, timeTotal, timeTarget;
|
||||||
|
timeTotal = 0;
|
||||||
|
timeTarget = 1000/FPS;
|
||||||
|
|
||||||
|
int frameCount = 0;
|
||||||
|
|
||||||
|
while(running){
|
||||||
|
timeStart = System.currentTimeMillis();
|
||||||
|
canvas = null;
|
||||||
|
|
||||||
|
try{
|
||||||
|
canvas = this.surfaceHolder.lockCanvas();
|
||||||
|
synchronized (surfaceHolder){
|
||||||
|
this.gameView.update();
|
||||||
|
this.gameView.draw(canvas);
|
||||||
|
}
|
||||||
|
} catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (canvas != null) {
|
||||||
|
try {
|
||||||
|
surfaceHolder.unlockCanvasAndPost(canvas);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timeRun = (System.currentTimeMillis() - timeStart);
|
||||||
|
timeWait = timeTarget - timeRun;
|
||||||
|
|
||||||
|
if (timeWait > 0) {
|
||||||
|
try {
|
||||||
|
this.sleep(timeWait);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timeTotal += System.currentTimeMillis()-timeStart;
|
||||||
|
frameCount++;
|
||||||
|
if (frameCount >= FPS){
|
||||||
|
averageFPS = 1000/((timeTotal/frameCount));
|
||||||
|
frameCount = 0;
|
||||||
|
timeTotal = 0;
|
||||||
|
|
||||||
|
Log.i(TAG, "GameLoopThread.run(): averageFPS=" + averageFPS);
|
||||||
|
Log.d(TAG, "GameLoopThread.run(): canvas.getHeight()=" + canvas.getHeight() + ", canvas.getWidth()=" + canvas.getWidth());
|
||||||
|
|
||||||
|
markerFrame = true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
markerFrame = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRunning(boolean r){
|
||||||
|
running = r;
|
||||||
|
|
||||||
|
if (running) {
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
116
app/src/main/java/com/hyperling/apps/games/GameObject.java
Executable file
@ -0,0 +1,116 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/22/16.
|
||||||
|
* https://youtu.be/kGqKNpk6VJw?list=PLWweaDaGRHjvQlpLV0yZDmRKVBdy6rSlg
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class GameObject {
|
||||||
|
protected int x;
|
||||||
|
protected int y;
|
||||||
|
protected int dx;
|
||||||
|
protected int dy;
|
||||||
|
protected int width;
|
||||||
|
protected int height;
|
||||||
|
|
||||||
|
protected int centerX;
|
||||||
|
protected int endX;
|
||||||
|
|
||||||
|
protected int centerY;
|
||||||
|
protected int bottomY;
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(int x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(int y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDx() {
|
||||||
|
return dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDx(int dx) {
|
||||||
|
this.dx = dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDy() {
|
||||||
|
return dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDy(int dy) {
|
||||||
|
this.dy = dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWidth(int width) {
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeight(int height) {
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCenterX() {
|
||||||
|
return centerX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCenterX(int centerX) {
|
||||||
|
this.centerX = centerX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEndX() {
|
||||||
|
return endX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndX(int endX) {
|
||||||
|
this.endX = endX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCenterY() {
|
||||||
|
return centerY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCenterY(int centerY) {
|
||||||
|
this.centerY = centerY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBottomY() {
|
||||||
|
return bottomY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBottomY(int bottomY) {
|
||||||
|
this.bottomY = bottomY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateEdgeLocations(){
|
||||||
|
endX = x + width;
|
||||||
|
bottomY = y + height;
|
||||||
|
|
||||||
|
centerX = (x + endX) / 2;
|
||||||
|
centerY = (y + bottomY) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rect getRect(){
|
||||||
|
return new Rect(x, y, x + width, y + height);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
203
app/src/main/java/com/hyperling/apps/games/GameView.java
Executable file
@ -0,0 +1,203 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.text.TextPaint;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/17/16.
|
||||||
|
* https://youtu.be/-XOMJYZmfkw?list=PLWweaDaGRHjvQlpLV0yZDmRKVBdy6rSlg
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class GameView extends SurfaceView implements SurfaceHolder.Callback{
|
||||||
|
|
||||||
|
public static final int WIDTH = 640;
|
||||||
|
public static final int HEIGHT = 400;
|
||||||
|
|
||||||
|
protected Resources resources;
|
||||||
|
protected final String sharedPreferencesKey, higherQualityKey, fpsKey;
|
||||||
|
|
||||||
|
protected static String TAG;
|
||||||
|
|
||||||
|
protected SharedPreferences sharedPreferences;
|
||||||
|
protected boolean higherQualityEnabled, fpsEnabled;
|
||||||
|
|
||||||
|
protected int gameSpeed = -5;
|
||||||
|
protected int boostQty;
|
||||||
|
protected long boostEnd;
|
||||||
|
protected boolean boosting;
|
||||||
|
|
||||||
|
protected GameLoopThread thread;
|
||||||
|
protected GameBackground background, clouds, lava;
|
||||||
|
|
||||||
|
protected TextPaint textPaint;
|
||||||
|
|
||||||
|
public GameView(Context context){
|
||||||
|
super(context);
|
||||||
|
|
||||||
|
// For filling strings and getting Bitmaps
|
||||||
|
resources = getResources();
|
||||||
|
|
||||||
|
// Keys
|
||||||
|
sharedPreferencesKey = resources.getString(R.string.sharedPreferencesKey);
|
||||||
|
higherQualityKey = resources.getString(R.string.higherQualityKey);
|
||||||
|
fpsKey = resources.getString(R.string.fpsKey);
|
||||||
|
|
||||||
|
// Initialize shared preferences
|
||||||
|
sharedPreferences = context.getSharedPreferences(sharedPreferencesKey, Context.MODE_PRIVATE);
|
||||||
|
higherQualityEnabled = sharedPreferences.getBoolean(higherQualityKey, false);
|
||||||
|
fpsEnabled = sharedPreferences.getBoolean(fpsKey, false);
|
||||||
|
|
||||||
|
// For output
|
||||||
|
TAG = resources.getString(R.string.TAG);
|
||||||
|
|
||||||
|
// Add the callback to SurfaceHolder (This allows control of events)
|
||||||
|
getHolder().addCallback(this);
|
||||||
|
|
||||||
|
// Initialize engine
|
||||||
|
thread = new GameLoopThread(getHolder(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String getTAG() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void boost(int boostMultiplier, long boostDuration){
|
||||||
|
if (!boosting){
|
||||||
|
boosting = true;
|
||||||
|
boostQty = boostMultiplier;
|
||||||
|
boostEnd = System.currentTimeMillis() + boostDuration;
|
||||||
|
|
||||||
|
gameSpeed *= boostQty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setGameSpeed(int newSpeed){
|
||||||
|
gameSpeed = newSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int findPlatformY(Player player, ArrayList<Platform> platforms){
|
||||||
|
|
||||||
|
// Get the tallest (smallest) platform.y where platform.y < player.y
|
||||||
|
int platformHighestY = HEIGHT*2;
|
||||||
|
for (Platform platform : platforms){
|
||||||
|
|
||||||
|
if (player.endX > platform.x &&
|
||||||
|
player.x < platform.endX &&
|
||||||
|
player.centerY <= platform.y &&
|
||||||
|
platform.y < platformHighestY){
|
||||||
|
Log.d(TAG, "GameView.findPlatformY():" +
|
||||||
|
" player.x=" + player.x +
|
||||||
|
", player.endX=" + player.endX +
|
||||||
|
", player.centerY=" + player.centerY +
|
||||||
|
", platform.x=" + platform.x +
|
||||||
|
", platform.endX=" + platform.endX +
|
||||||
|
", platform.y=" + platform.y +
|
||||||
|
", platformHighestY=" + platformHighestY);
|
||||||
|
|
||||||
|
platformHighestY = platform.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "GameView.findPlatformY(): player.y=" + player.y + ", platformHighestY=" + platformHighestY);
|
||||||
|
return platformHighestY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
|
// Safe to start the thread
|
||||||
|
textPaint = new TextPaint();
|
||||||
|
textPaint.setTextSize(textPaint.getTextSize() * 2);
|
||||||
|
|
||||||
|
thread.setRunning(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
|
// Try to stop the thread
|
||||||
|
boolean retry = true;
|
||||||
|
int retryCount = 0;
|
||||||
|
while(retry && retryCount < 1000){
|
||||||
|
try{
|
||||||
|
thread.setRunning(false);
|
||||||
|
thread.join();
|
||||||
|
thread = null;
|
||||||
|
retry = false;
|
||||||
|
} catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
retryCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
return super.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void pauseGame(String scoreKey, int score){
|
||||||
|
// Save and force a commit
|
||||||
|
saveScore(scoreKey, score);
|
||||||
|
sharedPreferences.edit().commit();
|
||||||
|
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void saveScore(String scoreKey, int score){
|
||||||
|
// Check if score is better than high score
|
||||||
|
int oldScore = sharedPreferences.getInt(scoreKey, 0);
|
||||||
|
Log.d(TAG, "GameView.saveScore(): score=" + score + ", oldScore=" + oldScore);
|
||||||
|
|
||||||
|
if (score > oldScore) {
|
||||||
|
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||||
|
editor.putInt(scoreKey, score);
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
int highScore = sharedPreferences.getInt(scoreKey, 0);
|
||||||
|
Log.d(TAG, "GameView.saveScore(): Saved, new highScore=" + highScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void update(){
|
||||||
|
// Check if the boost is over and end it
|
||||||
|
if (boosting && System.currentTimeMillis() > boostEnd){
|
||||||
|
boosting = false;
|
||||||
|
gameSpeed /= boostQty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
|
||||||
|
if (canvas != null) {
|
||||||
|
super.draw(canvas);
|
||||||
|
/*
|
||||||
|
final float scaleX = (float) getWidth()/WIDTH;
|
||||||
|
final float scaleY = (float) getHeight()/HEIGHT;
|
||||||
|
Log.d(TAG, "GameView.draw(): Canvas not null, scaling! scaleX=" + scaleX + ", scaleY=" + scaleY);
|
||||||
|
Log.d(TAG, "GameView.draw(): Canvas not null, scaling! getScaleX()=" + getScaleX() + ", getScaleY()=" + getScaleY());
|
||||||
|
final int savedState = canvas.save();
|
||||||
|
canvas.scale(scaleX, scaleY);
|
||||||
|
|
||||||
|
// Draw all the game's objects
|
||||||
|
background.draw(canvas);
|
||||||
|
|
||||||
|
// Prevent canvas from infinite scaling
|
||||||
|
canvas.restoreToCount(savedState);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
127
app/src/main/java/com/hyperling/apps/games/HighScoreActivity.java
Executable file
@ -0,0 +1,127 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.google.android.gms.ads.AdView;
|
||||||
|
|
||||||
|
public class HighScoreActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private String sharedPreferencesKey, adsKey, TAG, html;
|
||||||
|
private String[] allBirdScoreKeys, allChickenScoreKeys;
|
||||||
|
|
||||||
|
private SharedPreferences sharedPreferences;
|
||||||
|
|
||||||
|
LeaderboardHelper leaderboardHelper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_high_score);
|
||||||
|
|
||||||
|
TAG = getString(R.string.TAG);
|
||||||
|
|
||||||
|
// Get keys
|
||||||
|
sharedPreferencesKey = getString(R.string.sharedPreferencesKey);
|
||||||
|
allBirdScoreKeys = getResources().getStringArray(R.array.allBirdScoreKeys);
|
||||||
|
allChickenScoreKeys = getResources().getStringArray(R.array.allChickenScoreKeys);
|
||||||
|
adsKey = getString(R.string.adsKey);
|
||||||
|
|
||||||
|
// Shared preferences
|
||||||
|
sharedPreferences = getSharedPreferences(sharedPreferencesKey, MODE_PRIVATE);
|
||||||
|
|
||||||
|
// Bird stuff
|
||||||
|
LinearLayout birdScoreLayout = (LinearLayout) findViewById(R.id.birdScoreLayout);
|
||||||
|
loadScoreLayout(birdScoreLayout, allBirdScoreKeys);
|
||||||
|
|
||||||
|
// Chicken stuff
|
||||||
|
LinearLayout chickenScoreLayout = (LinearLayout) findViewById(R.id.chickenScoreLayout);
|
||||||
|
loadScoreLayout(chickenScoreLayout, allChickenScoreKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadScoreLayout(LinearLayout layout, String[] scoreKeys){
|
||||||
|
|
||||||
|
for (String key : scoreKeys){
|
||||||
|
int score = sharedPreferences.getInt(key, 0);
|
||||||
|
if (score > 0){
|
||||||
|
String label = key;
|
||||||
|
// Add spaces to string before uppercase and numbers
|
||||||
|
label = label.replaceAll(" ", "");
|
||||||
|
//label = label.replaceAll("0", "");
|
||||||
|
for (int i = 1; i < label.length(); i++){
|
||||||
|
if (label.charAt(i) == label.toUpperCase().charAt(i) || isNumeric(label.charAt(i))){
|
||||||
|
label = label.substring(0, i) + " " + label.substring(i);
|
||||||
|
i++;
|
||||||
|
if (isNumeric(label.charAt(i))){
|
||||||
|
label = label.substring(0, i) + "- Version " + label.substring(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label = label.concat(": ");
|
||||||
|
String scoreString = "" + score;
|
||||||
|
|
||||||
|
// Create UI Objects
|
||||||
|
LinearLayout linearLayout = new LinearLayout(this);
|
||||||
|
TextView tvLabel = new TextView(this);
|
||||||
|
TextView tvScore = new TextView(this);
|
||||||
|
|
||||||
|
// Set their text
|
||||||
|
tvLabel.setText(label);
|
||||||
|
tvScore.setText(scoreString);
|
||||||
|
|
||||||
|
// Finish the layout
|
||||||
|
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||||
|
linearLayout.addView(tvLabel);
|
||||||
|
linearLayout.addView(tvScore);
|
||||||
|
|
||||||
|
// Add score to layout
|
||||||
|
layout.addView(linearLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
leaderboardHelper = new LeaderboardHelper();
|
||||||
|
displayAds();
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
Runnable getHTML = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
html = leaderboardHelper.getTable("BirdScore009");
|
||||||
|
Log.d(TAG, "HighScoreActivity.onResume(): html=" + html);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Thread t = new Thread(getHTML);
|
||||||
|
t.start();
|
||||||
|
|
||||||
|
Log.d(TAG, "HighScoreActivity.onResume() html=" + html);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayAds(){
|
||||||
|
AdsHelper.toggleAds(sharedPreferences, adsKey, getApplicationContext(), (AdView) findViewById(R.id.adViewHighScores));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNumeric(char c){
|
||||||
|
try{
|
||||||
|
String s = "" + c;
|
||||||
|
int i = Integer.parseInt(s);
|
||||||
|
if (i >= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
//e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
69
app/src/main/java/com/hyperling/apps/games/LeaderboardHelper.java
Executable file
@ -0,0 +1,69 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 1/3/17.
|
||||||
|
* Get Unique Device ID: http://stackoverflow.com/questions/16869482/how-to-get-unique-device-hardware-id-in-android#16869491
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class LeaderboardHelper {
|
||||||
|
|
||||||
|
private final String baseURL = "https://hyperling.com:1337/hyper_games/";
|
||||||
|
private String getVariables = "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void addVariable(String key, String value){
|
||||||
|
if (getVariables.length() == 0) {
|
||||||
|
getVariables += "?";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
getVariables += "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
getVariables += key + "=" + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearVariables(){
|
||||||
|
getVariables = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTable(String id){
|
||||||
|
String newURL = baseURL + "?leaderboard_id=" + id;
|
||||||
|
String html = "";
|
||||||
|
|
||||||
|
URL url;
|
||||||
|
InputStream is = null;
|
||||||
|
BufferedReader br;
|
||||||
|
String line;
|
||||||
|
|
||||||
|
try {
|
||||||
|
url = new URL(newURL);
|
||||||
|
is = url.openStream(); // throws an IOException
|
||||||
|
br = new BufferedReader(new InputStreamReader(is));
|
||||||
|
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
html = html.concat(line);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (is != null) is.close();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// nothing to see here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
171
app/src/main/java/com/hyperling/apps/games/MainActivity.java
Executable file
@ -0,0 +1,171 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
|
import com.google.android.gms.ads.AdView;
|
||||||
|
|
||||||
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private Button btnGameBird, btnGameCow, btnGamePig, btnGameChicken, btnGameCat, btnGameSquirrel, btnOptions, btnHighScores, btnHelp;
|
||||||
|
|
||||||
|
private String TAG, sharedPreferencesKey, adsKey, birdScoreKey, chickenScoreKey;
|
||||||
|
|
||||||
|
private SharedPreferences sharedPreferences;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
TAG = getString(R.string.TAG);
|
||||||
|
|
||||||
|
// Keys
|
||||||
|
sharedPreferencesKey = getString(R.string.sharedPreferencesKey);
|
||||||
|
adsKey = getString(R.string.adsKey);
|
||||||
|
birdScoreKey = getString(R.string.birdScoreKey);
|
||||||
|
chickenScoreKey = getString(R.string.chickenScoreKey);
|
||||||
|
|
||||||
|
// Shared Preferences
|
||||||
|
sharedPreferences = getSharedPreferences(sharedPreferencesKey, MODE_PRIVATE);
|
||||||
|
|
||||||
|
// Initialize buttons
|
||||||
|
btnGameBird = (Button) findViewById(R.id.btnBirdGame);
|
||||||
|
btnGameCow = (Button) findViewById(R.id.btnGameCow);
|
||||||
|
btnGamePig = (Button) findViewById(R.id.btnGamePig);
|
||||||
|
btnGameChicken = (Button) findViewById(R.id.btnGameChicken);
|
||||||
|
btnGameCat = (Button) findViewById(R.id.btnGameCat);
|
||||||
|
btnGameSquirrel = (Button) findViewById(R.id.btnGameSquirrel);
|
||||||
|
btnOptions = (Button) findViewById(R.id.btnOptions);
|
||||||
|
btnHighScores = (Button) findViewById(R.id.btnHighScores);
|
||||||
|
btnHelp = (Button) findViewById(R.id.btnHelp);
|
||||||
|
|
||||||
|
// Set up game buttons
|
||||||
|
btnGameBird.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
doGameButton((Button) v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnGameCow.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
doGameButton((Button) v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnGamePig.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
doGameButton((Button) v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnGameChicken.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
doGameButton((Button) v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnGameCat.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
doGameButton((Button) v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnGameSquirrel.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
doGameButton((Button) v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set up other buttons
|
||||||
|
btnOptions.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
doOptionsButton();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnHighScores.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
doHighScoresButton();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
displayAds();
|
||||||
|
|
||||||
|
// Append high scores to button text
|
||||||
|
int score;
|
||||||
|
String newText;
|
||||||
|
|
||||||
|
score = sharedPreferences.getInt(birdScoreKey, 0);
|
||||||
|
Log.d(TAG, "MainActivity.onResume(): birdScore=" + score);
|
||||||
|
if (score > 0) {
|
||||||
|
newText = getString(R.string.btnGameBird) + '\n' + getString(R.string.btnHighScoreSubHeader).concat(" ") + score;
|
||||||
|
Log.d(TAG, "MainActivity.onResume(): newText=" + newText);
|
||||||
|
btnGameBird.setText(newText);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
btnGameBird.setText(getString(R.string.btnGameBird));
|
||||||
|
}
|
||||||
|
|
||||||
|
score = sharedPreferences.getInt(chickenScoreKey, 0);
|
||||||
|
if (score > 0) {
|
||||||
|
newText = getString(R.string.btnGameChicken) + '\n' + getString(R.string.btnHighScoreSubHeader).concat(" ") + score;
|
||||||
|
Log.d(TAG, "MainActivity.onResume(): newText=" + newText);
|
||||||
|
btnGameChicken.setText(newText);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
btnGameChicken.setText(getString(R.string.btnGameChicken));
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the game
|
||||||
|
private void doGameButton(Button b){
|
||||||
|
Log.i(TAG, "MainActivity.doCowGameButton()");
|
||||||
|
|
||||||
|
// Only get the game name, not the high score
|
||||||
|
String gameType, buttonText;
|
||||||
|
buttonText = b.getText().toString();
|
||||||
|
int newLine = buttonText.indexOf('\n');
|
||||||
|
if (newLine > 0) {
|
||||||
|
gameType = buttonText.substring(0, buttonText.indexOf('\n'));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
gameType = buttonText;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the GameActivity
|
||||||
|
Intent game = new Intent(MainActivity.this, GameActivity.class);
|
||||||
|
game.setAction(gameType);
|
||||||
|
startActivity(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to OptionsActivity
|
||||||
|
private void doOptionsButton(){
|
||||||
|
Log.i(TAG, "MainActivity.doOptionsButton()");
|
||||||
|
|
||||||
|
Intent options = new Intent(MainActivity.this, OptionsActivity.class);
|
||||||
|
startActivity(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayAds(){
|
||||||
|
AdsHelper.toggleAds(sharedPreferences, adsKey, getApplicationContext(), (AdView) findViewById(R.id.adViewMain));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doHighScoresButton(){
|
||||||
|
Intent highScores = new Intent(MainActivity.this, HighScoreActivity.class);
|
||||||
|
startActivity(highScores);
|
||||||
|
}
|
||||||
|
}
|
187
app/src/main/java/com/hyperling/apps/games/OptionsActivity.java
Executable file
@ -0,0 +1,187 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
|
import com.google.android.gms.ads.AdRequest;
|
||||||
|
import com.google.android.gms.ads.AdView;
|
||||||
|
import com.google.android.gms.ads.MobileAds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/22/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class OptionsActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private String sharedPreferencesKey, adsKey, higherQualityKey, fpsKey;
|
||||||
|
|
||||||
|
private SharedPreferences sharedPreferences;
|
||||||
|
|
||||||
|
private RelativeLayout layoutAds, layoutHigherQuality, layoutFPS;
|
||||||
|
private CheckBox cbAds, cbHigherQuality, cbFPS;
|
||||||
|
private boolean adsEnabled, higherQualityEnabled, fpsEnabled;
|
||||||
|
|
||||||
|
private Button btnDeletePreferences, btnConfirmDeletePreferences;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_options);
|
||||||
|
|
||||||
|
// Prevent the keyboard from popping up automatically
|
||||||
|
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
||||||
|
|
||||||
|
// Get SharedPreferences
|
||||||
|
sharedPreferencesKey = getString(R.string.sharedPreferencesKey);
|
||||||
|
sharedPreferences = getSharedPreferences(sharedPreferencesKey, MODE_PRIVATE);
|
||||||
|
|
||||||
|
// Set up Ads
|
||||||
|
adsKey = getString(R.string.adsKey);
|
||||||
|
layoutAds = (RelativeLayout) findViewById(R.id.optionAdsLayout);
|
||||||
|
cbAds = (CheckBox) findViewById(R.id.optionAdsCheckBox);
|
||||||
|
layoutAds.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
flipOption(adsKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cbAds.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
flipOption(adsKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setAds();
|
||||||
|
|
||||||
|
// Higher Quality Content
|
||||||
|
higherQualityKey = getString(R.string.higherQualityKey);
|
||||||
|
layoutHigherQuality = (RelativeLayout) findViewById(R.id.optionHigherQualityLayout);
|
||||||
|
cbHigherQuality = (CheckBox) findViewById(R.id.optionHigherQualityCheckBox);
|
||||||
|
layoutHigherQuality.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
flipOption(higherQualityKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cbHigherQuality.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
flipOption(higherQualityKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setHigherQuality();
|
||||||
|
|
||||||
|
// In-Game FPS
|
||||||
|
fpsKey = getString(R.string.fpsKey);
|
||||||
|
layoutFPS = (RelativeLayout) findViewById(R.id.optionFPSLayout);
|
||||||
|
cbFPS = (CheckBox) findViewById(R.id.fpsCheckBox);
|
||||||
|
layoutFPS.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
flipOption(fpsKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cbFPS.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
flipOption(fpsKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setFPS();
|
||||||
|
|
||||||
|
// Reset buttons
|
||||||
|
btnDeletePreferences = (Button) findViewById(R.id.btnDeletePreferences);
|
||||||
|
btnConfirmDeletePreferences = (Button) findViewById(R.id.btnConfirmDeletePreferences);
|
||||||
|
|
||||||
|
btnDeletePreferences.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
showConfirmDeletePreferencesButton((Button) v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnConfirmDeletePreferences.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
deletePreferences();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flipOption(String key){
|
||||||
|
boolean option = sharedPreferences.getBoolean(key, false);
|
||||||
|
|
||||||
|
// Save the setting
|
||||||
|
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||||
|
editor.putBoolean(key, !option);
|
||||||
|
editor.apply();
|
||||||
|
|
||||||
|
// Change the box
|
||||||
|
if (key.equals(adsKey)){
|
||||||
|
setAds();
|
||||||
|
}
|
||||||
|
else if (key.equals(higherQualityKey)){
|
||||||
|
setHigherQuality();
|
||||||
|
}
|
||||||
|
else if (key.equals(fpsKey)){
|
||||||
|
setFPS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setAds(){
|
||||||
|
adsEnabled = sharedPreferences.getBoolean(adsKey, false);
|
||||||
|
cbAds.setChecked(adsEnabled);
|
||||||
|
toggleAds();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleAds(){
|
||||||
|
// Enable ads?
|
||||||
|
adsEnabled = sharedPreferences.getBoolean(adsKey, false);
|
||||||
|
AdView mAdView = (AdView) findViewById(R.id.adViewOptions);
|
||||||
|
if (adsEnabled) {
|
||||||
|
mAdView.setVisibility(View.VISIBLE);
|
||||||
|
MobileAds.initialize(getApplicationContext(), "ca-app-pub-3940256099942544~3347511713");
|
||||||
|
AdRequest adRequest = new AdRequest.Builder()
|
||||||
|
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
|
||||||
|
.addTestDevice("C6A494DC6E7C9AC29102694D48487084") // Nexus 7
|
||||||
|
.addTestDevice("6545BCC9B60A394005546783687339B7") // Moto G
|
||||||
|
.build();
|
||||||
|
mAdView.loadAd(adRequest);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
mAdView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHigherQuality() {
|
||||||
|
higherQualityEnabled = sharedPreferences.getBoolean(higherQualityKey, false);
|
||||||
|
cbHigherQuality.setChecked(higherQualityEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFPS() {
|
||||||
|
fpsEnabled = sharedPreferences.getBoolean(fpsKey, false);
|
||||||
|
cbFPS.setChecked(fpsEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showConfirmDeletePreferencesButton(Button callButton){
|
||||||
|
callButton.setEnabled(false);
|
||||||
|
btnConfirmDeletePreferences.setVisibility(View.VISIBLE);
|
||||||
|
btnConfirmDeletePreferences.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deletePreferences(){
|
||||||
|
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||||
|
editor.clear();
|
||||||
|
editor.apply();
|
||||||
|
|
||||||
|
Intent resetScreen = new Intent(OptionsActivity.this, OptionsActivity.class);
|
||||||
|
startActivity(resetScreen);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
19
app/src/main/java/com/hyperling/apps/games/Platform.java
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/23/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Platform extends EnvironmentObject {
|
||||||
|
|
||||||
|
public Platform(Bitmap b, int w, int h, int x, int y){
|
||||||
|
super(b, w, h, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(int gameSpeed) {
|
||||||
|
super.update(gameSpeed);
|
||||||
|
}
|
||||||
|
}
|
155
app/src/main/java/com/hyperling/apps/games/Player.java
Executable file
@ -0,0 +1,155 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ling on 12/22/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class Player extends GameObject {
|
||||||
|
|
||||||
|
private String TAG;
|
||||||
|
|
||||||
|
//private Bitmap spritesheet;
|
||||||
|
private int score;
|
||||||
|
|
||||||
|
//private boolean up, down, left, right, sprint;
|
||||||
|
private boolean playing;
|
||||||
|
private Animation animation;
|
||||||
|
private long startTime;
|
||||||
|
|
||||||
|
public Player(Bitmap b, int w, int h, int numFrames){
|
||||||
|
TAG = GameView.getTAG();
|
||||||
|
|
||||||
|
setX(GameView.WIDTH/5);
|
||||||
|
setY(GameView.HEIGHT/2);
|
||||||
|
setDx(0);
|
||||||
|
setDy(0);
|
||||||
|
|
||||||
|
score = 0;
|
||||||
|
|
||||||
|
setWidth(w);
|
||||||
|
setHeight(h);
|
||||||
|
|
||||||
|
Bitmap[] image = new Bitmap[numFrames];
|
||||||
|
animation = new Animation();
|
||||||
|
|
||||||
|
for (int i = 0; i < numFrames; i++){
|
||||||
|
image[i] = Bitmap.createBitmap(b, width * i, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
animation.setFrames(image);
|
||||||
|
animation.setDelay(100);
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public void setUp(boolean b){
|
||||||
|
up = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDown(boolean b){
|
||||||
|
down = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeft(boolean b){
|
||||||
|
left = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRight(boolean b){
|
||||||
|
right = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSprint(boolean b){
|
||||||
|
sprint = b;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean isPlaying(){
|
||||||
|
return playing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlaying(boolean p){
|
||||||
|
playing = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScore() {
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(){
|
||||||
|
animation.update();
|
||||||
|
|
||||||
|
long elapsed = (System.currentTimeMillis() - startTime);
|
||||||
|
if (elapsed > 100){
|
||||||
|
score++;
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specific animals should override this
|
||||||
|
if (left){
|
||||||
|
dx = Math.abs(dx) * -1;
|
||||||
|
}
|
||||||
|
else if (right){
|
||||||
|
dx = Math.abs(dx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sprint){
|
||||||
|
dx *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (up){
|
||||||
|
dy += -1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
dy += 2;
|
||||||
|
}
|
||||||
|
if (dy < -5){
|
||||||
|
dy = -5;
|
||||||
|
}
|
||||||
|
if (dy > 10){
|
||||||
|
dy = 10;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Character specific as well
|
||||||
|
// Only move when going up or have not hit the ground yet.
|
||||||
|
if (y < GameView.HEIGHT - getHeight() || dy < 0) {
|
||||||
|
y += dy;
|
||||||
|
}
|
||||||
|
// Do not leave bottom of map
|
||||||
|
else{
|
||||||
|
y = GameView.HEIGHT - getHeight();
|
||||||
|
dy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not leave top of map
|
||||||
|
if (y < 0){
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
setEndX(getX() + getWidth());
|
||||||
|
setCenterX((getX() + getEndX()) / 2);
|
||||||
|
|
||||||
|
setBottomY(getY() + getHeight());
|
||||||
|
setCenterY((getY() + getBottomY()) / 2);
|
||||||
|
|
||||||
|
Log.d(TAG, "Player.update():" +
|
||||||
|
" score=" + score +
|
||||||
|
", x=" + x +
|
||||||
|
", dx=" + dx +
|
||||||
|
", y=" + y +
|
||||||
|
", dy=" + dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Canvas canvas){
|
||||||
|
canvas.drawBitmap(animation.getImage(), getX(), getY(), null);
|
||||||
|
}
|
||||||
|
}
|
BIN
app/src/main/res/drawable-nodpi/background_forest.png
Executable file
After Width: | Height: | Size: 122 KiB |
BIN
app/src/main/res/drawable-nodpi/background_forest_with_lava.png
Executable file
After Width: | Height: | Size: 147 KiB |
BIN
app/src/main/res/drawable-nodpi/background_forest_without_clouds.png
Executable file
After Width: | Height: | Size: 116 KiB |
BIN
app/src/main/res/drawable-nodpi/banner.png
Executable file
After Width: | Height: | Size: 32 KiB |
BIN
app/src/main/res/drawable-nodpi/bird.png
Executable file
After Width: | Height: | Size: 574 B |
BIN
app/src/main/res/drawable-nodpi/bird_enemy.png
Executable file
After Width: | Height: | Size: 554 B |
BIN
app/src/main/res/drawable-nodpi/bird_extra_life.png
Executable file
After Width: | Height: | Size: 347 B |
BIN
app/src/main/res/drawable-nodpi/chicken.png
Executable file
After Width: | Height: | Size: 995 B |
BIN
app/src/main/res/drawable-nodpi/clouds.png
Executable file
After Width: | Height: | Size: 7.5 KiB |
BIN
app/src/main/res/drawable-nodpi/enemy.png
Executable file
After Width: | Height: | Size: 178 B |
BIN
app/src/main/res/drawable-nodpi/icon.png
Executable file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable-nodpi/lava.png
Executable file
After Width: | Height: | Size: 42 KiB |
BIN
app/src/main/res/drawable-nodpi/normal_platform.png
Executable file
After Width: | Height: | Size: 427 B |
BIN
app/src/main/res/drawable-nodpi/test_player.png
Executable file
After Width: | Height: | Size: 439 B |
71
app/src/main/res/layout/activity_high_score.xml
Executable file
@ -0,0 +1,71 @@
|
|||||||
|
<?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:ads="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/activity_high_score"
|
||||||
|
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.hyperling.apps.games.HighScoreActivity">
|
||||||
|
|
||||||
|
<com.google.android.gms.ads.AdView
|
||||||
|
android:id="@+id/adViewHighScores"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
ads:adSize="BANNER"
|
||||||
|
ads:adUnitId="@string/interstitial_ad_unit_id_high_score" />
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/scrollViewHighScore"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_above="@+id/adViewHighScores">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:text="@string/birdScoreHeader"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="@dimen/textHeaderSize"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/birdScoreLayout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"/>
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/spaceSize" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:text="@string/chickenScoreHeader"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="@dimen/textHeaderSize"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/chickenScoreLayout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
125
app/src/main/res/layout/activity_main.xml
Executable file
@ -0,0 +1,125 @@
|
|||||||
|
<?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:ads="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/activity_main"
|
||||||
|
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.hyperling.apps.games.MainActivity">
|
||||||
|
|
||||||
|
<com.google.android.gms.ads.AdView
|
||||||
|
android:id="@+id/adViewMain"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
ads:adSize="BANNER"
|
||||||
|
ads:adUnitId="@string/interstitial_ad_unit_id_main" />
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/scrollViewMain"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_above="@+id/adViewMain">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="16dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:text="@string/tvGamesHeader"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnBirdGame"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/btnGameBird"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnGameCow"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/btnGameCow"
|
||||||
|
android:enabled="false"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnGamePig"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/btnGamePig"
|
||||||
|
android:enabled="false"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnGameChicken"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/btnGameChicken"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnGameCat"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/btnGameCat"
|
||||||
|
android:enabled="false"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnGameSquirrel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/btnGameSquirrel"
|
||||||
|
android:enabled="false"/>
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="16dp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnOptions"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/btnOptions"
|
||||||
|
android:textSize="30sp"/>
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="16dp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnHighScores"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/btnHighScores"
|
||||||
|
android:textSize="30sp"/>
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="16dp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnHelp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/btnHelp"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:enabled="false"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
</RelativeLayout>
|
292
app/src/main/res/layout/activity_options.xml
Executable file
@ -0,0 +1,292 @@
|
|||||||
|
<?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:ads="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/activity_options"
|
||||||
|
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.hyperling.apps.games.OptionsActivity">
|
||||||
|
|
||||||
|
<com.google.android.gms.ads.AdView
|
||||||
|
android:id="@+id/adViewOptions"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
ads:adSize="BANNER"
|
||||||
|
ads:adUnitId="@string/interstitial_ad_unit_id_options" />
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/scrollViewOptions"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_above="@+id/adViewOptions"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:layout_alignParentTop="true">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/optionGroupGeneral"
|
||||||
|
android:textSize="@dimen/textHeaderSize"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/separatorSize"
|
||||||
|
android:background="@color/colorPrimaryDark" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/optionAdsLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/optionAdsCheckBox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"/>
|
||||||
|
<TextView
|
||||||
|
android:text="@string/optionAds"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toLeftOf="@id/optionAdsCheckBox"
|
||||||
|
android:layout_toStartOf="@id/optionAdsCheckBox"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/separatorSize"
|
||||||
|
android:background="@color/colorPrimaryDark" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/spaceSize" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:text="@string/optionGroupInGame"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="@dimen/textHeaderSize"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/separatorSize"
|
||||||
|
android:background="@color/colorPrimaryDark" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/optionPracticeRoundLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/optionPracticeRoundCheckBox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:enabled="false"/>
|
||||||
|
<TextView
|
||||||
|
android:text="@string/optionPracticeRound"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toLeftOf="@id/optionPracticeRoundCheckBox"
|
||||||
|
android:layout_toStartOf="@id/optionPracticeRoundCheckBox"
|
||||||
|
android:textStyle="italic"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/separatorSize"
|
||||||
|
android:background="@color/colorPrimaryDark" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/optionHigherQualityLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/optionHigherQualityCheckBox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"/>
|
||||||
|
<TextView
|
||||||
|
android:text="@string/optionHigherQuality"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toLeftOf="@id/optionHigherQualityCheckBox"
|
||||||
|
android:layout_toStartOf="@id/optionHigherQualityCheckBox"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/separatorSize"
|
||||||
|
android:background="@color/colorPrimaryDark" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/optionFPSLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/fpsCheckBox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"/>
|
||||||
|
<TextView
|
||||||
|
android:text="@string/optionFPS"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toLeftOf="@id/fpsCheckBox"
|
||||||
|
android:layout_toStartOf="@id/fpsCheckBox"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/separatorSize"
|
||||||
|
android:background="@color/colorPrimaryDark" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/spaceSize" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:text="@string/optionGroupOnline"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="@dimen/textHeaderSize"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/separatorSize"
|
||||||
|
android:background="@color/colorPrimaryDark" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/optionNicknameLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/optionNicknameEditText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:enabled="false"/>
|
||||||
|
<!--android:hint="@string/optionNicknameHint"-->
|
||||||
|
<TextView
|
||||||
|
android:text="@string/optionNickname"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toLeftOf="@id/optionNicknameEditText"
|
||||||
|
android:layout_toStartOf="@id/optionNicknameEditText"
|
||||||
|
android:textStyle="italic"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/separatorSize"
|
||||||
|
android:background="@color/colorPrimaryDark" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/optionUploadLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/optionUploadCheckBox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:enabled="false"/>
|
||||||
|
<TextView
|
||||||
|
android:text="@string/optionUpload"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toLeftOf="@id/optionUploadCheckBox"
|
||||||
|
android:layout_toStartOf="@id/optionUploadCheckBox"
|
||||||
|
android:textStyle="italic"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/separatorSize"
|
||||||
|
android:background="@color/colorPrimaryDark" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/spaceSize" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:text="@string/optionGroupOther"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="@dimen/textHeaderSize"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/separatorSize"
|
||||||
|
android:background="@color/colorPrimaryDark" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnDeletePreferences"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/btnDeletePreferences"
|
||||||
|
android:gravity="center"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnConfirmDeletePreferences"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/btnConfirmDeletePreferences"
|
||||||
|
android:gravity="center"
|
||||||
|
android:enabled="false"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/separatorSize"
|
||||||
|
android:background="@color/colorPrimaryDark" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Executable file
After Width: | Height: | Size: 3.3 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Executable file
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Executable file
After Width: | Height: | Size: 4.7 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Executable file
After Width: | Height: | Size: 7.5 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Executable file
After Width: | Height: | Size: 10 KiB |
6
app/src/main/res/values-w820dp/dimens.xml
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
<resources>
|
||||||
|
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||||
|
(such as screen margins) for screens with more than 820dp of available width. This
|
||||||
|
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||||
|
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||||
|
</resources>
|
12
app/src/main/res/values/colors.xml
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!--
|
||||||
|
<color name="colorPrimary">#3F51B5</color>
|
||||||
|
<color name="colorPrimaryDark">#303F9F</color>
|
||||||
|
<color name="colorAccent">#FF4081</color>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<color name="colorPrimary">#330066</color>
|
||||||
|
<color name="colorPrimaryDark">#333333</color>
|
||||||
|
<color name="colorAccent">#FF9900</color>
|
||||||
|
</resources>
|
9
app/src/main/res/values/dimens.xml
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
<resources>
|
||||||
|
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||||
|
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||||
|
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="textHeaderSize">30sp</dimen>
|
||||||
|
<dimen name="spaceSize">16dp</dimen>
|
||||||
|
<dimen name="separatorSize">1dp</dimen>
|
||||||
|
</resources>
|
92
app/src/main/res/values/strings.xml
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">Hyper Games</string>
|
||||||
|
|
||||||
|
<string name="TAG">apps.hyperling.com.platformer</string>
|
||||||
|
|
||||||
|
<!-- Main Activity -->
|
||||||
|
<string name="tvGamesHeader">Games</string>
|
||||||
|
<string name="btnGameBird">Betty the Bird (Beta)</string>
|
||||||
|
<!-- Default Game -->
|
||||||
|
<!-- Testing only? Flappybird? -->
|
||||||
|
<string name="btnGameCow">Carly the Cow</string>
|
||||||
|
<!-- A cow must defend itself to escape the farmers trying to kill it. -->
|
||||||
|
<!-- Auto-runner. Cow can charge to scare farmers away. (They run off the map, cow does not kill or hit them) -->
|
||||||
|
<string name="btnGamePig">Patty the Pig</string>
|
||||||
|
<!-- A pig must hide from pursuers and avoid drying out in the sun using mud baths. -->
|
||||||
|
<!-- Press down to make the pig walk. Tapping rapidly makes it run for a short amount of time. You must avoid being noticed by patrols of farmers (like Deku Palace). -->
|
||||||
|
<!-- This is a top-down game? -->
|
||||||
|
<string name="btnGameChicken">Charlie the Chicken (Unfinished)</string>
|
||||||
|
<!-- Game where you must jump/fly over obstacles? -->
|
||||||
|
<!-- Auto-runner. Tapping makes it fly while holding down makes it run. Possible to get a running start and then fly? Avoid farmers and their nets. -->
|
||||||
|
<string name="btnGameCat">Kitty the Cat</string>
|
||||||
|
<!-- Full platformer like Super Mario World or Donkey Kong Country. -->
|
||||||
|
<!-- Tap the direction of the screen you'd like to move. Character is in the middle instead of on the left like an auto-runner. -->
|
||||||
|
<string name="btnGameSquirrel">Sammy the Squirrel</string>
|
||||||
|
<!-- Top-down like pig game, but like Frogger -->
|
||||||
|
<string name="btnOptions">Options</string>
|
||||||
|
<string name="btnHighScores">High Scores</string>
|
||||||
|
<string name="btnHelp">Help</string>
|
||||||
|
|
||||||
|
<string name="btnHighScoreSubHeader">High Score:</string>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Options Actvity -->
|
||||||
|
<string name="optionGroupGeneral">General</string>
|
||||||
|
<string name="optionGroupInGame">In Game</string>
|
||||||
|
<string name="optionGroupOnline">Online</string>
|
||||||
|
<string name="optionGroupOther">Other</string>
|
||||||
|
|
||||||
|
<string name="optionAds">Allow Ads on Menu Screens?</string>
|
||||||
|
<string name="optionPracticeRound">Play Practice Round when Starting New Games?</string>
|
||||||
|
<string name="optionHigherQuality">Allow Higher Quality Images and Animations?</string>
|
||||||
|
<string name="optionFPS">Display FPS?</string>
|
||||||
|
<string name="optionNickname">Nickname for Online Leaderboards:</string>
|
||||||
|
<string name="optionUpload">Allow Automatic High Score Uploads?</string>
|
||||||
|
|
||||||
|
<string name="optionNicknameHint">Type Name Here</string>
|
||||||
|
|
||||||
|
<string name="btnDeletePreferences">Delete High Scores and Reset Preferences</string>
|
||||||
|
<string name="btnConfirmDeletePreferences">Are you seriously sure that you seriously want to seriously delete everything? If so, press here!</string>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Shared Preferences -->
|
||||||
|
<string name="sharedPreferencesKey">HyperGames</string>
|
||||||
|
<!-- Options -->
|
||||||
|
<string name="adsKey">Ads</string>
|
||||||
|
<string name="practiceRoundKey">Practice</string>
|
||||||
|
<string name="higherQualityKey">HigherQuality</string>
|
||||||
|
<string name="fpsKey">FPS</string>
|
||||||
|
<string name="nicknameKey">Nickname</string>
|
||||||
|
<string name="uploadKey">Upload</string>
|
||||||
|
<!-- High Scores -->
|
||||||
|
<string name="birdScoreKey">BirdScore009</string>
|
||||||
|
<string name="cowScoreKey">CowScore</string>
|
||||||
|
<string name="pigScoreKey">PigScore</string>
|
||||||
|
<string name="chickenScoreKey">ChickenScore009</string>
|
||||||
|
<string name="catScoreKey">CatScore</string>
|
||||||
|
|
||||||
|
<!-- All Versions High Scores -->
|
||||||
|
<string name="birdScoreHeader">Bird Game Scores</string>
|
||||||
|
<string-array name="allBirdScoreKeys">
|
||||||
|
<item>BirdScore009</item>
|
||||||
|
<item>BirdScore008(Beta)</item>
|
||||||
|
<item>BirdScore007</item>
|
||||||
|
<item>BirdScore005</item>
|
||||||
|
<item>BirdScore004</item>
|
||||||
|
<item>BirdScore003</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string name="chickenScoreHeader">Chicken Game Scores</string>
|
||||||
|
<string-array name="allChickenScoreKeys">
|
||||||
|
<item>ChickenScore009</item>
|
||||||
|
<item>ChickenScore008(Alpha)</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<!-- -
|
||||||
|
This is an ad unit ID for an interstitial test ad. Replace with your own interstitial ad unit id.
|
||||||
|
For more information, see https://support.google.com/admob/answer/3052638
|
||||||
|
<!- -->
|
||||||
|
<string name="interstitial_ad_unit_id_main">ca-app-pub-9712416021907617/7877767281</string>
|
||||||
|
<string name="interstitial_ad_unit_id_options">ca-app-pub-9712416021907617/3307966880</string>
|
||||||
|
<string name="interstitial_ad_unit_id_high_score">ca-app-pub-9712416021907617/4784700088</string>
|
||||||
|
</resources>
|
15
app/src/main/res/values/styles.xml
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
|
||||||
|
<item name="android:textAllCaps">false</item>
|
||||||
|
<item name="android:textSize">18sp</item>
|
||||||
|
<item name="android:textStyle">normal</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
17
app/src/test/java/com/hyperling/apps/games/ExampleUnitTest.java
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
package com.hyperling.apps.games;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
*
|
||||||
|
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||||
|
*/
|
||||||
|
public class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
public void addition_isCorrect() throws Exception {
|
||||||
|
assertEquals(4, 2 + 2);
|
||||||
|
}
|
||||||
|
}
|
24
build.gradle
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
google()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||||
|
|
||||||
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
// in the individual module build.gradle files
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
39
changelog.txt
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
-= v0.9.0 | 2017-02-05 =-
|
||||||
|
Added Enemies to Chicken Game
|
||||||
|
Began Work on High Score Uploads
|
||||||
|
|
||||||
|
-= v0.8.1 | 2017-01-02 =-
|
||||||
|
Fixed Clouds on Bird Game's Low Quality Background
|
||||||
|
|
||||||
|
-= v008 | 2017-01-02 =-
|
||||||
|
Moved Chicken Game to Alpha
|
||||||
|
Added FPS and Fancy Graphics Settings
|
||||||
|
|
||||||
|
-= v007 | 2016-12-28 =-
|
||||||
|
Modified Bird Game Level Scaling
|
||||||
|
Better Class Definitions and Code Cleanup (Increased Performance)
|
||||||
|
Started Chicken Game
|
||||||
|
|
||||||
|
-= v006 | 2016-12-26 =-
|
||||||
|
Fixed High Score Being Erased
|
||||||
|
|
||||||
|
-= v005 | 2016-12-26 =-
|
||||||
|
Bird Game:
|
||||||
|
Added Lives
|
||||||
|
Added Dynamic Scaling
|
||||||
|
Added Instructions
|
||||||
|
General:
|
||||||
|
Added Score Saving When Exiting Game
|
||||||
|
Fixed New Icon
|
||||||
|
|
||||||
|
-= v004 | 2016-12-26 =-
|
||||||
|
Finished Bird Game
|
||||||
|
Added High Scores Menu
|
||||||
|
Added Reset Button in Options
|
||||||
|
Fixed Ads
|
||||||
|
|
||||||
|
-= v003 | 2016-12-24 =-
|
||||||
|
Fixed button not launching game correctly when high scores exist.
|
||||||
|
|
||||||
|
-= v002 | 2016-12-24 =-
|
||||||
|
Added High Score to Main Menu for Bird Game
|
BIN
gimp/BugByteBeach2.xcf
Executable file
BIN
gimp/background.xcf
Executable file
BIN
gimp/background_forest.png
Executable file
After Width: | Height: | Size: 122 KiB |
BIN
gimp/background_forest.xcf
Executable file
BIN
gimp/background_forest_no_clouds.xcf
Executable file
BIN
gimp/background_forest_with_lava.png
Executable file
After Width: | Height: | Size: 147 KiB |
BIN
gimp/background_forest_without_clouds.png
Executable file
After Width: | Height: | Size: 116 KiB |
BIN
gimp/banner.png
Executable file
After Width: | Height: | Size: 32 KiB |
BIN
gimp/banner.xcf
Executable file
BIN
gimp/bird.png
Executable file
After Width: | Height: | Size: 574 B |
BIN
gimp/bird.xcf
Executable file
BIN
gimp/bird_enemy.png
Executable file
After Width: | Height: | Size: 554 B |
BIN
gimp/bird_enemy.xcf
Executable file
BIN
gimp/bird_extra_life.png
Executable file
After Width: | Height: | Size: 347 B |
BIN
gimp/bird_extra_life.xcf
Executable file
BIN
gimp/chicken.png
Executable file
After Width: | Height: | Size: 995 B |
BIN
gimp/chicken.xcf
Executable file
BIN
gimp/clouds.png
Executable file
After Width: | Height: | Size: 7.5 KiB |
BIN
gimp/enemy.png
Executable file
After Width: | Height: | Size: 178 B |
BIN
gimp/enemy.xcf
Executable file
BIN
gimp/extra_life.xcf
Executable file
BIN
gimp/icon.png
Executable file
After Width: | Height: | Size: 14 KiB |
BIN
gimp/icon.xcf
Executable file
BIN
gimp/lava.png
Executable file
After Width: | Height: | Size: 42 KiB |
BIN
gimp/lava.xcf
Executable file
BIN
gimp/normal_platform.png
Executable file
After Width: | Height: | Size: 427 B |
BIN
gimp/normal_platform.xcf
Executable file
BIN
gimp/player.xcf
Executable file
BIN
gimp/test_player.png
Executable file
After Width: | Height: | Size: 439 B |
17
gradle.properties
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
# Project-wide Gradle settings.
|
||||||
|
|
||||||
|
# IDE (e.g. Android Studio) users:
|
||||||
|
# Gradle settings configured through the IDE *will override*
|
||||||
|
# any settings specified in this file.
|
||||||
|
|
||||||
|
# For more details on how to configure your build environment visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
|
|
||||||
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
|
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
|
# org.gradle.parallel=true
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Executable file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#Thu Jan 10 06:49:36 CST 2019
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
160
gradlew
vendored
Executable file
@ -0,0 +1,160 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
90
gradlew.bat
vendored
Executable file
@ -0,0 +1,90 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
1
settings.gradle
Executable file
@ -0,0 +1 @@
|
|||||||
|
include ':app'
|