ホームページ  >  記事  >  バックエンド開発  >  Webゲーム開発入門チュートリアル3(簡単なプログラム・アプリケーション)_PHPチュートリアル

Webゲーム開発入門チュートリアル3(簡単なプログラム・アプリケーション)_PHPチュートリアル

WBOY
WBOYオリジナル
2016-07-21 15:42:37888ブラウズ

Webゲーム開発入門チュートリアル2(ゲームモード+システム)
http://www.jb51.net/article/20724.htm

1. 開発言語を選択します
バックエンド: java .net php
フロントエンド: flex javascript ajax
データベース: mysql mssql
どの組み合わせを使用するかは実際には問題ではありません。重要なのは時間と費用です。複雑さは、テクノロジーや効果の実装ではなく、データの相互作用と完成度にあります。多くの場合、いくつかの問題が発生します。たとえば、地図を作成するにはどうすればよいでしょうか?キャラクターの動きを実装するにはどうすればよいですか?実際、これらの問題は技術的には比較的簡単に実装できます。問題は、実装後にデータがどのように相互作用するかにあります。データ相互作用の問題を解決しない限り、これらの技術的なポイントを実装することはほとんど意味がありません。私はphp+javascript+mysqlを使用しています。
理由: シンプルですぐに使用できます。比較的早く製品を作ることができます。
2. プログラムは簡単に適用できます。
、テンプレート
UIの変更を容易にするため。したがって、テンプレートを使用します。スマートテンプレートは非常に便利です。とてもシンプルです。コードはテンプレート内にネストすることもできます。唯一の問題は、アーティストがプログラミングの方法を知らない場合、テンプレートを変更するにはプログラミングが必要になることです。それは科学的ではありません。
スマート テンプレートのチュートリアルはオンラインで利用できます。ちょっと言ってください。 を使用して、テンプレート (.html ファイル) 内のコードをネストできます。渡された値を取得します。 $_obj[‘xxx’] または $_stack[0][‘’] を使用して、{xxx} に記述されたコードをネストします。 .php ファイルと同じであり、違いはありません。
、マップ
ゲームタイプがオゲームモードではないため、マップは自動生成されません。代わりに、すべてデータベースから呼び出されます。考え方はシンプルです。地図は大きな絵です。複数の小さな部分に切ります。大きな画像に対応する各小さなタイルの絶対座標がデータベースに記録されます。表示されたら、対応する座標エリアの小さなタイルを呼び出します。
コードは同様です:
$sql="select * from map where mapx between $xxx and $xxx and mapy between $yyy and $yyy ";
これは、マップ テーブルから横座標 xx から xx を取得することを意味します。垂直座標が xx から xx のすべての小さなタイル。たとえば、20。取得したすべてのデータを表示する関数 showMap(x,y) を作成するとします。マップには多くのレイヤーを含めることができます。
それぞれの小さなタイルは div です。特定のコントロールには CSS を使用するだけです。小さなタイルは div の背景として使用できます。 div内の画像としても使用できます。 div の左と上を制御するだけです。 (左と上は、大きなタイルに対する小さなタイルの絶対座標です) showMap(x,y) は、下の 2 つのレイヤーに配置されます。
1 つのレイヤーがマップ サイズを処理します:

1 つのレイヤーがドラッグを処理します:

コードをコピー コードは次のとおりです:

