ゼロから一まで,オンライン地主を絞る(上編)

11934 ワード

ゼロから一まで、オンライン地主を絞る(上編)AlloyTeam
作者:TAT.vorshen
背景:友達が深圳に遊びに来ました.深圳で何か面白いところがあれば、家で地主と戦っています.でも、計算が人に及ばないです.トランプが何枚かなくなってしまいました.暑い中、誰がカードを買いに行きたいですか?しかし、問題は大きくないです.モバイルインターネット時代のプログラム猿として、実体カードの代わりに携帯電話のオンライン地主を採用するのは当然です.
githubアドレス:https://github.com/vorshen/landlord
読む前に注意してください.本文は上下二編に分けられています.本編では準備作業と先端の配置に関する知識を紹介します.次のwebasseme blyコアロジックとserver端関連を実現します.
ソースはgithubに全部あるので、文章は思考の解説に偏っています.
余暇の時間は限られています.ゲームのスタイルは醜いです.細かいところも磨かれていません.ご了承ください.でもやはり閉ループになりました.ラインの下でブラック娯楽をするのは大丈夫です.
ゲームのスタイル
準備
技術選定と準備
typescript+canvas+webassembly+c+(server)はまずウェブで、人はそろってLAN server端が起動して、それからQQ、WeChat、ブラウザーが訪問して、直接開けました.Webである以上、typescriptでなければならないですね.tsを書いたと思いますが、一生jsを書きたくないでしょう.
斗地主は要素が多くなくて、クールなシーンがないゲームとして、実はdomは完全に耐えられます.しかし、Webゲームを作って、canvasを舞台にしなくてもいいです.どこかおかしいです.だから最終的にはcanvasでレンダリングします.ここでは成熟したレンダリングエンジンを使って、自分を鍛えることができません.
トレーナーとしての作品は、常に、現在の非常に人気のある技術として、webassembly、もちろん試してみたいです.だから、ゲームのいくつかの核心的なロジックはwebassemblyを採用して実現します.ここでは、次の詳細に説明します.
コーディング前
自分でゼロから一までですから、製品のデザイン開発は自分でしなければなりません.まず簡単にゲームの流れを整理します.私達のこの地主はQQ地主と違って、QQ地主はランダムに部屋に入るので、暗いことをつけることができません.私たちが求めているのは一緒に遊ぶことです.ゲームルームの概念は大きく違っています.
簡単に私達のゲームの流れを並べました.
  • は急速に入って、すぐ遊んで、登録する必要がない
  • 部屋を作ったり、部屋に捜索したりします.
  • 部屋に入ると、伝統的な地主論理
  • があります.
    伝統的な地主闘争の論理は以下の通りである.
    ここに貼ってきましたが、自分が本当に書き始めた時、整理していませんでした.つまり一台のボビンが上がってきたら、削ってください.その結果、多くの論理的な衝突点と細部点が発見されました.地主は小さなゲームのように見えますが、論理は複雑です.オンラインは単独機ではないので、ゲームの複雑さを過小評価しています.
    デザインは何も言いません.ネットで図を探したら基本的な要素になります.
    これから本番です.
    レイアウト
    横のスクリーン
    まず斗地主というゲームは横画面のものです.この卵は痛くなりました.ウェブの横画面に対するコントロールが弱いからです.私たちは横書きを強制することができません.すべてはシステムの振る舞いに依存します.
    横のスクリーンの制限がどれだけ使いにくいかというと、直接に縦のスクリーンで横のスクリーンをシミュレートしてもいいですか?つまり、携帯電話は縦画面の状態を維持しています.そして、ページ全体を回転させて、縦画面をシミュレートしました.レイアウトなどは横画面の通りに書いてもいいです.とても便利です.
    原理は以下の通りです
    大体のコード
    //             
    let width = this._app.root.offsetWidth;
    let height = this._app.root.offsetHeight;
    
    this._box = document.createElement('div');
    this._box.className = 'room-box';
    //     
    this._box.style.width = `${height}px`;
    this._box.style.height = `${width}px`;
    this._box.style.transform = `translateX(${width}px) rotate(90deg)`;
    注意しますこのような横画面は、クリックイベントのclientX/Yを直接使えなくなります.ここでも切り替えが必要です.具体的なコードはStage.tsの中にあります.ここでは展開しません.
    でも、この案はシミュレータ上では問題ないように見えます.
    でも、これは大丈夫だと思います.大丈夫です.だから、このような方式をとりました.
    似合います
    ゲームは3つのシーンページに分かれています.トップページ、ロビーページ、ルームページ.その中のトップページと大ホールページはつまり流れを歩いて、私達はとても自由で、部屋のページは対戦関係で、最も複雑で、ここは部屋のページで言います.以下は古典的なQQ斗地主の部屋ページです.
    私たちは大体モジュールを分けます.
    細かいことを考えないで、やはり比較的簡単です.主に六領域です.
  • トップ情報展示エリア
  • 底部情報展示エリア
  • 左プレイヤーエリア
  • 右側プレイヤーエリア
  • メインビュープレイヤーエリア
  • 特殊効果エリア
  • 私達はこれで出札の特効などを考えません.(いくつかの基礎的な素材を探したら私の命です.)domで実現すれば、直接flexの手配ははっきりしています.以下の通りです.
    
    
    
        
        
        
        
        <style>
            html,
            body {
                margin: 0;
                padding: 0;
                height: 100%;
            }
            .root {
                height: 100%;
    
                display: flex;
                flex-direction: column;
                justify-content: space-between;
            }
            .top-area {
                height: 45px;
                background-color: #1ca4fc;
    
                display: flex;
                flex-grow: 0;
            }
            .side-player {
                height: 125px;
    
                display: flex;
                flex-direction: row;
                justify-content: space-between;
                flex-grow: 1;
            }
            .left-player {
                width: 266px;
                background-color: #f7b92b;
    
                display: flex;
            }
            .right-player {
                width: 266px;
                background-color: #f7b92b;
    
                display: flex;
            }
            .main-player {
                height: 187.5px;
                background-color: #fc6554;
    
                display: flex;
                flex-grow: 0;
            }
        </style>
    
    
        <div class="root">
            <div class="top-area"/>
            <div class="side-player">
                <div class="left-player"/>
                <div class="right-player"/>
            </div>
            <div class="main-player"/>
        </div>
    
    </code></pre> 
     <p><span class="img-wrap"/></p> 
     <p>   flex   ,   ,  ,    canvas  ,<strong>                ?</strong><br/>           :</p> 
     <ol> 
      <li>canvas      </li> 
      <li>    </li> 
     </ol> 
     <h3>canvas      </h3> 
     <p>         canvas  ,    ,          ,   flex。             ,alloyrender、erget、easelJS    x,y           。</p> 
     <p>          canvas ,<strong>          </strong>,               ,         ,            。                    ,            ,              +               。         ,            。</p> 
     <p>                  ,      ;</p> 
     <p>        ,            ,               ,   hold   ,              。            ,      。</p> 
     <h3>    </h3> 
     <p>         「  」             。    ,        ,            ,          </p> 
     <ol> 
      <li>    +  </li> 
      <li>    +   </li> 
     </ol> 
     <p>         :<br/><span class="img-wrap"/><br/><span class="img-wrap"/></p> 
     <p>             </p> 
     <p>「    +  」:           ,           </p> 
     <p>「    +   」:        ,           </p> 
     <p>    ,               </p> 
     <h1>  </h1> 
     <p>         ,    ,               。      canvas     ,                </p> 
     <ul> 
      <li>DisplayObject       ,       ,       </li> 
      <li>Container    </li> 
      <li>Bitmap    </li> 
      <li>Text    </li> 
     </ul> 
     <p>                    ,<strong>         (   ),    (  )      ,       </strong>。     github     。<br/>                  <br/><span class="img-wrap"/></p> 
     <p>               ,      ,        base   。          。</p> 
     <ol> 
      <li>         ,       。</li> 
      <li>  1    ,           base     </li> 
      <li>         (         ,          )</li> 
      <li>   、      </li> 
     </ol> 
     <p>         。</p> 
     <p>                  ,   </p> 
     <p>BasePukesContainer          ,   ,          。     (HandPukes)、     (DesktopPukes)      ,  BasePukesContainer       </p> 
     <p>  ,     BasePukesContainer             ,      </p> 
     <ol> 
      <li>      (   )  </li> 
      <li>         </li> 
      <li>            、     </li> 
     </ol> 
     <p>   ,  BasePukesContainer   ,      <br/><span class="img-wrap"/></p> 
     <p>         base     ,        </p> 
     <p>      (     github)</p> 
     <pre><code>class BasePukesContainer extends Container {
        //      
        protected _pukeWidth: number;
        //      
        protected _pukeHeight: number;
        //          
        protected _horizontalAlign: PUKE_HORIZONTAL_ALIGN;
        //          
        protected _verticalAlign: PUKE_VERTICAL_ALIGN;
        //             
        private _interval: number;
    
        /**
         *        
         * @param {*} object 
         */
        protected _deletePuke(object: BasePuke) {}
    
        /**
         *        
         * @param {*} puke 
         */
        protected _postPuke(puke: BasePuke, zIndex?: number) {}
    
        /**
         *              
         */
        protected _updatePukes() {}
    
        constructor(options: i_BasePukesContainerOptions) {}
    
        /**
         *        
         * @param {string[]} pukes
         */
        deletePukes(pukes: string[]) {}
    
        /**
         *        
         * @param {string[]} pukes
         */
        postPukes(pukes: string[]) {}
    
        /**
         *      
         */
        deleteAll() {}
    }</code></pre> 
     <p>                ,                 ,    、    ,                 ,      ,        。</p> 
     <h1>  </h1> 
     <p>           ,              </p> 
     <h2>  </h2> 
     <p>         ,      ,touchstart touchmove       。   canvas  dom,     ,      fill   ,    stroke   ,          。</p> 
     <p>             ,              。</p> 
     <p>  fill             ,  ,     canvas       。    event clientX/Y   canvas   ,          。</p> 
     <p>      <br/><span class="img-wrap"/></p> 
     <p>(x3, y3)  clientX/Y</p> 
     <p>      ,     (x1, y1),     canvas     (x', y')</p> 
     <p>         canvas       ,   (x', y')  [x2, y2, w, h]      ,         ,   ,          </p> 
     <p>        ,     。            ……</p> 
     <h4>    </h4> 
     <p><span class="img-wrap"/><br/>     (  )    ,           ,     ?</p> 
     <h4>    </h4> 
     <p><span class="img-wrap"/><br/>         ,      canvas   ,       container ,            ?       ,     ?</p> 
     <h4>     </h4> 
     <p><span class="img-wrap"/><br/>         ,    ;     ,    ,          ?</p> 
     <h2>  </h2> 
     <p>      ,                      ,                  ,       。  Container        ,      。</p> 
     <pre><code>/**
     * touchstart,touchmove     
     */
    private _touch = (data: { x: number, y: number }) => {
        let {
            x, y
        } = data;
        let len = this._children.length;
        let i;
        let temp: BasePuke;
        let puke: BasePuke | undefined;
    
        for (i = len - 1; i >= 0; i--) {
            temp = <basepuke>this._children[i];
            if (temp.contain(x, y)) {
                puke = temp;
                break;
            }
        }
    
        if (puke) {
            this._choosePuke(puke);
        }
    }</basepuke></code></pre> 
     <p>           ,<strong>                    , canvas       ,      </strong>。     ,            ,            。</p> 
     <p>                  ,        (x1, y1) ,          [x2, y2, w, h]    (  :  x2, y2        )</p> 
     <p>       (x1, y2)      ,   (x2, y2)      ,        <br/>    :</p> 
     <pre><code>// DisplayObject.ts
    /**
     *      AABB 
     *   ,  x,y global   ,    transform
     *           
     * @param {*} x 
     * @param {*} y 
     */
    contain(x: number, y: number) {
        let point = new Point(x, y);
        let matrix: Matrix2D;
    
        //         
        if (this._parent) {
            matrix = this._parent._getGlobalMatrix();
        } else {
            matrix = new Matrix2D();
        }
    
        //      
        matrix.invert();
        
        //        
        point.transformWithMatrix(matrix);
    
        let rect = this._getAABB();
    
        return rect.contains(point);
    }</code></pre> 
     <p>               ,<strong>           ,        </strong>。         ,      ,      ,          ,      ,       。</p> 
     <p>         ,            。</p> 
     <p>           ,                            ,         「 」。       ,     「 」      ,   ,             :     。      ,       ,          (              )。</p> 
     <h1>  </h1> 
     <p>   ,       。         ,                ,       ,             ,        ,         ,              ,           。</p> 
     <p><strong>           ?          ?             ?             ?Webassembly     ,    ?</strong></p> 
     <p>      。</p> 
     <hr/> 
     <blockquote>
       AlloyTeam           。 
      <br/>    : alloyteam@qq.com 
      <br/>        AlloyTeam  Web     (  ) 
     </blockquote> 
     <p><span class="img-wrap"/></p> 
    </div>
                                </div>
                            </div>