├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── markdown-navigator.xml ├── markdown-navigator │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── gdx-box2d.jar │ └── gdx.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── audio │ │ ├── bumper │ │ │ ├── dinga1.ogg │ │ │ ├── dingc1.ogg │ │ │ ├── dingc2.ogg │ │ │ ├── dingd1.ogg │ │ │ ├── dinge1.ogg │ │ │ └── dingg1.ogg │ │ └── misc │ │ │ ├── andBounce2.ogg │ │ │ ├── ball1.ogg │ │ │ ├── flipper1.ogg │ │ │ ├── message2.ogg │ │ │ ├── rolloverE.ogg │ │ │ └── startup1.ogg │ └── tables │ │ ├── table1.json │ │ ├── table2.json │ │ ├── table3.json │ │ ├── table4.json │ │ └── table5.json │ ├── java │ └── com │ │ └── homescreenarcade │ │ ├── ArcadeCommon.java │ │ ├── FireButtonWidget.java │ │ ├── GameControlWidget.java │ │ ├── GameWallpaperService.java │ │ ├── LauncherActivity.java │ │ ├── LeftRightWidget.java │ │ ├── UpDownWidget.java │ │ ├── blockdrop │ │ ├── Animator.java │ │ ├── BlockBoardView.java │ │ ├── BlockDropWallpaper.java │ │ ├── PieceGenerator.java │ │ ├── Row.java │ │ ├── Square.java │ │ ├── WorkThread.java │ │ ├── components │ │ │ ├── Board.java │ │ │ ├── Component.java │ │ │ ├── Controls.java │ │ │ ├── Display.java │ │ │ ├── GameState.java │ │ │ └── Sound.java │ │ └── pieces │ │ │ ├── IPiece.java │ │ │ ├── JPiece.java │ │ │ ├── LPiece.java │ │ │ ├── OPiece.java │ │ │ ├── Piece.java │ │ │ ├── Piece3x3.java │ │ │ ├── Piece4x4.java │ │ │ ├── SPiece.java │ │ │ ├── TPiece.java │ │ │ └── ZPiece.java │ │ ├── invaders │ │ ├── Coordinate.java │ │ ├── GridObject.java │ │ ├── Invader.java │ │ ├── InvaderView.java │ │ ├── InvadersWallpaper.java │ │ ├── ObjectManager.java │ │ ├── Shell.java │ │ ├── Shield.java │ │ ├── SpaceInvadersActivity.java │ │ ├── Spaceship.java │ │ └── Tank.java │ │ ├── mazeman │ │ ├── GameActivity.java │ │ ├── GameEngine.java │ │ ├── GameSurfaceView.java │ │ ├── Maze.java │ │ ├── MazeManWallpaper.java │ │ ├── Monster.java │ │ ├── Pacmon.java │ │ └── SoundEngine.java │ │ └── pinball │ │ ├── AudioPlayer.java │ │ ├── Ball.java │ │ ├── BaseFieldDelegate.java │ │ ├── BouncyActivity.java │ │ ├── CanvasFieldView.java │ │ ├── Clock.java │ │ ├── Color.java │ │ ├── Field.java │ │ ├── FieldDriver.java │ │ ├── FieldLayout.java │ │ ├── FieldViewManager.java │ │ ├── GLFieldView.java │ │ ├── GameMessage.java │ │ ├── GameState.java │ │ ├── IFieldRenderer.java │ │ ├── OrientationListener.java │ │ ├── PinballWallpaper.java │ │ ├── Point.java │ │ ├── ScoreView.java │ │ ├── VPSoundpool.java │ │ ├── elements │ │ ├── Box2DFactory.java │ │ ├── BumperElement.java │ │ ├── DropTargetGroupElement.java │ │ ├── FieldElement.java │ │ ├── FieldElementCollection.java │ │ ├── FlipperElement.java │ │ ├── RolloverGroupElement.java │ │ ├── SensorElement.java │ │ ├── WallArcElement.java │ │ ├── WallElement.java │ │ └── WallPathElement.java │ │ ├── fields │ │ ├── Field1Delegate.java │ │ ├── Field2Delegate.java │ │ ├── Field3Delegate.java │ │ ├── Field4Delegate.java │ │ └── Field5Delegate.java │ │ └── util │ │ ├── FrameRateManager.java │ │ ├── GLVertexList.java │ │ ├── GLVertexListManager.java │ │ ├── JSONUtils.java │ │ └── MathUtils.java │ ├── jniLibs │ ├── armeabi-v7a │ │ └── libgdx-box2d.so │ ├── armeabi │ │ └── libgdx-box2d.so │ └── x86 │ │ └── libgdx-box2d.so │ └── res │ ├── drawable-hdpi │ ├── food.png │ ├── ghost_door.png │ ├── ic_launcher.png │ ├── ic_mazeman.jpg │ ├── ic_pause_circle_outline_white_48dp.png │ ├── ic_play_circle_outline_white_48dp.png │ ├── power.png │ └── wall.png │ ├── drawable-mdpi │ ├── ic_invaders.png │ ├── ic_pause_circle_outline_white_48dp.png │ ├── ic_play_circle_outline_white_48dp.png │ └── status_bg.9.png │ ├── drawable-nodpi │ ├── bluey_sprite.png │ ├── example_appwidget_preview.png │ ├── game_over_classic.png │ ├── pacmon_sprite_green.png │ ├── pacmon_sprite_orange.png │ ├── redy_sprite.png │ ├── violet_sprite.png │ └── yellowy_sprite.png │ ├── drawable-xhdpi │ ├── blue_btn.png │ ├── blue_yellow.png │ ├── green_btn.png │ ├── ic_pause_circle_outline_white_48dp.png │ ├── ic_play_circle_outline_white_48dp.png │ ├── invaders_tank.png │ ├── mazeman_small.png │ ├── pin_ball.png │ ├── red_btn.png │ ├── red_green.png │ └── yellow_btn.png │ ├── drawable-xxhdpi │ ├── bullet.9.png │ ├── ic_launcher.png │ ├── ic_pause_circle_outline_white_48dp.png │ ├── ic_play_circle_outline_white_48dp.png │ └── iconinger_v2.png │ ├── drawable-xxxhdpi │ ├── block_piece.png │ ├── ic_pause_circle_outline_white_48dp.png │ ├── ic_pause_shortcut.png │ ├── ic_pinball.png │ ├── ic_play_circle_outline_white_48dp.png │ ├── ic_play_shortcut.png │ └── pinball_notif.png │ ├── layout │ ├── fire_button_widget.xml │ ├── get_ready_view.xml │ ├── instruction_view.xml │ ├── launcher_activity.xml │ ├── left_right_widget.xml │ ├── pinball_main.xml │ ├── status_life_icon.xml │ ├── status_notification.xml │ ├── status_text.xml │ └── up_down_widget.xml │ ├── raw │ ├── alien_bullet.mp3 │ ├── alien_death.mp3 │ ├── blaster.mp3 │ ├── clear2_free.ogg │ ├── death.mp3 │ ├── drop_free.ogg │ ├── extra_life.mp3 │ ├── fortress_hit.mp3 │ ├── game_over.mp3 │ ├── gameover2_free.ogg │ ├── key_free.ogg │ ├── lemmings03.ogg │ ├── pacmon_dies.ogg │ ├── pacmon_eating_cherry.ogg │ ├── pacmon_eating_ghost.ogg │ ├── pacmon_extra_live.mp3 │ ├── pacmon_intermission.mp3 │ ├── pacmon_opening_song.ogg │ ├── pacmon_waka_waka.ogg │ ├── sadrobot01.ogg │ └── tetris_free.ogg │ ├── values-v14 │ └── dimens.xml │ ├── values-v16 │ └── strings.xml │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ ├── styles.xml │ └── tetris_constants.xml │ └── xml │ ├── blockdrop_wallpaper.xml │ ├── fire_button_widget_info.xml │ ├── invaders_wallpaper.xml │ ├── left_right_widget_info.xml │ ├── mazeman_wallpaper.xml │ ├── pinball_wallpaper.xml │ └── up_down_widget_info.xml ├── build.gradle ├── copying.txt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── meta ├── favicon.ico ├── feature_graphic.png ├── feature_graphic.xcf ├── ic_launcher.xcf ├── index.html ├── pacman_300.png ├── red_green.png ├── screenshot_blockdrop.png ├── screenshot_invaders.png ├── screenshot_mazeman.png └── screenshot_pinball.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | /meta/archive/* 11 | /meta/releases/* 12 | *.keystore 13 | *.jks 14 | desktop.ini -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/markdown-navigator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 33 | 34 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /.idea/markdown-navigator/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 26 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 53 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Home Screen Arcade 2 | *Home Screen Arcade* is a game platform that runs entirely on the home screen of your Android device. 3 | 4 | It's a tech demo - an experiment in what can be done with normally-staid home screen components - but it's also surprisingly playable. Your game controllers are widgets, your score and game status are shown in a (heads-up) notification, and the action happens in a live wallpaper. 5 | 6 | As a demo, this version of the app includes open-source tributes to three classic arcade video games, as well as an open-source pinball (arguably the most classic arcade game of all). See the **Credits** below for details. All four games are functional, but improvement is always possible; the goal here is to demonstrate the platform. As such, only the minimum of changes was made to each game's existing source code. 7 | 8 | If you're interested in the **platform**'s source, the core is `GameWallpaperService`, an abstract `WallpaperService` subclass that ties the platform together: 9 | 10 | - It serves as a base class for the live wallpaper services that 11 | implement specific games. 12 | - It receives action broadcasts from the 13 | game-control widgets, passing them along to its descendants as method 14 | calls. 15 | - Broadcasts from the actual game code are also received here to 16 | update score, level, and other game status, which 17 | `GameWallpaperService` displays as a heads-up notification. 18 | 19 | Subclasses of `GameWallpaperService` serve as the interface between *Home Screen Arcade* and the actual game code. Like all wallpaper services, each implements both the `Service` and its inner `Engine` class. Each is responsible for managing the lifecycle of the game itself, and also implements an `onDraw` method, which is where the game's graphics get transferred to a `Canvas` that will be shown on the device's home screen. 20 | 21 | ##Credits and Licensing 22 | 23 | *Invaders* is adapted from [Android Space Invaders](https://sourceforge.net/projects/droidspceinvdrs) under the GNU General Public License 3.0. The original Space Invaders game is Copyright (C) 1978 Taito Corporation. 24 | 25 | *Block Drop* is adapted from [Blockinger](https://github.com/vocollapse/Blockinger) under the GNU General Public License 3.0. The original Tetris game is (R) & (C) 1985-2017 Tetris Holding. 26 | 27 | *Maze-Man* is adapted from [Pac-Mon](https://code.google.com/archive/p/game-pacmon) under the Apache License 2.0. The original Pac-Man game is (C) 1980 Bandai Namco Games. 28 | 29 | *Pinball* is adapted from [Vector Pinball](https://github.com/dozingcat/Vector-Pinball) under the GNU General Public License 3.0 30 | 31 | The button image is used with the gracious permission of [Colin O'Dell](https://play.google.com/store/apps/developer?id=Colin+O%27Dell) 32 | 33 | *Home Screen Arcade* itself is copyright 2017 Sterling Udell, and is distributed under the terms of the GNU General Public License 3.0, https://www.gnu.org/licenses/gpl-3.0.en.html 34 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.homescreenarcade" 9 | minSdkVersion 14 10 | targetSdkVersion 25 11 | versionCode 1 12 | versionName "0.1" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | shrinkResources false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | compile fileTree(dir: 'libs', include: ['*.jar']) 25 | compile 'com.android.support:appcompat-v7:25.3.0' 26 | } 27 | -------------------------------------------------------------------------------- /app/libs/gdx-box2d.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/libs/gdx-box2d.jar -------------------------------------------------------------------------------- /app/libs/gdx.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/libs/gdx.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 37 | 38 | 39 | 40 | 41 | 44 | 45 | 46 | 50 | 51 | 52 | 53 | 54 | 57 | 58 | 59 | 63 | 64 | 65 | 66 | 67 | 70 | 71 | 72 | 74 | 75 | 76 | 77 | 78 | 79 | 82 | 83 | 84 | 86 | 87 | 88 | 89 | 90 | 91 | 94 | 95 | 96 | 98 | 99 | 100 | 101 | 102 | 103 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /app/src/main/assets/audio/bumper/dinga1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/bumper/dinga1.ogg -------------------------------------------------------------------------------- /app/src/main/assets/audio/bumper/dingc1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/bumper/dingc1.ogg -------------------------------------------------------------------------------- /app/src/main/assets/audio/bumper/dingc2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/bumper/dingc2.ogg -------------------------------------------------------------------------------- /app/src/main/assets/audio/bumper/dingd1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/bumper/dingd1.ogg -------------------------------------------------------------------------------- /app/src/main/assets/audio/bumper/dinge1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/bumper/dinge1.ogg -------------------------------------------------------------------------------- /app/src/main/assets/audio/bumper/dingg1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/bumper/dingg1.ogg -------------------------------------------------------------------------------- /app/src/main/assets/audio/misc/andBounce2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/misc/andBounce2.ogg -------------------------------------------------------------------------------- /app/src/main/assets/audio/misc/ball1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/misc/ball1.ogg -------------------------------------------------------------------------------- /app/src/main/assets/audio/misc/flipper1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/misc/flipper1.ogg -------------------------------------------------------------------------------- /app/src/main/assets/audio/misc/message2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/misc/message2.ogg -------------------------------------------------------------------------------- /app/src/main/assets/audio/misc/rolloverE.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/misc/rolloverE.ogg -------------------------------------------------------------------------------- /app/src/main/assets/audio/misc/startup1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/assets/audio/misc/startup1.ogg -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/ArcadeCommon.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade; 2 | 3 | /** 4 | * Constants used as keys to pass data to the broadcast receivers in GameWallpaperService. 5 | * 6 | * Created by Sterling on 2017-03-02. 7 | */ 8 | 9 | public class ArcadeCommon { 10 | // Actions, coming from controller widgets or the "scoreboard" notification 11 | static final String ACTION_LEFT = "com.homescreenarcade.LEFT"; 12 | static final String ACTION_RIGHT = "com.homescreenarcade.RIGHT"; 13 | static final String ACTION_UP = "com.homescreenarcade.ACTION_UP"; 14 | static final String ACTION_DOWN = "com.homescreenarcade.ACTION_DOWN"; 15 | static final String ACTION_FIRE = "com.homescreenarcade.FIRE"; 16 | static final String ACTION_PAUSE = "com.homescreenarcade.PAUSE"; 17 | // At one time, I had a 4-in-1 D-Pad controller widget. It would be easy to bring back if desired. 18 | // static final String ACTION_DPAD_UP = "com.homescreenarcade.ACTION_DPAD_UP"; 19 | // static final String ACTION_DPAD_DOWN = "com.homescreenarcade.ACTION_DPAD_DOWN"; 20 | // static final String ACTION_DPAD_LEFT = "com.homescreenarcade.ACTION_DPAD_LEFT"; 21 | // static final String ACTION_DPAD_RIGHT = "com.homescreenarcade.ACTION_DPAD_RIGHT"; 22 | 23 | public static final String ACTION_STATUS = "com.homescreenarcade.STATUS"; 24 | // Status keys, coming from game logic, mostly to update the "scoreboard" 25 | public static final String STATUS_INCREMENT_SCORE = "increment"; 26 | public static final String STATUS_RESET_SCORE = "reset"; 27 | public static final String STATUS_LIVES = "lives"; 28 | public static final String STATUS_LEVEL = "level"; 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/FireButtonWidget.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade; 2 | 3 | import android.app.PendingIntent; 4 | import android.appwidget.AppWidgetManager; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.widget.RemoteViews; 8 | 9 | /** 10 | * Simple one-button widget for "Fire" functionality. 11 | */ 12 | public class FireButtonWidget extends GameControlWidget { 13 | protected void updateAppWidget(Context context, AppWidgetManager appWidgetManager, 14 | int appWidgetId) { 15 | RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.fire_button_widget); 16 | views.setOnClickPendingIntent(R.id.fire_btn, 17 | PendingIntent.getBroadcast(context, 0, new Intent(ArcadeCommon.ACTION_FIRE), 0)); 18 | 19 | appWidgetManager.updateAppWidget(appWidgetId, views); 20 | } 21 | 22 | @Override 23 | public void onEnabled(Context context) { 24 | super.onEnabled(context); 25 | } 26 | 27 | @Override 28 | public void onDisabled(Context context) { 29 | super.onDisabled(context); 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/GameControlWidget.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade; 2 | 3 | import android.appwidget.AppWidgetManager; 4 | import android.appwidget.AppWidgetProvider; 5 | import android.content.Context; 6 | 7 | /** 8 | * Common ancestor for widgets that control gameplay. Pretty standard appwidget stuff. 9 | * 10 | * Created by Sterling on 2017-03-09. 11 | */ 12 | 13 | abstract class GameControlWidget extends AppWidgetProvider { 14 | protected abstract void updateAppWidget(Context context, AppWidgetManager appWidgetManager, 15 | int appWidgetId); 16 | @Override 17 | public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 18 | // There may be multiple widgets active, so update all of them 19 | for (int appWidgetId : appWidgetIds) { 20 | updateAppWidget(context, appWidgetManager, appWidgetId); 21 | } 22 | } 23 | 24 | @Override 25 | public void onEnabled(Context context) { 26 | // Register existence when the first widget is created 27 | context.getSharedPreferences("settings", Context.MODE_PRIVATE) 28 | .edit() 29 | .putBoolean(getClass().getSimpleName(), true) 30 | .apply(); 31 | } 32 | 33 | @Override 34 | public void onDisabled(Context context) { 35 | context.getSharedPreferences("settings", Context.MODE_PRIVATE) 36 | .edit() 37 | .putBoolean(getClass().getSimpleName(), false) 38 | .apply(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/LauncherActivity.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade; 2 | 3 | import android.annotation.TargetApi; 4 | import android.app.WallpaperManager; 5 | import android.content.ComponentName; 6 | import android.content.Intent; 7 | import android.os.Build; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.os.Bundle; 10 | import android.view.View; 11 | 12 | import com.homescreenarcade.mazeman.MazeManWallpaper; 13 | import com.homescreenarcade.pinball.PinballWallpaper; 14 | import com.homescreenarcade.invaders.InvadersWallpaper; 15 | import com.homescreenarcade.blockdrop.BlockDropWallpaper; 16 | 17 | /** 18 | * A simple activity to get the user started playing games on their home screen. 19 | */ 20 | public class LauncherActivity extends AppCompatActivity { 21 | 22 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | 27 | setContentView(R.layout.launcher_activity); 28 | 29 | if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { 30 | // ACTION_CHANGE_LIVE_WALLPAPER wasn't supported before JB, so hide the buttons. They'll 31 | // just have to figure out how to set the LWPs themselves. 32 | findViewById(R.id.invaders).setVisibility(View.GONE); 33 | findViewById(R.id.block_drop).setVisibility(View.GONE); 34 | findViewById(R.id.mazeman).setVisibility(View.GONE); 35 | findViewById(R.id.pinball).setVisibility(View.GONE); 36 | 37 | } else { 38 | // JB or later: set up the LWP-shortcut buttons 39 | 40 | findViewById(R.id.invaders).setOnClickListener(new View.OnClickListener() { 41 | @Override 42 | public void onClick(View v) { 43 | Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER) 44 | .putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, 45 | new ComponentName(LauncherActivity.this, InvadersWallpaper.class)); 46 | startActivity(intent); 47 | finish(); 48 | } 49 | }); 50 | 51 | findViewById(R.id.block_drop).setOnClickListener(new View.OnClickListener() { 52 | @Override 53 | public void onClick(View v) { 54 | Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER) 55 | .putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, 56 | new ComponentName(LauncherActivity.this, BlockDropWallpaper.class)); 57 | startActivity(intent); 58 | finish(); 59 | } 60 | }); 61 | 62 | findViewById(R.id.mazeman).setOnClickListener(new View.OnClickListener() { 63 | @Override 64 | public void onClick(View v) { 65 | Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER) 66 | .putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, 67 | new ComponentName(LauncherActivity.this, MazeManWallpaper.class)); 68 | startActivity(intent); 69 | finish(); 70 | } 71 | }); 72 | 73 | findViewById(R.id.pinball).setOnClickListener(new View.OnClickListener() { 74 | @Override 75 | public void onClick(View v) { 76 | Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER) 77 | .putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, 78 | new ComponentName(LauncherActivity.this, PinballWallpaper.class)); 79 | startActivity(intent); 80 | finish(); 81 | } 82 | }); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/LeftRightWidget.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade; 2 | 3 | import android.app.PendingIntent; 4 | import android.appwidget.AppWidgetManager; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.widget.RemoteViews; 8 | 9 | 10 | /** 11 | * Two-button widget for horizontal actions. 12 | */ 13 | public class LeftRightWidget extends GameControlWidget { 14 | protected void updateAppWidget(Context context, AppWidgetManager appWidgetManager, 15 | int appWidgetId) { 16 | RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.left_right_widget); 17 | views.setOnClickPendingIntent(R.id.left_btn, 18 | PendingIntent.getBroadcast(context, 0, new Intent(ArcadeCommon.ACTION_LEFT), 0)); 19 | views.setOnClickPendingIntent(R.id.right_btn, 20 | PendingIntent.getBroadcast(context, 0, new Intent(ArcadeCommon.ACTION_RIGHT), 0)); 21 | 22 | appWidgetManager.updateAppWidget(appWidgetId, views); 23 | } 24 | 25 | @Override 26 | public void onEnabled(Context context) { 27 | super.onEnabled(context); 28 | } 29 | 30 | @Override 31 | public void onDisabled(Context context) { 32 | super.onDisabled(context); 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/UpDownWidget.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade; 2 | 3 | import android.app.PendingIntent; 4 | import android.appwidget.AppWidgetManager; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.widget.RemoteViews; 8 | 9 | /** 10 | * Two-button widget for vertical actions. 11 | */ 12 | public class UpDownWidget extends GameControlWidget { 13 | protected void updateAppWidget(Context context, AppWidgetManager appWidgetManager, 14 | int appWidgetId) { 15 | RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.up_down_widget); 16 | views.setOnClickPendingIntent(R.id.up_btn, 17 | PendingIntent.getBroadcast(context, 0, new Intent(ArcadeCommon.ACTION_UP), 0)); 18 | views.setOnClickPendingIntent(R.id.down_btn, 19 | PendingIntent.getBroadcast(context, 0, new Intent(ArcadeCommon.ACTION_DOWN), 0)); 20 | 21 | appWidgetManager.updateAppWidget(appWidgetId, views); 22 | } 23 | 24 | @Override 25 | public void onEnabled(Context context) { 26 | super.onEnabled(context); 27 | } 28 | 29 | @Override 30 | public void onDisabled(Context context) { 31 | super.onDisabled(context); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/Animator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop; 39 | 40 | import com.homescreenarcade.R; 41 | import com.homescreenarcade.blockdrop.components.Board; 42 | 43 | import android.content.Context; 44 | import android.graphics.Bitmap; 45 | import android.graphics.Canvas; 46 | 47 | public class Animator { 48 | 49 | public static final int animationStageIdle = 0; 50 | public static final int animationStageFlash = 1; 51 | public static final int animationStageBurst = 2; 52 | 53 | // Config 54 | private long flashInterval; 55 | private long flashFinishTime; 56 | private int squareSize; 57 | 58 | // State 59 | private long startTime; 60 | private int stage; 61 | private boolean drawEnable; 62 | private long nextFlash; 63 | 64 | // Data 65 | private Row row; 66 | private Bitmap bitmapRow; 67 | private int flashCount; 68 | private int rawFlashInterval; 69 | 70 | // Constructor 71 | public Animator(Context c, Row r) { 72 | rawFlashInterval = c.getResources().getInteger(R.integer.clearAnimation_flashInterval); 73 | flashCount = c.getResources().getInteger(R.integer.clearAnimation_flashCount); 74 | stage = animationStageIdle; 75 | this.row = r; 76 | drawEnable = true; 77 | startTime = 0; 78 | flashFinishTime = 0; 79 | nextFlash = 0; 80 | flashInterval = 0; 81 | squareSize = 0; 82 | } 83 | 84 | public void cycle(long time, Board board) { 85 | if(stage == animationStageIdle) 86 | return; 87 | 88 | if(time >= flashFinishTime) 89 | finish(board); 90 | else if (time >= nextFlash) { 91 | nextFlash += flashInterval; 92 | drawEnable = !drawEnable; 93 | board.invalidate(); 94 | } 95 | } 96 | 97 | public void start(Board board, int currentDropInterval) { 98 | bitmapRow = row.drawBitmap(squareSize); 99 | stage = animationStageFlash; 100 | startTime = System.currentTimeMillis(); 101 | flashInterval = Math.min( // Choose base flash interval on slow levels and shorter interval on fast levels. 102 | rawFlashInterval, 103 | (int)((float)currentDropInterval / (float)flashCount) 104 | ); 105 | flashFinishTime = startTime + 2*flashInterval*flashCount; 106 | nextFlash = startTime + flashInterval; 107 | drawEnable = false; 108 | board.invalidate(); 109 | } 110 | 111 | public boolean finish(Board board) { 112 | if(animationStageIdle == stage) 113 | return false; 114 | stage = animationStageIdle; 115 | row.finishClear(board); 116 | drawEnable = true; 117 | return true; 118 | } 119 | 120 | public void draw(int x, int y, int ss, Canvas c) { 121 | //float scaleFactor = flashFinishTime / (flashFinishTime-flashProgress); 122 | //Bitmap bm = Bitmap.createBitmap(brustWidth, burstHeight, Bitmap.Config.ARGB_8888); 123 | //Canvas tamp = new Canvas(bm); 124 | //transparentPaint.setAlpha(do{(shit.here())}while(you += shit)); 125 | this.squareSize = ss; 126 | if(drawEnable) { 127 | if(stage == animationStageIdle) 128 | bitmapRow = row.drawBitmap(ss); 129 | //bitmapRow.scale(scaleFactor, scaleFactor, px, py); 130 | if (bitmapRow != null) 131 | c.drawBitmap(bitmapRow, x, y, null); 132 | } 133 | } 134 | 135 | public void startFlash() { 136 | 137 | } 138 | 139 | public void cancelBurst() { 140 | 141 | } 142 | 143 | public void startBurst() { 144 | 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/BlockBoardView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop; 39 | 40 | import android.content.Context; 41 | import android.graphics.PixelFormat; 42 | import android.util.AttributeSet; 43 | import android.view.SurfaceHolder; 44 | import android.view.SurfaceView; 45 | import android.view.SurfaceHolder.Callback; 46 | 47 | public class BlockBoardView extends SurfaceView implements Callback { 48 | 49 | public interface GameInterface { 50 | void startGame(BlockBoardView blockBoardView); 51 | void endGame(); 52 | } 53 | 54 | private GameInterface host; 55 | 56 | public BlockBoardView(Context context) { 57 | super(context); 58 | } 59 | 60 | public BlockBoardView(Context context, AttributeSet attrs) { 61 | super(context,attrs); 62 | } 63 | 64 | public BlockBoardView(Context context, AttributeSet attrs, int defStyle) { 65 | super(context,attrs,defStyle); 66 | } 67 | 68 | public void setHost(GameInterface ga) { 69 | host = ga; 70 | } 71 | 72 | public void init() { 73 | setZOrderOnTop(true); 74 | getHolder().addCallback(this); 75 | getHolder().setFormat(PixelFormat.TRANSPARENT); 76 | } 77 | 78 | @Override 79 | public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { 80 | 81 | } 82 | 83 | @Override 84 | public void surfaceCreated(SurfaceHolder arg0) { 85 | host.startGame(this); 86 | } 87 | 88 | @Override 89 | public void surfaceDestroyed(SurfaceHolder arg0) { 90 | host.endGame(); 91 | } 92 | } 93 | 94 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/PieceGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop; 39 | 40 | import java.util.Random; 41 | 42 | public class PieceGenerator { 43 | 44 | public static final int STRAT_RANDOM = 0; 45 | public static final int STRAT_7BAG = 1; 46 | 47 | int strategy; 48 | int bag[]; 49 | int bagPointer; 50 | private Random rndgen; 51 | 52 | public PieceGenerator(int strat) { 53 | bag = new int[7]; 54 | for(int i = 0; i < 7; i++) //initial Permutation 55 | bag[i] = i; 56 | 57 | rndgen = new Random(System.currentTimeMillis()); 58 | if(strat==STRAT_RANDOM) 59 | this.strategy = STRAT_RANDOM; 60 | else 61 | this.strategy = STRAT_7BAG; 62 | 63 | // Fill initial Bag 64 | for(int i = 0; i < 6; i++) { 65 | int c = rndgen.nextInt(7-i); 66 | int t = bag[i]; bag[i] = bag[i+c]; bag[i+c] = t; /* swap */ 67 | } 68 | bagPointer = 0; 69 | } 70 | 71 | public int next() { 72 | if(strategy== STRAT_RANDOM) 73 | return rndgen.nextInt(7); 74 | else { 75 | if(bagPointer < 7) { 76 | bagPointer++; 77 | return bag[bagPointer - 1]; 78 | } else { 79 | // Randomize Bag 80 | for(int i = 0; i < 6; i++) { 81 | int c = rndgen.nextInt(7-i); 82 | int t = bag[i]; bag[i] = bag[i+c]; bag[i+c] = t; /* swap */ 83 | } 84 | bagPointer = 1; 85 | return bag[bagPointer - 1]; 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/Square.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop; 39 | 40 | import android.content.Context; 41 | import android.graphics.Bitmap; 42 | import android.graphics.Canvas; 43 | import android.graphics.Paint; 44 | 45 | import com.homescreenarcade.R; 46 | 47 | public class Square { 48 | 49 | public static final int type_empty = 0; 50 | public static final int type_blue = 1; 51 | public static final int type_orange = 2; 52 | public static final int type_yellow = 3; 53 | public static final int type_red = 4; 54 | public static final int type_green = 5; 55 | public static final int type_magenta = 6; 56 | public static final int type_cyan = 7; 57 | 58 | private int type; 59 | private Paint paint; 60 | private Bitmap bm; 61 | private Bitmap phantomBM; 62 | private Canvas canv; 63 | private Canvas phantomCanv; 64 | //private Context context; 65 | private int squaresize; 66 | private int phantomAlpha; 67 | 68 | public Square(int type, Context c) { 69 | this.type = type; 70 | paint = new Paint(); 71 | phantomAlpha = c.getResources().getInteger(R.integer.phantom_alpha); 72 | squaresize = 0; 73 | switch(type){ 74 | case type_blue: 75 | paint.setColor(c.getResources().getColor(R.color.square_blue)); 76 | break; 77 | case type_orange: 78 | paint.setColor(c.getResources().getColor(R.color.square_orange)); 79 | break; 80 | case type_yellow: 81 | paint.setColor(c.getResources().getColor(R.color.square_yellow)); 82 | break; 83 | case type_red: 84 | paint.setColor(c.getResources().getColor(R.color.square_red)); 85 | break; 86 | case type_green: 87 | paint.setColor(c.getResources().getColor(R.color.square_green)); 88 | break; 89 | case type_magenta: 90 | paint.setColor(c.getResources().getColor(R.color.square_magenta)); 91 | break; 92 | case type_cyan: 93 | paint.setColor(c.getResources().getColor(R.color.square_cyan)); 94 | break; 95 | case type_empty: 96 | return; 97 | default: // error: white 98 | paint.setColor(c.getResources().getColor(R.color.square_error)); 99 | break; 100 | } 101 | } 102 | 103 | public void reDraw(int ss) { 104 | if(type == type_empty) 105 | return; 106 | 107 | squaresize = ss; 108 | bm = Bitmap.createBitmap(ss, ss, Bitmap.Config.ARGB_8888); 109 | phantomBM = Bitmap.createBitmap(ss, ss, Bitmap.Config.ARGB_8888); 110 | canv = new Canvas(bm); 111 | phantomCanv = new Canvas(phantomBM); 112 | 113 | paint.setAlpha(255); 114 | canv.drawRect(0, 0, squaresize, squaresize, paint); 115 | paint.setAlpha(phantomAlpha); 116 | phantomCanv.drawRect(0, 0, squaresize, squaresize, paint); 117 | //canv.draw 118 | } 119 | 120 | public Square clone(Context c) { 121 | return new Square(type, c); 122 | } 123 | 124 | public boolean isEmpty() { 125 | if(type == type_empty) 126 | return true; 127 | else 128 | return false; 129 | } 130 | 131 | public void draw(int x, int y, int squareSize, Canvas c, boolean isPhantom) { // top left corner of square 132 | if(type == type_empty) 133 | return; 134 | 135 | if(squareSize != squaresize) 136 | reDraw(squareSize); 137 | 138 | if(isPhantom) { 139 | c.drawBitmap(phantomBM, x, y, null); 140 | } else { 141 | c.drawBitmap(bm, x, y, null); 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/components/Component.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop.components; 39 | 40 | import com.homescreenarcade.blockdrop.BlockDropWallpaper; 41 | 42 | public abstract class Component { 43 | 44 | protected BlockDropWallpaper host; 45 | 46 | public Component(BlockDropWallpaper ga) { 47 | host = ga; 48 | } 49 | 50 | public void reconnect(BlockDropWallpaper ga) { 51 | host = ga; 52 | } 53 | 54 | public void disconnect() { 55 | host = null; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/pieces/IPiece.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop.pieces; 39 | 40 | import com.homescreenarcade.blockdrop.Square; 41 | 42 | import android.content.Context; 43 | 44 | public class IPiece extends Piece4x4 { 45 | 46 | private Square iSquare; 47 | 48 | public IPiece(Context c) { 49 | super(c); 50 | iSquare = new Square(Piece.type_I,c); 51 | pattern[2][0] = iSquare; 52 | pattern[2][1] = iSquare; 53 | pattern[2][2] = iSquare; 54 | pattern[2][3] = iSquare; 55 | reDraw(); 56 | } 57 | 58 | @Override 59 | public void reset(Context c) { 60 | super.reset(c); 61 | pattern[2][0] = iSquare; 62 | pattern[2][1] = iSquare; 63 | pattern[2][2] = iSquare; 64 | pattern[2][3] = iSquare; 65 | reDraw(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/pieces/JPiece.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop.pieces; 39 | 40 | import com.homescreenarcade.blockdrop.Square; 41 | 42 | import android.content.Context; 43 | 44 | public class JPiece extends Piece3x3 { 45 | 46 | private Square jSquare; 47 | 48 | public JPiece(Context c) { 49 | super(c); 50 | jSquare = new Square(Piece.type_J,c); 51 | pattern[1][0] = jSquare; 52 | pattern[1][1] = jSquare; 53 | pattern[1][2] = jSquare; 54 | pattern[2][2] = jSquare; 55 | reDraw(); 56 | } 57 | 58 | @Override 59 | public void reset(Context c) { 60 | super.reset(c); 61 | pattern[1][0] = jSquare; 62 | pattern[1][1] = jSquare; 63 | pattern[1][2] = jSquare; 64 | pattern[2][2] = jSquare; 65 | reDraw(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/pieces/LPiece.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop.pieces; 39 | 40 | import com.homescreenarcade.blockdrop.Square; 41 | 42 | import android.content.Context; 43 | 44 | public class LPiece extends Piece3x3 { 45 | 46 | private Square lSquare; 47 | 48 | public LPiece(Context c) { 49 | super(c); 50 | lSquare = new Square(Piece.type_L,c); 51 | pattern[1][0] = lSquare; 52 | pattern[1][1] = lSquare; 53 | pattern[1][2] = lSquare; 54 | pattern[2][0] = lSquare; 55 | reDraw(); 56 | } 57 | 58 | @Override 59 | public void reset(Context c) { 60 | super.reset(c); 61 | pattern[1][0] = lSquare; 62 | pattern[1][1] = lSquare; 63 | pattern[1][2] = lSquare; 64 | pattern[2][0] = lSquare; 65 | reDraw(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/pieces/OPiece.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop.pieces; 39 | 40 | import com.homescreenarcade.blockdrop.Square; 41 | 42 | import android.content.Context; 43 | 44 | public class OPiece extends Piece4x4 { 45 | 46 | private Square oSquare; 47 | 48 | public OPiece(Context c) { 49 | super(c); 50 | oSquare = new Square(Piece.type_O,c); 51 | pattern[1][1] = oSquare; 52 | pattern[1][2] = oSquare; 53 | pattern[2][1] = oSquare; 54 | pattern[2][2] = oSquare; 55 | reDraw(); 56 | } 57 | 58 | @Override 59 | public void reset(Context c) { 60 | super.reset(c); 61 | pattern[1][1] = oSquare; 62 | pattern[1][2] = oSquare; 63 | pattern[2][1] = oSquare; 64 | pattern[2][2] = oSquare; 65 | reDraw(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/pieces/SPiece.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop.pieces; 39 | 40 | import com.homescreenarcade.blockdrop.Square; 41 | 42 | import android.content.Context; 43 | 44 | public class SPiece extends Piece3x3 { 45 | 46 | private Square sSquare; 47 | 48 | public SPiece(Context c) { 49 | super(c); 50 | sSquare = new Square(Piece.type_S,c); 51 | pattern[1][1] = sSquare; 52 | pattern[1][2] = sSquare; 53 | pattern[2][0] = sSquare; 54 | pattern[2][1] = sSquare; 55 | reDraw(); 56 | } 57 | 58 | @Override 59 | public void reset(Context c) { 60 | super.reset(c); 61 | pattern[1][1] = sSquare; 62 | pattern[1][2] = sSquare; 63 | pattern[2][0] = sSquare; 64 | pattern[2][1] = sSquare; 65 | reDraw(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/pieces/TPiece.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop.pieces; 39 | 40 | import com.homescreenarcade.blockdrop.Square; 41 | 42 | import android.content.Context; 43 | 44 | public class TPiece extends Piece3x3 { 45 | 46 | private Square tSquare; 47 | 48 | public TPiece(Context c) { 49 | super(c); 50 | tSquare = new Square(Piece.type_T,c); 51 | pattern[1][0] = tSquare; 52 | pattern[1][1] = tSquare; 53 | pattern[1][2] = tSquare; 54 | pattern[2][1] = tSquare; 55 | reDraw(); 56 | } 57 | 58 | @Override 59 | public void reset(Context c) { 60 | super.reset(c); 61 | pattern[1][0] = tSquare; 62 | pattern[1][1] = tSquare; 63 | pattern[1][2] = tSquare; 64 | pattern[2][1] = tSquare; 65 | reDraw(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/blockdrop/pieces/ZPiece.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Simon Willeke 3 | * contact: hamstercount@hotmail.com 4 | */ 5 | 6 | /* 7 | This file is part of Blockinger. 8 | 9 | Blockinger is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | Blockinger is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Blockinger. If not, see . 21 | 22 | Diese Datei ist Teil von Blockinger. 23 | 24 | Blockinger ist Freie Software: Sie k�nnen es unter den Bedingungen 25 | der GNU General Public License, wie von der Free Software Foundation, 26 | Version 3 der Lizenz oder (nach Ihrer Option) jeder sp�teren 27 | ver�ffentlichten Version, weiterverbreiten und/oder modifizieren. 28 | 29 | Blockinger wird in der Hoffnung, dass es n�tzlich sein wird, aber 30 | OHNE JEDE GEW�HELEISTUNG, bereitgestellt; sogar ohne die implizite 31 | Gew�hrleistung der MARKTF�HIGKEIT oder EIGNUNG F�R EINEN BESTIMMTEN ZWECK. 32 | Siehe die GNU General Public License f�r weitere Details. 33 | 34 | Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 35 | Programm erhalten haben. Wenn nicht, siehe . 36 | */ 37 | 38 | package com.homescreenarcade.blockdrop.pieces; 39 | 40 | import com.homescreenarcade.blockdrop.Square; 41 | 42 | import android.content.Context; 43 | 44 | public class ZPiece extends Piece3x3 { 45 | 46 | private Square zSquare; 47 | 48 | public ZPiece(Context c) { 49 | super(c); 50 | zSquare = new Square(Piece.type_Z,c); 51 | pattern[1][0] = zSquare; 52 | pattern[1][1] = zSquare; 53 | pattern[2][1] = zSquare; 54 | pattern[2][2] = zSquare; 55 | reDraw(); 56 | } 57 | 58 | @Override 59 | public void reset(Context c) { 60 | super.reset(c); 61 | pattern[1][0] = zSquare; 62 | pattern[1][1] = zSquare; 63 | pattern[2][1] = zSquare; 64 | pattern[2][2] = zSquare; 65 | reDraw(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/invaders/Coordinate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Space Invaders 3 | * 4 | * Copyright (C) 2012 Glow Worm Applications 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | package com.homescreenarcade.invaders; 22 | 23 | public class Coordinate { 24 | public int x, y; 25 | Coordinate(int argX, int argY){ 26 | x=argX;y=argY; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/invaders/GridObject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Space Invaders 3 | * 4 | * Copyright (C) 2012 Glow Worm Applications 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | package com.homescreenarcade.invaders; 22 | 23 | public class GridObject { 24 | protected boolean grid[][]; 25 | int x = 0; 26 | int y = 0; 27 | int i = 0, j = 0; 28 | GridObject(boolean[][]b){ 29 | this(b,0,0); 30 | } 31 | GridObject(boolean[][] b, int Xco, int Yco){ 32 | x=Xco; y=Yco; grid=b; 33 | } 34 | public void reset(){ 35 | i=0; j=0; 36 | } 37 | public int height(){ 38 | return grid.length; 39 | } 40 | public int width(){ 41 | return grid[0].length; 42 | } 43 | public Coordinate next(){ 44 | 45 | for(;i x-level){ 35 | return true; 36 | } 37 | } else { 38 | if(levelSize < x+level+ObjectManager.INVADER_WIDTH){ 39 | return true; 40 | } 41 | } 42 | return false; 43 | } 44 | void horizontalMove(int level, boolean right){ 45 | if(!right){ 46 | level*=-1; 47 | } 48 | x+=level; 49 | } 50 | void verticalMove(){ 51 | y+=ObjectManager.INVADER_HEIGHT; 52 | } 53 | 54 | @Override 55 | public void registerHit() { 56 | ObjectManager.incrementScore(10); 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/invaders/Shell.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Space Invaders 3 | * 4 | * Copyright (C) 2012 Glow Worm Applications 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | package com.homescreenarcade.invaders; 22 | 23 | class Shell { 24 | private int x, y, py; 25 | private boolean up; 26 | Shell(int X, int Y, boolean UP ){ 27 | x=X; y=Y;py=Y; up = UP; 28 | } 29 | 30 | boolean progress(int levelHeight ){ 31 | int move = 4; 32 | 33 | if( up ){ 34 | move *= -1; 35 | } 36 | py = y; 37 | y += move; 38 | 39 | if(y > levelHeight || y< 0){ 40 | return false; 41 | } 42 | return true; 43 | } 44 | Coordinate pos(){ 45 | return new Coordinate(x,y); 46 | } 47 | boolean collisionDetect( GridObject obj ){ 48 | 49 | Coordinate co; 50 | obj.reset(); 51 | 52 | while((co=obj.next())!=null){ 53 | if(co.x == x){ 54 | if( y >= py ){ 55 | if( co.y <= y && co.y >= py ){ 56 | obj.registerHit(); 57 | return true; 58 | } 59 | } else { 60 | if( co.y <= py && co.y >= y ){ 61 | obj.registerHit(); 62 | return true; 63 | } 64 | 65 | } 66 | } 67 | } 68 | 69 | return false; 70 | } 71 | public boolean isUp(){ 72 | return up; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/invaders/Shield.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Space Invaders 3 | * 4 | * Copyright (C) 2012 Glow Worm Applications 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | package com.homescreenarcade.invaders; 22 | 23 | public class Shield extends GridObject { 24 | 25 | Shield(boolean[][] b) { 26 | super(b); 27 | } 28 | Shield(boolean[][] b, int Xco, int Yco) { 29 | super(b, Xco, Yco); 30 | } 31 | public void collision(Shell s){ 32 | int shellX = s.pos().x; 33 | int index = shellX - x; 34 | if(index < 0 || index >= grid[0].length ){ 35 | return; 36 | } 37 | if(s.isUp()){ 38 | for(int i=grid.length-1;i>=0;i--){ 39 | if(grid[i][index]){ 40 | explode(i, index); 41 | return; 42 | } 43 | } 44 | } else { 45 | for(int i = 0;i< grid.length;i++){ 46 | if(grid[i][index]){ 47 | explode(i, index); 48 | return; 49 | } 50 | } 51 | } 52 | } 53 | 54 | private void explode(int i, int j){ 55 | if(i>grid.length-1 || 56 | i < 0 || 57 | j > grid[i].length-1 || 58 | j< 0){ 59 | return; 60 | } 61 | grid[i][j]=false; 62 | if(i != 0){ 63 | grid[i-1][j]=false; 64 | if(j !=0){ 65 | grid[i-1][j-1]=false; 66 | } 67 | if(j != grid[i].length-1){ 68 | grid[i-1][j+1]=false; 69 | } 70 | } 71 | if(i != grid.length-1){ 72 | grid[i+1][j]=false; 73 | if(j !=0){ 74 | grid[i+1][j-1]=false; 75 | } 76 | if(j != grid[i].length-1){ 77 | grid[i+1][j+1]=false; 78 | } 79 | } 80 | if(j !=0){ 81 | grid[i][j-1]=false; 82 | } 83 | if(j != grid[i].length-1){ 84 | grid[i][j+1]=false; 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/invaders/SpaceInvadersActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Space Invaders 3 | * 4 | * Copyright (C) 2012 Glow Worm Applications 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | package com.homescreenarcade.invaders; 22 | 23 | import java.util.Timer; 24 | import java.util.TimerTask; 25 | import android.app.Activity; 26 | import android.hardware.Sensor; 27 | import android.hardware.SensorEvent; 28 | import android.hardware.SensorEventListener; 29 | import android.hardware.SensorManager; 30 | import android.os.Bundle; 31 | import android.os.PowerManager; 32 | 33 | public class SpaceInvadersActivity extends Activity implements SensorEventListener { 34 | /** Called when the activity is first created. */ 35 | 36 | private InvaderView mView = null; 37 | 38 | private PowerManager mPowerManager; 39 | private SensorManager mSensorManager; 40 | // private WakeLock mWakeLock; 41 | private Sensor mAccelerometer; 42 | 43 | private Timer mUpdate; 44 | private InvaderTimer mEvent; 45 | private boolean mUseAccelerometer = false; 46 | private int mAccelerometerThreshold = 20; 47 | @Override 48 | public void onCreate(Bundle savedInstanceState) { 49 | super.onCreate(savedInstanceState); 50 | 51 | // Get an instance of the SensorManager 52 | mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 53 | 54 | 55 | // Get an instance of the PowerManager 56 | mPowerManager = (PowerManager) getSystemService(POWER_SERVICE); 57 | 58 | 59 | // Create a bright wake lock 60 | // mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, 61 | // getClass().getName()); 62 | 63 | 64 | 65 | 66 | mView = new InvaderView(getApplicationContext()); 67 | setContentView(mView); 68 | 69 | mUpdate = new Timer(); 70 | mEvent = new InvaderTimer(); 71 | mUpdate.schedule(mEvent, 0 ,80); 72 | 73 | mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 74 | 75 | mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_UI); 76 | } 77 | 78 | @Override 79 | protected void onResume() { 80 | super.onResume(); 81 | // mWakeLock.acquire(); 82 | if(mView!=null){ 83 | mView.updatePrefs(); 84 | } 85 | mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_UI); 86 | } 87 | 88 | @Override 89 | protected void onPause() { 90 | super.onPause(); 91 | // mWakeLock.release(); 92 | mSensorManager.unregisterListener(this); 93 | } 94 | 95 | 96 | class InvaderTimer extends TimerTask { 97 | @Override 98 | public void run() { 99 | runOnUiThread(new Runnable() { 100 | public void run() { 101 | mView.postInvalidate(); 102 | } 103 | }); 104 | } 105 | } 106 | 107 | @Override 108 | public void onAccuracyChanged(Sensor arg0, int arg1) { 109 | //Do Nothing 110 | 111 | } 112 | 113 | @Override 114 | public void onSensorChanged(SensorEvent event) { 115 | if(mUseAccelerometer){ 116 | accelerometerControl(event); 117 | return; 118 | } else { 119 | return; 120 | } 121 | } 122 | 123 | private void accelerometerControl(SensorEvent event) { 124 | float xSens; 125 | 126 | if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) 127 | return; 128 | 129 | xSens = event.values[1]; 130 | // if(xSens > mAccelerometerThreshold){ 131 | // mMove = true; 132 | // mMoveLeft = false; 133 | // mTouch = true; 134 | // return; 135 | // } 136 | // if(xSens < -mAccelerometerThreshold){ 137 | // mMove = true; 138 | // mTouch = true; 139 | // mMoveLeft = true; 140 | // return; 141 | // } 142 | // mMove = false; 143 | // if(mFire == false){ 144 | // mTouch = false; 145 | // } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/invaders/Spaceship.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Space Invaders 3 | * 4 | * Copyright (C) 2012 Glow Worm Applications 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | package com.homescreenarcade.invaders; 22 | 23 | public class Spaceship extends GridObject { 24 | 25 | public Spaceship(boolean[][] b) { 26 | super(b); 27 | } 28 | public Spaceship(boolean[][] b, int Xco, int Yco) { 29 | super(b, Xco, Yco); 30 | } 31 | public void advance(){ 32 | x-=3; 33 | } 34 | public boolean isValid(){ 35 | if(x + ObjectManager.SPACESHIP_WIDTH < 0){ 36 | return false; 37 | } 38 | return true; 39 | } 40 | 41 | @Override 42 | public void registerHit() { 43 | ObjectManager.incrementScore(100); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/invaders/Tank.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Space Invaders 3 | * 4 | * Copyright (C) 2012 Glow Worm Applications 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | package com.homescreenarcade.invaders; 22 | 23 | public class Tank extends GridObject { 24 | 25 | protected boolean mMoveable = true; 26 | protected int mLevelWidth; 27 | int mFireCount = 0; 28 | Tank(boolean[][] b) { 29 | super(b); 30 | 31 | } 32 | Tank(boolean[][] b,int Xco, int Yco, int Width) { 33 | super(b,Xco,Yco); 34 | mLevelWidth=Width; 35 | } 36 | public void horizontalMove( boolean right , int Width){ 37 | int move = 5; 38 | if(mMoveable){ 39 | if(!right){ 40 | move*=-1; 41 | } 42 | x+=move; 43 | 44 | if(x<0){ 45 | x=0; 46 | }else if(x + ObjectManager.TANK_WIDTH > Width ){ 47 | x= Width - ObjectManager.TANK_WIDTH; 48 | } 49 | } 50 | mMoveable=false; 51 | } 52 | public void allowNewMove(){ 53 | mMoveable=true; 54 | if(mFireCount > 0){mFireCount--;} 55 | } 56 | public Shell update(int xtouch, int ytouch){ 57 | 58 | if(xtouch < mLevelWidth/3){ 59 | horizontalMove(false,mLevelWidth); 60 | } else if(xtouch > mLevelWidth*2/3){ 61 | horizontalMove(true ,mLevelWidth); 62 | } else { 63 | if( mFireCount == 0 ){ 64 | mFireCount += 10; 65 | return new Shell(x + ObjectManager.TANK_WIDTH/2, 66 | y - 1 , true); 67 | } 68 | } 69 | return null; 70 | 71 | } 72 | 73 | public Shell update(boolean fire, boolean move, boolean left){ 74 | 75 | if(move){ 76 | if(left){ 77 | horizontalMove(false,mLevelWidth); 78 | } else { 79 | horizontalMove(true ,mLevelWidth); 80 | } 81 | } 82 | if(fire){ 83 | if( mFireCount == 0 ){ 84 | mFireCount += 10; 85 | return new Shell(x + ObjectManager.TANK_WIDTH/2, 86 | y - 1 , true); 87 | } 88 | } 89 | return null; 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/mazeman/GameActivity.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.mazeman; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.Context; 6 | import android.content.DialogInterface; 7 | import android.content.Intent; 8 | import android.hardware.Sensor; 9 | import android.hardware.SensorEvent; 10 | import android.hardware.SensorEventListener; 11 | import android.hardware.SensorManager; 12 | import android.os.Bundle; 13 | import android.view.Display; 14 | 15 | public class GameActivity extends Activity implements SensorEventListener{ 16 | final int RIGHT = 1, LEFT = 2, UP = 4, DOWN = 8; 17 | 18 | private com.homescreenarcade.mazeman.GameSurfaceView gameView; 19 | private SensorManager mySensorManager; 20 | private Sensor myAccelerometer; 21 | 22 | //change in x and y of pac-mon 23 | private float xAccel; 24 | private float yAccel; 25 | private com.homescreenarcade.mazeman.GameEngine gameEngine; 26 | private com.homescreenarcade.mazeman.SoundEngine soundEngine; 27 | 28 | /** Called when the activity is first created. */ 29 | @Override 30 | public void onCreate(Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | 33 | mySensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 34 | myAccelerometer = mySensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 35 | mySensorManager.registerListener(this, myAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); 36 | 37 | int level = getIntent().getIntExtra("level", 1); 38 | 39 | soundEngine = new com.homescreenarcade.mazeman.SoundEngine(this); 40 | gameEngine = new com.homescreenarcade.mazeman.GameEngine(this, soundEngine, level); 41 | 42 | Display display = getWindowManager().getDefaultDisplay(); 43 | int width = display.getWidth(); 44 | int height = display.getHeight(); 45 | gameView = new com.homescreenarcade.mazeman.GameSurfaceView(this, gameEngine, width, height); 46 | 47 | setContentView(gameView); 48 | 49 | 50 | } 51 | 52 | @Override 53 | protected void onPause() { 54 | // TODO Auto-generated method stub 55 | super.onPause(); 56 | gameEngine.pause(); 57 | gameView.pause(); 58 | 59 | } 60 | 61 | @Override 62 | protected void onResume() { 63 | // TODO Auto-generated method stub 64 | super.onResume(); 65 | gameEngine.resume(); 66 | gameView.resume(); 67 | } 68 | 69 | @Override 70 | protected void onDestroy() { 71 | // TODO Auto-generated method stub 72 | mySensorManager.unregisterListener(this); 73 | super.onDestroy(); 74 | //gameView.pause(); 75 | } 76 | 77 | 78 | @Override 79 | public void finish() { 80 | // TODO Auto-generated method stub 81 | 82 | Intent intent = new Intent(); 83 | 84 | intent.putExtra("level", gameEngine.level); 85 | intent.putExtra("status", gameEngine.status); 86 | 87 | setResult(RESULT_OK, intent); 88 | 89 | soundEngine.endMusic(); 90 | super.finish(); 91 | } 92 | 93 | 94 | @Override 95 | public void onBackPressed() { 96 | AlertDialog.Builder builder = new AlertDialog.Builder(this); 97 | builder.setMessage("Do you want to quit?").setCancelable(false) 98 | .setPositiveButton("Quit", new DialogInterface.OnClickListener() { 99 | public void onClick(DialogInterface dialog, int which) { 100 | GameActivity.this.finish(); 101 | } 102 | }) 103 | .setNegativeButton("Resume", new DialogInterface.OnClickListener() { 104 | public void onClick(DialogInterface dialog, int which) { 105 | dialog.cancel(); 106 | } 107 | }); 108 | AlertDialog alert = builder.create(); 109 | alert.show(); 110 | } 111 | 112 | public void onAccuracyChanged(Sensor arg0, int arg1) { 113 | // TODO Auto-generated method stub 114 | 115 | } 116 | 117 | //get values of accelerometer 118 | public void onSensorChanged(SensorEvent event) { 119 | 120 | try { 121 | Thread.sleep(16); 122 | } catch (InterruptedException e) { 123 | // TODO Auto-generated catch block 124 | e.printStackTrace(); 125 | } 126 | 127 | xAccel = event.values[0]; 128 | yAccel = event.values[1]; 129 | //float z = event.values[2]; 130 | 131 | if(yAccel < 2.8F ){ // tilt up 132 | gameEngine.setInputDir(UP); 133 | //gameView.setDir(1); 134 | } 135 | if(yAccel > 7.5F ){ // tilt down 136 | gameEngine.setInputDir(DOWN); 137 | //gameView.setDir(2); 138 | } 139 | if (xAccel < -1.8F ) { // tilt to 140 | // right 141 | gameEngine.setInputDir(RIGHT); 142 | //gameView.setDir(3); 143 | } 144 | if (xAccel > 1.8F ) { // tilt to 145 | // left 146 | gameEngine.setInputDir(LEFT); 147 | //gameView.setDir(4); 148 | } 149 | 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/mazeman/Monster.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.mazeman; 2 | 3 | public class Monster { 4 | 5 | private int x; 6 | private int y; 7 | private int dir; 8 | private int normalSpeed; 9 | 10 | private int state; // 0 = in cage, 1 = door step, 2 outside 11 | 12 | 13 | public Monster(){ 14 | x = 7 * 32; 15 | y = 9 * 32; 16 | dir = 8; 17 | normalSpeed = 2; 18 | state = 0; 19 | } 20 | 21 | // reset ghost when player die 22 | public void reset(){ 23 | x = 7 * 32; 24 | y = 9 * 32; 25 | dir = 8; 26 | } 27 | 28 | 29 | 30 | public int getX() { 31 | return x; 32 | } 33 | 34 | 35 | 36 | public void setX(int x) { 37 | this.x = x; 38 | } 39 | 40 | 41 | 42 | public int getY() { 43 | return y; 44 | } 45 | 46 | 47 | 48 | public void setY(int y) { 49 | this.y = y; 50 | } 51 | 52 | 53 | 54 | public int getDir() { 55 | return dir; 56 | } 57 | 58 | 59 | 60 | public int getNormalSpeed() { 61 | return normalSpeed; 62 | } 63 | 64 | 65 | 66 | public void setNormalSpeed(int normalSpeed) { 67 | this.normalSpeed = normalSpeed; 68 | } 69 | 70 | 71 | 72 | public void setDir(int newDirection) { 73 | this.dir = newDirection; 74 | 75 | } 76 | 77 | 78 | 79 | public int getState() { 80 | return state; 81 | } 82 | 83 | 84 | 85 | public void setState(int state) { 86 | this.state = state; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/mazeman/Pacmon.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.mazeman; 2 | 3 | public class Pacmon { 4 | 5 | public static final int UP = 4; 6 | public static final int DOWN = 8; 7 | public static final int RIGHT = 1; 8 | public static final int LEFT = 2; 9 | 10 | //position by grid 11 | private int pX; 12 | private int pY; 13 | 14 | private int pXOrigin; 15 | private int pYOrigin; 16 | 17 | private int pLives; 18 | private int pNormalSpeed; 19 | private int pPowerSpeed; 20 | 21 | private int dir; // direction of movement 0 = not moving 22 | 23 | public Pacmon (){ 24 | pX = pY = 32; 25 | pXOrigin = pYOrigin = 1; 26 | pLives = 2; 27 | pNormalSpeed = 2; 28 | pPowerSpeed = 4; 29 | dir = RIGHT; 30 | } 31 | 32 | public void reset(){ 33 | pX = pY = 32; 34 | pXOrigin = pYOrigin = 1; 35 | dir = RIGHT; 36 | } 37 | 38 | public int getpX() { 39 | return pX; 40 | } 41 | 42 | public int getpY() { 43 | return pY; 44 | } 45 | 46 | public int getpXOrigin() { 47 | return pXOrigin; 48 | } 49 | 50 | public int getpYOrigin() { 51 | return pYOrigin; 52 | } 53 | 54 | public int getpLives() { 55 | return pLives; 56 | } 57 | 58 | public int getpNormalSpeed() { 59 | return pNormalSpeed; 60 | } 61 | 62 | public int getpPowerSpeed() { 63 | return pPowerSpeed; 64 | } 65 | 66 | public int getDir() { 67 | return dir; 68 | } 69 | 70 | public void setDir(int dir){ 71 | this.dir = dir; 72 | } 73 | 74 | public void setpX(int pX) { 75 | this.pX = pX; 76 | } 77 | 78 | public void setpY(int pY) { 79 | this.pY = pY; 80 | } 81 | 82 | public void setpXOrigin(int pXOrigin) { 83 | this.pXOrigin = pXOrigin; 84 | } 85 | 86 | public void setpYOrigin(int pYOrigin) { 87 | this.pYOrigin = pYOrigin; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/mazeman/SoundEngine.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.mazeman; 2 | 3 | import java.util.HashMap; 4 | 5 | 6 | import android.content.Context; 7 | import android.media.AudioManager; 8 | import android.media.SoundPool; 9 | 10 | import com.homescreenarcade.R; 11 | 12 | 13 | // Sound Manager, provide method to play sounds and music 14 | public class SoundEngine { 15 | private static final int EATFOOD = 1, EATGHOST = 2, DIE = 3, READY = 4, 16 | GAMEOVER = 5; 17 | //private static final int EATCHERRY = 6; 18 | 19 | private SoundPool sounds; 20 | private HashMap soundsMap; 21 | // private MediaPlayer music; 22 | private Context context; 23 | private AudioManager mgr; 24 | 25 | public SoundEngine(Context context) { 26 | this.context = context; 27 | 28 | sounds = new SoundPool(5, AudioManager.STREAM_RING, 0); 29 | 30 | soundsMap = new HashMap(); 31 | soundsMap.put(EATFOOD, sounds.load(context, R.raw.pacmon_waka_waka, 1)); 32 | soundsMap.put(EATGHOST, sounds.load(context, R.raw.pacmon_eating_ghost, 1)); 33 | soundsMap.put(DIE, sounds.load(context, R.raw.pacmon_dies, 1)); 34 | soundsMap.put(READY, sounds.load(context, R.raw.pacmon_opening_song,1)); 35 | soundsMap.put(GAMEOVER, sounds.load(context, R.raw.pacmon_opening_song, 1)); 36 | //soundsMap.put(EATCHERRY, sounds.load(context, R.raw.pacmon_eating_cherry, 1)); 37 | 38 | AudioManager mgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 39 | 40 | // the music that is played at the beginning 41 | // music = MediaPlayer.create(context, R.raw.gameplaymusic); 42 | // music.setLooping(true); 43 | } 44 | 45 | //play the sound depends on the input request 46 | public void play(int sound) { 47 | AudioManager mgr = (AudioManager) context 48 | .getSystemService(Context.AUDIO_SERVICE); 49 | float streamVolumeCurrent = mgr 50 | .getStreamVolume(AudioManager.STREAM_RING); 51 | float streamVolumeMax = mgr 52 | .getStreamMaxVolume(AudioManager.STREAM_RING); 53 | float volume = streamVolumeCurrent / streamVolumeMax; 54 | 55 | sounds.play(soundsMap.get(sound), volume, volume, 1, 0, 1.f); 56 | } 57 | 58 | //when pacmon eats food 59 | public void playEatFood(){ 60 | play(EATFOOD); 61 | } 62 | 63 | //when pacmon eat ghost in power mode 64 | public void playEatGhost(){ 65 | play(EATGHOST); 66 | } 67 | 68 | public void playEatCherry(){ 69 | //play(EATCHERRY); 70 | } 71 | 72 | //when pacmon die 73 | public void playDie(){ 74 | play(DIE); 75 | } 76 | 77 | public void playMusic(){ 78 | // music.start(); 79 | } 80 | 81 | public void stopMusic(){ 82 | // music.pause(); 83 | } 84 | 85 | public void endMusic(){ 86 | sounds.release(); 87 | 88 | // music.release(); 89 | } 90 | 91 | public void playReady(){ 92 | play(READY); 93 | } 94 | 95 | public void playWin(){ 96 | 97 | } 98 | 99 | public void playGameOver(){ 100 | play(GAMEOVER); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/AudioPlayer.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | public interface AudioPlayer { 4 | 5 | void playStart(); 6 | 7 | void playBall(); 8 | 9 | void playFlipper(); 10 | 11 | void playScore(); 12 | 13 | void playMessage(); 14 | 15 | void playRollover(); 16 | 17 | public static class NoOpPlayer implements AudioPlayer { 18 | private static final NoOpPlayer INSTANCE = new NoOpPlayer(); 19 | 20 | public static NoOpPlayer getInstance() { 21 | return INSTANCE; 22 | } 23 | 24 | private NoOpPlayer() {} 25 | 26 | @Override public void playStart() {} 27 | @Override public void playBall() {} 28 | @Override public void playFlipper() {} 29 | @Override public void playScore() {} 30 | @Override public void playMessage() {} 31 | @Override public void playRollover() {} 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/Ball.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | import com.badlogic.gdx.math.MathUtils; 4 | import com.badlogic.gdx.math.Vector2; 5 | import com.badlogic.gdx.physics.box2d.Body; 6 | import com.badlogic.gdx.physics.box2d.CircleShape; 7 | import com.badlogic.gdx.physics.box2d.World; 8 | import com.homescreenarcade.pinball.elements.Box2DFactory; 9 | 10 | /** 11 | * Represents a ball in play. Not part of the elements package because balls are created and 12 | * removed at "runtime" rather than being part of the table definition. 13 | */ 14 | public class Ball { 15 | private final Body body; 16 | private Color primaryColor; 17 | private Color secondaryColor; 18 | 19 | private Ball(Body body, Color primaryColor, Color secondaryColor) { 20 | this.body = body; 21 | this.primaryColor = primaryColor; 22 | this.secondaryColor = secondaryColor; 23 | } 24 | 25 | public static Ball create(World world, float x, float y, float radius, 26 | Color primaryColor, Color secondaryColor) { 27 | Body ballBody = Box2DFactory.createCircle(world, x, y, radius, false); 28 | ballBody.setBullet(true); 29 | // Default is radius of 0.5, if different we want the mass to be the same (could be 30 | // configurable if needed), so adjust density proportional to square of the radius. 31 | if (radius != 0.5f) { 32 | ballBody.getFixtureList().get(0).setDensity((0.5f*0.5f) / (radius*radius)); 33 | ballBody.resetMassData(); 34 | } 35 | return new Ball(ballBody, primaryColor, secondaryColor); 36 | } 37 | 38 | public void draw(IFieldRenderer renderer) { 39 | CircleShape shape = (CircleShape)body.getFixtureList().get(0).getShape(); 40 | Vector2 center = body.getPosition(); 41 | float radius = shape.getRadius(); 42 | renderer.fillCircle(center.x, center.y, radius, primaryColor); 43 | 44 | // Draw a smaller circle to show the ball's rotation. 45 | float angle = body.getAngle(); 46 | float smallCenterX = center.x + (radius / 2) * MathUtils.cos(angle); 47 | float smallCenterY = center.y + (radius / 2) * MathUtils.sin(angle); 48 | renderer.fillCircle(smallCenterX, smallCenterY, radius / 4, secondaryColor); 49 | } 50 | 51 | public Vector2 getPosition() { 52 | return body.getPosition(); 53 | } 54 | 55 | public Vector2 getLinearVelocity() { 56 | return body.getLinearVelocity(); 57 | } 58 | 59 | public void applyLinearImpulse(Vector2 impulse) { 60 | body.applyLinearImpulse(impulse, body.getWorldCenter(), true); 61 | } 62 | 63 | public Body getBody() { 64 | return body; 65 | } 66 | 67 | public Color getPrimaryColor() { 68 | return primaryColor; 69 | } 70 | public void setPrimaryColor(Color primaryColor) { 71 | this.primaryColor = primaryColor; 72 | } 73 | 74 | public Color getSecondaryColor() { 75 | return secondaryColor; 76 | } 77 | public void setSecondaryColor(Color secondaryColor) { 78 | this.secondaryColor = secondaryColor; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/BaseFieldDelegate.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | import java.util.List; 4 | 5 | import com.badlogic.gdx.physics.box2d.Body; 6 | import com.homescreenarcade.pinball.elements.DropTargetGroupElement; 7 | import com.homescreenarcade.pinball.elements.FieldElement; 8 | import com.homescreenarcade.pinball.elements.FlipperElement; 9 | import com.homescreenarcade.pinball.elements.RolloverGroupElement; 10 | import com.homescreenarcade.pinball.elements.SensorElement; 11 | 12 | 13 | /** 14 | * This class implements the Field.Delegate interface and does nothing for each of the interface 15 | * methods. Real delegates can subclass this class to avoid having to create empty implementations 16 | * for events they don't care about. If a field definition doesn't specify a delegate class, an 17 | * instance of this class will be used as a placeholder delegate. 18 | */ 19 | public class BaseFieldDelegate implements Field.Delegate { 20 | 21 | @Override public void allDropTargetsInGroupHit(Field field, DropTargetGroupElement targetGroup) {} 22 | 23 | @Override public void allRolloversInGroupActivated(Field field, RolloverGroupElement rolloverGroup) {} 24 | 25 | @Override public void flippersActivated(Field field, List flippers) {} 26 | 27 | @Override public void processCollision(Field field, FieldElement element, Body hitBody, Ball ball) {} 28 | 29 | @Override public void gameStarted(Field field) {} 30 | 31 | @Override public void ballLost(Field field) {} 32 | 33 | @Override public void gameEnded(Field field) {} 34 | 35 | @Override public void tick(Field field, long nanos) {} 36 | 37 | @Override public void ballInSensorRange(Field field, SensorElement sensor, Ball ball) {} 38 | 39 | @Override public boolean isFieldActive(Field field) { 40 | return false; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/CanvasFieldView.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.support.annotation.NonNull; 7 | import android.util.AttributeSet; 8 | import android.view.KeyEvent; 9 | import android.view.MotionEvent; 10 | import android.view.SurfaceView; 11 | 12 | import com.homescreenarcade.pinball.elements.FieldElement; 13 | 14 | /** 15 | * Draws the game field. Field elements are defined in world coordinates, which this view 16 | * transforms to screen/pixel coordinates. 17 | */ 18 | public class CanvasFieldView extends SurfaceView implements IFieldRenderer { 19 | 20 | public CanvasFieldView(Context context, AttributeSet attrs) { 21 | super(context, attrs); 22 | setFocusable(true); 23 | } 24 | 25 | FieldViewManager manager; 26 | 27 | Paint paint = new Paint(); {paint.setAntiAlias(true);} 28 | Paint textPaint = new Paint(); {textPaint.setARGB(255, 255, 255, 255);} 29 | Canvas canvas; 30 | 31 | @Override 32 | public void setManager(FieldViewManager value) { 33 | this.manager = value; 34 | } 35 | 36 | 37 | /** 38 | * Called when the view is touched. Activates flippers, starts a new game if one is not in 39 | * progress, and launches a ball if one is not in play. 40 | */ 41 | @Override public boolean onTouchEvent(MotionEvent event) { 42 | return manager.handleTouchEvent(event); 43 | } 44 | 45 | @Override public boolean onKeyDown(int keyCode, KeyEvent event) { 46 | return manager.handleKeyDown(keyCode, event); 47 | } 48 | 49 | @Override public boolean onKeyUp(int keyCode, KeyEvent event) { 50 | return manager.handleKeyUp(keyCode, event); 51 | } 52 | 53 | /** 54 | * Main draw method, called from FieldDriver's game thread. Calls each FieldElement's draw() 55 | * method passing itself as the IFieldRenderer implementation. 56 | */ 57 | @Override public void doDraw() { 58 | Canvas c = this.getHolder().lockCanvas(); 59 | if (c != null) { 60 | doDraw(c); 61 | this.getHolder().unlockCanvasAndPost(c); 62 | } 63 | } 64 | public void doDraw(@NonNull Canvas c) { 65 | c.drawARGB(255, 0, 0, 0); 66 | paint.setStrokeWidth(manager.highQuality ? 3 : 0); 67 | // call draw() on each FieldElement, draw balls separately 68 | this.canvas = c; 69 | 70 | for(FieldElement element : manager.getField().getFieldElementsArray()) { 71 | element.draw(this); 72 | } 73 | 74 | manager.getField().drawBalls(this); 75 | 76 | if (manager.showFPS()) { 77 | if (manager.getDebugMessage()!=null) { 78 | c.drawText(""+manager.getDebugMessage(), 10, 10, textPaint); 79 | } 80 | } 81 | } 82 | 83 | 84 | // Implementation of IFieldRenderer drawing methods that FieldElement classes can call. 85 | // Assumes cacheScaleAndOffsets has been called. 86 | @Override public void drawLine(float x1, float y1, float x2, float y2, Color color) { 87 | this.paint.setARGB(color.alpha, color.red, color.green, color.blue); 88 | this.canvas.drawLine(manager.world2pixelX(x1), manager.world2pixelY(y1), 89 | manager.world2pixelX(x2), manager.world2pixelY(y2), this.paint); 90 | } 91 | 92 | @Override public void fillCircle(float cx, float cy, float radius, Color color) { 93 | drawCircle(cx, cy, radius, color, Paint.Style.FILL); 94 | } 95 | 96 | @Override public void frameCircle(float cx, float cy, float radius, Color color) { 97 | drawCircle(cx, cy, radius, color, Paint.Style.STROKE); 98 | } 99 | 100 | void drawCircle(float cx, float cy, float radius, Color color, Paint.Style style) { 101 | this.paint.setARGB(color.alpha, color.red, color.green, color.blue); 102 | this.paint.setStyle(style); 103 | float rad = radius * manager.getCachedScale(); 104 | this.canvas.drawCircle(manager.world2pixelX(cx), manager.world2pixelY(cy), rad, paint); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/Clock.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | public interface Clock { 4 | 5 | long currentTimeMillis(); 6 | 7 | long nanoTime(); 8 | 9 | public static class SystemClock implements Clock { 10 | private static SystemClock INSTANCE = new SystemClock(); 11 | 12 | public static SystemClock getInstance() { 13 | return INSTANCE; 14 | } 15 | 16 | private SystemClock() {} 17 | 18 | @Override public long currentTimeMillis() { 19 | return System.currentTimeMillis(); 20 | } 21 | 22 | @Override public long nanoTime() { 23 | return System.nanoTime(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/Color.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * An immutable RGB color. 7 | */ 8 | // TODO: cache instances. 9 | public class Color { 10 | public final int red, green, blue, alpha; 11 | private Color inverse; 12 | 13 | private Color(int r, int g, int b, int a, Color inverse) { 14 | this.red = r; 15 | this.green = g; 16 | this.blue = b; 17 | this.alpha = a; 18 | if (inverse == null) { 19 | inverse = new Color(255 - r, 255 - g, 255 - b, a, this); 20 | } 21 | this.inverse = inverse; 22 | } 23 | 24 | public static Color fromRGB(int r, int g, int b) { 25 | return new Color(r, g, b, 255, null); 26 | } 27 | 28 | public static Color fromRGB(int r, int g, int b, int a) { 29 | return new Color(r, g, b, a, null); 30 | } 31 | 32 | public static Color fromList(List rgb) { 33 | if (rgb.size() == 3) { 34 | return fromRGB(rgb.get(0).intValue(), rgb.get(1).intValue(), rgb.get(2).intValue()); 35 | } 36 | else if (rgb.size() == 4) { 37 | return fromRGB(rgb.get(0).intValue(), rgb.get(1).intValue(), 38 | rgb.get(2).intValue(), rgb.get(3).intValue()); 39 | } 40 | else { 41 | throw new IllegalArgumentException("Invalid color size: " + rgb.size()); 42 | } 43 | } 44 | 45 | public Color inverted() { 46 | return inverse; 47 | } 48 | 49 | public Color blendedWith(Color other, double fraction) { 50 | if (fraction < 0) fraction = 0; 51 | if (fraction > 1) fraction = 1; 52 | return fromRGB( 53 | (int) (this.red + (other.red - this.red) * fraction), 54 | (int) (this.green + (other.green - this.green) * fraction), 55 | (int) (this.blue + (other.blue - this.blue) * fraction), 56 | (int) (this.alpha + (other.alpha - this.alpha) * fraction)); 57 | } 58 | 59 | @Override public boolean equals(Object obj) { 60 | if (obj instanceof Color) { 61 | Color other = (Color)obj; 62 | return (red==other.red && green==other.green && blue==other.blue && alpha==other.alpha); 63 | } 64 | return false; 65 | } 66 | 67 | @Override public int hashCode() { 68 | return (red<<24) | (green<<16) | (blue<<8) | alpha; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/FieldDriver.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | import com.homescreenarcade.pinball.util.FrameRateManager; 4 | 5 | /** 6 | * Class to manage the game thread which updates the game's internal state and draws to the 7 | * FieldView. Controls the frame rate and attempts to keep it as consistent as possible. Because 8 | * this class manipulates the Field object in a separate thread, all access to the Field from the 9 | * game thread and main thread must be synchronized. 10 | */ 11 | public class FieldDriver { 12 | 13 | FieldViewManager fieldViewManager; 14 | Field field; 15 | 16 | boolean running; 17 | Thread gameThread; 18 | boolean canDraw = false; 19 | 20 | FrameRateManager frameRateManager = new FrameRateManager( 21 | new double[] {60, 50, 45, 40, 30}, 22 | new double[] {57, 48, 43, 38}); 23 | double averageFPS; 24 | 25 | // Sleep this long when field.hasActiveElements() is false. 26 | static long INACTIVE_FRAME_MSECS = 250; 27 | 28 | public void setFieldViewManager(FieldViewManager value) { 29 | this.fieldViewManager = value; 30 | } 31 | 32 | public void setField(Field value) { 33 | this.field = value; 34 | } 35 | 36 | /** Starts the game thread running. Does not actually start a new game. */ 37 | public void start() { 38 | running = true; 39 | gameThread = new Thread() { 40 | @Override 41 | public void run() { 42 | threadMain(); 43 | } 44 | }; 45 | gameThread.start(); 46 | } 47 | 48 | /** Stops the game thread, which will pause updates to the game state and view redraws. */ 49 | public void stop() { 50 | running = false; 51 | if (gameThread != null) 52 | try { 53 | gameThread.join(); 54 | } 55 | catch(InterruptedException ex) {} 56 | } 57 | 58 | 59 | /** 60 | * Main loop for the game thread. Repeatedly calls field.tick to advance the game simulation, 61 | * redraws the field, and sleeps until it's time for the next frame. Dynamically adjusts sleep 62 | * times in an attempt to maintain a consistent frame rate. 63 | */ 64 | void threadMain() { 65 | while (running) { 66 | frameRateManager.frameStarted(); 67 | boolean fieldActive = true; 68 | if (field!=null && fieldViewManager.canDraw()) { 69 | try { 70 | synchronized(field) { 71 | long nanosPerFrame = 72 | (long)(1000000000L / frameRateManager.targetFramesPerSecond()); 73 | long fieldTickNanos = (long)(nanosPerFrame*field.getTargetTimeRatio()); 74 | // If field isn't doing anything, sleep for a long time. 75 | fieldActive = field.hasActiveElements(); 76 | if (!fieldActive) { 77 | fieldTickNanos = 78 | (long)(INACTIVE_FRAME_MSECS*1000000*field.getTargetTimeRatio()); 79 | } 80 | field.tick(fieldTickNanos * 3, 4); 81 | } 82 | drawField(); 83 | } 84 | catch(Exception ex) { 85 | ex.printStackTrace(); 86 | } 87 | } 88 | 89 | // If field is inactive, clear start time history and bail. 90 | if (!fieldActive) { 91 | frameRateManager.clearTimestamps(); 92 | setAverageFPS(0); 93 | try { 94 | Thread.sleep(INACTIVE_FRAME_MSECS); 95 | } 96 | catch(InterruptedException ignored) {} 97 | continue; 98 | } 99 | 100 | frameRateManager.sleepUntilNextFrame(); 101 | 102 | // For debugging, show frames per second and other info. 103 | if (frameRateManager.getTotalFrames() % 100 == 0) { 104 | fieldViewManager.setDebugMessage(frameRateManager.fpsDebugInfo()); 105 | setAverageFPS(frameRateManager.currentFramesPerSecond()); 106 | } 107 | } 108 | } 109 | 110 | /** Calls FieldViewManager.doDraw to render the game field to the display. */ 111 | void drawField() { 112 | fieldViewManager.draw(); 113 | } 114 | 115 | /** 116 | * Resets the frame rate and forgets any locked rate, called when rendering quality is changed. 117 | */ 118 | public void resetFrameRate() { 119 | frameRateManager.resetFrameRate(); 120 | } 121 | 122 | public double getAverageFPS() { 123 | return averageFPS; 124 | } 125 | public void setAverageFPS(double value) { 126 | averageFPS = value; 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/GameMessage.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | /** Simple class to hold a message displayed in the ScoreView above the game field. 4 | */ 5 | 6 | public class GameMessage { 7 | public String text; 8 | public long duration; 9 | public long creationTime; 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/GameState.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | import android.content.Intent; 4 | import android.support.v4.content.LocalBroadcastManager; 5 | 6 | import com.homescreenarcade.ArcadeCommon; 7 | 8 | public class GameState { 9 | 10 | // Defines how score multiplier is affected when ball is lost. 11 | public static enum MultiplierBehavior { 12 | REMOVE, // Reset to 1. 13 | HOLD, // Don't change. 14 | ROUND_HALF_DOWN, // Reduce by half and round down, the default. 15 | } 16 | 17 | boolean gameInProgress = false; 18 | private boolean paused = true; 19 | 20 | int ballNumber; 21 | int extraBalls; 22 | int totalBalls = 3; 23 | boolean unlimitedBalls; 24 | 25 | long score; 26 | double scoreMultiplier; 27 | MultiplierBehavior multiplierBehavior; 28 | 29 | LocalBroadcastManager statusMgr; 30 | 31 | public void startNewGame() { 32 | score = 0; 33 | ballNumber = 1; 34 | scoreMultiplier = 1; 35 | multiplierBehavior = MultiplierBehavior.ROUND_HALF_DOWN; 36 | 37 | gameInProgress = true; 38 | paused = false; 39 | 40 | Intent scoreIntent = new Intent(ArcadeCommon.ACTION_STATUS) 41 | .putExtra(ArcadeCommon.STATUS_RESET_SCORE, true) 42 | .putExtra(ArcadeCommon.STATUS_LIVES, totalBalls - ballNumber); 43 | statusMgr.sendBroadcast(scoreIntent); 44 | } 45 | 46 | public void doNextBall() { 47 | switch (multiplierBehavior) { 48 | case REMOVE: 49 | scoreMultiplier = 1; 50 | break; 51 | case HOLD: 52 | break; 53 | case ROUND_HALF_DOWN: 54 | scoreMultiplier = Math.max(1, Math.floor(scoreMultiplier/2)); 55 | break; 56 | } 57 | 58 | if (extraBalls>0) { 59 | --extraBalls; 60 | } 61 | else if (unlimitedBalls || ballNumber < totalBalls) { 62 | ++ballNumber; 63 | } 64 | else { 65 | gameInProgress = false; 66 | } 67 | 68 | if (statusMgr != null) { 69 | Intent scoreIntent = new Intent(ArcadeCommon.ACTION_STATUS) 70 | .putExtra(ArcadeCommon.STATUS_LIVES, totalBalls - ballNumber); 71 | statusMgr.sendBroadcast(scoreIntent); 72 | } 73 | } 74 | 75 | public void addScore(long points) { 76 | score += points * scoreMultiplier; 77 | 78 | if (statusMgr != null) { 79 | Intent scoreIntent = new Intent(ArcadeCommon.ACTION_STATUS) 80 | .putExtra(ArcadeCommon.STATUS_INCREMENT_SCORE, (int) (points * scoreMultiplier)); 81 | statusMgr.sendBroadcast(scoreIntent); 82 | } 83 | } 84 | 85 | public void addExtraBall() { 86 | ++extraBalls; 87 | } 88 | 89 | public void incrementScoreMultiplier() { 90 | scoreMultiplier += 1; 91 | } 92 | 93 | public boolean isGameInProgress() { 94 | return gameInProgress; 95 | } 96 | public void setGameInProgress(boolean value) { 97 | gameInProgress = value; 98 | } 99 | 100 | public boolean isPaused() { 101 | return paused; 102 | } 103 | public void setPaused(boolean value) { 104 | paused = value; 105 | } 106 | 107 | public int getBallNumber() { 108 | return ballNumber; 109 | } 110 | public void setBallNumber(int ballNumber) { 111 | this.ballNumber = ballNumber; 112 | } 113 | 114 | public int getExtraBalls() { 115 | return extraBalls; 116 | } 117 | public void setExtraBalls(int extraBalls) { 118 | this.extraBalls = extraBalls; 119 | } 120 | 121 | public int getTotalBalls() { 122 | return totalBalls; 123 | } 124 | public void setTotalBalls(int totalBalls) { 125 | this.totalBalls = totalBalls; 126 | } 127 | 128 | public boolean hasUnlimitedBalls() { 129 | return unlimitedBalls; 130 | } 131 | public void setUnlimitedBalls(boolean unlimited) { 132 | this.unlimitedBalls = unlimited; 133 | } 134 | 135 | public long getScore() { 136 | return score; 137 | } 138 | public void setScore(long score) { 139 | this.score = score; 140 | } 141 | 142 | public double getScoreMultiplier() { 143 | return scoreMultiplier; 144 | } 145 | public void setScoreMultiplier(double scoreMultiplier) { 146 | this.scoreMultiplier = scoreMultiplier; 147 | } 148 | 149 | public MultiplierBehavior getMultiplierBehavior() { 150 | return multiplierBehavior; 151 | } 152 | public void setMultiplierBehavior(MultiplierBehavior behavior) { 153 | multiplierBehavior = behavior; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/IFieldRenderer.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | /** 4 | * This interface defines methods that draw graphical elements such as lines as circles to display 5 | * the field. An implementation of this interface is passed to FieldElement objects so they can draw 6 | * themselves without depending directly on Android UI classes. 7 | */ 8 | 9 | public interface IFieldRenderer { 10 | 11 | public void setManager(FieldViewManager manager); 12 | 13 | public void drawLine(float x1, float y1, float x2, float y2, Color color); 14 | 15 | public void fillCircle(float cx, float cy, float radius, Color color); 16 | 17 | public void frameCircle(float cx, float cy, float radius, Color color); 18 | 19 | public void doDraw(); 20 | 21 | public int getWidth(); 22 | 23 | public int getHeight(); 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/OrientationListener.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | import android.content.Context; 4 | import android.hardware.Sensor; 5 | import android.hardware.SensorEvent; 6 | import android.hardware.SensorEventListener; 7 | import android.hardware.SensorManager; 8 | 9 | /** 10 | * Class which listens for orientation change events and delivers callback events with orientation 11 | * values. Getting orientation values requires reading gravitational and magnetic field values and 12 | * calling a bunch of SensorManager methods with rotation matrices; this class handles all of that 13 | * and just provides a callback method with azimuth, pitch, and roll values. 14 | */ 15 | 16 | public class OrientationListener implements SensorEventListener { 17 | 18 | public static interface Delegate { 19 | /** Callback method for orientation updates. All values are in radians. 20 | * @param azimuth rotation around Z axis. 0=north, pi/2=east. 21 | * @param pitch rotation around X axis. 0=flat, negative=titled up, positive=tilted down. 22 | * @param roll rotation around Y axis. 0=flat, negative=tilted left, positive=tilted right. 23 | */ 24 | public void receivedOrientationValues(float azimuth, float pitch, float roll); 25 | } 26 | 27 | Context context; 28 | int rate; 29 | Delegate delegate; 30 | SensorManager sensorManager; 31 | 32 | /** 33 | * Creates an OrientationListener with the given rate and callback delegate. Does not start 34 | * listening for sensor events until start() is called. 35 | * @param context Context object, typically either an Activity or getContext() from a View 36 | * @param rate constant from SensorManager, e.g. SensorManager.SENSOR_DELAY_GAME 37 | * @param delegate callback object implementing the Delegate interface method. 38 | */ 39 | public OrientationListener(Context context, int rate, Delegate delegate) { 40 | this.context = context; 41 | this.rate = rate; 42 | this.delegate = delegate; 43 | sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); 44 | } 45 | 46 | /** Starts listening for sensor events and making callbacks to the delegate. */ 47 | public void start() { 48 | sensorManager.registerListener(this, 49 | sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), rate); 50 | sensorManager.registerListener(this, 51 | sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), rate); 52 | } 53 | 54 | /** Stops listening for sensor events and making callbacks to the delegate. */ 55 | public void stop() { 56 | sensorManager.unregisterListener(this); 57 | } 58 | 59 | 60 | // Values used to compute orientation based on gravitational and magnetic fields. 61 | float[] R = new float[16]; 62 | float[] I = new float[16]; 63 | float[] mags = null; 64 | float[] accels = null; 65 | 66 | float[] orientationValues = {0f, 0f, 0f}; 67 | 68 | /** 69 | * SensorEventListener method called when sensor values are updated. Reads gravitational and 70 | * magnetic field information, and when both are available computes the orientation values 71 | * and calls the delegate with them. 72 | */ 73 | @Override public void onSensorChanged(SensorEvent event) { 74 | switch(event.sensor.getType()) { 75 | case Sensor.TYPE_MAGNETIC_FIELD: 76 | mags = event.values.clone(); 77 | break; 78 | case Sensor.TYPE_ACCELEROMETER: 79 | accels = event.values.clone(); 80 | break; 81 | } 82 | 83 | if (mags!=null && accels!=null) { 84 | SensorManager.getRotationMatrix(R, I, accels, mags); 85 | SensorManager.getOrientation(R, orientationValues); 86 | delegate.receivedOrientationValues( 87 | orientationValues[0], orientationValues[1], orientationValues[2]); 88 | } 89 | } 90 | 91 | @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { 92 | // Ignored SensorListener method. 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/Point.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * An immutable 2D point. 7 | */ 8 | public class Point { 9 | public final float x, y; 10 | 11 | private Point(float x, float y) { 12 | this.x = x; 13 | this.y = y; 14 | } 15 | 16 | public static Point fromXY(float x, float y) { 17 | return new Point(x, y); 18 | } 19 | 20 | public static Point fromList(List xyList) { 21 | return fromXY(xyList.get(0).floatValue(), xyList.get(1).floatValue()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/elements/Box2DFactory.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball.elements; 2 | 3 | import com.badlogic.gdx.math.Vector2; 4 | import com.badlogic.gdx.physics.box2d.Body; 5 | import com.badlogic.gdx.physics.box2d.BodyDef; 6 | import com.badlogic.gdx.physics.box2d.CircleShape; 7 | import com.badlogic.gdx.physics.box2d.FixtureDef; 8 | import com.badlogic.gdx.physics.box2d.PolygonShape; 9 | import com.badlogic.gdx.physics.box2d.World; 10 | 11 | /** 12 | * Methods to create Box2D shapes. 13 | */ 14 | 15 | public class Box2DFactory { 16 | 17 | /** Creates a circle object with the given position and radius. Resitution defaults to 0.6. */ 18 | public static Body createCircle(World world, float x, float y, float radius, boolean isStatic) { 19 | CircleShape sd = new CircleShape(); 20 | sd.setRadius(radius); 21 | 22 | FixtureDef fdef = new FixtureDef(); 23 | fdef.shape = sd; 24 | fdef.density = 1.0f; 25 | fdef.friction = 0.3f; 26 | fdef.restitution = 0.6f; 27 | 28 | BodyDef bd = new BodyDef(); 29 | bd.allowSleep = true; 30 | bd.position.set(x, y); 31 | Body body = world.createBody(bd); 32 | body.createFixture(fdef); 33 | if (isStatic) { 34 | body.setType(BodyDef.BodyType.StaticBody); 35 | } 36 | else { 37 | body.setType(BodyDef.BodyType.DynamicBody); 38 | } 39 | return body; 40 | } 41 | 42 | /** 43 | * Creates a wall by constructing a rectangle whose corners are (xmin,ymin) and (xmax,ymax), 44 | * and rotating the box counterclockwise through the given angle. Restitution defaults to 0. 45 | */ 46 | public static Body createWall(World world, float xmin, float ymin, float xmax, float ymax, float angle) { 47 | return createWall(world, xmin, ymin, xmax, ymax, angle, 0f); 48 | } 49 | 50 | /** 51 | * Creates a wall by constructing a rectangle whose corners are (xmin,ymin) and (xmax,ymax), 52 | * and rotating the box counterclockwise through the given angle, with specified restitution. 53 | */ 54 | public static Body createWall(World world, float xmin, float ymin, float xmax, float ymax, 55 | float angle, float restitution) { 56 | float cx = (xmin + xmax) / 2; 57 | float cy = (ymin + ymax) / 2; 58 | float hx = Math.abs((xmax - xmin) / 2); 59 | float hy = Math.abs((ymax - ymin) / 2); 60 | PolygonShape wallshape = new PolygonShape(); 61 | // Don't set the angle here; instead call setTransform on the body below. This allows future 62 | // calls to setTransform to adjust the rotation as expected. 63 | wallshape.setAsBox(hx, hy, new Vector2(0f, 0f), 0f); 64 | 65 | FixtureDef fdef = new FixtureDef(); 66 | fdef.shape = wallshape; 67 | fdef.density = 1.0f; 68 | if (restitution>0) fdef.restitution = restitution; 69 | 70 | BodyDef bd = new BodyDef(); 71 | bd.position.set(cx, cy); 72 | Body wall = world.createBody(bd); 73 | wall.createFixture(fdef); 74 | wall.setType(BodyDef.BodyType.StaticBody); 75 | wall.setTransform(cx, cy, angle); 76 | return wall; 77 | } 78 | 79 | /** Creates a segment-like thin wall with 0.05 thickness going from (x1,y1) to (x2,y2) */ 80 | public static Body createThinWall(World world, float x1, float y1, float x2, float y2, float restitution) { 81 | // Determine center point and rotation angle for createWall. 82 | float cx = (x1 + x2) / 2; 83 | float cy = (y1 + y2) / 2; 84 | float angle = (float)Math.atan2(y2-y1, x2-x1); 85 | float mag = (float)Math.hypot(y2-y1, x2-x1); 86 | return createWall(world, cx - mag/2, cy-0.05f, cx + mag/2, cy+0.05f, angle, restitution); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/elements/BumperElement.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball.elements; 2 | 3 | import static com.homescreenarcade.pinball.util.MathUtils.asFloat; 4 | 5 | import java.util.Collections; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import com.badlogic.gdx.math.Vector2; 10 | import com.badlogic.gdx.physics.box2d.Body; 11 | import com.badlogic.gdx.physics.box2d.World; 12 | import com.homescreenarcade.pinball.Ball; 13 | import com.homescreenarcade.pinball.Color; 14 | import com.homescreenarcade.pinball.Field; 15 | import com.homescreenarcade.pinball.IFieldRenderer; 16 | 17 | /** 18 | * This FieldElement subclass represents a bumper that applies an impulse to a ball when it hits. 19 | * The impulse magnitude is controlled by the "kick" parameter in the configuration map. 20 | */ 21 | 22 | public class BumperElement extends FieldElement { 23 | 24 | public static final String POSITION_PROPERTY = "position"; 25 | public static final String RADIUS_PROPERTY = "radius"; 26 | public static final String KICK_PROPERTY = "kick"; 27 | 28 | static final Color DEFAULT_COLOR = Color.fromRGB(0, 0, 255); 29 | 30 | Body bumperBody; 31 | List bumperBodySet; 32 | 33 | float radius; 34 | float cx, cy; 35 | float kick; 36 | 37 | @Override public void finishCreateElement(Map params, FieldElementCollection collection) { 38 | List pos = (List)params.get(POSITION_PROPERTY); 39 | this.radius = asFloat(params.get(RADIUS_PROPERTY)); 40 | this.cx = asFloat(pos.get(0)); 41 | this.cy = asFloat(pos.get(1)); 42 | this.kick = asFloat(params.get(KICK_PROPERTY)); 43 | } 44 | 45 | @Override public void createBodies(World world) { 46 | bumperBody = Box2DFactory.createCircle(world, cx, cy, radius, true); 47 | bumperBodySet = Collections.singletonList(bumperBody); 48 | } 49 | 50 | @Override public List getBodies() { 51 | return bumperBodySet; 52 | } 53 | 54 | @Override public boolean shouldCallTick() { 55 | // Needs to call tick to decrement flash counter, but can use superclass tick() implementation. 56 | return true; 57 | } 58 | 59 | 60 | Vector2 impulseForBall(Ball ball) { 61 | if (this.kick <= 0.01f) return null; 62 | // Compute unit vector from center of bumper to ball, and scale by kick value to get impulse. 63 | Vector2 ballpos = ball.getPosition(); 64 | Vector2 thisPos = bumperBody.getPosition(); 65 | float ix = ballpos.x - thisPos.x; 66 | float iy = ballpos.y - thisPos.y; 67 | float mag = (float)Math.hypot(ix, iy); 68 | float scale = this.kick / mag; 69 | return new Vector2(ix*scale, iy*scale); 70 | } 71 | 72 | @Override public void handleCollision(Ball ball, Body bodyHit, Field field) { 73 | Vector2 impulse = this.impulseForBall(ball); 74 | if (impulse!=null) { 75 | ball.applyLinearImpulse(impulse); 76 | flashForFrames(3); 77 | } 78 | } 79 | 80 | @Override public void draw(IFieldRenderer renderer) { 81 | float px = bumperBody.getPosition().x; 82 | float py = bumperBody.getPosition().y; 83 | renderer.fillCircle(px, py, radius, currentColor(DEFAULT_COLOR)); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/elements/FieldElementCollection.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball.elements; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | 9 | public class FieldElementCollection { 10 | 11 | List allElements = new ArrayList(); 12 | Map elementsById = new HashMap(); 13 | 14 | List flipperElements = new ArrayList(); 15 | List leftFlipperElements = new ArrayList(); 16 | List rightFlipperElements = new ArrayList(); 17 | 18 | Map variables = new HashMap(); 19 | 20 | public void addElement(FieldElement element) { 21 | allElements.add(element); 22 | if (element.getElementId() != null) { 23 | elementsById.put(element.getElementId(), element); 24 | } 25 | if (element instanceof FlipperElement) { 26 | FlipperElement flipper = (FlipperElement) element; 27 | flipperElements.add(flipper); 28 | (flipper.isLeftFlipper() ? leftFlipperElements : rightFlipperElements).add(flipper); 29 | } 30 | } 31 | 32 | public void setVariable(String key, Object value) { 33 | variables.put(key, value); 34 | } 35 | 36 | public List getAllElements() { 37 | return allElements; 38 | } 39 | 40 | public List getFlipperElements() { 41 | return flipperElements; 42 | } 43 | 44 | public List getLeftFlipperElements() { 45 | return leftFlipperElements; 46 | } 47 | 48 | public List getRightFlipperElements() { 49 | return rightFlipperElements; 50 | } 51 | 52 | public FieldElement getElementForId(String id) { 53 | return elementsById.get(id); 54 | } 55 | 56 | public Object getVariable(String key) { 57 | if (!variables.containsKey(key)) { 58 | throw new IllegalArgumentException("Variable not set: " + key); 59 | } 60 | return variables.get(key); 61 | } 62 | 63 | public Object getVariableOrDefault(String key, Object defaultValue) { 64 | return (variables.containsKey(key)) ? variables.get(key) : defaultValue; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/elements/SensorElement.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball.elements; 2 | 3 | import static com.homescreenarcade.pinball.util.MathUtils.asFloat; 4 | 5 | import java.util.Collections; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import com.badlogic.gdx.math.Vector2; 10 | import com.badlogic.gdx.physics.box2d.Body; 11 | import com.badlogic.gdx.physics.box2d.World; 12 | import com.homescreenarcade.pinball.Ball; 13 | import com.homescreenarcade.pinball.Field; 14 | import com.homescreenarcade.pinball.IFieldRenderer; 15 | 16 | /** 17 | * This FieldElement subclass is used to identify areas on the table that should cause custom 18 | * behavior when the ball enters. A SensorElement has no bodies and don't draw anything. The area 19 | * it monitors is a rectangle defined by the "rect" parameter as a [xmin,ymin,xmax,ymax] list. 20 | * During every tick() invocation, a sensor determines if any of the field's balls are within its 21 | * area, and if so calls the field delegate's ballInSensorRange method. 22 | */ 23 | 24 | public class SensorElement extends FieldElement { 25 | 26 | public static final String RECT_PROPERTY = "rect"; 27 | 28 | float xmin, ymin, xmax, ymax; 29 | 30 | @Override public void finishCreateElement(Map params, FieldElementCollection collection) { 31 | List rectPos = (List)params.get(RECT_PROPERTY); 32 | this.xmin = Math.min(asFloat(rectPos.get(0)), asFloat(rectPos.get(2))); 33 | this.ymin = Math.min(asFloat(rectPos.get(1)), asFloat(rectPos.get(3))); 34 | this.xmax = Math.max(asFloat(rectPos.get(0)), asFloat(rectPos.get(2))); 35 | this.ymax = Math.max(asFloat(rectPos.get(1)), asFloat(rectPos.get(3))); 36 | } 37 | 38 | @Override public void createBodies(World world) { 39 | // Not needed. 40 | } 41 | 42 | @Override public boolean shouldCallTick() { 43 | return true; 44 | } 45 | 46 | boolean ballInRange(Ball ball) { 47 | Vector2 bpos = ball.getPosition(); 48 | // Test against rect. 49 | if (bpos.xxmax || bpos.yymax) { 50 | return false; 51 | } 52 | return true; 53 | } 54 | 55 | @Override public void tick(Field field) { 56 | List balls = field.getBalls(); 57 | for(int i=0; i getBodies() { 67 | return Collections.emptyList(); 68 | } 69 | 70 | @Override public void draw(IFieldRenderer renderer) { 71 | // No UI. 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/elements/WallArcElement.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball.elements; 2 | 3 | import static com.homescreenarcade.pinball.util.MathUtils.asFloat; 4 | import static com.homescreenarcade.pinball.util.MathUtils.toRadians; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import com.badlogic.gdx.physics.box2d.Body; 11 | import com.badlogic.gdx.physics.box2d.World; 12 | import com.homescreenarcade.pinball.Color; 13 | import com.homescreenarcade.pinball.IFieldRenderer; 14 | 15 | /** 16 | * This FieldElement subclass approximates a circular wall with a series of straight wall segments 17 | * whose endpoints lie on a circle or ellipse. It is defined in the layout JSON as follows: 18 | * { 19 | * "class": "WallArcElement", 20 | * "center": [5.5, 10], // Center of circle or ellipse. 21 | * "xradius": 2.5, // Radius in the horizontal direction. 22 | * "yradius": 2, // Radius in the y direction. 23 | * "minangle": 45, // Starting angle in degrees, 0 is to the right of the center, 90 is up. 24 | * "maxangle": 135, // Ending angle in degrees. 25 | * "segments": 10, // Number of straight wall segments to use to approximate the arc. 26 | * "color": [255,0,0] // Optional RGB values for the arc's color. 27 | * } 28 | * 29 | * For circular walls, the "radius" attribute can be used instead of xradius and yradius. 30 | */ 31 | 32 | public class WallArcElement extends FieldElement { 33 | 34 | public static final String CENTER_PROPERTY = "center"; 35 | public static final String RADIUS_PROPERTY = "radius"; 36 | public static final String X_RADIUS_PROPERTY = "xradius"; 37 | public static final String Y_RADIUS_PROPERTY = "yradius"; 38 | public static final String NUM_SEGMENTS_PROPERTY = "segments"; 39 | public static final String MIN_ANGLE_PROPERTY = "minangle"; 40 | public static final String MAX_ANGLE_PROPERTY = "maxangle"; 41 | public static final String IGNORE_BALL_PROPERTY = "ignoreBall"; 42 | 43 | public List wallBodies = new ArrayList(); 44 | float[][] lineSegments; 45 | 46 | @Override public void finishCreateElement(Map params, FieldElementCollection collection) { 47 | List centerPos = (List)params.get(CENTER_PROPERTY); 48 | float cx = asFloat(centerPos.get(0)); 49 | float cy = asFloat(centerPos.get(1)); 50 | 51 | // Can specify "radius" for circle, or "xradius" and "yradius" for ellipse. 52 | float xradius, yradius; 53 | if (params.containsKey(RADIUS_PROPERTY)) { 54 | xradius = yradius = asFloat(params.get(RADIUS_PROPERTY)); 55 | } 56 | else { 57 | xradius = asFloat(params.get(X_RADIUS_PROPERTY)); 58 | yradius = asFloat(params.get(Y_RADIUS_PROPERTY)); 59 | } 60 | 61 | Number segments = (Number)params.get(NUM_SEGMENTS_PROPERTY); 62 | int numsegments = (segments!=null) ? segments.intValue() : 5; 63 | float minangle = toRadians(asFloat(params.get(MIN_ANGLE_PROPERTY))); 64 | float maxangle = toRadians(asFloat(params.get(MAX_ANGLE_PROPERTY))); 65 | float diff = maxangle - minangle; 66 | // Create numsegments line segments to approximate circular arc. 67 | lineSegments = new float[numsegments][]; 68 | for(int i=0; i getBodies() { 90 | return wallBodies; 91 | } 92 | 93 | @Override public void draw(IFieldRenderer renderer) { 94 | Color color = currentColor(DEFAULT_WALL_COLOR); 95 | for (float[] segment : this.lineSegments) { 96 | renderer.drawLine(segment[0], segment[1], segment[2], segment[3], color); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/elements/WallPathElement.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball.elements; 2 | 3 | import static com.homescreenarcade.pinball.util.MathUtils.asFloat; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import com.badlogic.gdx.physics.box2d.Body; 10 | import com.badlogic.gdx.physics.box2d.World; 11 | import com.homescreenarcade.pinball.IFieldRenderer; 12 | 13 | /** 14 | * FieldElement subclass which represents a series of wall segments. The segments are defined in 15 | * the "positions" parameter as a list of [x,y] values, for example: 16 | * { 17 | * "class": "WallPathElement", 18 | * "positions": [[5,5], [5,10], [8,10], [5, 15]] 19 | * } 20 | */ 21 | 22 | public class WallPathElement extends FieldElement { 23 | 24 | public static final String POSITIONS_PROPERTY = "positions"; 25 | public static final String IGNORE_BALL_PROPERTY = "ignoreBall"; 26 | 27 | List wallBodies = new ArrayList(); 28 | float[][] lineSegments; 29 | 30 | @Override public void finishCreateElement(Map params, FieldElementCollection collection) { 31 | @SuppressWarnings("unchecked") 32 | List> positions = (List>)params.get(POSITIONS_PROPERTY); 33 | // N positions produce N-1 line segments 34 | lineSegments = new float[positions.size()-1][]; 35 | for(int i=0; i startpos = positions.get(i); 37 | List endpos = positions.get(i+1); 38 | 39 | float[] segment = {asFloat(startpos.get(0)), asFloat(startpos.get(1)), 40 | asFloat(endpos.get(0)), asFloat(endpos.get(1))}; 41 | lineSegments[i] = segment; 42 | } 43 | } 44 | 45 | @Override public void createBodies(World world) { 46 | if (getBooleanParameterValueForKey(IGNORE_BALL_PROPERTY)) return; 47 | 48 | for (float[] segment : this.lineSegments) { 49 | Body wall = Box2DFactory.createThinWall(world, segment[0], segment[1], segment[2], segment[3], 0f); 50 | this.wallBodies.add(wall); 51 | } 52 | } 53 | 54 | @Override public List getBodies() { 55 | return wallBodies; 56 | } 57 | 58 | @Override public void draw(IFieldRenderer renderer) { 59 | for (float[] segment : this.lineSegments) { 60 | renderer.drawLine(segment[0], segment[1], segment[2], segment[3], currentColor(DEFAULT_WALL_COLOR)); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/fields/Field1Delegate.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball.fields; 2 | 3 | import com.homescreenarcade.pinball.Ball; 4 | import com.homescreenarcade.pinball.BaseFieldDelegate; 5 | import com.homescreenarcade.pinball.Field; 6 | import com.homescreenarcade.pinball.elements.DropTargetGroupElement; 7 | import com.homescreenarcade.pinball.elements.RolloverGroupElement; 8 | import com.homescreenarcade.pinball.elements.SensorElement; 9 | import com.homescreenarcade.pinball.elements.WallElement; 10 | 11 | public class Field1Delegate extends BaseFieldDelegate { 12 | 13 | @Override public void allRolloversInGroupActivated(Field field, RolloverGroupElement rolloverGroup) { 14 | // Rollover groups increment field multiplier when all rollovers are activated. 15 | rolloverGroup.setAllRolloversActivated(false); 16 | field.getGameState().incrementScoreMultiplier(); 17 | field.showGameMessage(((int)field.getGameState().getScoreMultiplier()) + "x Multiplier", 1500); 18 | 19 | // Multiball for ramp shot if extra ball rollovers all lit. 20 | if ("RampRollovers".equals(rolloverGroup.getElementId())) { 21 | RolloverGroupElement extraBallRollovers = 22 | (RolloverGroupElement)field.getFieldElementById("ExtraBallRollovers"); 23 | if (extraBallRollovers.allRolloversActive()) { 24 | extraBallRollovers.setAllRolloversActivated(false); 25 | startMultiball(field); 26 | } 27 | } 28 | } 29 | 30 | private void restoreLeftBallSaver(Field field) { 31 | ((WallElement)field.getFieldElementById("BallSaver-left")).setRetracted(false); 32 | } 33 | 34 | private void restoreRightBallSaver(Field field) { 35 | ((WallElement)field.getFieldElementById("BallSaver-right")).setRetracted(false); 36 | } 37 | 38 | private void startMultiball(final Field field) { 39 | field.showGameMessage("Multiball!", 2000); 40 | restoreLeftBallSaver(field); 41 | restoreRightBallSaver(field); 42 | 43 | Runnable launchBall = new Runnable() { 44 | @Override 45 | public void run() { 46 | if (field.getBalls().size() <3 ) field.launchBall(); 47 | } 48 | }; 49 | field.scheduleAction(1000, launchBall); 50 | field.scheduleAction(3500, launchBall); 51 | } 52 | 53 | @Override public void allDropTargetsInGroupHit(Field field, DropTargetGroupElement targetGroup) { 54 | // Activate ball saver for left and right groups. 55 | String id = targetGroup.getElementId(); 56 | if ("DropTargetLeftSave".equals(id)) { 57 | restoreLeftBallSaver(field); 58 | field.showGameMessage("Left Save Enabled", 1500); 59 | } 60 | else if ("DropTargetRightSave".equals(id)) { 61 | restoreRightBallSaver(field); 62 | field.showGameMessage("Right Save Enabled", 1500); 63 | } 64 | // For all groups, increment extra ball rollover. 65 | RolloverGroupElement extraBallRollovers = 66 | (RolloverGroupElement)field.getFieldElementById("ExtraBallRollovers"); 67 | if (extraBallRollovers != null && !extraBallRollovers.allRolloversActive()) { 68 | extraBallRollovers.activateFirstUnactivatedRollover(); 69 | if (extraBallRollovers.allRolloversActive()) { 70 | field.showGameMessage("Shoot Ramp for Multiball", 1500); 71 | } 72 | } 73 | } 74 | 75 | // Support for enabling launch barrier after ball passes by it and hits sensor, 76 | // and disabling for new ball or new game. 77 | private void setLaunchBarrierEnabled(Field field, boolean enabled) { 78 | WallElement barrier = (WallElement)field.getFieldElementById("LaunchBarrier"); 79 | barrier.setRetracted(!enabled); 80 | } 81 | 82 | @Override public void ballInSensorRange(Field field, SensorElement sensor, Ball ball) { 83 | // Enable launch barrier. 84 | if ("LaunchBarrierSensor".equals(sensor.getElementId())) { 85 | setLaunchBarrierEnabled(field, true); 86 | } 87 | else if ("LaunchBarrierRetract".equals(sensor.getElementId())) { 88 | setLaunchBarrierEnabled(field, false); 89 | } 90 | } 91 | 92 | @Override public void gameStarted(Field field) { 93 | setLaunchBarrierEnabled(field, false); 94 | } 95 | 96 | @Override public void ballLost(Field field) { 97 | setLaunchBarrierEnabled(field, false); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/util/GLVertexList.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball.util; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.ByteOrder; 5 | import java.nio.FloatBuffer; 6 | 7 | import javax.microedition.khronos.opengles.GL10; 8 | 9 | public class GLVertexList { 10 | 11 | FloatBuffer vertexBuffer = null; 12 | FloatBuffer colorBuffer = null; 13 | int numVertices; 14 | 15 | int vertexIndex; 16 | int colorIndex; 17 | 18 | float[] vertexCoords = null; 19 | float[] colorComponents = null; 20 | 21 | int glMode; 22 | 23 | public void setGLMode(int glMode) { 24 | this.glMode = glMode; 25 | } 26 | 27 | public void begin() { 28 | numVertices = 0; 29 | vertexIndex = colorIndex = 0; 30 | } 31 | 32 | public void addVertex(float x, float y) { 33 | if (vertexCoords==null) { 34 | vertexCoords = new float[10]; 35 | } 36 | else if (vertexIndex+1 >= vertexCoords.length) { 37 | float[] newArray = new float[2*vertexCoords.length]; 38 | System.arraycopy(vertexCoords, 0, newArray, 0, vertexIndex); 39 | vertexCoords = newArray; 40 | vertexBuffer = null; 41 | } 42 | vertexCoords[vertexIndex++] = x; 43 | vertexCoords[vertexIndex++] = y; 44 | 45 | numVertices++; 46 | } 47 | 48 | public void addColor(float r, float g, float b, float alpha) { 49 | if (colorComponents==null) { 50 | colorComponents = new float[20]; 51 | } 52 | else if (colorIndex+4 >= colorComponents.length) { 53 | float[] newArray = new float[2*colorComponents.length]; 54 | System.arraycopy(colorComponents, 0, newArray, 0, colorIndex); 55 | colorComponents = newArray; 56 | colorBuffer = null; 57 | } 58 | colorComponents[colorIndex++] = r; 59 | colorComponents[colorIndex++] = g; 60 | colorComponents[colorIndex++] = b; 61 | colorComponents[colorIndex++] = alpha; 62 | } 63 | 64 | public void addColor(float r, float g, float b) { 65 | addColor(r, g, b, 1.0f); 66 | } 67 | 68 | public void end() { 69 | // update buffers, (re)creating if needed 70 | if (vertexBuffer==null || vertexBuffer.capacity()0) { 77 | if (colorBuffer==null || colorBuffer.capacity()4) { 88 | gl.glEnableClientState(GL10.GL_COLOR_ARRAY); 89 | } 90 | else { 91 | gl.glDisableClientState(GL10.GL_COLOR_ARRAY); 92 | } 93 | 94 | gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer); 95 | if (colorIndex>4) { 96 | gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer); 97 | } 98 | else if (colorIndex==4) { 99 | // single color 100 | gl.glColor4f( 101 | colorComponents[0], colorComponents[1], colorComponents[2], colorComponents[3]); 102 | } 103 | 104 | gl.glDrawArrays(glMode, 0, numVertices); 105 | } 106 | 107 | public FloatBuffer getVertexBuffer() { 108 | return vertexBuffer; 109 | } 110 | public FloatBuffer getColorBuffer() { 111 | return colorBuffer; 112 | } 113 | 114 | public int getVertexCount() { 115 | return numVertices; 116 | } 117 | 118 | static FloatBuffer makeFloatBuffer(int size) { 119 | ByteBuffer vbb = ByteBuffer.allocateDirect(size * 4); 120 | vbb.order(ByteOrder.nativeOrder()); 121 | FloatBuffer texBuffer = vbb.asFloatBuffer(); 122 | texBuffer.position(0); 123 | return texBuffer; 124 | } 125 | 126 | 127 | } 128 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/util/GLVertexListManager.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball.util; 2 | 3 | import javax.microedition.khronos.opengles.GL10; 4 | 5 | public class GLVertexListManager { 6 | 7 | GLVertexList[] vertexLists; 8 | int[] glModes; 9 | int vertexListCount; 10 | 11 | public GLVertexListManager() { 12 | vertexLists = new GLVertexList[10]; 13 | for(int i=0; i=vertexLists.length) { 36 | GLVertexList[] newArray = new GLVertexList[2*vertexLists.length]; 37 | System.arraycopy(vertexLists, 0, newArray, 0, vertexLists.length); 38 | this.vertexLists = newArray; 39 | } 40 | GLVertexList vl = vertexLists[vertexListCount]; 41 | if (vl==null) { 42 | vertexLists[vertexListCount] = vl = new GLVertexList(); 43 | } 44 | vl.setGLMode(glMode); 45 | vl.begin(); 46 | vertexListCount++; 47 | return vl; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/util/JSONUtils.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import org.json.JSONArray; 10 | import org.json.JSONException; 11 | import org.json.JSONObject; 12 | 13 | public class JSONUtils { 14 | 15 | /** 16 | * If argument is a JSONArray or JSONObject, returns the equivalent List or Map. If argument 17 | * is JSONObject.NULL, returns null. Otherwise, returns the argument unchanged. 18 | */ 19 | public static Object objectFromJSONItem(Object jsonItem) { 20 | if (jsonItem==JSONObject.NULL){ 21 | return null; 22 | } 23 | if (jsonItem instanceof JSONArray) { 24 | return listFromJSONArray((JSONArray)jsonItem); 25 | } 26 | if (jsonItem instanceof JSONObject) { 27 | return mapFromJSONObject((JSONObject)jsonItem); 28 | } 29 | return jsonItem; 30 | } 31 | 32 | /** 33 | * Returns a List with the same objects in the same order as jsonArray. Recursively converts 34 | * nested JSONArray and JSONObject values to List and Map objects. 35 | */ 36 | public static List listFromJSONArray(JSONArray jsonArray) { 37 | List result = new ArrayList(); 38 | try { 39 | for(int i=0; i mapFromJSONObject(JSONObject jsonObject) { 56 | Map result = new HashMap(); 57 | try { 58 | for(Iterator ki = jsonObject.keys(); ki.hasNext(); ) { 59 | String key = ki.next(); 60 | Object value = objectFromJSONItem(jsonObject.get(key)); 61 | result.put(key, value); 62 | } 63 | } 64 | catch(JSONException ex) { 65 | throw new RuntimeException(ex); 66 | } 67 | return result; 68 | } 69 | 70 | /** Parses the string argument as a JSON array and converts to a List. */ 71 | public static List listFromJSONString(String jsonString) { 72 | try { 73 | return listFromJSONArray(new JSONArray(jsonString)); 74 | } 75 | catch (JSONException ex) { 76 | throw new RuntimeException(ex); 77 | } 78 | } 79 | 80 | /** Parses the string argument as a JSON object and converts to a Map. */ 81 | public static Map mapFromJSONString(String jsonString) { 82 | try { 83 | return mapFromJSONObject(new JSONObject(jsonString)); 84 | } 85 | catch (JSONException ex) { 86 | throw new RuntimeException(ex); 87 | } 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/homescreenarcade/pinball/util/MathUtils.java: -------------------------------------------------------------------------------- 1 | package com.homescreenarcade.pinball.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class MathUtils { 7 | 8 | public static final double TAU = 2 * Math.PI; 9 | 10 | public static float asFloat(Object obj, float defvalue) { 11 | if (obj instanceof Number) return ((Number)obj).floatValue(); 12 | if (obj instanceof String) { 13 | try { 14 | return Float.parseFloat((String)obj); 15 | } 16 | catch (NumberFormatException ex) { 17 | // log? 18 | } 19 | } 20 | return defvalue; 21 | } 22 | 23 | public static float asFloat(Object obj) { 24 | return asFloat(obj, 0); 25 | } 26 | 27 | public static List asFloatList(List values) { 28 | if (values == null) return null; 29 | List converted = new ArrayList(); 30 | for (int i=0; i asDoubleList(List values) { 54 | if (values == null) return null; 55 | List converted = new ArrayList(); 56 | for (int i=0; i asIntList(List values) { 80 | if (values == null) return null; 81 | List converted = new ArrayList(); 82 | for (int i=0; i max) return max; 107 | return x; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libgdx-box2d.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/jniLibs/armeabi-v7a/libgdx-box2d.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libgdx-box2d.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/jniLibs/armeabi/libgdx-box2d.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libgdx-box2d.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/jniLibs/x86/libgdx-box2d.so -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/food.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-hdpi/food.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ghost_door.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-hdpi/ghost_door.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_mazeman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-hdpi/ic_mazeman.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_pause_circle_outline_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-hdpi/ic_pause_circle_outline_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_play_circle_outline_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-hdpi/ic_play_circle_outline_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/power.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-hdpi/power.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/wall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-hdpi/wall.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_invaders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-mdpi/ic_invaders.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_pause_circle_outline_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-mdpi/ic_pause_circle_outline_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_play_circle_outline_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-mdpi/ic_play_circle_outline_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/status_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-mdpi/status_bg.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/bluey_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-nodpi/bluey_sprite.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/example_appwidget_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-nodpi/example_appwidget_preview.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/game_over_classic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-nodpi/game_over_classic.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/pacmon_sprite_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-nodpi/pacmon_sprite_green.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/pacmon_sprite_orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-nodpi/pacmon_sprite_orange.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/redy_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-nodpi/redy_sprite.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/violet_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-nodpi/violet_sprite.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/yellowy_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-nodpi/yellowy_sprite.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/blue_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xhdpi/blue_btn.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/blue_yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xhdpi/blue_yellow.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/green_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xhdpi/green_btn.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_pause_circle_outline_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xhdpi/ic_pause_circle_outline_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_play_circle_outline_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xhdpi/ic_play_circle_outline_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/invaders_tank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xhdpi/invaders_tank.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/mazeman_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xhdpi/mazeman_small.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/pin_ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xhdpi/pin_ball.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/red_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xhdpi/red_btn.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/red_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xhdpi/red_green.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/yellow_btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xhdpi/yellow_btn.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/bullet.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxhdpi/bullet.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_pause_circle_outline_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxhdpi/ic_pause_circle_outline_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_play_circle_outline_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxhdpi/ic_play_circle_outline_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/iconinger_v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxhdpi/iconinger_v2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/block_piece.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxxhdpi/block_piece.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_pause_circle_outline_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxxhdpi/ic_pause_circle_outline_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_pause_shortcut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxxhdpi/ic_pause_shortcut.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_pinball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxxhdpi/ic_pinball.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_play_circle_outline_white_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxxhdpi/ic_play_circle_outline_white_48dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_play_shortcut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxxhdpi/ic_play_shortcut.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/pinball_notif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StringMon/homescreenarcade/f54e9e4a43f96f793bc11f9696f33ff0af34ca25/app/src/main/res/drawable-xxxhdpi/pinball_notif.png -------------------------------------------------------------------------------- /app/src/main/res/layout/fire_button_widget.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/get_ready_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/instruction_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 15 | 22 | 28 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/launcher_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 18 |