//ドラッグを処理するための JS コード。 (インターネットからコピーしました。この人のおかげです。)
<script> <br>function fDragging(obj, e, limit){ <br>if(!e) e=window.event; <br>var x=parseInt;左); <br>var y=parseInt(obj.style.top); <br>var y_=e.clientY-y; <br>if(document.addEventListener)マウスムーブ', inFmove, true); <br>document.addEventListener('mouseup', inFup, true); <br>document.body.style.cursor="move"; 'onmousemove', inFmove); <br>document.body.style.cursor="move"; <br>inFstop(e) <br>function inFmove(e) ){ <br>var evt; <br>if(!e)e=window.event; <br>var op=obj.parentNode; <br>var opY=parseInt (op.style.top); <br>if((e.clientX-x_)else if((e.clientX-x_+obj.offsetWidth+opX)>(opX+op.offsetWidth) )) false を返す; <br>if(e.clientY-y_else if((e.clientY-y_+obj.offsetHeight+opY)>(opY+op.offsetHeight)) を返す//status=e.clientY-y_; <br>obj.style.left=e.clientX-x_+'px'; <br>obj.style.top=e.clientY-y_+'px'; ); <br>} // ショール.qiu スクリプト <br>function inFup(e){ <br>if(!e)e=window.event; <br>if(document.removeEventListener){ <br>document.removeEventListener('mousemove', inFmove, true); <br>document.removeEventListener('mouseup', inFup, true); <br>} else if(document.detachEvent('onmouse', inFmove); inFup); <br>} <br>inFstop(e); <br>document.body.style.cursor="auto"; <br>//Google マップと同様のドラッグ効果を実現します。 <br>ajaxRead('map.php?mapx='+(e.clientX-x_)+'&mapy='+(e.clientY-y_)+'','2'); <br>} // shawl.qiu スクリプト <br> function inFstop(e){ <br>if(e.stopPropagation) return e.stopPropagation(); <br>else return e.cancelBubble=true; <br>} // shawl.qiu スクリプト <br>function inFabort(e){ <br>if(e.preventDefault) ) return e.preventDefault(); <br>else return e.returnValue=false; <br>} // shawl.qiu スクリプト <br></script>
次のコードに注目してください:
ajaxRead('map.php?mapx='+(e.clientX-x_)+'&mapy='+(e.clientY-y_)+'','2');このセンテンスコードの位置は、レイヤーをドラッグした後にマウスを放したときにトリガーされます。代わりに、alert("マップはここにドラッグされました"); を使用できます。効果をテストします。このコードの意味は、現在のマップに従って座標をドラッグすることです。 ajaxを呼び出します。それはデータベースから地図情報を再度取得することです。 AjaxRead() は ajax 呼び出し関数です。すべて自分で書くことができます。また、prototype.js などのフレームワークを使用して記述することもできます。
//Ajax 処理コード。 (インターネットからコピーして、少し変更しました...ああ、なぜコピーし続けるのか...主に開発時間を節約するためです...もう 1 つの点は、私の JavaScript が非常にゴミであるということです (*^__^*)ふふ)

コードをコピーします コードは次のとおりです:
function ajaxRead(file,action)
{
var xmlObj = null;
if(window.XMLHttpRequest)
{
xmlObj = new XMLHttpRequest; () ;
}
else if (window.ActiveXObject)
{
xmlObj = new ActiveXObject("Microsoft.XMLHTTP")
}
else
{
return;
function ajaxDo(action)
switch(action)
{
case "2 ":
document.getElementById('display').innerHTML = xmlObj.responseText;//ここで表示されるのは、ページの上部レベルにある ID です。上記のマップコードをこのレイヤーに配置する必要があります。たとえば、
は、Firefox と IE の間の互換性を容易にするために ID と名前を書き込みます。
break;
}
}
xmlObj.onreadystatechange = function()
{
/*
if(xmlObj.readyState == 1)//ロード状態。
{
document.getElementById('xianshi2').innerHTML = "読み込み中";
}
*/
if(xmlObj.readyState == 4)//完了時。
{
ajaxDo(action);
}
}
xmlObj.open ('GET', file, true);
//xmlObj.reload('GET', file, true);
//xmlObj.abort ('');
}


コード全体の意味は次のとおりです:
マップをドラッグしてマウスを放した後、表示レイヤーはデータを取り戻します。更新は表示されません。地図内の写真はすべてpng32の透過画像を使用しております。 Ie7もff3も大丈夫です。 IE6に遭遇した場合。 。代わりにgifを使用してください。マップ.php関数。取得した x と y に従って、対応する小さなタイルを表示します。この関数は実際には上記の showMap(x,y) であり、Google マップでのドラッグに非常に似ています。しかし、それははるかに簡単です。シンプルかつ効果的。 2. キャラクター 2. キャラクターの属性
要件が設定されているため。キャラクターには装備ボーナスとステータスボーナス(バフ、デバフ)が必要です。このとき、必要なボーナスをすべてキャラクタークラスに入れます。はとても良い方法です。
おそらく次のようになります:



コードをコピーします
コードは次のとおりです: class role {
// ロールデータを取得します。
getRloe()
{
データベースからロール情報を取得します。
}
//装備ボーナスを獲得します。
getEquip()
{
装備ボーナス情報を取得します。
}
//ステータスボーナスを取得
getState()
{
ステータスボーナス情報を取得します。
}
//上記で取得した情報を加算、減算、または調整します。
//文字データを返します。
xxx を返してください
}


