HTML5_html5 チュートリアルのヒントを使って簡単な弾むボール ゲームを作成する

WBOY
リリース: 2016-05-16 15:46:41
オリジナル
1865 人が閲覧しました

一週間以上キャンバスを学習していますが、キャンバスは本当に楽しいと思います。 Canvas を学ぶ人はおそらく私と同じような考えを持っており、ゲームを書くという姿勢で Canvas を学習しています。したがって、運動学、衝突検出、およびいくつかの単純なアルゴリズムが基礎となります。これまでゲームを作ったことがなかった私にとって、学ぶのは本当に大変でした。今日は、キャンバスを使用して、最も単純な重力と衝突検出を使用して、最も単純な弾むボール ゲームを作成する方法について説明します。

まずデモに行きましょう: 弾むボールのデモ (キャンバス内の空白領域をクリックすると、ボールに新しい速度が与えられます)

【ボールオブジェクトの作成】

最初のステップは、ボール オブジェクトを作成し、ボールのコンストラクターを記述することです:

コードをコピー
コードは次のとおりです。以下のように:

var Ball = function(x, y, r, color){
this.x = x;
this.y = y;
this。 = x;
this.oldy = y;
this.vx = 0;
this.vy = 0;this.radius = r;
this.color = color;
}

ボールの属性は非常に単純です。xy はボールの座標、vx と vy はボールの水平初速度と垂直初速度です。 radius はボールの半径、color はボールの色 (異なるボールを区別するため)、oldx と oldy は前のフレームでのボールの位置を記録し、ボール間の衝突後の位置補正に使用されます。後段で(実際には後で役に立たない) 上記については、oldx を使用して設定すると、位置補正が直接計算されますが、記録すると必然的に使用されます)。

ボールの属性を記述した後、ボールのプロトタイプにボールのアクションを記述します:

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

Ball.prototype = {
paint:function(){
ctx.save();
ctx.beginPath();
ctx .arc(this.x , this.y , this.radius , 0 , Math.PI*2);
ctx.fillStyle=this.color;
ctx.fill();
ctx .restore ();
this.movi​​ng = false;
},
run:function(t){
if(!this.candrod) {
this.paint();
return};
this.oldx = this.x;
this.oldy = this.y;


if(Math.abs(this.vx) < 0.01){
this.vx = 0;
}
else this.vx = this.vx>0?モカリ*t : モカリ*t;

this.vy = this.vy g * t;

this.x = t * this.vx * pxpm;
this.y = t * this.vy * pxpm;< /p>

if(this.y > Canvas.height - ballRadius || this.y < ballRadius){
this.y = this.y < ballRadius ? : (canvas.height - ballRadius);
this.vy = -this.vy*collarg
}
if(this.x > Canvas.width - ballRadius || this.x < ballRadius){
this.x = this .x < ballRadius ? ballRadius : (canvas.width - ballRadius);
this.derectionX = !this.derectionX;
this.vx = -this.vx*collarg;
}
this .paint();
},

}

ボールを動かす方法は 2 つしかありません。1 つ目は自分で描く方法で、2 つ目はボールの動きをコントロールする方法です。 t は、現在のフレームと前のフレーム間の時間差です。ボールの速度の増分を計算してボールの変位の増分を取得するために使用され、それによってボールの新しい位置を計算し、ボールを再描画します。新しい位置が得られると、ボールの新しい位置が壁を超えるかどうかも判断され、超えた場合にはボールが跳ね返るように速度が修正されます。

2 番目のメソッドの定数 ballRadius =30、g = 9.8、mocali = 0.5、balls = []、collarg = 0.8、pxpm = Canvas.width/20; 意味は明らかです。ballradius はボールの半径です。 、g は重力加速度、mocali は空気抵抗によって生じる水平方向の減速度、ball は小さな球体を格納するために使用される配列、collagen は弾性係数です。 pxpm はピクセルとメートルの間のマッピングであり、キャンバスを幅 20 メートルの領域として扱います。

【衝突検知】

ボール オブジェクトを作成したら、ボール間の衝突の記述を開始します。

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

