ホームページ ウェブフロントエンド jsチュートリアル 伝説のゲームの JS 模倣 (コード付き)

伝説のゲームの JS 模倣 (コード付き)

Apr 12, 2018 pm 04:40 PM
javascript 情熱的な

今回は、レジェンド オブ ブラッド ゲームの JS 模倣 (コード付き) を紹介します。レジェンド オブ ブラッド ゲームの JS 模倣の 注意事項 は何ですか? 以下は実際的なケースです。

ゲームの最初のバージョンは 2014 年に開発されました。ブラウザは html+css+js を使用し、サーバーは asp+php を使用し、通信は ajax を使用し、データ ストレージは access+mySql を使用します。ただし、いくつかの問題がありました (当時はノードの使い方を知らなかったので、ASP で複雑なロジックを記述するのは非常に困難でした。当時は Canvas 上での記述がほとんどなく、DOM レンダリングは簡単にパフォーマンスのボトルネックに達する可能性がありました)。 、放棄されました。その後、キャンバスを使用したバージョンがリメイクされました。この記事は 2018 年に書かれたものです。

1.開発前の準備

比較的複雑な PC ゲームを実装するのに Javascript を使用する理由

1. PC側のオンラインゲームをjsで実装することが可能です。 PC や携帯電話のハードウェア構成のアップグレード、ブラウザの更新、さまざまな H5 ライブラリの開発により、js でオンライン ゲームを実装することはますます困難になってきています。ここでの難しさは主に 2 つの側面にあります。1 つはブラウザのパフォーマンス、もう 1 つは非常に複雑なロジックを含むゲームの反復に耐えられるほど JS コードを拡張できるかどうかです。

2. 現在のjsゲームの中には大規模なものが少ないので参考にしてください。マルチプレイヤー接続、サーバー側のデータ ストレージ、複雑なインタラクションを伴うほとんど (ほぼすべて) のゲームは、Flash を使用して開発されています。しかし、flash は結局衰退しつつありますが、js は急速に発展しており、ブラウザさえあれば実行できます。

2001 年の伝説的なゲームを選んだ理由

もちろん、最初の理由は古いゲームへの思い入れです。もう 1 つのより重要な理由は、他のゲームのプレイ方法を知らないか、プレイ方法は知っているが素材 (画像、サウンド) を持っていないことです。効果など)。ゲームのマップ、キャラクターやモンスターのモデル、アイテムや装備の図を収集し、それらを処理して解析してから js 開発に使用するのに多大な労力を費やすのは時間の無駄だと思います。

以前にレジェンド ゲームのマテリアルをいくつか収集し、幸運にもレジェンド オブ レジェンド クライアント リソース ファイル (github アドレス) を抽出する方法を見つけたので、コードを直接書き始めることができ、準備時間をいくらか節約できます。

起こり得る困難

1. ブラウザのパフォーマンス: これが最も難しい点です。ゲームが 40 フレームを維持したい場合、js が計算するために各フレームに残る時間は 25 ミリ秒のみです。また、レンダリングは通常、計算よりも多くのパフォーマンスを消費するため、js に残される実際の時間はわずか約 10 ミリ秒です。

2. 不正行為対策: ユーザーがインターフェイスを直接呼び出したり、ネットワーク要求データを改ざんしたりすることを防ぐにはどうすればよいですか?目標は、js を使用してより複雑なゲームを実装することであり、オンライン ゲームではこれを考慮する必要があるため、比較的成熟したソリューションが必要です。これはこの記事の焦点では​​ありません。

2.全体のデザイン

ブラウザ側

画面描画にはキャンバスを使用します。

dom(p)+css と比較して、canvas はより複雑なシーンのレンダリングとイベント管理を処理できます。たとえば、次のシーンには、プレイヤー、動物、地面にあるアイテム、および一番下のマップの画像の 4 つの画像が含まれています。 (実際には、地面の影、文字、動物、物体をマウスでポイントしたときに表示される対応する名前、地面の影もあります。読みやすさのため、内容についてはあまり考慮しません。 )

このとき、「動物をクリックすると動物を攻撃、アイテムをクリックするとアイテムを拾う」という効果を実現したい場合は、動物とアイテムのイベントを監視する必要があります。 dom メソッドを使用する場合、いくつかの難しい問題に対処する必要があります:

