1
0
mirror of https://github.com/flutter/samples.git synced 2025-11-10 23:08:59 +00:00

Add game_template (#1180)

Adds a template / sample for games built in Flutter, with all the bells and whistles, like ads, in-app purchases, audio, main menu, settings, and so on.

Co-authored-by: Parker Lougheed
Co-authored-by: Shams Zakhour
This commit is contained in:
Filip Hracek
2022-05-10 15:08:43 +02:00
committed by GitHub
parent 5143bcf302
commit daa024a829
208 changed files with 8993 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
// Copyright 2022, the Flutter project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import '../audio/audio_controller.dart';
import '../audio/sounds.dart';
import '../games_services/games_services.dart';
import '../settings/settings.dart';
import '../style/palette.dart';
import '../style/responsive_screen.dart';
class MainMenuScreen extends StatelessWidget {
const MainMenuScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final palette = context.watch<Palette>();
final gamesServicesController = context.watch<GamesServicesController?>();
final settingsController = context.watch<SettingsController>();
final audioController = context.watch<AudioController>();
return Scaffold(
backgroundColor: palette.backgroundMain,
body: ResponsiveScreen(
mainAreaProminence: 0.45,
squarishMainArea: Center(
child: Transform.rotate(
angle: -0.1,
child: const Text(
'Flutter Game Template!',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Permanent Marker',
fontSize: 55,
height: 1,
),
),
),
),
rectangularMenuArea: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () {
audioController.playSfx(SfxType.buttonTap);
GoRouter.of(context).go('/play');
},
child: const Text('Play'),
),
_gap,
if (gamesServicesController != null) ...[
_hideUntilReady(
ready: gamesServicesController.signedIn,
child: ElevatedButton(
onPressed: () => gamesServicesController.showAchievements(),
child: const Text('Achievements'),
),
),
_gap,
_hideUntilReady(
ready: gamesServicesController.signedIn,
child: ElevatedButton(
onPressed: () => gamesServicesController.showLeaderboard(),
child: const Text('Leaderboard'),
),
),
_gap,
],
ElevatedButton(
onPressed: () => GoRouter.of(context).go('/settings'),
child: const Text('Settings'),
),
_gap,
Padding(
padding: const EdgeInsets.only(top: 32),
child: ValueListenableBuilder<bool>(
valueListenable: settingsController.muted,
builder: (context, muted, child) {
return IconButton(
onPressed: () => settingsController.toggleMuted(),
icon: Icon(muted ? Icons.volume_off : Icons.volume_up),
);
},
),
),
_gap,
const Text('Music by Mr Smith'),
_gap,
],
),
),
);
}
/// Prevents the game from showing game-services-related menu items
/// until we're sure the player is signed in.
///
/// This normally happens immediately after game start, so players will not
/// see any flash. The exception is folks who decline to use Game Center
/// or Google Play Game Services, or who haven't yet set it up.
Widget _hideUntilReady({required Widget child, required Future<bool> ready}) {
return FutureBuilder<bool>(
future: ready,
builder: (context, snapshot) {
// Use Visibility here so that we have the space for the buttons
// ready.
return Visibility(
visible: snapshot.data ?? false,
maintainState: true,
maintainSize: true,
maintainAnimation: true,
child: child,
);
},
);
}
static const _gap = SizedBox(height: 10);
}