フラッターゲーム:起動時にWelcomeページ

免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/hekaiyou/article/details/96916442

この記事の内容は、上の次のコードの完了時にああする必要があります!

その他のリソースをロード

まず、使用するには、以下をダウンロードしたゲームのリソースどのような追加されたコンテンツについて話をするので、ここでは、以前にダウンロードの一環として、ファイルを。

  • ブランディング/ title.png:ゲームタイトル画像、勧告7:4サイズ、つまり7x4タイル
  • UI /開始button.png:ボタンゲームを開始するために、提言2:1のサイズ、すなわち6x3ブロック
  • BG /負け-splash.png:画像ゲームオーバー、勧告7:5サイズ、すなわち、7x5のタイル
  • UI /ダイアログ-credits.png:バージョン情報]ダイアログボックスの勧告3:2サイズ、すなわち、12x8タイル
  • UI /ダイアログ-help.png:ほぼ同じサイズと、ダイアログボックスのヘルプ
  • UI /アイコン-credits.png:アイコンについては、ブロックサイズを二乗することをお勧めします
  • UI /アイコン-help.png:ヘルプアイコン、アイコンサイズと同じで

これらのリソースの理解がやっている、彼らはに次のコードを追加し始めたpubspec.yamlファイルのassetsセクション。

flutter:
  uses-material-design: true

  assets:
    ...
    - assets/images/bg/lose-splash.png
    - assets/images/branding/title.png
    - assets/images/ui/dialog-credits.png
    - assets/images/ui/dialog-help.png
    - assets/images/ui/icon-credits.png
    - assets/images/ui/icon-help.png
    - assets/images/ui/start-button.png

開いmain.dartたファイルを、そしてちょうどでpubspec.yaml追加するリソースファイルを渡すFlame.images.loadAllと呼ばれる文字列(Stringリスト)。

  Flame.images.loadAll(<String>[
    ...
    'bg/lose-splash.png',
    'branding/title.png',
    'ui/dialog-credits.png',
    'ui/dialog-help.png',
    'ui/icon-credits.png',
    'ui/icon-help.png',
    'ui/start-button.png',
  ]);

これは、ゲームのリソースの事前ロードの一部を完了します。

準備ゲームのページ

良いゲームは、長い試合後、勝敗だけでなく、特定のページの結果をウェルカムページやゲームのページを持って、そしてプレイヤーがゲームのページへようこそページから切り替える必要があるとき、[スタート]ボタンをクリックする必要があります。だから、私たちのゲームは、次の3つのページを持っている必要があります。

  • Welcomeページ:あなたがゲームを初めて開いたとき、ウェルカムページ、またはメインページを呼び出し、ビューは、ゲームタイトルの中央に表示され、その後、ページの下部には、[スタート]ボタンを表示します。
  • ゲームのページ:プレイヤーがゲームをプレイするとき、これはタイトルのゲームを隠しページを参照してください、と蚊のランダムな運動に焦点を当てています。
  • 失敗ページ:プレイヤーが失敗したときにプレイヤーが失敗した場合、スプラッシュページがあるだろう、特定の状況があり、障害の迅速なスプラッシュイメージプレーヤーの試合になるだろう、とスタートボタンで、プレイヤーは再び開始することができ、画面の中央です。

上記の3つのページの場合、同じ背景を表示し、蚊が試合リアルガイドプレイヤーに歓迎し、また、最後のゲームプレイヤーがゲームのページがメインページで、ウェルカムページが実際のホーム・ページで感じさせるれ、表示されていますページの終了後の失敗は、プレイヤーは、ページの残りの部分を失敗し、再度起動しています。

この目的のために、我々はあなたが整数を使用してこれを行うことができ、現在のページを、記録する必要があり、ページ番号またはページも0-2から録画する文字列を指定できます。

ダートの言語では、列挙(そこにあるenumだけで、このような状況に対処するために使用することができます)データ型は、我々は、ゲームのプレイヤーが列挙またはページへのときにページの変更を指示しているページが表示されます。新しい作成しlib/view.dartたファイルを、次のコードを追加します。

enum View {
  home,
  playing,
  lost,
}

今、あなたはそれが私たちのために、現在のページの値が保存されます、ゲームのためにインスタンス変数を追加する必要があります。そのため、ページの前にインポートするためにそれを使用するためにView列挙して、インスタンス変数を追加します。我々は(それをアクティブなページの名前activeViewタイプ設定、)View列挙型を。

開いhit-game.dartたファイルを、次のコードを提出します。

...
import 'package:hello_flame/view.dart';

class HitGame extends Game {
  ...
  View activeView = View.home;

だから私たちは、それぞれのページを処理する準備が整いました。

実現ウェルカムページ

すでに単にウェルカムページは言った、とのコードで、ページはちょうど別の論理同様の構成要素である、自分のサブアセンブリを持つことができています。また、仮想することができ、関係なく、プレイヤーが実際にページを見るもの、それが常に表示されません。

ページを定義するときにウェルカムページならば、私たちは他のコンポーネントと同様に、コンポーネントクラスを使用します、我々は単に(ゲームループからそのインスタンスをレンダリング呼び出すrender)、更新(update)メソッド。

まず、libディレクトリの作成viewsディレクトリ内のフォルダを作成しviews/home-view.dartたファイルを、次のコードを記述します。

import 'dart:ui';
import 'package:flame/sprite.dart';
import 'package:hello_flame/hit-game.dart';

class HomeView {
  final HitGame game;
  Rect titleRect;
  Sprite titleSprite;

