【第2話】Flutterでwebゲーム作ろっかなって思った 【Hello F*****g World】

#チュートリアルより動くものが見たかった
私は悪い子なので、実際に動くものが先に見たいのです。
足し算をやってから掛け算の勉強なんてしたくないのです。
とりあえず微積をやって大砲の着弾地点予測を求めて敵艦を沈めたいのですアイザック・ニュートン先生！

ということでゲームのコードを公開している人たちのところへ行って学んできます
https://medium.com/flutter-community/from-zero-to-a-multiplatform-flutter-game-in-a-week-8245da931c7e

動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**動かない**


ちっ、ペロッとコピってペロッと動かして、盗んでｹﾞﾍﾍ　動かしてｹﾞﾍﾍ
ってやりたかったのに、なんかだめですね。
しかし、上記の先生以外のコードなんかも色々見たんですけど、結構わかりやすくてｽｯｶｽｶなのに見栄えよくできてますね。言わゆるバエるUIを作りやすい感じします。イイですね

ということでtutorialに潜ります。

#Tutorialやろ(https://flutter.dev/docs/get-started/codelab

##Step 1:HELL OH THIS WORLD(この世界は地獄である
とりあえず作業フォルダ作って　flutter create .
そしたらlib/main.dartをおもむろに開き、下のコードでmain()とMyAppを上書きする
flutter run -d chromeすると・・・まぁそりゃ動く


```
import 'package:flutter/material.dart';

void main() => runApp(MyApp());
// void main(){
//   runApp(MyApp());//function定義はどっちでも良いのだ。thisが絡むときとかは注意するのだ
// } 
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }
}
```


- main()から始まるよ=>も対応してるもちろん{}でファンクション定義してもいいよ
- StatelessWidgetとはこいつがwidget(部品)だよと定義するものだよ。Flutterでは全てがwidgetだよ
- widgetのお仕事はbuild()メソッドを持っていることだよ。他のwidgetとの関係性からどうやって表示されるのかを定義するよ
- Center widgetにtextがというchild widget(子widget)が入っているのがこの例題の作りだよ。　
- サブツリーがどーのコーの難しいこと言ってるけど、よくわからん次行こ！

##Step 2:外部パッケージつかってみよ
オープンソースのパッケージ、english_wordsを使うよ

###1:pubspec.yamlにenglish_wordsを入れるよ
(Version Lens最強かもしれん、入れてなかったら入れて
ファイル変更したらセーブしろよ！変更はセーブしないと意味がないからな！ by 村人A

```
dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2

  english_words: ^3.1.5
```

###2:flutter pub get する
追加したdependenciesについて解決してくれるよ

###3-4:実際に使ってみる
dependenciesに入ってる子についてのコード置換は自動で走るっぽいよ、
勝手にimportもしてくれる。
手動でimport書いたら、お前まだ使ってないやんけって波線がでるよ、ｳｯｻｲﾈ！

```
import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';

void main(){
  runApp(MyApp());
} 

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final wordPair = WordPair.random();
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: Text(wordPair.asPascalCase),
        ),
      ),
    );
  }
}
```
###5:実行してみよう！
flutter run -d chrome　で実行だ

- hot reloadできるよ！appが走っている間に、コード書き換えてリロードしてそれ試すとかいうやつだね！今回はランダム要素を入れたので、リロードするたびに真ん中に出てくる言葉が変わるね！
- 赤いメッセージ気になったらグーグル翻訳するといいよ。今回出てくるのはビルド時のなんかのキャッシュを捨てましたみたいなメッセージだね！
- クロームで表示されてる言葉を確認したら、実行を指示したコンソール上でRだ！リロードのRでhot reloadできる！

##Step 3:Stateful なwidgetを追加しよう
Stateless:変化しない
Statefull:変化します（しなくても別にいいけどね

Stateful widgetには２つ必要なclassがある
１つ目：State class
２つ目：StatefulWidget classというState classのinstanceを作成するクラス（factoryみたいなこと？）
StatefulWidget は変化しません。State classは変化します。

このステップではRandomWordsという名前のstatefulなwidgetを作るぞ！

###1~3 ちっこいのつくろ
下のコードみたいな感じになります。

```
//ロジックとかはこっちにゴリゴリ書いていくそうです。（そりゃそうだ
class RandomWordsState extends State<RandomWords> {
  @override
  Widget build(BuildContext context) {
    final wordPair = WordPair.random();
    return Text(wordPair.asPascalCase);
  }
}

//こっちはclass factoryの役割っぽいね
class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => RandomWordsState();
}
```

###4　MyAppの中で実際に使ってみよう
こんな感じで使えます。コードの差分みてﾌﾑﾌﾑしたい人はtutorialのurlのStep３の４番を見てね。
私のインデントの数字と対応してます。

```
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: RandomWords(),
        ),
      ),
    );
  }
}
```

##Step4 無限スクロールリストビューを作る
ランダム　+　list + スクロール　＝　無限スクロールリストビュー
このスクロールの部分にはListViewというものを使用します。つまり
(RandomWordsState  +  List ) + ListView みたいな使い方をすると考えられる

###1~ \_suggestionsというlistを作って、そこにRandomwordsStateを入れていってなんか表示して出来上がる
"_"（アンダースコア）つかうとprivateメンバとして振る舞うそうです

説明長すぎてよくわからなかったけど、コードはこんな感じになります。

```
import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Startup Name Generator',
      home: RandomWords(),
    );
  }
}

//実態はこっち
class RandomWordsState extends State<RandomWords> {
  final _suggestions = <WordPair>[];
  final _biggerFont = const TextStyle(fontSize: 18.0);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Startup Name Generator'),
      ),
      body: _buildSuggestions(),
    );
  }

  Widget _buildSuggestions() {
    return ListView.builder(
        padding: const EdgeInsets.all(16.0),
        itemBuilder: /*1*/ (BuildContext context,int i) {
          final index = i ; /*3*/
          if (index >= _suggestions.length) {
            _suggestions.addAll(generateWordPairs().take(10)); /*4*/
          }
          return _buildRow(_suggestions[index]);
        });
  }

  Widget _buildRow(WordPair pair) {
    return ListTile(
      title: Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => RandomWordsState();
}

```
###コード解説
EdgeInsets：表示するときの端っこからの距離をピクセルで指定するみたいです。
itemBuilder：ListViewの中の要素一つ一つについて何を作って表示するのか管理してくれるビルダーさん
新しい行のindexがきちゃったら作る（１０個づつ作ってるなコレ）、そうじゃなかったら今までに作っておいたのを返すって感じのロジックがfinalとかifとかそのあたりのお話です。
チュートリアル元のコードがすげーわかりにくかったので、無駄な部分全部消しました。多分読みやすいと思います。


ListViewについて詳しく知りたい方はすでにこの道を通り過ぎていったニキがいましたのでそちらをご確認ください。
https://qiita.com/tasogarei/items/d41e4d0d3cc5dfae4314

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173892/53a73fa0-90fc-64e5-8699-7174d0208b33.png)


#まとめ
ということで、なんとなくflutterを理解しましたので、次回はゲームUIっぽいのを作っていきます。

... to be continued.