ホームページ  >  記事  >  テクノロジー周辺機器  >  幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

WBOY
WBOY転載
2023-04-11 22:16:071493ブラウズ

2 年以上前、Adobe は 2020 年 12 月 31 日に Flash のサポートを終了するという注目を集める発表を行い、ひとつの時代の終わりを告げました。

2 年後、Adobe はすでに Flash Player の初期バージョンのアーカイブをすべて公式 Web サイトから削除し、Flash ベースのコンテンツの実行をブロックしました。 Microsoft はまた、Adobe Flash Player のサポートを終了し、Microsoft ブラウザ上での実行を禁止しました。 Adobe Flash Player コンポーネントは、2021 年 7 月に Windows Update によって完全に削除されました。

Flashが棚から消えた後も、世界の片隅で、この「かつての仲間」は、まだ残された力を振り絞っていた。

Hapland は 2005 年に発売された Flash パズル ゲームで、多くの人にとって子供時代の思い出でもあります。ゲームでは、プレイヤーはモンスターに食べられたり地雷で爆破されたりすることなく、この世界の人々の助けを求めてレベルを開く方法を見つける必要があります。

このゲームのグラフィックは Flash で描画され、コードも Flash で記述され、すべてのアニメーションは Flash タイムラインで完成します。このゲームには「骨の中にフラッシュ」があると理解できます。

ゲーム開発業界の一員として、Robin Allen は人々が Hapland ゲームを特に気に入っていることに気づき、Flash ベースのゲームの Steam バージョンにいくつかの修正を加えたいと考えました。描画を含むゲーム。グラフィックの向上、フレーム レートの 60FPS への増加、追加の「秘密」などの追加。

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

こんな時はどうすればいいでしょうか?著者は実験のプロセスを詳しく説明します。

いくつかの失敗体験

失敗した試み 1:

私の最初の試みFlash を使用してゲームを実行可能ファイルとしてエクスポートしましたが、パフォーマンスが 2005 年と同じくらい悪かったために失敗しました。現在のフレームレートで動作するものを作りたいと考えています。 Flash Playerを削除したいです。

失敗した試行 2:

第 2 に、Adobe AIR (Flash デスクトップ ランタイム) のいじりに時間がかかりすぎました。 Starling (GPU 上で Flash シーンを描画するためのライブラリ)。

最終的にこれを諦めたのは、AIR には非常に多くの問題があり、ひどいものだったからでもありますが、最後に奇妙な Adob​​e の結果になりたくなかったからでもあります。私は自分のものを持ち、やりたいことができるようにしたいと思っていました。たとえば、Linux に移行したい場合はどうすればよいでしょうか?

今後の道は明らかでした。独自の Flash プレーヤーを作成する必要がありました。

計画

Hapland の仕組みは次のとおりです。ここにはスプライト ツリーがあり、Flash では、アニメーション スプライトは、再生矢印が到達したときに実行される特定のフレームにコードをアタッチできます。ハプランド氏はこのアプローチをよく使用します。ゲーム キャラクターの移動経路はすべて非常に長いタイムライン アニメーションであり、キャラクターには、ドアが閉まった後にドアを開ける、地雷原に到達した場合に爆発する前に引き金を引くなど、フレームごとのアクションが含まれることがよくあります。

タイムラインの小さな「a」はフレーム アクションです。

幸いなことに、.fla ファイルは単なる XML です。それを解析し、関連するデータをシンプルなカスタム形式にエクスポートし、それを読み取り、シーンを描画し、入力を処理し、アニメーションを実行するプレーヤーを作成するだけで済みました。

Hapland は依然として Flash プロジェクトであり、Flash Editor で作成および管理されます。Flash Player のみが置き換えられます。

ラスター化ベクトル

Flash はラスター グラフィックスをサポートしていますが、実際にはベクター グラフィックス用に設計されています。そのため、Flash ムービーはダイヤルアップ接続でも高速に読み込まれます。

Hapland グラフィックスはすべてベクター グラフィックスです。 GPU はベクター グラフィックスの描画をあまり好みませんが、テクスチャ付きの三角形の大きなバッチを好みます。したがって、これらのベクトルをラスタライズする必要があります。

私はそれらをオフラインでラスタライズし、ラスタ ファイルをゲームにパッケージ化することにしました。ゲームの実行中にこれらをラスタライズして小さな実行可能ファイルにできたら楽しいでしょうが、余分な可動部分は作りたくないのです。私は、開発マシンでできるだけ多くのコードを実行して、常に監視できるようにしたいと考えています。