関数collision(){
for(var i=0;i for(var j=0;j var b1 = ball[i],b2 = ball[j];
if(b1 !== b2){
var rc = Math.sqrt(Math.pow(b1.x - b2.x) , 2) Math.pow(b1.y - b2.y , 2));
if(Math.ceil(rc)

//衝突後の速度の増分を取得します
var ax = ((b1.vx - b2.vx)*Math.pow((b1.x - b2.x) , 2) (b1.vy - b2.vy)*(b1.x - b2.x)*(b1.y - b2.y))/Math.pow(rc , 2)
var ay = ((b1.vy - b2.vy) )*Math.pow((b1.y - b2.y) , 2) (b1.vx - b2.vx)*(b1.x - b2.x) (b1.y - b2.y))/Math. pow(rc, 2)

// ボールに新しい速度を与えます
b1.vx = (b1.vx-ax)*collarg;
b1.vy = (b1.vy-ay)*collarg;
b2 .vx = (b2.vx ax)*collarg;
b2.vy = (b2.vy ay)*collarg;

//2 つのボールの斜めの切断位置を取得し、ねじりを加えます
var clength = ((b1.radius b2.radius)-rc)/2;
var cx = clength * (b1 .x-b2 .x)/rc;
var cy = clength * (b1.y-b2.y)/rc;
b1.x = b1.x cx;
b1.y = b1 .y cy;
b2.x = b2.x-cx;
b2.y = b2.y-cy;
}
}
}
}
}


毎フレーム、ボール間の衝突が判定され、2 つのボールの中心間の距離が 2 つのボールの半径の和より小さい場合、2 つのボールが衝突していることが証明されます。ボールが衝突しました。次に、2 つのボールが衝突した後の速度の変化を計算します。 ax と ay は速度の変化です。
背後にある長い式は次のとおりです:
2015512173816364.png (334×192)

具体的な原理については説明しません。原理を知りたい場合は、小球衝突のアルゴリズム設計 をクリックしてください。 次の段落は、衝突検出が繰り返されることでボールが正常に跳ね返るのを防ぐため、2 つのボールの中心間の距離を計算し、2 つのボールの斜めの位置を計算し、ボールの位置を計算します。 2つのボールが修正されました。

【モーションアニメーション】

最終ステップ:

コードをコピーします
コードは次のとおりです。
< /p>

canvas.onclick = function(event){
event =event ||
var x =event.clientX document.body.scrollLeft document.documentElement.scrollLeft - Canvas.offsetLeft;
var y=event.clientY document.body.scrollTop document.documentElement.scrollTop - Canvas.offsetTop;

balls.forEach(function(){
this.vx = (x - this.x)/20; //初速度 m/s
this.vy = (y - this.y) /20;
});
}

関数 animate(){
ctx.save();
ctx.fillStyle = "rgba(255,255,255,0.2)";
ctx.fillRect(0,0,canvas.width,canvas) .height)
ctx.restore();
// ctx.clearRect(0,0,canvas.width,canvas.height)

var t1 = new Date();
var t = (t1 - t0)/1000;
collision();
balls.forEach(function(){
this.run (t);
});

t0 = t1;

if("requestAnimationFrame" in window){
requestAnimationFrame(animate);
}
else if("webkitRequestAnimationFrame" in window){
webkitRequestAnimationFrame(animate);
}
else if("msRequestAnimationFrame" in window){
msRequestAnimationFrame(animate);
}
else if("mozRequestAnimationFrame" in window){
mozRequestAnimationFrame(animate);
}
}
}

キャンバスをクリックしてボールに初速度を与え、アニメーションの各フレームを実行するために使用される方法がアニメーションです。上記の ctx.fillStyle = "rgba(255,255,255,0.2)"; ctx.fillRect(0,0,canvas.width,canvas.height) は、ボールにゴースト シャドウを追加するものであると思います。それが気に入らない場合は、clearRect を使用して直接クリアしてください。次に、各フレームの時間差を計算し、小ボール配列内の小ボール配列をトラバースして再描画します。次に、衝突検出のための衝突メソッドを追加します。アニメーションは終了しました。

この時点で、ソースコードアドレス:

が書き込まれています。

https://github.com/whxaxes/canvas-test/blob/gh-pages/src/Other-demo/shotBall.html

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!