  HomeView(this.game) {}

  void render(Canvas c) {}

  void update(double t) {}
}

上記のコードで、ファーストクラスおよび使用する定義ファイルをインポートし、その後、我々は名前の定義HomeView3つのインスタンス変数、であるのいずれかを持つクラスをfinal、あなたは、このクラスのインスタンスを作成するときに転送し、割り当てる必要があります。一方のクラスは、コンストラクタ、さらに二つの方法、すなわち、(ゲームループをレンダリング有するrender)および更新(update)メソッド。

コンストラクタで初期化titleRectしてtitleSprite、彼らは(レンダリングすることができるように変数をrender使用)の方法を。

  HomeView(this.game) {
    titleRect = Rect.fromLTWH(
      game.tileSize,
      (game.screenSize.height / 2) - (game.tileSize * 4),
      game.tileSize * 7,
      game.tileSize * 4,
    );
    titleSprite = Sprite('branding/title.png');
  }

上記二行、第一行動titleRect変数割り当て、第二行動titleSprite変数。前記titleRect変数の値が矩形である(Rect定義)、4行は、植物コンストラクタに対応する.fromLTWH必要なパラメータ。

我々は判断するため7×4のタイルのヘッダ中に表示画像を、それがなりgame.tileSize * 7、そしてgame.tileSize * 4最後の二つのパラメータに伝達、これら2つのパラメータは、矩形の幅と高さに対応します。

左(のためのleft)パラメータから9タイルの画面サイズの幅、タイトル画像差し引くことによって7タイルのサイズを得ることができる矩形の幅2余分なスペースタイル。これらのタイトル画像の中心にするために2、追加のタイルが画像シフトの左右に振り分け1タイル。だから、ここではに導入game.tileSize * 1または単に渡しますgame.tileSize

トップ(top私たちは、画面の中央に画像のタイトルをしたくないので)パラメータは、異なっています。、単純に画面の高さ割ることによって、画面の中央の位置を計算するには2から減算に、4タイトル画像の高さのタイルサイズを、あなたは中央の適切なオフセット位置を取得することができます。

今、私たちは、初期化titleRecttitleSprite実際の画像を表示するためのコードを書き始めることができ、(レンダリングrender次のコードを追加し、)メソッドを。

  void render(Canvas c) {
    titleSprite.renderRect(c, titleRect);
  }

今開いてhit-game.dartファイルを、およびインポートするHomeViewクラスファイルを、その後、追加HomeViewhomeViewのインスタンス変数を。次に、画面サイズを決定する際にインスタンス変数を初期化する必要があり、そのコールはresize後に、なりますinitialize次のコードのメソッドを追加します。

...
import 'package:hello_flame/views/home-view.dart';

class HitGame extends Game {
  ...
  View activeView = View.home;
  HomeView homeView;

  ...

  void initialize() async {
    ...
    homeView = HomeView(this);
    produceFly();
  }

最後に、レンダリングのオンスクリーン使用HomeView(レンダリングrender)、したがって、ゲームクラス(レンダリングrender)メソッドを、最後の呼び出しがするHomeView(例えば、レンダリングrender、その最終的なレンダリング)メソッドを。

我々は最初の背景をしたいので、表示順序と同じ順序のレンダリングするので、その後、蚊は、最後には、画面上のタイトル画像は、すべてのコンテンツが配置されていることを保証します画像のタイトルです。

  void render(Canvas canvas) {
    background.render(canvas);
    enemy.forEach((Fly fly) => fly.render(canvas));

    if (activeView == View.home) homeView.render(canvas);
  }

上記のコード、最初のアクティブなビューを(決定されるactiveView)は、現在メインビューであり、もしそうであれば、レンダリングHomeView例えば、そうでない場合、レンダリング(render)メソッドは、コードの行をスキップし、したがって提示しないHomeView例。

次の図に示すように、今すぐゲームを実行、あなたは結果を見ることができます。

ここに画像を挿入説明

ゲームはページ内にまだあったときしかし、その後、プレイヤーはまだクリックすると、蚊を取り除くが、それは大丈夫だ、それはゲームへの影響はありません。次に、プレイヤーがゲームを開始しますので、スタートボタンがなければなりません。まず、名前の別のコンポーネントを作成しStartButton、新しい置くcomponents/start-button.dartファイルを。

import 'dart:ui';
import 'package:flame/sprite.dart';
import 'package:hello_flame/hit-game.dart';

class StartButton {
  final HitGame game;
  Rect rect;
  Sprite sprite;

  StartButton(this.game) {}

  void render(Canvas c) {}

  void update(double t) {}