Flash は、ベクター グラフィックを XML 形式で保存します。 XML はグラフィック データには悪い選択だと言うかもしれませんが、あなたは Macromedia の製品マネージャーではありません。これを見てください:

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

.fla ファイル内のベクトル データ。

文句を言っているわけではありません。おかげで仕事が楽になります。

仕様にアクセスすることはできませんが、これをラスタライズすることは問題ありません。ベクター グラフィックスのベジェ曲線モデルは、PostScript 以来広く普及しています。これらの API はすべて同じように機能します。試行錯誤の末、これらの形状定義を解析し、Mac の CoreGraphics ライブラリを使用して PNG にレンダリングするプログラムを作成しました。

CoreGraphics は疑わしい選択です。私は Mac で作業しており、多くの依存関係があるため、これを選択しました。しかし、それは機能したため、Windows バージョンであっても、常に Mac でグラフィックスをラスタライズする必要がありました。これをもう一度やるとしたら、おそらくクロスプラットフォーム ライブラリを選択するでしょう。

これらの PNG をレンダリングした後、エクスポーターはそれらをアトラスに組み立てますか?いいえ、すべてを高さで並べ替えてから、文書内のテキストと同じように 1 行ずつ移動するだけです。最適とは程遠いですが、十分です。

わかりやすくするために、アトラスは 2048 × 2048 ピクセルです。これは、OpenGL 3.2 実装がサポートする必要がある最小テクスチャ サイズです。

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

Hapland 3 のイラスト セット。

図形のラスタライズは非常に遅いので、ビルド時間を適切に保つために、変更されていないもののレンダリングをスキップする必要があります。 Flash で使用される圧縮 XML 形式には、各ファイルの最終変更フィールドがありますが、Flash はそれらを正しく使用していないようなので、それらを信頼することはできません。

代わりに、各形状の XML をハッシュし、変更された場合にのみ再構築します。 Flash は変更されていないオブジェクト内の XML タグを再配置することを好むため、これでも失敗しますが、やはりこれで十分です。

アセンブラでのバイナリ ファイルの書き込み

エクスポーターは、アニメーション データをカスタム バイナリ形式に書き込みます。タイムラインをフレームごとに調べて、各フレームのすべての変更を書き出すだけです。

バイナリ ファイルに直接書き込む代わりに、ここにアセンブリ リストを書き込むことを考えましたが、それが気に入っています。 CPU 命令はなく、データだけが存在するため、16 進数エディターでバイトを参照する代わりにアセンブリ ファイルを見て何が生成されたかを確認できるため、デバッグが容易になります。

output.bin

13 92 49 EC : BD 31 E8 FF
09 DD BE DE : C9 5A 1D 36
3F C0 4E 31 : 52 FD 41 C6
8B 5D C0 20 : 19 1F 5F 1F
54 97 8C 27 : 34 1F 30 EA
A9 A9 E0 55 : 40 29 A3 19
89 BC 5F 24 : 3A 98 FD B9
DE 15 F2 D4 : 2A B7 41 2C
4E 9D 37 D9 : E2 13 4B 01
36 3F 40 08 : AC 3C FF 84
E9 AE C5 2C : 11 2F 69 CF
63 CE 85 D1 : A7 CB B1 1A
5F 5B 60 1A : 77 99 71 B0
60 6E C4 C7 : 73 1F EA 1F
31 0D 0C 39 : B0 86 70 42

output.asm

; Left Side
timeline_132:; --- Left Side, Frame 0 ---
.frame_0:; --- Left Side, Frame 0, Layer 22 ---
db Quad
dd 0.152926, 0.162029, 0.184475, 1.000000 ; color
dd 799.599976, -20.950001dd 799.599976, 556.650024dd 46.000000, 556.650024dd 46.000000, -20.950001; --- Left Side, Frame 0, Layer 21 ---
; instance of shape [Left Side] [Wall Shadows] [Frame 0]
dd Shape
dw 1560

どちらをデバッグしますか?

アセンブラを使用せずに、エクスポーターにバイトを 1 つのファイルに書き込み、同時に別のテキストのリストを別のファイルに書き込むこともできましたが、そうしませんでした。

##1) アセンブラはすでに存在します;

2) デバッグする必要はありません;

3) タグをサポートしています。

导出器的其余部分大多不够有趣;它只是 walk the tree 并将变换矩阵、颜色效果等事物,然后继续游戏程序本身。我选择用 C++ 编写这个,因为我已经知道它,并且新事物让我害怕。

场景图

Hapland 非常适合场景图。这是 Flash 使用的模型,Hapland 就是围绕它设计的,因此尝试使用不同的模型是没有意义的。

