へっぽこSEが◯時間でFlutter(iOS、android、web)で2Dゲームアプリを作ってみる(4)

どうも、すえきあおいです。
結論から言うと、今日やるチュートリアルは成功しました。フルのソースコードはこちらにあるので、面倒な人はダウンロードどうぞ。
知識は身についてきましたが、まだアプリ開発自体は1ナノも前進しておりません(白目
これでも自分的には良いペースで進んでいる(前はハマってからず〜〜〜〜っとハマり続けて、疲れて、諦めて、ボンヤーリして気付いたら1ヶ月、みたいなペースだったw)ので、三度目の正直を信じて別のチュートリアル動画をみながらレッツトライすることにしました。
ネバーギブアップ٩( ‘ω’ )و
今日試したこと:もう一度。別のYouTube動画で解説みながらイチから作ってみる
Flutterはバリバリ進化中のライブラリなので、1年前のソースだともう古い(そのまま真似して実装しても動かない)んだってことがよくわかりました。休日を1日棒に振って学びました。
と、いうことで、チュートリアル動画で新しくてきちんと解説してくれているこちらの動画をチョイス!
なんかテトリス的なものを作ろうとしているみたい。
最初にイメージ図を用意して概要まで解説してくれるとは、なんて親切なんでしょう!コレは期待できますね!
準備
- Android Studioで「新しいFlutterアプリを作る」でプロジェクトを新規作成(涙
以下、やったことは動画を見ながら真似してやったことなので、わかりにくかったら動画の方を参照してくださいな。
やったこと① Scaffold を使って アプリのベースを作る
まずは、main.dartのデフォルトのコードを全部消して以下のように書き直します。
lib/main.dart
import 'package:flutter/material.dart';
import 'score_bar.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: Tetris(),);
}
}
class Tetris extends StatefulWidget {
@override
State createState() => _TetrisState();
}
// 「_」をつけるとプライベートになる
class _TetrisState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TETRIS'),
centerTitle: true,
backgroundColor: Colors.indigoAccent,
),
backgroundColor: Colors.indigo,
);
}
}
やったこと② ScoreBar(点数を表示する場所)を追加する
次に、main.dartのbodyにSafeAreaを配置し、中にScoreBarクラスを置きます。
Score Barの中身は新しいファイルに実装していきます。
lib/main.dart
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TETRIS'),
centerTitle: true,
backgroundColor: Colors.indigoAccent,
),
backgroundColor: Colors.indigo,
body: SafeArea(
child: Column(
children: [
// 全てのWidgetを一つのファイルに入れると面倒になる。
// 必要なWidgetをでばっくで見つけることも難しくなる。
// なので、別ファイルにクラスを宣言します。
// ScoreBarクラスはインジケータを表示するWidgetです。
ScoreBar(),
],
),
)
);
}
}
次に、ScoreBarクラスを別ファイルに実装していきます。
lib/score_bar.dart
import 'package:flutter/material.dart';
//スコアは頻繁に更新されるため、ScoreBarはStatefulWidgetである必要があります。
class ScoreBar extends StatefulWidget {
@override
State createState() => _ScoreBarState();
}
class _ScoreBarState extends State {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.indigo[800], Colors.indigo[500]],
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.all(10.0),
child: Text(
'Score: 0',
style:TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
],
),
);
}
}
BoxDecorationでグラデーションをつけてるあたり、お洒落ですね!
ここまでやったら、main.dartの最上部に以下を追記します。
lib/main.dart
import 'score_bar.dart';
コレで実行できます!
やったこと③ SafeAreaの残りの部分を3:1に分割する
まず、残りの部分、ということでExpandedを使っていきます。(これも過去記事で勉強した甲斐あって理解できました)
main.dart
body: SafeArea( child: Column( children: [ // 全てのWidgetを一つのファイルに入れると面倒になる。 // 必要なWidgetをでばっくで見つけることも難しくなる。 // なので、別ファイルにクラスを宣言します。 // ScoreBarクラスはインジケータを表示するWidgetです。 ScoreBar(), Expanded( //残りの部分 child:Row( //縦に分割したいときはRowを使う children: [ Flexible( //残りの部分を分割するので、Flexibleを使う flex: 3, child: Padding( padding: EdgeInsets.fromLTRB(10.0, 10.0, 5.0, 10.0), child: Container( color: Colors.red, ), ), ), Flexible( flex: 1, child: Padding( padding: EdgeInsets.fromLTRB(5.0, 10.0, 10.0, 10.0), child:Container( color: Colors.green, ), ), ), ], ), ), ], ), ),
とりあえず、ここまでうまくいきました!
動画では8:52しか経ってません(笑)
思ったんですが、動画ってとても勉強しやすいですね。学びも多かったです。
小技ですが、createStateって打ったらあとはエディタが入力補完してくれて、
@override StatefulElement createElement() { // TODO: implement createElement return super.createElement(); }
まで自動でコーディングされるとか知らなかったので感動しました。入力保管の域を超えている…(`・∀・´)
次回はいよいよゲームエリアを作っていきます。
進むと楽しいですね。ワクワク!
それでは!