Add original project.
42
.gitignore
vendored
@ -33,3 +33,45 @@ google-services.json
|
||||
# Android Profiling
|
||||
*.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'
|