我将场景存储在内存中,作为一棵节点树,每个节点都有一个变换,可以自行绘制并接受鼠标点击。每个具有自己行为的游戏对象都是其自己类的实例,派生自 Node.js。「面向对象」目前在游戏开发圈子里并不流行,但我使用的是 Flash,所以显然不关心这个问题。

Hapland 使用的 Flash 功能,如颜色变换和遮罩,都是存在的。不过我没有像 Flash 那样实现任意遮罩,只是实现了矩形剪辑并编辑了我所有的图形,所以所有的遮罩都是矩形。

框架脚本

几乎所有的 Hapland 逻辑都包含在附加到时间轴帧的 ActionScript 中。要如何导出所有这些东西?我可不想在我的游戏中包含 ActionScript 解释器。

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

一个简单的帧动作。

最后,我们使用了一些技巧,我的导出器从每一帧读取 ActionScript 并应用大量正则表达式以尝试将其转换为 C++。例如,crate.lid.play () 可能会变成 crate ()→lid ()→play ();。这两种语言在句法上非常相似,这对于许多更简单的框架动作来说效果很好,但它仍然留下了相当多的错误代码,除了手动重写所有剩余的框架动作之外别无他法。

对于 C++ 中的所有框架脚本,它们在构建时被提取并成为每个符号的 Node 子类上的方法。还会生成一个调度方法以在正确的时间调用,看起来像这样:

void tick() override {
 switch (currentFrame) {
 case 1: _frame_1(); break;
 case 45: _frame_45(); break;
 case 200: _frame_200(); break;
 }
}

需要指出的最后一件事是脚本系统最终是某种静态类型的,这有点难受。游戏输出的最终游戏对象如下所示:

struct BigCrate: Node {
 BigCrateLid *lid() { return (BigCrateLid *)getChild("lid"); }
 BigCrateLabel *label() { return (BigCrateLabel *)getChild("label"); }

 void swingOpen() { ... }
 void snapShut() { ... }
 void burnAway() { ... }
};

因此,即使一切仍然是大量的自动字符串名称查找,类型安全的单板会阻止你在错误的对象上调用错误的函数,从而使你免于在动态语言中遇到的那类烦人的 bug。

纵横比

HD 重置版游戏都会遇到画面拉伸的问题,最初的 Flash 游戏很多是页游,甚至没有全屏运行的能力,所以它们只是使用设计者喜欢的宽高比,大多是 3:2 左右。

如今最常见的纵横比似乎是 16:9,16:10 在笔记本电脑上也很流行。我希望游戏在其中任何一个方面看起来都不错,没有任何黑条或拉伸。要做到这一点的唯一方法是从原件上切掉一些部分,或者在上面添加一些部分。

所以,我为游戏画面画了两个矩形,一个比例为 16:9,另一个比例为 16:10。然后游戏根据屏幕的宽高比在它们之间进行插值,并使用插值矩形作为视图边界。只要所有重要的游戏元素都在这些矩形的交叉点内,并且它们的公共边界矩形不超出场景边缘,就可以很好地工作。

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

Hapland 2 的 16:10 和 16:9 框,与原来的 3:2 不同。

色空間に関する問題

いくつかのテストの後、Flash は線形空間ではなく知覚空間でアルファ ブレンディングとカラー変換を行うことがわかりました。これは数学的には疑わしいですが、その一方で、多くのグラフ作成プログラムがこのように動作することも知っておく必要があり、これは数学者にとって一種の問題ではありますが、消費者ツールが人々の期待どおりに動作することを望んでいます。しかし、根本的にこれは間違っています!アンチエイリアスなどの問題が発生する可能性があります。

ベクター グラフィックをラスタライズし、アンチエイリアス出力が必要な場合、ラスタライザーはアルファ値、いわゆる「オーバーレイ値」を出力します。これは、特定のピクセルがベクトル シェイプで半分覆われている場合、そのピクセルは alpha = 0.5 で出力されることを意味します。

しかし、Flash では、アルファが 0.5 である場合、それは知覚的に前景色と背景色の中間であることを意味します。

これはまったく同じものではありません。

不透明な黒いピクセルの上に半分覆われた白いピクセルが 50% グレーとして認識されるべきではありません。それは光の仕組みではなく、ベクトル ラスタライズの仕組みでもありません。ラスタライザは、背景色が分からなければ、「このピクセルは背景色と前景色の間の xx% を感知する必要がある」と言うことができません。

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

