ホームページ ウェブフロントエンド H5 チュートリアル html5で簡単なマルチプレイ飛行機ゲームを実装する例を詳しく解説

html5で簡単なマルチプレイ飛行機ゲームを実装する例を詳しく解説

May 13, 2017 pm 03:36 PM

1 年以上前に、Zhang Dan 先生が書いた、socket.io のチュートリアルを見ました (元のリンクが開けないので、再投稿しました)。その後、大学院時代のプロジェクトでも .Net ソケットを使用し、複数のクライアント間の通信が非常に興味深く、Events や Delegation などの概念を理解して適用した時期でもありました。最近、グループ内でのマップボックスの研究に対する熱意と、@开 Uncle、@老宇、@F3earth のメンバー全員からの支援とインスピレーションに触発されて、突然時間をかけて、マップボックス gl js とソケットをベースにした飛行機戦争ゲームを作成しました。 .io!ただし、機能インターフェイスは非常にシンプルです。さらに、コードは比較的原始的であり、適切にリファクタリングされていません。しかし、基本的にフレームワークはあるので、それを書き留めて分析するだけです。ソース コードに興味がある場合、または開発と最適化の作業に参加したい場合は、git リポジトリにアクセスしてください: Jqmap2

全体的なアーキテクチャ

簡単に言えば、ゲーム全体の設計アイデアは次のとおりです:

サーバーはリッスンします接続 (接続イベント) が確立された後、クライアントによって初めて送信されたユーザー名、座標、および現在の航空機の方向がクライアント データ プールに追加されます (現在は単純に処理されています)。クライアント配列)として。次に、クライアントのデータがサーバーに同期されます。

将来的には、クライアントの航空機の座標、機首方位、その他の情報も定期的にサーバーに送信され (socket.send)、サーバーが他のすべてのクライアントに同時にブロードキャストできるようになります。実際、サーバーはメッセージを中継する責任があることを明らかにしています。その目的は、すべてのクライアント間でプレイヤーの航空機のステータスを一貫した状態に保つことです。

WebSocket は双方向通信であるため、クライアントはサーバーに定期的にメッセージを送信する必要があります。さらに重要なのは、サーバーから送信されるさまざまなメッセージ (メッセージ イベント) を処理して、どのメッセージがユーザーをオンラインに歓迎するかを区別することです。ニュース、または A が B に勝ったというニュース。

このプロセス中、フロントエンドとサーバーは WebSocket 接続を維持し、常に通信を続けます。従来のポーリングやロング ポーリングと比較して、トラフィックとパフォーマンスが節約されます。一般に、ゲームのロジックはさまざまなメッセージ イベントに基づいており、接続イベントによってソケット接続が生成され、ソケット接続にはメッセージ イベントなどが含まれます。

バックエンド websocket

あまりにもナンセンスなので、いくつかの重要なコードを実装する方法を簡単に見てみましょう。

// バックエンドキープロセスの実装