a. レンダリングの順序は イベント処理 の順序とは異なり (z-index が小さい場合は、最初にイベントを処理する必要がある場合があります)、追加の処理が必要です。例えば上記の例では、モンスターやアイテムをクリックする際にキャラクターをクリックしやすいため、キャラクターに対して「クリックイベント貫通」処理を行う必要があります。さらに、イベント処理の順序は固定されていません。キャラクターの解放を必要とするスキル (ゲーム内の治療など) を持っている場合、この時点でキャラクターはイベント監視を行う必要があります。したがって、要素がイベントを処理する必要があるかどうか、およびイベントが処理される順序はゲームの状態によって異なります。 DOM のイベント バインディングはニーズを満たすことができなくなりました。

b. プレーヤーのモデル、プレーヤーの名前、プレーヤーのスキル効果など、関連する要素を同じ dom ノード に配置するのは困難です。これらは

に配置する必要があります。 または コンテナ内では管理が簡単です (このようにして、複数の要素の位置を親要素から継承でき、位置を個別に扱う必要がありません)。しかし、この方法では、z-index を扱うのが難しくなります。たとえば、プレーヤー A がプレーヤー B の上にある場合、A は B によって隠されます。 したがって、A の z-index を小さくする必要がありますが、プレーヤー A の名前が B の名前や影によって隠されてはなりませんが、これは達成できません。 。簡単に言えば、 DOM 構造の保守性は画面表示の効果を犠牲にし、その逆も同様です。

c. パフォーマンスの問題。たとえ効果が犠牲になったとしても、レンダリングに DOM を使用すると、必然的に多くのネストされた関係が生じ、すべての要素のスタイルが頻繁に変更され、ブラウザーの再描画やリフローが継続的にトリガーされます。

キャンバスレンダリングロジックとプロジェクトロジックの分離

Canvas のさまざまなレンダリング操作 (drawImage、fillText など) など) がプロジェクト コードと一緒に配置されるため、後でプロジェクトを保守できなくなることは避けられません。いくつかの既存のキャンバス ライブラリを検討し、vue のデータ バインディング+ デバッグ ツールと組み合わせて、新しいキャンバス ライブラリ Easycanvas (github アドレス) を作成しました。vue と同様に、プラグイン Elements を介してキャンバスのデバッグをサポートします。

この方法では、ゲーム全体のレンダリング部分がはるかに簡単になります。必要なのは、ゲームの現在の状態を管理し、サーバーによってソケットから返されたデータに基づいてデータを更新することだけです。 「データの変更によるビューの変更」は Easycanvas の責任です 。たとえば、下の図のアイテムをラッピングするプレーヤーの実装では、ラッピング コンテナの位置とバックパック内の各要素の配置規則を指定するだけで、ラップされた各アイテムを配列にバインドします。この配列を管理します。はい (Easycanvas は、データを画面にマッピングするプロセスを担当します)。

たとえば、5 行 8 列の合計 40 個のアイテムのスタイルは、次の形式で Easycanvas に渡すことができます (インデックスはアイテムのインデックス、アイテムの x 方向の間隔は 36、y 方向の間隔は 32) )。そして、このロジックは、項目の配列がどのように変更されたり、パッケージがどこにドラッグされたりしても、各項目の相対位置は固定されます。 Canvas 上でのレンダリングに関しては、プロジェクト自体を考慮する必要がないため、メンテナンス性が向上します。

りー

キャンバスレイヤードレンダリング

仮定: ゲームは 40 フレームを維持する必要があり、ブラウザは幅 800、高さ 600、面積 480,000 (以下、画面領域として 480,000 と呼びます) です。

同じキャンバスを使用してレンダリングする場合、このキャンバスのフレーム番号は 40 で、1 秒あたり少なくとも 40 の画面領域を描画する必要があります。ただし、複数の要素が同じ座標点で重なっている可能性があります。たとえば、下部の UI、ヘルス バー、ボタンが重なっており、それらが結合してシーン マップをブロックしています。したがって、これらを合計すると、ブラウザの 1 秒あたりの描画量は、ゆうに 100 画面領域を超える可能性があります。

