Skip to content

Commit

Permalink
feat: add action button
Browse files Browse the repository at this point in the history
  • Loading branch information
Agnieszka Forajter committed Mar 4, 2024
1 parent 59968d5 commit 52476eb
Show file tree
Hide file tree
Showing 15 changed files with 115 additions and 308 deletions.
265 changes: 24 additions & 241 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,259 +1,42 @@
# Endless Runner Template
Welcome to Better World! A Flutter game created using Flame engine. Experience real-world challenges: clean energy, waste sorting, deforestation, and more. Watch the world change with your actions. Join us for a Better World!

This is a starter Flutter and Flame project with an endless runner game built
in Flutter & Flame, it includes the following features:
## Inspiration
Seeing organizations like Global Citizen leveraging technologies like Flutter to change the world and make a difference has motivated us profoundly. We aspire to join this initiative and raise awareness about the environmental challenges our world currently faces. In Appunite, we found interest in Flutter from the beta phase and seeing such actions, we decided to join! That's why we created Better World.

Flutter features:
- A `FlameGame` base
- Main menu screen
- Basic navigation
- Game-y theming
- Settings
- Sound
## What it does
Our project offers a fresh perspective on the world's challenges. Instead of focusing on just one issue, we've created a changing world with 6 mini-games, each with its own gameplay and tackling a different global problem. As players progress through each game, they earn points and see how their actions improve the Better World. They also collect badges that they can store in Google Wallet.

Flame features:
- Player steering
- Collision detection
- Parallax
- Effects
- Spawns
Our mini-games serve not only to point out the pressing issues but also to present viable solutions. Following each mini-gaming session, players are introduced to organizations actively engaged in effecting positive change in the respective fields. This allows players to not only educate themselves further on the issues but also to contribute financially to these noble causes.

You can jump directly into building your game in `lib/flame_game/`.
Our goal is simple: raise awareness and encourage action. We want players to feel empowered to change the world.