ブレンディングは知覚 (sRGB) 空間で行われます。上: 透明な白地に黒、中央: 白地に透明な黒、下: 線形 (物理的に正確な) 空間で行われた同じグレーのブレンド。 50% のカバレッジは 50% のグレーとは異なって見えることに注意してください。

つまり、アンチエイリアス処理されたラスタライズされたシェイプはアルファの 1 つの定義を使用し、Flash にエクスポートされたアルファ透明度、グラデーション、およびカラー変換は別の定義を使用します。ただし、レンダリング パイプラインにはアルファ チャネルが 1 つしかありません。では、レンダラーはアルファ値をどのように解釈すべきでしょうか?それらを知覚的なブレンド要素として解釈すると、半透明のオブジェクトは正しく見えますが、アンチエイリアス処理されたすべてのエッジは間違って見えます。それらをカバレッジ値として解釈する場合は、その逆も同様です。いつも何かが間違っているように見えます!

ここでは、深刻な解決策は 2 つだけだと思います: 1) 2 つのアルファ チャネルを設定し、1 つはオーバーレイ用、もう 1 つは知覚ブレンディング用; 2) AA なしですべての形状をラスタライズし、すべてを描画します非常に大きなフレームバッファを使用し、フィルタリングによってそれを縮小します。

#これらのアイデアはどれも実現されていないことを認めざるを得ません。これらの半透明のものは Flash やゲームでは問題があるように見えましたが、ゲームが正常に見えるまでグラフィックを徐々に調整しました。 Flash の透明オブジェクトは決して私が意図したものとはなりませんが、そのようなオブジェクトはそれほど多くないので、それは大したことではありません。

他のすべてが正しいことを確認するために、さまざまな強度の色、色相回転効果 10 などを含む「カラー テスト」グラフィックを作成し、ゲームに実行させました。それを表示し、Flash で正しく動作することを確認します。

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

色を比較する問題になりました。

フレーム レート

オリジナルの Flash ゲームの公称フレーム レートは 24FPS ですが、実際には Flash Player が必要とする任意のフレーム レートで実行されます。 Flash では、24FPS を要求して 15FPS が得られることもあれば、30FPS を要求して突然 24FPS が得られることもありますが、これはまったく厳密ではないようです。

ゲームを 60FPS にリメイクしたかったのですが、これは、Hapland が作成された時点では約 24FPS でプレイすることが期待されていたという事実をいじることを意味しました。 Flash のアニメーション ツールは、連続時間ではなく離散フレームに基づいています。

最初にエクスポーターにすべてのフレームを 2 倍にし、タイムライン フレームごとに 2 つのフレームをエクスポートするように依頼しました。これにより、24FPS が 48FPS に直接増加しましたが、必要に応じて 60 にはなりませんでした。アニメーションは 25 のままです。 % もっと早く。解決策は昔ながらの手動作業です。ゲームを完全にクリアして、速すぎるように見えるアニメーションに手動で余分なフレームを追加します。

現時点では、Hapland ゲームのかなり優れた C 変換ができており、少なくともあと 1 ~ 2 年は最新のコンピュータで確実に実行できるでしょう。でも、何か付加価値を提供したいという気持ちがどうしても拭えなかったので、新しいものを追加するのは必然でした。古いグラフィックやアニメーションの多くを描き直すことに加えて、いくつかの大きな変更も加えました。

時間の節約

Hapland 3 は、それほど圧倒的ではないようにする必要があると思います。このゲームのレベルは長く、死んで最初からやり直さなければならない場所がたくさんあります。おそらく 2006 年ならそれが楽しかったかもしれませんが、私たちは今大人なので、そんな時間はありません。

状態の保存はエミュレータにあるべき機能です。「状態の保存」を押すと、コンソールのメモリをファイルにダンプすることで、現在のゲーム全体が記録されます。失敗した場合は、「Loading State」を押すと、やり直したい場所の近くに戻ることができます。

Flash ではプログラマがその状態全体にアクセスできないため、ネイティブ Flash ゲームに状態保存を実装することは実現できません。しかし、今回はすべて自分のコードを使用しているため、それは可能です。

ゾーンと呼ばれるものがあります。これは、すべてのメモリを固定サイズのブロックに割り当てる単なるアロケーターです。すべてのシーン ノードは現在の領域内に割り当てられます。保存と復元を実装するには、アクティブ領域と別の「状態保存領域」の 2 つの領域だけが必要です。状態を保存するには、アクティブな領域を保存された状態の領域に memcpy します。状態をロードするには、memcpy を逆の方法で返します。

繰り返しレベル