この描画は、キャンバス全体のあらゆる場所でビューが更新されるため、最適化するのが困難です。それは、プレイヤーや動物の動き、ボタンの特殊効果、特定のスキルの効果の変化である可能性があります。この場合、プレイヤーが動かなくても、服が「風になびく」効果(実際にはスプライトアニメーションが次の絵に再生されます)やポーションの瓶が現れるなどの影響でキャンバス全体が再描画されます。地面。なぜなら ゲームの特定のフレームが前のフレームと区別できないことは、ゲーム画面の一部であっても変化しないことはほとんど不可能です。ゲーム画面全体が常に更新されます。

なぜなら、ゲームの特定のフレームが前のフレームと区別できないことはほとんど不可能であり、画面は常に更新されるからです。

そこで今回は3枚のキャンバスを重ねる配置を採用しました。 Easycanvasのイベント処理は配信に対応しているため、先頭のキャンバスがクリックされても、クリックを終了する要素がなければ後続のキャンバスもイベントを受け取ることができます。 3 つのキャンバスは、UI、地面 (マップ)、エルフ (キャラクター、動物、スキルの特殊効果など) を担当します:

この階層化の利点は、レイヤーごとの最大フレーム数を必要に応じて調整できることです。

例えば ​​UI レイヤーですが、多くの UI は通常動かず、動いたとしてもあまり精密な描画を必要としないため、フレーム数は適切に、たとえば 20 フレームに減らすことができます。このようにして、プレイヤーの体力が 100 から 20 に減少した場合、ビューは 50 ミリ秒以内に更新され、50 ミリ秒の切り替えはプレイヤーには感じられません。体力とかあるから UI層のデータは短時間に複数回連続して変化することが難しく、50msの遅延は人間が認識しにくいため、頻繁な描画は必要ありません。 。 1 秒あたり 20 フレームを保存すると、おそらく 10 画面領域の描画を保存できるでしょう。

もう 1 つの例は、プレイヤーが移動したときにのみマップが変化する地面です。このようにして、プレーヤーが動いていない場合、フレームごとに 1 つの画面領域を保存できます。プレーヤーが移動する際の滑らかさを確保する必要があるため、地上での最大フレーム レートは低すぎてはなりません。地上フレームが 30 フレームの場合、プレイヤーが静止している場合、1 秒あたり 30 の画面領域を保存できます (このプロジェクトでは、マップはほぼ画面いっぱいに描画されます)。また、他のプレイヤーや動物の動きによって地面が変化することはなく、地面レイヤーを再描画する必要もありません。

スプライトレイヤーの最大フレームレートを下げることはできません。このレイヤーはキャラクターの動きなどゲームの核となる部分を表示するため、最大フレームレートを40に設定します。 このように、1 秒あたりに描画される領域は、プレーヤーが動いているときは 80 ~ 100 画面領域になりますが、プレーヤーが動いていないときは 50 画面領域しかありません。ゲームでは、プレイヤーは立ち止まったままモンスターと戦い、入力し、アイテムを整理し、スキルを解放するため、長時間にわたって地面の描画がトリガーされず、パフォーマンスが大幅に節約されます。

サーバー側

目標は js を使用してマルチプレイヤー オンライン ゲームを実装することであるため、サーバーはノードとソケットを使用してブラウザと通信します。このもう 1 つの利点は、マップ上の特定の座標点に障害物があるかどうかを判断するなど、一部の共通ロジックを両端で再利用できることです。

Node 側のプレーヤーやシーンなどのゲーム関連データはすべてメモリに保存され、定期的にファイルと同期されます。 Node サービスが開始されるたびに、データがファイルからメモリに読み取られます。このように、プレーヤーの数が増えると、ファイルの読み取りと書き込みの頻度が急激に増加し、パフォーマンスの問題が発生します。 (その後、安定性を向上させるために、読み取りおよび書き込みプロセス中のサーバーの再起動によって引き起こされるファイルの損傷を避けるために、「メモリ ファイル バックアップ」方式を使用して、ファイルの読み取りおよび書き込み用のバッファが追加されました)。