When you're ready for things like ads, in-app purchases, achievements,
analytics, crash reporting, and so on, there are resources ready for you
at [flutter.dev/games](https://flutter.dev/games).
## How we built it
Flutter and Dart helped us build the app's core, while Firebase managed the backend. Rive and Flame made the game engaging, and Figma helped design the user interface. We collaborated using Github and Slack. Together, these tools helped us create Better World, aiming to make a positive impact.

## Challenges we ran into
Ideation Phase - with numerous issues we aimed to address, the application underwent significant evolution from its initial concept. Striking a balance between educational content and engaging gameplay posed a considerable challenge.

# Getting started
Rive Animations - Rive, while promising, still a bit unstable technology, causing several issues such as malfunctioning triggers and refresh problems, which hindered the development process.

Clone this project and run the following command in its root directory:
Understanding the basics of the Flame Engine - as newcomers to game development, we had to invest significant time in familiarizing ourselves with the fundamentals of the Flame engine.

```terminal
flutter create . --project-name endless_runner
```
State Management - While we typically rely on Bloc for state management, we found that controllers worked better for the game mechanism. Although ChangeNotifier and ValueNotifier were readily available in the Flutter template provided, managing screen refreshes proved to be more challenging, particularly to ensure proper functionality of Rive animations inputs on our main map.

This will create the necessary platform files, such as `ios/`, `android/`,
`web/`, `macos/`, `linux/` or `windows/`, depending on your installation of Flutter.
## Accomplishments that we're proud of

After this, the game compiles and works out of the box. It comes with things
like a main menu, a router, a settings screen, and audio.
When building a new game, this is likely everything you first need.
In just 2 months, our small team successfully crafted a beautiful, functional, multiplatform and potentially impactful game using our favorite technology, Flutter. We're proud of delivering a product that has the potential to reach a wide audience and make a positive difference in the world.

When you're ready to enable more advanced integrations, like ads
and in-app payments, read the _Integrations_ section below.
## What we learned
We discovered the multitude of incredible organizations tirelessly working to improve our world.

We gained invaluable experience working within a real startup environment, where accountability extends beyond coding and graphics to deliver every aspect of the project.

# Development
We understood the basics of the Flame engine, diving into the game development and animation.

Usually you will open the template in your favorite IDE, like Android Studio
or Visual Studio Code, and from there you will be able to run the game in debug
mode directly. Usually by pressing a green play button.
## What's next for Better World

To run the game in debug mode directly from the terminal you can do:
Our next steps involve releasing the game on the Play Store and App Store to reach a wider audience. We aim to continue spreading awareness about the environmental issues highlighted in the game and inspire more individuals to take action.

flutter run

This assumes you have an Android emulator, iOS Simulator, or an attached
physical device.

It is often convenient to develop your game as a desktop app.
For example, you can run `flutter run -d macOS`, and get the same UI
in a desktop window on a Mac. That way, you don't need to use a
simulator/emulator or attach a mobile device. This template supports
desktop development by disabling integrations like AdMob for desktop.


## Code organization

Code is organized in a loose and shallow feature-first fashion.
In `lib/`, you'll therefore find directories such as `audio`, `main_menu`
or `settings`. Nothing fancy, but usable.

```
lib
├── app_lifecycle
├── audio
├── flame_game
├── level_selection
├── main_menu
├── player_progress
├── settings
├── style
└── main.dart
└── router.dart
```

The state management approach is intentionally low-level. That way, it's easy to
take this project and run with it, without having to learn new paradigms, or having
to remember to run `flutter pub run build_runner watch`. You are,
of course, encouraged to use whatever paradigm, helper package or code generation
scheme that you prefer.


## Building for production

To build the app for iOS (and open Xcode when finished):

```shell
flutter build ipa && open build/ios/archive/Runner.xcarchive
```

To build the app for Android (and open the folder with the bundle when finished):

```shell
flutter build appbundle && open build/app/outputs/bundle/release
```

While the template is primarily meant for mobile games, you can also publish
for the web. This might be useful for web-based demos, for example,
or for rapid play-testing. The following command requires installing
[`peanut`](https://pub.dev/packages/peanut/install).

```bash
flutter pub global run peanut \
--web-renderer canvaskit \
--extra-args "--base-href=/name_of_your_github_repo/" \
&& git push origin --set-upstream gh-pages
```

The last line of the command above automatically pushes
your newly built web game to GitHub pages, assuming that you have
that set up.

Lastly, it is of course possible to build your game for desktop platforms:
Windows, Linux and macOS.
Follow the [standard instructions](https://docs.flutter.dev/platform-integration/desktop).


# Integrations

Focus on making your core gameplay fun first. Don't worry about
integrations like ads, in-app purchases, analytics, and so on.
It's easy to add them later, and you can find recipes and codelabs
for them at [flutter.dev/games](https://flutter.dev/games).

Change the package name of your game
before you start any of the deeper integrations.
[StackOverflow has instructions](https://stackoverflow.com/a/51550358/1416886)
for this, and the [`rename`](https://pub.dev/packages/rename) tool
(on pub.dev) automates the process.


## Audio

Audio is enabled by default and ready to go. You can modify code
in `lib/audio/` to your liking.

You can find some music
tracks in `assets/music` — these are Creative Commons Attribution (CC-BY)
licensed, and are included in this repository with permission. If you decide
to keep these tracks in your game, please don't forget to give credit
to the musician, [Mr Smith][].

[Mr Smith]: https://freemusicarchive.org/music/mr-smith

The repository also includes a few sound effect samples in `assets/sfx`.
These are public domain (CC0) and you will almost surely want to replace
them because they're just recordings of a developer doing silly sounds
with their mouth.


## Logging

The template uses the [`logging`](https://pub.dev/packages/logging) package
to log messages to the console. This makes it very easy to log messages
from anywhere with something like the following:

```dart
import 'package:logging/logging.dart';
final _log = Logger('Foo');
void foo() {
_log.info('Hello, world!');
}
```

This will show up in the console as:

```text
[Foo] Hello, world!
```

When using Flutter DevTools, all the metadata of the log message is preserved,
so you can filter by logger name, log level, and so on.

Later, when you're closer to production, you can gather these log messages
(see `lib/main.dart`) and send them to a service like Firebase Crashlytics
when appropriate.
See [`firebase_crashlytics`](https://pub.dev/packages/firebase_crashlytics)
for more information.


## Settings

The settings page is enabled by default, and accessible both
from the main menu and through the "gear" button in the play session screen.

Settings are saved to local storage using the
[`shared_preferences`](https://pub.dev/packages/shared_preferences)
package.
To change what preferences are saved and how, edit files in
`lib/settings/persistence`.


# Icon

To update the launcher icon, first change the files
`assets/icon-adaptive-foreground.png` and `assets/icon.png`.
Then, run the following:

```bash
flutter pub run flutter_launcher_icons:main
```

You can [configure](https://github.com/fluttercommunity/flutter_launcher_icons#book-guide)
the look of the icon in the `flutter_icons:` section of `pubspec.yaml`.


# Troubleshooting

## CocoaPods

When upgrading to higher versions of Flutter or plugins, you might encounter an error when
building the iOS or macOS app. A good first thing to try is to delete the `ios/Podfile.lock`
file (or `macos/Podfile.lock`, respectively), then trying to build again. (You can achieve
a more thorough cleanup by running `flutter clean` instead.)

If this doesn't help, here are some more methods:

- See if everything is still okay with your Flutter and CocoaPods installation
by running `flutter doctor`. Revisit the macOS
[Flutter installation guide](https://docs.flutter.dev/get-started/install/macos)
if needed.
- Update CocoaPods specs directory:

```sh
cd ios
pod repo update
cd ..
```

(Substitute `ios` for `macos` when appropriate.)
- Open the project in Xcode,
[increase the build target](https://stackoverflow.com/a/38602597/1416886),
then select _Product_ > _Clean Build Folder_.

## Warnings in console

When running the game for the first time, you might see warnings like the following:

> Note: Some input files use or override a deprecated API.
or

> warning: 'viewState' was deprecated in macOS 11.0: Use -initWithState: instead
These warning come from the various plugins that are used by the template. They are not harmful
and can be ignored. The warnings are meant for the plugin authors, not for you, the game developer.
## How to run the project
To run the project you don't need any additional setup than cloning the repository. The game works on Android, iOS, macos and web.
6 changes: 6 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,8 @@ PODS:
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- url_launcher_ios (0.0.1):
- Flutter
- wakelock_plus (0.0.1):
- Flutter

Expand All @@ -782,6 +784,7 @@ DEPENDENCIES:
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- rive_common (from `.symlinks/plugins/rive_common/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)

SPEC REPOS:
Expand Down Expand Up @@ -825,6 +828,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/rive_common/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
wakelock_plus:
:path: ".symlinks/plugins/wakelock_plus/ios"

Expand Down Expand Up @@ -856,6 +861,7 @@ SPEC CHECKSUMS:
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
rive_common: 3a4c254c6e4db7e4b9e05daeb3d1f47ae4f7bf76
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586
wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47

PODFILE CHECKSUM: 4f1c12611da7338d21589c0b2ecd6bd20b109694
Expand Down
8 changes: 8 additions & 0 deletions lib/challenges/challenge_type_enum.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ enum ChallengeType {
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Fpipes_badge.svg?alt=media&token=3129490c-2ba9-4e5e-8c97-3f407bbde5c1',
badgeUrl:
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Fpipes_badge_hero.svg?alt=media&token=ec085b24-8573-4363-aa3e-faef9bb6ea41',
organizationUrl: 'https://www.unep.org/explore-topics/water/what-we-do/global-wastewater-initiative-gwwi',
),
recycling(
title: 'Recycle Rush',
Expand All @@ -43,6 +44,7 @@ enum ChallengeType {
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Frecycling_badge.svg?alt=media&token=d3bd2cf9-3e33-4f13-84b9-2d8501caeb7d',
badgeUrl:
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Frecycling_badge_hero.svg?alt=media&token=cde27413-c3b3-4968-91a9-4865bf0d7ce6',
organizationUrl: 'https://www.bir.org',
),
solarPanel(
title: 'Solar Panel Cleanup',
Expand All @@ -60,6 +62,7 @@ enum ChallengeType {
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Fpanel_badge.svg?alt=media&token=67d72897-2950-4ab8-8b16-465810fbefdf',
badgeUrl:
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Fpanel_badge_hero.svg?alt=media&token=8ac058c7-c9ac-4cf9-8cde-985b3a6f6362',
organizationUrl: 'https://www.eurosolar.org/donate/',
),
trees(
title: 'Plant a Forest',
Expand All @@ -77,6 +80,7 @@ enum ChallengeType {
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Ftrees_badge.svg?alt=media&token=d37f5658-7bff-4ac0-9c74-3118edfd9747',
badgeUrl:
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Ftrees_badge_hero.svg?alt=media&token=7338baa7-9813-489a-bf0d-7ba822b4fd67',
organizationUrl: 'https://onetreeplanted.org/products/plant-trees',
),
ocean(
title: 'Plastic Free',
Expand All @@ -94,6 +98,7 @@ enum ChallengeType {
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Focean_badge.svg?alt=media&token=37884bd4-ba2d-4164-a8e0-f64a83cfbb5e',
badgeUrl:
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Focean_badge_hero.svg?alt=media&token=3c32d76b-f6ee-4240-ba97-e3bb75bda74c',
organizationUrl: 'https://theoceancleanup.com/help-clean/',
),
lightsOut(
title: 'Lights Out Challenge',
Expand All @@ -111,6 +116,7 @@ enum ChallengeType {
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Flights_off_badge.svg?alt=media&token=6b7347e2-277b-4690-8e52-01f82692f074',
badgeUrl:
'https://firebasestorage.googleapis.com/v0/b/flutter-game-challenge.appspot.com/o/badges%2Flights_off_badge_hero.svg?alt=media&token=0d66abb8-7be2-411f-a64d-d5a436d3647e',
organizationUrl: 'https://www.savingourstars.org/howtohelp',
);

const ChallengeType({
Expand All @@ -127,6 +133,7 @@ enum ChallengeType {
required this.badgeTitle,
required this.badgeUrl,
required this.badgeLogoUrl,
required this.organizationUrl,
});

final String title;
Expand All @@ -142,6 +149,7 @@ enum ChallengeType {
final String badgeTitle;
final String badgeUrl;
final String badgeLogoUrl;
final String organizationUrl;

int? getChallengeScore(ChallengesEntity challenges) {
return switch (this) {
Expand Down
Loading

0 comments on commit 52476eb

Please sign in to comment.