主なアイデア
ベンチマークアプリケーション、エンジン、さまざまなソフトウェアシステムについての書籍、記事、チュートリアルが多数書かれています。
古いウィキペディアがこの主題に関して私たちに与えているものは次のとおりです。
パフォーマンステスト、ベンチマーク(英語ベンチマーク)-コンピューターシステムの比較パフォーマンス特性を決定するために必要な制御タスク。
しかし、ゲームエンジンのベンチマークの問題に反対側から少し触れたらどうでしょうか。 多くの場合、ゲーム開発用のすべてのゲームエンジンとSDK(だけでなく)は、非常に直感的で簡単に消化できるツールとして宣伝されています。 私たちは学習するためのシンプルさを販売しています。驚くべき学習とエントリー曲線、軽量で美しい例が示されています。1つのコード画面が起動されると、ある種の素晴らしい魔法が作成されます。 だから、今後のLudum Dareイベントの準備として、私はもう一度「マーケット」が単純なエメレに何を提供するのかを見てみることにしました-1年なしで1週間ゲーム開発に携わった人。 つまり、CAの人々のグループの1つであり、エンジンの消化しやすいこれらの非常に優れた品質を販売しています。
ゲームを作成するためのさまざまなエンジンで作業しながら、自分自身をベンチマークしようとしたらどうでしょうか? はい、はい、それは彼らの生産性です。 文字通り、それらのいくつかを取り、ラップトップ、インターネット、ストップウォッチを備えた洞窟に閉じ込めて、すべての結果をきちんとしたタブレットに書き留めてから、結論を出そうとします。 同時に、私はそれが気に入っていることに気付きました。
ベンチマークについて
したがって、テストオブジェクトは3つのゲームエンジンです。 ここで、「構成」を多少なりとも形式的に(可能な限り)正式に説明する価値があります(はい、典型的なベンチマーク結果の場合のように、実行した鉄の構成、ベンチマークの説明などを記述します)。
「構成」または自己紹介
私はJava開発者です。 5年以上の産業開発の経験。 また、私はJavaScriptで少し書いたLua(本当に、本当に)シェル。 高等技術教育。 デザインコースを受講せず、ゲームデザインも学ばず、さまざまなPCゲームの熱烈なファンでした。 昨年、彼は最も単純なコンピューターゲームの作成に興味を持ちました。
タスクについて
ゲームDoodle Jumpのクローンのテストプロジェクトが選択されました。 多くの人がこのゲームを知っているか、プレイしたことがあると思います。これはAndroid向けの非常にクールで非常に発達したゲームです。
規制は次のとおりです。
- 各エンジンには4時間の時間があります。 これには、勉強、知り合い、鼻をほじる、プロトタイプを作成しようとする、ゲームをデバッグする、一般にゲームを作成する全サイクルが含まれます。
- 30分ごとに、短い休憩中に、作業内容を何らかの形で修正するために行われたことを記録し、さらなる作業計画の概要を示し、メモやメモなどを作成します。
- 各エンジンのテストを開始する前に、ゲームプロジェクトを構成要素に分解して、従来のユニットを割り当てようとします。 したがって、オウムの各エンジンのゲーム開発者の「生産性」を測定し、結果を言葉ではなく、少なくともいくつかの数で比較できます。
ゲームのコンポーネントへの分解
非常に抽象的でトップレベルのフォームでは、次のように自分がゲームのコンポーネントを構成しています。
- プレーヤー(スプライト、ジャンプ動作、押されたボタンへの反応)
- レベルオブジェクト:プラットフォーム、敵など
- 物理学:プレーヤーのジャンプ速度、自由落下の加速、プラットフォームは、上からジャンプした場合にのみ衝突を処理し、プラットフォームの底部から交差する場合はプレーヤーを通過させます。
- 手続き型レベルの生成:初期化と新しいプラットフォームと敵の飛行中のレベルへの追加(任意の場所に、ただし特定のルールと制限付き)、プレイヤーに魅力的なゲーム状況を作成
- プレイヤーがレベルを上に移動するときに追従する「カメラ」。 カメラはプレーヤーの視界を維持し、プレーヤーと徐々に「バウンド」し、レンダリング領域に表示される新しいプラットフォームを表示する必要があります(カメラの視界内)
-
Game Over
トリガーメカニズム。 プレーヤーは、表示領域の下端に到達すると負けます(少なくとも1回ジャンプした後) - プレーヤーの得点。 プレーヤーの身長カウンターを更新するだけです。 最後に到達したプラットフォーム(最後にプッシュしたプラットフォーム)に応じてカウンターを更新します
-
HUD
:プレーヤーの進行状況を表示します。 高さ表示。
簡単にするために、各コンポーネントにオウムユニットの1ポイントを割り当てます。 合計最大-つまり プロジェクトの完全なプレイ可能なバージョンは8ポイントです。
以下は、ディスプレイで使用されるアセットです。 これらは手描きです(ご覧のとおり、私はアーティストではありません)。キャラクターとプラットフォームのスプライトは64x64、* .png形式の寸法です。
また、いくつかのフローチャートを示します。
- したがって、プレーヤーの「性別」の計算が実装されます(ジャンプして、画面が移動し、画面の端からの逸脱が溝を意味することを忘れないでください)
- そして、各ビートでのプレーヤーの垂直速度(
y_velocity
)とy
座標を計算して更新します。これは、重力加速度(GRAVITY
)とプラットフォームに影響されます。
- 水平速度を計算するアルゴリズムは、他のメカニズムと同様に、記事の範囲外でした。
ところで、私にはまだ質問があります:
- プレーヤーにカメラトラッキングを実装する方が良いでしょうか? これまでのところ、プレーヤーが到達できた最後の最も高いプラットフォームの垂直座標に関連付けられているため、このプラットフォームは表示領域の下部にあり、生成されたレベルの新しい部分が表示されます。
- プラットフォーム生成アルゴリズム自体。 私の考えによれば、これは一種の「プラットフォームの工場」であり、ゲームサイクル(
dt
)の各サイクルで、レベルにランダムな高さ(特定のしきい値、プレイヤーのジャンプの高さを超えず、特定の割合以上で存在する最高のプラットフォームプラットフォームが互いにくっつかないように、その高さ)プレーヤーが進んだときにレベルに新しいプラットフォームを追加します。 ここでは、ゲームの複雑さを増すという問題も興味深いです。これらのプラットフォームを生成するモードをどのように変更するかです。
これら2つの間違いなくゲームデザインの問題に関するコメントやPMでのアイデア、ライフハック、提案に非常に満足しています。
エンジンについて
私にとって非常に興味深い機能を持つ3つの候補が選ばれました。 そのため、テストの結果を分析するときに覚えておくと便利なパラメーターを以下にまとめます。
エンジン | YaP | エンジンの経験(0-いいえ、1-経験といくつかの簡単な書面によるゲームがあります、2-エンジンは、全体にわたってマスターされています | PLの経験(0-いいえ、1-構文、言語のイディオムについての経験と十分な知識と理解がある、2-このPLの長所 |
---|---|---|---|
展開する | ルア | 0 | 1 |
Love2d | ルア | 1 | 1 |
Fxgl | Java | 0 | 2 |
そのため、選択が非常に興味深いことがわかります。 エンジンの品質と特性のさまざまな組み合わせを扱うという点で興味深いです。 そして、最終的に解決するものを見てみましょう:私はすでに少し手を手に入れたエンジン、ポンプされたYP、または有望なチップを備えた完全に新鮮で新しいエンジンですが、完全にはマスターされていません。さらに、メインの開発言語ではありません。
Unity / Unreal Engine /その他の恐ろしいエンジンなどはいかがですか?
多くの人は、なぜ私が標準的な方法を採用せず、私たちの時代の最も一般的な旗艦、UnityまたはUnreal Engineを採用しなかったのかと疑問に思うでしょう。 このように考えを定式化します。非常にシンプルで、ミニマルで、小さなゲームを作りたいです。 ゲームの仕組みを構成する2つのゲーム要素、1つのプレイ可能なキャラクター、単純なレベルの生成、および特殊な効果や古いアーケードマシンのような非常に従来的な特殊効果なし。 ですから、比speaking的に言えば、私の仕事は黒い四角に赤い円を描くことであり、そのためにPhotoshop
を撮ることに招待されています。 簡単に言えば、 Unity
一連の機能、モード、および機能が私を怖がらせました。 この段階で、ゲームの詳細をすべて理解したいと思います。
これは、おそらく最適なチューニングとエコシステムではなく、限られた機能セットを備えたシンプルで小さなエンジンによって最適に行われますが、シンプルさと制限にも独自の美しさがあります。 限られたツールセットだけで-Love2Dの場合、あなたのツールはあなたのコードであり、他には何もありません。あなたはファン、クールな何かを書き、キャラクターやプレイヤーの環境を復活させることに集中します。 すでにより複雑なエンジンが選択肢を広げ、コードを書くことは多くのことにスムーズに流れます:スクリプト(コード)の作成、スクリプトのリンク、アセットのマッピング、構成の追加、構成の再定義、サードパーティプラグインの混合、サードパーティプラグインのスクリプトと構成の作成、複数回のクリック何十ものダイアログとウィンドウ...とりあえず、このような洗練された疑いもなく高度で強力なゲーム開発エンジンを今でも恐れていると言いましょう。 まあ、私は再びC#/ JS / C ++を覚えて、それらに書きたくありません。
このビデオへのリンクを使用してエンジンを選択するときの動機を要約します。著者は文字通り、私自身や他の人に言葉で定式化しようとしたものを文字通り私の言語から文字通り削除したようです: https : //www.youtube.com/watch ?v = JH8xwNOQ0TM
展開する
Defold
は、Kingのクロスプラットフォームエンジンです。
サポートされているプラットフォーム:
- Html5(WebGl)
- Android 2.3(APIレベル9)+
- iOS 8.0以降
- Windows Vista +
- OSX 10.7+
- Linux
奇妙な事実は、キングがアクティビジョンブリザードに所有されていることです。
エンジンでは、開発言語であるLua
に魅了されました。Luaは、ゲームビルド用の多数のプラットフォームのサポートと、独自のクロスプラットフォームIDE
配布をLinuxにもインストールできます。 これにより、 Defold
vs Corona SDK
。
以下は、コントロールポイントで行われたログです。
いや | 時間 | コメント |
---|---|---|
1 | 30m | 1人のチューター、エディターの入門的な説明をいくつか見て、テストプロジェクトをテストしました(クリックハンドラーのコーディング、トレーニングプロジェクトのドックの読み取り) |
2 | 1時間 | テストトレーニングプロジェクトにいくつかの変更を追加しました。 おそらく、あなたのプロジェクトを取り上げて、少なくともそこに何かを実装しようとする時でしょうか? |
3 | 1時間30分 | ジャンピングメイド(ビヘイビア付きスプライト)。 悪くない! :) |
4 | 2時間 | 制御を追加します。 また、プラットフォームと衝突を追加するときですか? 管理とプラットフォームを追加しましたが、残念ながら、私は衝突を処理することができませんでした.. |
5 | 2時間30分 | 衝突! 男性がプラットフォームにジャンプして、さらにプラットフォームからプッシュする方法を知っていることが必要です。 じゃあ 競合がありますが、これまでのところメカニックは曲がっています:) |
6 | 3時間 | やれやれ、矛盾があり、それは真実のようです。 プラットフォームのコピーをいくつか配置しようとしました。 |
7 | 3時間30分 | ここで、プレーヤーが新しいより高いプラットフォームにジャンプするときに浮かぶフローティングカメラについて考える必要があります。 私は前進しませんでしたが、カメラをねじ込む複雑さだけに埋もれています...スナップのようで、カメラをセットアップするのはとても簡単です。 |
8 | 4時間 | HUD。 プレーヤーの現在の床からの高さを表示します。 |
以下のネタバレでは、時間の経過を示すgifアニメーションがいくつかあります。
0-1h
1〜2時間
4時間
結果、ベンチマークポイント:
- プレーヤー(スプライト、ジャンプ動作、押されたボタンに対する反応)
(V) Yes
- レベルオブジェクト:プラットフォーム、敵など
(V) Yes
- 物理学:プレイヤーのジャンプ速度、自由落下加速、プラットフォームは、上からジャンプされた場合にのみ衝突を処理し、プラットフォームの底部から交差した場合はプレイヤーを通過させます。
(V) Yes
- 手続き型レベルの生成:初期化とレベルへの追加(任意の場所に、ただし特定のルールと制限がある)新しいプラットフォームと敵をその場で追加し、プレイヤーに魅力的なゲーム状況を作成します
(X) No
- プレイヤーがレベルを上に移動するときに追従する「カメラ」。 カメラはプレーヤーをプレーヤーの視野内に保ち、徐々に「バウンス」して、レンダリング領域(カメラの視野内)に表示される新しいプラットフォームを表示する必要があります
(X) No
- ゲームオーバートリガーメカニズム。 プレーヤーは、可視領域の下端に到達すると負けます(少なくとも1回はジャンプした後)
(X) No
- プレーヤーの得点。 プレーヤーの身長カウンターを更新するだけです。 最後に到達したプラットフォーム(最後にプッシュしたプラットフォーム)に応じてカウンターを更新します
(V) Yes
- HUD:プレーヤーの進行状況を表示します。 高さ表示。 必要に応じて、元のゲームには進行状況インジケーターがないようです。
(V) Yes
ベンチマークスコア:5/8
Love2d
これは非常にミニマルですが、十分に強力で柔軟なプロトタイプエンジンです。 一般に、十分な器用さを備えているため、本格的なゲームを市場に公開するのにも適しています。 いくつかの良いインスピレーションの例があります。 オフハンド、 ワンおよびツー 。
一般に、このエンジンについては、Habrの非常に適切な一連のチュートリアルをお勧めします。これは、このエンジンの開発に拍車をかけ、強力な弾みを与えました。最初の部分へのリンクのみを提供し、それから残りの部分にアクセスできます:
そのため、以下はチェックポイントで行われたログです。
いや | 時間 | コメント |
---|---|---|
1 | 30m | プロジェクトのセットアップ、基本的なハンドラーの作成、プレーヤークラスの作成(ジャンプロジックと重力を使用したフレームワークはまだ機能しません) |
2 | 1時間 | プラットフォームが描かれた工場が作られ、ジャンプマンが作られました。 やった! |
3 | 1時間30分 | hardoncolliderライブラリをねじ込もうとしています。 公式ウェブサイトのドックが古いバージョンに従って書かれているという事実に関連するフラストレーション、現在のドックの検索、衝突のねじ込み。 衝突はまだ実装されていません |
4 | 2時間 | 競合がありますが、それらは曲線です:( |
5 | 2時間30分 | 衝突が発生し、いくつかの欠陥がありますが、一般的に-規範。 プレイヤーのジャンプに続いて、プレイヤーを追跡するカメラを固定しようとします。 まだあまり成功していない.. |
6 | 3時間 | プラットフォームの世代がありますが、衝突はまだバグがあり、ラメです:( |
7 | 3時間30分 | ゲームオーバーの定義が実装されました-プレイヤーが表示領域の下端を越えたという決定です。 スコアリングが実装されています-つまり 最後に撮影した高さの左上隅に表示する |
8 | 4時間 | Love2dエンジンでDoodle Jumpクローンを4時間開発した後に達成されたことについては、以下の表を参照してください。 |
エンジンの「パフォーマンス」を計算します。
- プレーヤー(スプライト、ジャンプ動作、押されたボタンに対する反応)
(V) Yes
- レベルオブジェクト:プラットフォーム、敵など
(V) Yes
- 物理学:プレイヤーのジャンプ速度、自由落下加速、プラットフォームは、上からジャンプされた場合にのみ衝突を処理し、プラットフォームの底部から交差した場合はプレイヤーを通過させます。
(V) Yes
/(X) No
// *実装されていますが、完全なものではなく、重大な欠陥があります。 ここにアイテムを完成させるために0.5ポイントを入れます。 - 手続きレベルの生成:初期化と新しいプラットフォームと敵の飛行中のレベルへの追加(任意の場所に、ただし特定のルールと制限付き)、プレイヤーに魅力的なゲーム状況を作成
(V) Yes
- プレイヤーがレベルを上に移動するときに追従する「カメラ」。 カメラはプレーヤーの視界を維持し、プレーヤーと徐々に「跳ね返り」、レンダリング領域に表示される新しいプラットフォームを表示します(カメラの視界内)
(V) Yes
- ゲームオーバートリガーメカニズム。 プレーヤーは、表示領域の下端に到達すると負けます(少なくとも1回はジャンプした後)
(V) Yes
- プレーヤーの得点。 プレーヤーの身長カウンターを更新するだけです。 最後に到達したプラットフォーム(最後にプッシュしたプラットフォーム)に応じてカウンターを更新します
(V) Yes
- HUD:プレーヤーの進行状況を表示します。 高さ表示。 必要に応じて、元のゲームには進行状況インジケーターがないようです。
(V) Yes
ベンチマークスコア: 7.5 / 8
Java
おそらく、論理的および論理的なステップは、開発言語が私が最も経験と器用さを持っている言語であるエンジンを詳しく調べることでしょうか? 実際、直観といくつかの内的な感覚が私をこのことから少し遠ざけました。 事実、学生として、私はjMonkey
エンジンを使用しているクラスメートがjMonkey
でいるのを何とか見ました。 ツーリング、エンジンの操作、ドキュメント、これらすべてが一緒になって、ある種のあまり好ましくない状況を作り出しました。 エンジンは単にあなたにそれを友達にする機会を与えなかったようで、その使用は非常に不愉快に見えました。
それでも、今日利用できるものを見ることにし、 2D
のみを十分に保証するエンジンにのみ注目しました3D
サポートについては気にしませんでした。 エンジンの1つであるLightweight Java Game Library 3には、その名前に導入語Lightweight
れています。 皮肉なことに、メインページの最も単純で基本的な例(数画面にわたる)は、単に怖がってしまいました。
はい、もちろん、 Java
非常に冗長です。 しかし、非常にコンパクトで表現力豊かなものを書くことができることを知っています。 美しくコンパクトなAPIを見ました。
そして、結局、選択はFXGL
落ちました。 最初は、面白いものや図書館が開発される前に起こる熱意と楽しい興奮はありませんでした。 しかし、すでに最初の例とドキュメントと例の短いページから、このエンジンは私をますます驚かせました。 彼が提案したアプローチとAPIのすべてが論理的で理解しやすく、一貫性がありました。 ゲーム、ハンドラーロジック、 HUD
、 AI
、衝突、その他の要素に対して明確で柔軟なループを構築するのに役立ちました。
興味深い瞬間とFXGLチップ:
名前からわかるように、視覚部分では、エンジンはJavaFX API(
JavaFX
はグラフィックフレームワークとして使用されます)を使用し、レンダリングとレイアウトのすべての利点と反利点を備えています。 一般的に、これは良い決定であると思います。 したがって、著者は多くの問題を回避しました(レンダリングコンポーネントを実装および保守する必要はありませんJava
エコシステムの洗練されたソリューションを使用できます)。 著者自身が彼の最初のチュートリアルの1つで言っていることを以下に示します。私はこのフレーズが本当に好きでした。
「ほとんどのUIオブジェクトでは、ホイールを再発明する必要がないため、単にJavaFXオブジェクトを使用します。」
しかし、一般に、もちろん、
JavaFX
多くの機能といくつかの欠点もあります(詳細についてはあまり詳しくありません)が、私が知る限り、プロジェクトでのJavaFX
の使用にはいくつかのライセンス制限があり、JavaFX
ようですJDK
限定配信(Oracle
、おそらくそれ以上)でのみ使用されOracle
。
リポジトリから傾斜したテストプロジェクトは、それに基づいてゲームのスカルプトを開始し、ゲームを開始するたびに
logs/
プロジェクトlogs/
追加しlogs/
。 これは非常に便利で、すぐにデバッグ情報を見ることができます。診断に非常に役立ち、エンジンの研究で突然プラグインに遭遇した場合、どこで混乱したかを理解できます。
また(明らかに、基本設定で)、ゲームは
Esc
押すことでポップアップメニューを提供します。 また、素晴らしいボーナスです。コードまたは構成によってカスタマイズされるか、少なくとも無効にされることを願っています。
デバッグはついにここで動作します ! ついに!
Love2D
に言っても、不便で不快です。
開発ログ
以下は私の進歩の簡単な要約です。30分間隔の後に達成されたことと、私の考えとコメントのいくつかを簡単に書きました。 これらの4時間で私の意識のログを見てください!
いや | 時間 | コメント |
---|---|---|
1 | 30m | いくつかのチュートリアルを学びました。 基本的なAPIとゲームループ構造。 スプライトの描画、オブジェクトの移動、HUDの表示および更新の方法を学びました。 ゲームに衝突をねじ込み始めました。 |
2 | 1時間 | 衝突体(バウンディングボックス)と「床から押し出すことができる」ジャンピングボックスがあります(つまり、画面の下側の境界の定義があります) |
3 | 1時間30分 | プラットフォーム構築ファクトリー(PlatformFactory.java)の基礎が構築されました。 私たちはなんとか「衝突を飼いならす」ことに成功し、プラットフォームからのキャラクターの反発を達成することができたようです。 これは間違いなく新しいエンジンの成功であり、GitHubWikiチュートリアルの半分を読んだ経験があります。 |
4 | 2時間 | プラットフォームとの衝突が少し確定しましたが、まだバグがあり、完全ではありません。 かなり迅速にカメラでトラッキングを行うことができました。これも少しシャープで不器用ですが、研磨の滑らかさはベンチマークの範囲外であり、特にFXGLでの経験です。 また、プラットフォームが最後に生成されたプラットフォームから許容可能なランダムな距離で生成されるように、プラットフォーム生成ファクトリーのコードを追加することは難しくありませんでした。 また、プレーヤーの進行に合わせてそれらを生成するコードもメインゲームサイクルに統合されました。 私にとってはかなり良い進歩です。 |
5 | 2時間30分 | じゃあ この時点で、実質的にゲーム全体の準備ができています。 すべての基本コンポーネントが実装されています。 プレイヤーをプラットフォームから遠ざけるための正しいメカニズムでさえ(すごい!)ファイルで磨き上げてファイナライズしましたが、これは前の2つのエンジンでは完全には達成できませんでした。 おそらく、蓄積された経験と直観がすでにここで影響を受けていると私は主張しません。 また、新しいプラットフォームの位置を計算するためのランダマイザーが少しミュートされ、以前のパラメーターでは絶対に達成できないプラットフォームが登場し、ゲームオーバーに至りました。 |
6 | 3時間 | Doodle Jumpのもう1つの重要な機能(メインタスクの範囲外にあったもの)が実装されました-プレイヤーがレベルの左端または右端を飛び越えると、スピード(インパルス)を維持しながら反対側に現れます。 このゲームプレイは、Doodle Jumpの非常に重要なコンポーネントです。 他の要素の中でゲームを多様でキャッチーなものにしているもの。 また、ゲームのリセット機能(Reset)がすぐにスローされ、敵と敵のAIのコードがスローされました。 これまでのところ、これはゲーム内ではなく、プロトタイプレベルです。 |
7 | 3時間30分 | レベルで敵をランダムに生成するアルゴリズムが実装されています。 それはまったく完璧ではありませんが、すでにプレイヤーに楽しさと挑戦の要素を追加しています。 AI , — - , , . . |
8 | 4h | . — . , . , , Space
. |
GIF- , .
0-1h
1h-1h 30m
2h 30m(実際、ゲームの基本的な要素はすべてここに実装されています)
3h 30m
4h
"" … , , , ? .
Benchmark Score: 8
, ,
:
YaP | (0 — , 1 — , 2 — | (0 — , 1 — , , 2 — | Benchmark Score | コードの行 | |
---|---|---|---|---|---|
Defold | Lua | 0 | 1 | 5/8 | 166 |
Love2D | Lua | 1 | 1 | 7.5/8 | 701 |
FXGL | Java | 0 | 2 | 8 | 582 |
, , , ( ). , , Java FXGL
, , Lua
, . , , .
:
-
FXGL
? 私はそうは思わないでしょう。Love2D
,Defold
, , , ,Love2D
- , . - , . , . (, ), . , - . , , , , . , , , . .
- gif-, . . , , "" , .
?
, - , ?
だから:
- , . , , , , . - , - (
Love2D
). - - ,
Love2D
, .F to pay respect
. - . , , , - - , , (, , )
- . 4 , . -
Game Jam
, . - ! , , - Roadmap , , . (!) (?) . 30数分で完成品に移行できました。進歩は刺激を与え、力を与え、失敗は問題へのアプローチを考えたり修正したり、精神的および一時的なリソースを再分配してリストの主要な要素を完成させなくなりました。私を信じて、これはあなたが望むなら、最高のマネージャーのスキルやリードを自分の中に押し込んでいるようなものです!おそらく、この技術は、私が腕に、彼の他のペットのプロジェクトに取ると、当然の到来に適用されます44回目
Ludum Dare
。