私はこれを特に取り上げます。キャラクターオブジェクトにボーナスが入っていないからです。戦うか何かをしなければならないたびに。キャラクターデータを取得した後は、コード処理のボーナスを大量に追加する必要があります。繰り返しが多すぎます。コードを目の前に置くと、世界は平和になります。 。 。
、小道具
小道具はかなり特別です。種類も使い方もたくさんあるので、保管場所が複数あったり、個性的な小道具があったりするかもしれません。ある日、私は Web World of Warcraft のコードを調べました。彼の唯一の小道具は時計だったことが判明した。 (1、オークションハウス、2、バックパック、3、倉庫、4、店舗) などの小道具の位置を扱うフィールドがあります。この方法は非常に優れています。ただし、プロップの複雑さが増す場合。たとえば、異なる倉庫、異なるオークションハウスを合成する必要があるなどです。またはサブテーブルのみ。
基本アイテムテーブル:
id
itemname name
itemprice 価格
itemimage 画像
itemtype タイプ
uptype 追加タイプ
uppoint ポイント追加
addtype 追加タイプ (永続)
addpoint ポイント追加 (永続)
cleardebuff デバフをクリア
addbuff バフを追加
まずはアップタ​​イプから。すべて xx|yy|zz の形式で記述できます。 1対1で対応するのがベストです。区切り文字は自分で選択できます。
データを呼び出して処理するときは、次のようなメソッドを使用できます:



コードをコピーします
コードは次のとおりです: $uptype =explode("|", $iteminfo['uptype' ]); $uppoint =explode("|", $iteminfo['uppoint']);
for ($j=0;$j{
echo $uptype[$ j];
エコー $ アップポイント
}


倉庫、オークションハウス、ショップ、バックパックなど。小道具を置く場所。プロパティ ID を保存する ID フィールドがある限り。水平テーブルか垂直テーブルかについては、実際のニーズに応じて選択できます。これまでのところ、プロップはかなり良い状態にあるようです。このときプランナーさんはこう言いました。小道具はユニークであり、エンチャントできる必要があります。 OK、次にプロパティ テーブルにすべての組み合わせを入力します。合成は a+b=c だけです。 。一つの計算。たとえば、エンチャントされる可能性のあるものは 40 個あります。エンチャント可能なアイテムが 200 個。 40*200=8000。プランナーが同意しないのは明らかです。次に、問題はプログラムです。対処方法。テーブルを追加します。
一意のプロップテーブル:
id 固有のプロップID (通常のプロップIDと重複できません。バックパックなどに便利です)
temp_id 一時ID (デフォルトは0。プロップを合成するときに使用できます。)
itemid オリジナルのプロップID (プロップを取得します)初期値)
fumo_id エンチャントID。 (デフォルトは 0、つまりエンチャントなし)
エンチャントテーブル: (つまり追加された属性)
id
uptype タイプを追加
uppoint ポイントを追加
cleardebuff デバフをクリア
addbuff バフを追加
次に関数の変更を見てみましょう
最初は prop クラスです:
class Item
{
getItem()
{
//以前は、ID に基づいてアイテム情報を直接取得できました。
//エンチャントが追加されました
//最初にアイテムIDが固有のアイテムであるかどうかを判断します。 (たとえば、通常の props 1-10000。一意の props ID は 10001 から始まります。これが良くないと思われる場合は、基本的な props テーブルにフィールドを追加します。props が一意であるかどうかを判断します)
if (props は一意です) )
{
//一意からプロップテーブルは元のプロップIDとエンチャントIDを取得します
//元のプロップID、またはプロップの基本情報に基づいて。
//エンチャントIDに従って、エンチャントボーナス情報を取得します。
//両辺の値を加算します。
小道具情報を返します。
}
else
{
小道具情報を直接取得します。
}
}
}
魅力的な機能:
アイテム A. (基本プロップ) + プロップ B。 (基本的な小道具) = 小道具 C. (唯一のプロップ)
つまり、エンチャント関数が実行されたときに唯一のプロップが生成されます。バックパックを例に考えてみましょう。エンチャント前。
バックパックの中のアイテムA。 IDは1です。
バックパックの中のアイテムB。 IDは2です。
エンチャント機能実行後。プロップ A と B の ID は 0 (水平テーブル) に設定されるか、削除されます (垂直テーブル)。一意の番号を生成します。 temp_id。 (md5 を生成するだけです。) 固有の prop を生成します。このとき、temp_id に従って、A のバックパックは再度ユニークなプロップの ID を取得します。小道具、比較的完全なソリューション。
以下の部分はすべてビジネス上の問題に関係しているため、アイデアとほんの少しのコードしか提供できません。
------------------------------------------------- -----------------------------
、タイマー
は、xx 時間待機した後に xx を実行するという問題を処理します。 PHP には sleep() 関数が付属しています。待ち時間もコントロール可能です。
しかし、明らかに、用途と効率の両方の点で。どちらもゲームのタイミングをサポートするには十分ではありません。考え方はシンプルです。カウントダウンする必要があるイベントのすべてのパラメーター、および開始時刻と終了時刻。すべてテーブルに保存されます。フロントではJavaScriptを使用してカウントダウンを行い、タイムアップになると、ajax経由でタイムアップ後のハンドラーを呼び出します。バックグラウンドは一定時間ごとに呼び出し時間が経過すると処理プログラムを自動実行します。
少なくとも 3 つの PHP ページが必要です。
アクセスタイミングを書き込むためのコンテンツです。
処理受付時間が経過すると操作は終了します。
処理のバックグラウンドは定期的に更新され、判定時間が経過すると実行が終了します。判定時間が経過するまでは処理は行われません。
奇跡: タイマーには異なるイベントに対応する異なるタイマーがありますか、それとも同じタイマーを複数のイベントに対して呼び出すことができますか? プレイヤーが建物の建設にかかる時間を計るためにタイマーを呼び出し、その後再度呼び出す場合、このタイマーが使用されます。別の建物の建設時間を計測することは可能ですか?
キーボード上の灰:
複数のイベントが 1 つのタイマーに対応します。
タイマーにフィールドを追加できます。例えば、アクションタイプ(イベントタイプ)と呼ばれます
各ユーザーは同時に複数のことを処理できます。ただ、すべてのものには決まった番号があるというだけです。
たとえば、ユーザーは同時に 5 つのことを行うことができます。その場合、actiontype の直接の番号は 1 ~ 5 になります。タイマーを呼び出すと、さまざまな数値に基づいて、これがユーザーの最初の「スレッド」であることがわかります。
奇跡
異なるユーザーが同じタイマーを呼び出しても、競合は発生しません
キーボード上の灰:
もちろん違います。見て。 userid はユーザーを識別するために使用できます。 actiontype を使用して、どのスレッドであるかを判断できます。
、イベント制御
タイマー、処理start()、process()、end()と組み合わせる
コードをコピー コードは次のとおりです:
インターフェイスアクション
{
function doAction();
function processAction();
// 単純なイベントファクトリー
class ActionFactory
{
public function getAction($what) )
{
$ActionName = $what;
return new $ActionName;
}
}
//たとえば、move
class Move は Action を実装します
{
function doAction()
{
特定の実行関数
プロセスが完了しますか?すべてここで判断されます。
}
function beginAction()
{
イベントの開始時に実行されます。
ここでタイマーにデータを保存できます。将来的には、データはタイマーから取得されるようになります。
}
function processAction()
{
タイマーからデータを取得します。
イベント実行のプロセス。たとえば、ユーザーがページを更新したときなどです。まだカウントダウンしてるなら。それなら、ここに電話してください。
}
function endAction()
{
タイマーからデータを取得します。
イベント終了のプロセス。
タイマーが終了したら、イベントを完了してください。
}
}
//初めて呼び出されたとき。
$Action = new ActionFactory();
$InstanceAction = $Action->getAction("Move");
$InstanceAction->doAction();後で呼ばれたとき。
$Action = new ActionFactory();
$InstanceAction = $Action->getAction("Move");
//このとき、イベントのパラメータまたはデータがタイマーから取得されます。
$InstanceAction->doAction();