var app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server); // 引入socket.io 库
io.on('connection', function(socket) { // 开始监听客户端的websocket连接请求,connection事件产生 socket 对象
    socket.emit('open'); // 向该客户端发送open事件.
    // init client drone obj for each connection !!
    var client = {
        name: false,
        color: getColor(),
        direction: 0,
        coordinates: [0, 0]
    }
    // message from client.
    socket.on('message', function(msg) {
        if (!client.name && msg.name) { // 如果是第一次连接,把用户的名字存储起来,并且广播给所有客户端。
          var obj  = { }; // 构建发送给其他客户端的消息
          obj = msg;
          clients.push(client); // 加入后台维持的客户端数组
          socket.broadcast.emit('message', obj); // 广播欢迎语给其他客户端
        } else if ( client.name == msg.name ) { // 客户端发来的飞机状态消息
            // 广播给其他客户端
          socket.broadcast.emit('message', obj);
        }
    }
}
ログイン後にコピー

バックグラウンド処理プロセスは、基本的に、クライアントから送信されたメッセージを受け入れ、他のクライアントに転送するだけで済みます (ランダムについては説明しません)。敵機の位置など。もちろん、すべてのクライアントが一連の敵機情報を共有するように後で変更され、同じ BOSS と戦うことができます。)ただし、フロントエンドは、ビジネス ニーズに応じてサーバーからのメッセージを個別に処理する必要があります

フロントエンド ソケットと航空機モデル

フロントエンド ビジネスは、WebSocket メッセージの処理に加えて比較的複雑です。 、位置、速度、方向、血液量、武器と装備などを含む一連の航空機データ モデルを構築する必要があります (非常に複雑になる可能性があるため、ここでは簡単に扱います)。

var socket;
try {
    socket = io.connect("http://123.206.201.245:3002");
    socket.on('open', function(){  // 当服务端确认连接后,开始发送第一次数据。
        statusBar.innerText = "已经连上服务器..";
        var askName = prompt("来,取个名字", "");
    }
    socket.on("message", function(json) { // 其实收到的是js 对象,这一点很牛逼。因为双向通信过程中传递的是 Binary 形式的数据,不需要再次解析了。
      if (json.type === "welcome" && json.text.name) {
          // .. 显示其他用户登录消息
      } else if (json.type === "defeat") {
          // .. 在前端的敌机数据模型中移除空血槽的飞机
      } else if (drone && json.text.name != drone.name) {
          // .. 传来的其他客户端飞机消息
          featureCol.features.forEach(function(drone) {
          // featureCol 是所有敌机数据集合,根据用户名check是更新还是新增.
          }
      }
   }
ログイン後にコピー

その他の問題には次のようなものがあります:

航空機データには、サーバーへの随時の変更アップロードとレンダリングが含まれます。レンダリングでは geojson オブジェクトをマップボックス API のソース データとして使用するので、サーバー側のメッセージを受信したらすぐにすべての航空機の位置を再描画する必要がありますか?ここでは、ソースの setData() メソッドが setInterval を通じて定期的に呼び出され、再描画が実装されます。

航空機の弾丸の軌道計算には、ユーザーがスペースバーを押した瞬間の航空機の位置と方向が含まれます。

弾丸と敵航空機との衝突検出により、処理が簡素化されます。 : set a 定数を航空機の体積として使用し、弾丸の飛行中に弾丸と敵機との距離をリアルタイムで計算します。地図の縮尺が小さい場合は検出半径が大きくなり、地図の縮尺が大きい場合はそれに応じて検出半径が小さくなります。

現時点では、弾丸飛行中の衝突判定の計算量が多すぎて、スタック問題が発生し、CPU使用率が高く、アプリケーション全体で約100~130Mbのメモリを消費する可能性があります。 . 言及しないと多くの小さな問題があります。 。本当に頭を使いました。

分析するポイントを 1 つまたは 2 つ選択してください。1 つは弾丸の飛行プロセス、もう 1 つはロボット敵機のランダムな動作制御です

// setPostion is to update Mydrone position.
function setPosition() {
    // direction in Rad. Generally, 1 Rad stands for 100km
    var current_rotate = map.getBearing(); 
    if (!manual && Math.random() > 0.95) { // 这边有意思,在每秒50帧的情况下,不是每一帧都会随机微调飞机的方向。而是5%的概率。
        direction += (Math.random() - 0.5) /5;
    }    
    // 根据飞机朝向和速度更新位置。
    point.coordinates[0] += speed * Math.sin(direction) / 100;
    point.coordinates[1] += speed * Math.cos(direction) / 100;
    // 校正飞机的朝向显示。因为默认情况下mapbox是根据你的视角随时调整图标方向。但实际上飞机图标的朝向必须和飞机运行方向一致,而不是简单的和标注一样。
    current_rotate = (-current_rotate) + direction * (180 / Math.PI);
}
ログイン後にコピー

以下は弾丸の飛行の計算プロセスです。

// start: fire location, target: bullet destination, duration: total animation time
function renderBulvar(start, target, direction, duration) {
    // target is geojson POINT, add Temp point in layer.. 
    var interval = 20, ratio = interval/duration, real_point = start, range = 0.4, count = 0, hitted = false;
    if (target.coordinates) {
        var targetSource = map.getSource('drone-target');
        window.setInterval(function(){
            if (count > duration/interval) { // 到达终点,不计算了
            } else {
                // 子弹每一帧跑一定比例的路程,最终到达指定终点
                real_point.coordinates[0] += Math.sin(direction)*ratio*range;
                real_point.coordinates[1] += Math.cos(direction)*ratio*range;
                targetSource.setData(real_point);
                if (!hitted){
                    hitted = testCrash(real_point.coordinates); // 感觉这里的hitted 有问题.
                }
                count += 1;
            }
        }, interval);
    }
ログイン後にコピー

到这里其实基本介绍了这个游戏的制作过程,经历了一些不成熟的想法,总共花了近十个小时完成目前的开发。还没有严谨地考虑过代码结构和 函数复杂程序,特别是子弹飞行和碰撞等部分,碰撞到后就终结子弹飞行等等。各位如果感兴趣,愿意完成 To DO list中的事情或者有何建议,请访问git仓库: Jqmap2 。请各位大神多提修改意见!

喜欢的同学请关注、收藏相关专题,会不断更新文章。希望和大家分享!!

【相关推荐】

1. 特别推荐“php程序员工具箱”V0.1版本下载

2. 免费h5在线视频教程

3. php.cn原创html5视频教程

以上がhtml5で簡単なマルチプレイ飛行機ゲームを実装する例を詳しく解説の詳細内容です。詳細については、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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

HTMLの表の境界線 HTMLの表の境界線 Sep 04, 2024 pm 04:49 PM

HTML の表の境界線に関するガイド。ここでは、HTML でのテーブルの境界線の例を示しながら、テーブル境界線を定義する複数の方法について説明します。

HTML のネストされたテーブル HTML のネストされたテーブル Sep 04, 2024 pm 04:49 PM

これは、HTML でのネストされたテーブルのガイドです。ここでは、テーブル内にテーブルを作成する方法をそれぞれの例とともに説明します。

HTML 左マージン HTML 左マージン Sep 04, 2024 pm 04:48 PM

HTML マージン左のガイド。ここでは、HTML margin-left の概要とその例、およびそのコード実装について説明します。

HTML テーブルのレイアウト HTML テーブルのレイアウト Sep 04, 2024 pm 04:54 PM

HTML テーブル レイアウトのガイド。ここでは、HTML テーブル レイアウトの値と例および出力について詳しく説明します。

HTML入力プレースホルダー HTML入力プレースホルダー Sep 04, 2024 pm 04:54 PM

HTML 入力プレースホルダーのガイド。ここでは、コードと出力とともに HTML 入力プレースホルダーの例について説明します。

HTML 内のテキストの移動 HTML 内のテキストの移動 Sep 04, 2024 pm 04:45 PM

HTML でのテキストの移動に関するガイド。ここでは、概要、マーキー タグが構文でどのように機能するか、および実装例について説明します。

HTML 順序付きリスト HTML 順序付きリスト Sep 04, 2024 pm 04:43 PM

HTML 順序付きリストのガイド。ここでは、HTML 順序付きリストと型の導入とその例についても説明します。

HTML の onclick ボタン HTML の onclick ボタン Sep 04, 2024 pm 04:49 PM

HTML オンクリック ボタンのガイド。ここでは、それらの紹介、動作、例、およびさまざまなイベントでの onclick イベントについてそれぞれ説明します。

See all articles