  void onTapDown() {}
}

这个类定义与其他组件类大致相同,不同的是它有一个onTapDown处理程序,我们将在这里编写“开始”游戏的代码。首先在构造函数中初始化rectsprite变量。

  StartButton(this.game) {
    rect = Rect.fromLTWH(
      game.tileSize * 1.5,
      (game.screenSize.height * .75) - (game.tileSize * 1.5),
      game.tileSize * 6,
      game.tileSize * 3,
    );
    sprite = Sprite('ui/start-button.png');
  }

上面的代码与HomeView类构造函数中,标题图像的初始化基本相同。不同的是,除了6×3个图块大小外,还有左侧(left)和顶部(top)偏移。

开始按钮的宽度为6个图块,这意味着在屏幕的9个图块宽度上有3个额外的图块,这样的话,每侧都有1.5个图块,所以这里将game.tileSize * 1.5提供给左侧(left)参数。对于顶部(top)参数,这样就可以让按钮的垂直位置恰好位于屏幕高度的四分之三即0.75的位置。

在初始化rectsprite变量之后,需要渲染图像,所以要下面代码添加到render函数中。

  void render(Canvas c) {
    sprite.renderRect(c, rect);
  }

接下来需要在游戏类中添加一个StartButton组件的实例,打开hit-game.dart文件,导入依赖,然后将实例变量与其他实例变量一起添加。同时在确定屏幕大小后,使用StartButton类的新实例初始化startButton变量,并在render方法中增加下面代码。

...
import 'package:hello_flame/components/start-button.dart';

class HitGame extends Game {
  ...
  HomeView homeView;
  StartButton startButton;

  ...

  void initialize() async {
    ...
    startButton = StartButton(this);
    produceFly();
  }

  ...

  void render(Canvas canvas) {
    ...
    if (activeView == View.home || activeView == View.lost) {
      startButton.render(canvas);
    }
  }

上面代码中,我们添加的这4行代码,分别是导入StartButton类、创建StartButton类的实例并将其存储在实例变量中、最后展示StartButton到屏幕上。

现在运行游戏,可以看到开始按钮会在欢迎页面和失败页面上呈现,这样玩家就可以从欢迎页面或失败页面重新开始游戏了。

ここに画像を挿入説明

处理开始按钮

在上一步中,我们让开始按钮显示在屏幕上,但是点击没有反应,不用急,接下来就开始处理开始按钮的响应逻辑。首先,需要确保点击不会穿过物体,例如在点击开始按钮(startButton)时,同一位置的蚊子不应该接收到点击事件。

在游戏类的onTapDown处理程序中创建一个isHandled变量,用于保存当前是否已调用了点击处理程序,在onTapDown处理程序的开始处创建它,并将初始值设置为false。在检查点击是否命中矩形(Rect)组件之前,先检查isHandled是否仍为false值,然后再调用组件的点击处理程序。

  void onTapDown(TapDownDetails d) {
    bool isHandled = false;

    if (!isHandled && startButton.rect.contains(d.globalPosition)) {
      if (activeView == View.home || activeView == View.lost) {
        startButton.onTapDown();
        isHandled = true;
      }
    }

    enemy.forEach((Fly fly) {
      if (fly.flyRect.contains(d.globalPosition)) {
        fly.onTapDown();
      }
    });
  }

上面代码中,首先对isHandled进行检查,确保尚未处理点击事件,这个检查项与检查点击是否在开始按钮(startButton)的rect属性内是一起的。如果通过了这些条件的检查,再额外检查玩家是否当前处于欢迎页面或失败页面中。

只有满足所有条件,游戏才会调用开始按钮的onTapDown处理程序,变量isHandled也被设置为true,让下面的代码知道已经处理了这次的点击。接下来要做的是,使用isHandled检查把之前的蚊子点击处理程序包装起来。

  void onTapDown(TapDownDetails d) {
    ...

    if (!isHandled) {
      enemy.forEach((Fly fly) {
        if (fly.flyRect.contains(d.globalPosition)) {
          fly.onTapDown();
          isHandled = true;
        }
      });
    }
  }

上面的代码基本上与上面类似,首先包含了对isHandled的检查,这使得代码块只会没有处理开始按钮的情况下运行,其次,如果至少有一个蚊子被点击,则将isHandled变量设置为true

次に、開いてcomponents/start-button.dart、ファイルを[スタート]ボタンをクリックし、実際の符号化処理を開始します。スタートボタンを呼び出すことでonTapHandler、ゲームをする必要がactiveView設定されView.playing、ので、ここで最初の定義をインポートView列挙文書を。そして、onTapDownゲームのがあるでしょうactiveView所望の値に設定します。

...
import 'package:hello_flame/view.dart';

class StartButton {
  ...

  void onTapDown() {
    game.activeView = View.playing;
  }
}

今、ゲームを実行した後、あなたは私達の前のゲームのページに、なくなっている[スタート]ボタン、ヘッダー画像、および[スタート]ボタンをクリックして見ることができます。

ここに画像を挿入説明

おすすめ

転載: blog.csdn.net/hekaiyou/article/details/96916442