ウィキペディアを信じているなら、 卓球は卓球の最も簡単なシミュレーターであることがわかります。 ピンポンボールを置き換える小さな正方形が、画面に沿って直線経路に沿って移動します。 彼が競技場の周囲または描かれたラケットのいずれかに当たった場合、彼の軌道は衝突の角度に応じて変化します。
ゲームプレイでは、プレイヤーは目標を守るためにラケットを垂直に動かします。 プレーヤーが相手のラケットにボールを送ることに成功した場合、1ポイントを獲得します...
マウスでプレイできるようにゲームを実装し、対戦相手はコンピューターによって制御されるようにします。 それでは始めましょう。 まず、この投稿で何が起こっているかを完全に理解するために、 基本を説明している投稿に慣れておくことをお勧めします。
メガプロジェクトは、 pong.htmとpong.jsの2つのファイルで構成され、実際には1つのフォルダーに作成して保存する必要があります。
HTMLファイルの内容:
< html >
< head >
< meta charset = "utf-8" >
< title > html5Pong < / title >
< script src = "pong.js" >< / script >
< / head >
< body >
<canvas id = "pong" > wtf?! < / canvas>
< script > init() < / script >
< / body >
< / html >
実際、ゲームのすべての仕組みはpong.jsファイルに転送され、将来のゲームの最初の行を追加します。
//
function init ( ) {
canvas = document. getElementById ( "pong" ) ;
canvas. width = 480 ; //
canvas. height = 320 ; //
context = canvas. getContext ( '2d' ) ;
draw ( ) ;
}
//
function draw ( ) {
context. fillStyle = "#000" ;
context. fillRect ( 0 , 0 , 480 , 320 ) ;
}
init ( ) ;
ブラウザでhtmlファイルを開くと、実際にキャンバスを黒でペイントするこのスクリプトの動作を見ることができます。
ゲームオブジェクト
Pongのすべてのゲームオブジェクトは長方形であり、これにより作業が非常に容易になります。 四角形の描画に必要なすべてのフィールドとdrawメソッドを含む小さなRectクラスを定義しましょう。
function rect ( color , x , y , width , height ) {
this . color = color ; //
this . x = x ; //
this . y = y ; //
this . width = width ; //
this . height = height ; //
this . draw = function ( ) //
{
context. fillStyle = this . color ;
context. fillRect ( this . x , this . y , this . width , this . height ) ;
}
}
競技場、プレーヤー、および「ボール」にオブジェクトを追加して、初期化およびレンダリング機能の内容をわずかに変更します
//
function init ( ) {
//
game = new rect ( "#000" , 0 , 0 , 480 , 320 ) ;
// -
ai = new rect ( "#fff" , 10 , game. height / 2 - 40 , 20 , 80 ) ;
player = new rect ( "#fff" , game. width - 30 , game. height / 2 - 40 , 20 , 80 ) ;
//
ai. scores = 0 ;
player. scores = 0 ;
// ""
ball = new rect ( "#fff" , 40 , game. height / 2 - 10 , 20 , 20 ) ;
canvas = document. getElementById ( "pong" ) ;
canvas. width = game. width ;
canvas. height = game. height ;
context = canvas. getContext ( "2d" ) ;
draw ( ) ;
}
//
function draw ( ) {
game. draw ( ) ; //
//
context. font = 'bold 128px courier' ;
context. textAlign = 'center' ;
context. textBaseline = 'top' ;
context. fillStyle = '#ccc' ;
context. fillText ( ai. scores , 100 , 0 ) ;
context. fillText ( player. scores , game. width - 100 , 0 ) ;
for ( var i = 10 ; i < game. height ; i += 45 ) //
{
context. fillStyle = "#ccc" ;
context. fillRect ( game. width / 2 - 10 , i , 20 , 30 ) ;
}
ai. draw ( ) ; //
player. draw ( ) ; //
ball. draw ( ) ; //
}
ここでファイルを開くと、ゲームのすべての要素を見ることができます。
人生がありますように
もちろん、この段階でのすべては非常に良いように見えますが、静的な画像は必要なものではありません。 そこで、ボールを「復活」させます。 これを行うには、draw()関数を呼び出す新しいplay()関数を作成し、タイマー、つまりsetInterval(play、1000/50)を使用してinit()からplay自体を呼び出します。 プレーヤーのy座標を、キャンバスの周りを移動するマウスの座標にバインドします。 更新機能には、マウス座標やその他の喜びなど、行う必要のある変更が含まれています。 以下のアクションで混乱しないように、出力が必要なpong.jsファイル全体のコード:
//
function rect ( color , x , y , width , height ) {
this . color = color ;
this . x = x ;
this . y = y ;
this . width = width ;
this . height = height ;
this . draw = function ( ) {
context. fillStyle = this . color ;
context. fillRect ( this . x , this . y , this . width , this . height ) ;
} ;
}
//
function playerMove ( e ) {
var y = e. pageY ;
if ( player. height / 2 + 10 < y && y < game.height - player.height / 2 - 10 ) {
player. y = y - player. height / 2 ;
}
}
//
function draw ( ) {
game. draw ( ) ; //
//
context. font = 'bold 128px courier' ;
context. textAlign = 'center' ;
context. textBaseline = 'top' ;
context. fillStyle = '#ccc' ;
context. fillText ( ai. scores , 100 , 0 ) ;
context. fillText ( player. scores , game. width - 100 , 0 ) ;
for ( var i = 10 ; i < game. height ; i += 45 )
//
{
context. fillStyle = "#ccc" ;
context. fillRect ( game. width / 2 - 10 , i , 20 , 30 ) ;
}
ai. draw ( ) ; //
player. draw ( ) ; //
ball. draw ( ) ; //
}
//
function update ( ) {
//
ball. x += ball. vX ;
ball. y += ball. vY ;
}
function play ( ) {
draw ( ) ; //
update ( ) ; //
}
//
function init ( ) {
//
game = new rect ( "#000" , 0 , 0 , 480 , 320 ) ;
// -
ai = new rect ( "#fff" , 10 , game. height / 2 - 40 , 20 , 80 ) ;
player = new rect ( "#fff" , game. width - 30 , game. height / 2 - 40 , 20 , 80 ) ;
//
ai. scores = 0 ;
player. scores = 0 ;
// ""
ball = new rect ( "#fff" , 40 , game. height / 2 - 10 , 20 , 20 ) ;
//
ball. vX = 2 ; //
ball. vY = 2 ; //
canvas = document. getElementById ( "pong" ) ;
canvas. width = game. width ;
canvas. height = game. height ;
context = canvas. getContext ( "2d" ) ;
canvas. onmousemove = playerMove ;
setInterval ( play , 1000 / 50 ) ;
}
ゲームの衝突
最も興味深いことは、ボールが競技場の外に飛ばないように、ラケットをタッチするように教える必要があるということから始まります。 以下は彼女のコードです
function collision ( objA , objB ) {
if ( objA. x + objA. width > objB. x &&
objA. x < objB. x + objB. width &&
objA. y + objA. height > objB. y &&
objA. y < objB. y + objB. height ) {
return true ;
}
else {
return false ;
}
}
ここで、ボールが競技場の外に飛ぶだけではないように、更新機能をわずかに調整する必要があります。
function update ( ) {
//
//
if ( ball. y < 0 || ball. y + ball. height > game. height ) {
//
ball. vY = - ball. vY ;
}
//
if ( ball. x < 0 ) {
//
ball. vX = - ball. vX ;
player. scores ++;
}
if ( ball. x + ball. width > game. width ) {
//
ball. vX = - ball. vX ;
ai. scores ++;
}
//
if ( ( collision ( ai , ball ) && ball. vX < 0 ) || ( collision ( player , ball ) && ball. vX > 0 ) ) {
ball. vX = - ball. vX ;
}
//
ball. x += ball. vX ;
ball. y += ball. vY ;
}
ゲームをプレイすることはほぼ可能です。ボールは正しく飛行し、ラケットはそれを打ち負かすことができます。対戦相手は本当にわずかに死体を持っていますが、小さな機能で修正します。
function aiMove ( ) {
var y ;
//
var vY = Math. abs ( ball. vY ) - 2 ;
if ( ball. y < ai. y + ai. height / 2 ) {
y = ai. y - vY ;
}
else {
y = ai. y + vY ;
}
if ( 10 < y && y < game. height - ai. height - 10 ) {
ai. y = y ;
}
}
関数呼び出しは更新に配置する必要があります。
まとめ
実際に、彼らはそれを書いたが、それは少しだけ修正するために残っており、今では本格的なピンポンです。 プレイしたゲームの統計とスコアを画面に表示し、速度の変更をマウスクリックに関連付けます。 ここでは、コメントでいっぱいの簡単な統計でPONGを見つけることができます。