、戦闘
リアルタイムおよび半リアルタイムのターンベースの戦闘 (2 人以上によるリアルタイムのターンベースの戦闘) は比較的面倒です。
少なくとも以下を含めてください:
フロントデスク:
招待情報を自動的に受信します。アヤックス
戦闘プロセスを表示します。アヤックス
ラウンドまでのカウントダウン。 JavaScript
バックエンド:
招待の送信、承諾、拒否、タイムアウト。テーブル。戦闘データ。テーブル。ラウンド時間、どのラウンドなどを含む、両当事者または複数の当事者のデータを保存します。
戦闘コントロール。一連の機能。プレイヤーの操作を処理し、戦闘データ テーブルに操作を保存します。時間が経過してから操作を行ってください。
軍隊を派遣した後、直接戦闘レポートに戻ります。
イベントに書くだけです。
function endAction()
{
タイマーからデータを取得します。
ラウンドを生成し、戦闘レポートを生成します。
}
注: 仕事の都合により、このシリーズを更新する前に一定期間中断する必要がある場合があります。ご容赦ください。 。 。




http://www.bkjia.com/PHPjc/320886.html
www.bkjia.com

本当

技術記事 Web ゲーム開発入門チュートリアル 2 (ゲームモード + システム) http://www.jb51.net/article/20724.htm 1. 開発言語を選択します バックエンド: java .net php フロントエンド: flex javascript ajax データベース...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。