ゼロから一まで,オンライン地主を絞る(上編)
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地主はランダムに部屋に入るので、暗いことをつけることができません.私たちが求めているのは一緒に遊ぶことです.ゲームルームの概念は大きく違っています.
簡単に私達のゲームの流れを並べました.は急速に入って、すぐ遊んで、登録する必要がない 部屋を作ったり、部屋に捜索したりします. 部屋に入ると、伝統的な地主論理 があります.
伝統的な地主闘争の論理は以下の通りである.
ここに貼ってきましたが、自分が本当に書き始めた時、整理していませんでした.つまり一台のボビンが上がってきたら、削ってください.その結果、多くの論理的な衝突点と細部点が発見されました.地主は小さなゲームのように見えますが、論理は複雑です.オンラインは単独機ではないので、ゲームの複雑さを過小評価しています.
デザインは何も言いません.ネットで図を探したら基本的な要素になります.
これから本番です.
レイアウト
横のスクリーン
まず斗地主というゲームは横画面のものです.この卵は痛くなりました.ウェブの横画面に対するコントロールが弱いからです.私たちは横書きを強制することができません.すべてはシステムの振る舞いに依存します.
横のスクリーンの制限がどれだけ使いにくいかというと、直接に縦のスクリーンで横のスクリーンをシミュレートしてもいいですか?つまり、携帯電話は縦画面の状態を維持しています.そして、ページ全体を回転させて、縦画面をシミュレートしました.レイアウトなどは横画面の通りに書いてもいいです.とても便利です.
原理は以下の通りです
大体のコード
でも、この案はシミュレータ上では問題ないように見えます.
でも、これは大丈夫だと思います.大丈夫です.だから、このような方式をとりました.
似合います
ゲームは3つのシーンページに分かれています.トップページ、ロビーページ、ルームページ.その中のトップページと大ホールページはつまり流れを歩いて、私達はとても自由で、部屋のページは対戦関係で、最も複雑で、ここは部屋のページで言います.以下は古典的なQQ斗地主の部屋ページです.
私たちは大体モジュールを分けます.
細かいことを考えないで、やはり比較的簡単です.主に六領域です.トップ情報展示エリア 底部情報展示エリア 左プレイヤーエリア 右側プレイヤーエリア メインビュープレイヤーエリア 特殊効果エリア 私達はこれで出札の特効などを考えません.(いくつかの基礎的な素材を探したら私の命です.)domで実現すれば、直接flexの手配ははっきりしています.以下の通りです.
作者: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斗地主の部屋ページです.
私たちは大体モジュールを分けます.
細かいことを考えないで、やはり比較的簡単です.主に六領域です.
<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>