Node側はインターフェース、データ、インスタンスなど複数の層に分かれています。 「インターフェイス」はブラウザとの対話を担当します。 「データ」とは、薬の名前や効果、モンスターの速さや体力などの静的なデータであり、ゲームルールの一部です。 「インスタンス」とは、例えばあるプレイヤーの薬が「薬データ」のインスタンスです。別の例として、「鹿インスタンス」は属性「現在の血液量」を持ち、鹿 A は 10、鹿 B は 14 で、「鹿」自体は「初期血液量」のみを持ちます。

3. シーンマップの実装

マップシーン

マップ シーンの部分から始めましょう。これはレンダリングに依然として Easycanvas に依存しています。

考える

プレイヤーは常に画面中央に固定されているため、プレイヤーの動きは実質的にマップの動きとなります。たとえば、プレイヤーが左に走ると、マップは右に移動します。先ほども述べたように、プレイヤーは 3 つのキャンバスの中間層にいて、マップは最下層に属しているため、プレイヤーはマップをブロックする必要があります。

これは合理的なように思えますが、マップ内に木がある場合、「プレイヤーのレベルは常に木よりも高い」は間違いです。現時点では、2 つの大きな解決策があります:

地図は階層化されており、「地上」と「地上」が分離されています。たとえば、下の図では、左側が地面に、右側が地面に、プレイヤーを 2 つのレイヤーの間に配置し、中央にキャラクターを挟むように重ねて描画します。 これで問題は解決したように見えますが、実際には 2 つの新しい問題が発生します。 1 つ目は、プレイヤーが「地上」のもの (木など) によってブロックされる場合があるということです。もう 1 つは、「地上」のものをブロックできる必要がある場合です。 (たとえば、この木の下に立つと、頭が木を遮ってしまいます)。もう 1 つの問題は、レンダリングのパフォーマンス コストが増加することです。プレイヤーは常に変更されるため、「地面」レイヤーは頻繁に再描画する必要があります。これにより、大きな地上地図のレンダリングをできるだけ節約するため、元のデザインが崩れ、キャンバスの階層化がより複雑になります。

地図は階層化されておらず、「地上」と「地上」が一緒に描かれています。プレーヤーが木の後ろにいる場合、以下に示すように、プレーヤーの透明度を 0.5 に設定します。 これには欠点が 1 つだけあります。それは、プレイヤーの体が不透明または半透明のいずれかであり (マップ上を歩くモンスターにもこの効果があります)、完全に現実的ではありません。理想的な効果は、プレイヤーの体の一部が隠れるシーンがあることだからです。ただし、これはパフォーマンスに優れており、コードの保守も簡単です。現在、このソリューションを使用しています。

では、「地図」画像のどの部分が木であるかをどのように判断するのでしょうか?通常、ゲームには大きなマップ記述ファイル (実際には配列) があり、0、1、2 などの数字を使用して、通過できる場所、障害物がある場所、乗り換えポイントなどを識別します。熱血伝説の「説明ファイル」は48×32を最小単位として記述されているため、熱血伝説におけるプレイヤーのアクションは「チェス盤」のような感覚になります。ユニットが小さいほどスムーズになりますが、ユニットが占める体積は大きくなり、この記述を生成するプロセスに時間がかかります。

本題に入りましょう。

達成しました

私は友人に、レジェンド オブ レジェンド クライアントで「ブナ州」のマップをエクスポートするのを手伝ってもらいました。そのサイズは幅 33,600、高さ 22,400 で、私のコンピューターの数百倍です。コンピューターの爆発を防ぐには、コンピューターを複数のチャンクに分割して読み込む必要があります。凡例の最小単位は 48x32 であるため、マップを 480x320 の 4900 (70x70) の画像ファイルに分割します。

この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。

推奨読書:

FileReaderは、写真をアップロードする前にローカルプレビューを実装します

vue-dplayer hls再生を実装する手順の詳細な説明

以上が伝説のゲームの JS 模倣 (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

JavaScript で HTTP ステータス コードを簡単に取得する方法 JavaScript で HTTP ステータス コードを簡単に取得する方法 Jan 05, 2024 pm 01:37 PM

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開発では、バックエンド インターフェイスとの対話を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具体的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開始したときに、サービスが

JavaScriptでinsertBeforeを使用する方法 JavaScriptでinsertBeforeを使用する方法 Nov 24, 2023 am 11:56 AM

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

See all articles