Hapland は、合計 3 つありますが、特に長いゲームではありませんが、プレイヤーにはさらに数時間のゲームプレイ時間を提供したいと常に考えています。 。そこで私は、各ゲームに「セカンド クエスト」を与えることにしました。これは、レイアウトとパズルが少し異なる、元のレベルの修正バージョンです。このような Second Quest を作成するのは、まったく新しいゲームを作成するよりも手間がかかりませんが、それでも何らかの追加の価値が得られます。

Second Quest を作成するということで、約 15 年ぶりに Flash パズル ゲームの開発を再開することになり、正直、とてもうれしかったです。レトロな Flash UI は素晴らしく、ボタンにはエッジがあり、アイコンはリアルで、スペースがうまく活用されています。

古い時代の UI を使用すると、忘れられたローマのテクノロジーを発見した考古学者のような気分になります。 UI デザインの失われた芸術、素敵です。

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

#これはどんな魔法ですか?

Flash にはバグが多く、動作が遅く、非常に基本的な機能が欠けていますが、基本的には嫌いではありません。もちろん、最新のものを使用する方が快適です。アプリケーションの。

2 番目のミッションが最初のミッションとあまりにも似てしまうのを防ぐために、新しい背景が必要になり、シーン全体が水平方向に反転されました。

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

ハプランド 3.

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

Hapland 3 の 2 番目のクエスト。

音楽

BGM には、自分のハード ドライブの内容を使用し、追加の音楽を作成して、各ゲームのサウンドトラックの環境を簡単に作成しました。ある時、日本での休暇中、何の理由もなく山の頂上でフィールドレコーディングセッションを行ったのですが、それを何かに使えてとても嬉しかったです。タイトル スクリーンの音楽を担当するミュージシャンをインターネットで見つけて、エンド クレジット用に自分でギター コードをいくつか録音しましたが、エフェクトに埋もれていたので、私がギターの学習が下手だとは言えません。

ツールに関しては、楽曲に応じてLogicかLiveを使い分けています。レコーディングにはLogicが適しており、サウンドデザインにはLiveが適していると思います。

実績システム

Steam では、プレイヤーは常に実績を見ることを好みますが、これは簡単ではありません。実績の設定はゲーム デザイナーのアイデアに依存します。しかし実際には大したことはありません。

アチーブメント システムを Steam にアップロードするのは面倒です。単にリストを定義してコマンド ライン ツールに入力するだけでは済みません。Steam コラボレーション パートナーの Web サイトをゆっくりと慎重にクリックする必要があります。混乱を招く PHP フレームワークを 1 つずつ追加していきます。

大手で重要なゲーム スタジオであれば、これを我慢する必要はなく、一括アップロード ツールを提供しているように思えますが、私は明らかにそうではありません。それらの中の一つ 。そこで、構築された HTTP 呼び出しを確認し、ログイン Cookie を保存し、独自の HTTP 呼び出しを作成しました。

いくつかの修正の後、私は控えめな実績セットに落ち着きました。各ハプランド ゲームの完了に 1 つ、セカンド クエストごとに 1 つ、さらに大きな秘密のロックを解除するために 2 つです。誰も見つけられない愚かで曖昧な秘密は何の成果にもなりません。何が起こるかに満足する必要があります。

幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。

Steamworks UI の実績システム。

公証の問題

私は主に Mac でゲームを開発していますが、Apple は開発プロセス中に「公証」を発明しました。新しいバージョンの MacOS は、アプリの開発者に Apple に年会費を支払うかどうかを尋ねるネットワーク リクエストを Apple に送信します。開発者が年会費を支払わない場合、MacOS はアプリが壊れていることを強く示唆するダイアログ ボックスを表示し、起動を拒否します。

したがって、Windows は、このゲームの最初の、そしておそらく唯一のリリース プラットフォームになります。

使用するライブラリ

最終的にエンド ユーザーに提供されるソフトウェアでは、通常、依存関係を最小限に抑えたいと考えますが、高品質のソフトウェアを使用することは重要です。も必要です。 OpenGL と標準オペレーティング システムに加えて、これは Hapland Trilogy 実行可能ファイルが最終的にリンクするライブラリの完全なリストです:

  • Steam SDK
  • cute_sound
  • ##stb_vorbis
  • #stb_image
  • ##結論
#ここで重要なのは、テクノロジーを正しく理解すれば、人々はゲームをプレイしているときに背後に何があるのか​​さえ気付かないため、時々「おい、私がやったことを見てみろ!」と言いたくなることがあります。

以上が幼少期の思い出を保存するために、開発者は古代のプログラミングを使用することにしました。これは、Flash でゲームを高解像度でリメイクしたものです。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事は51cto.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。