1

私はこのようなゲームを作っています:

スマイリーゲーム

黄色のスマイリーは赤いスマイリーから逃げなければなりません。黄色のスマイリーが境界に当たると、ゲームは終了します。赤いスマイリーが境界に当たると、以下に示すように、来たのと同じ角度で跳ね返ります。

バウンス角

10 秒ごとに新しい赤いスマイリーが大きな円の中に現れます。赤いスマイリーが黄色に当たると、ゲームは終了します。赤いスマイリーの速度と開始角度はランダムになります。黄色のスマイリーを矢印キーで操作します。私が抱えている最大の問題は、複数の赤いスマイリーを作成し、それらが来た角度で境界から赤いスマイリーを反射することです。赤いスマイリーに開始角度を与え、それが来た角度でバウンスする方法がわかりません。ヒントがあればうれしいです!Mycanvas のサイズは html ファイルで 700x700 です。

私のjsソースコード:

var canvas = document.getElementById("mycanvas");

var ctx = canvas.getContext("2d");

// Object containing some global Smiley properties.
var SmileyApp = {
   radius: 15,
   xspeed: 0,
   yspeed: 0,
   xpos:200,  // x-position of smiley
   ypos: 200  // y-position of smiley
};

var SmileyRed = {
   radius: 15,
   xspeed: 0,
   yspeed: 0,
   xpos:350,  // x-position of smiley
   ypos: 65  // y-position of smiley
};
function drawBigCircle() {
 var centerX = canvas.width / 2;
      var centerY = canvas.height / 2;
      var radiusBig = 300;

      ctx.beginPath();
      ctx.arc(centerX, centerY, radiusBig, 0, 2 * Math.PI, false);
//      context.fillStyle = 'green';
//      context.fill();
      ctx.lineWidth = 5;
 //     context.strokeStyle = '#003300'; // green
      ctx.stroke();
}

function lineDistance( positionx, positiony )
{
  var xs = 0;
  var ys = 0;

  xs = positionx - 350;
  xs = xs * xs;

  ys = positiony - 350;
  ys = ys * ys;

  return Math.sqrt( xs + ys );
}
function drawSmiley(x,y,r) {
   // outer border
   ctx.lineWidth = 3;
   ctx.beginPath();
   ctx.arc(x,y,r, 0, 2*Math.PI);
  //red ctx.fillStyle="rgba(255,0,0, 0.5)";
   ctx.fillStyle="rgba(255,255,0, 0.5)";
   ctx.fill();
   ctx.stroke();

   // mouth
   ctx.beginPath();
   ctx.moveTo(x+0.7*r, y);
   ctx.arc(x,y,0.7*r, 0, Math.PI, false);

   // eyes
   var reye = r/10;
   var f = 0.4;
   ctx.moveTo(x+f*r, y-f*r);
   ctx.arc(x+f*r-reye, y-f*r, reye, 0, 2*Math.PI);
   ctx.moveTo(x-f*r, y-f*r);
   ctx.arc(x-f*r+reye, y-f*r, reye, -Math.PI, Math.PI);

   // nose
   ctx.moveTo(x,y);
   ctx.lineTo(x, y-r/2);
   ctx.lineWidth = 1;
   ctx.stroke();
}

function drawSmileyRed(x,y,r) {
   // outer border
   ctx.lineWidth = 3;
   ctx.beginPath();
   ctx.arc(x,y,r, 0, 2*Math.PI);
  //red 
  ctx.fillStyle="rgba(255,0,0, 0.5)";
  //yellow ctx.fillStyle="rgba(255,255,0, 0.5)";
   ctx.fill();
   ctx.stroke();

   // mouth
   ctx.beginPath();
   ctx.moveTo(x+0.4*r, y+10);
   ctx.arc(x,y+10,0.4*r, 0, Math.PI, true);

   // eyes
   var reye = r/10;
   var f = 0.4;
   ctx.moveTo(x+f*r, y-f*r);
   ctx.arc(x+f*r-reye, y-f*r, reye, 0, 2*Math.PI);
   ctx.moveTo(x-f*r, y-f*r);
   ctx.arc(x-f*r+reye, y-f*r, reye, -Math.PI, Math.PI);

   // nose
   ctx.moveTo(x,y);
   ctx.lineTo(x, y-r/2);
   ctx.lineWidth = 1;
   ctx.stroke();
}


// --- Animation of smiley moving with constant speed and bounce back at edges of canvas ---
var tprev = 0;   // this is used to calculate the time step between two successive calls of run
function run(t) {
   requestAnimationFrame(run);
   if (t === undefined) {
      t=0;
   }
   var h = t - tprev;   // time step 
   tprev = t;

   SmileyApp.xpos += SmileyApp.xspeed * h/1000;  // update position according to constant speed
   SmileyApp.ypos += SmileyApp.yspeed * h/1000;  // update position according to constant speed
   // change speed direction if smiley hits canvas edges
   if (lineDistance(SmileyApp.xpos, SmileyApp.ypos) + SmileyApp.radius > 300) {
     alert("Game Over");
   }

   // redraw smiley at new position
   ctx.clearRect(0,0,canvas.height, canvas.width);
   drawBigCircle();
   drawSmiley(SmileyApp.xpos, SmileyApp.ypos, SmileyApp.radius);
   drawSmileyRed(SmileyRed.xpos, SmileyRed.ypos, SmileyRed.radius);
}

run();     

// --- Control smiley motion with left/right arrow keys                        
function arrowkeyCB(event) {
   event.preventDefault();

   if (event.keyCode === 37) { // left arrow
      SmileyApp.xspeed = -100; 
      SmileyApp.yspeed = 0;
   } else if (event.keyCode === 39) { // right arrow
      SmileyApp.xspeed = 100; 
      SmileyApp.yspeed = 0;
   } else if (event.keyCode === 38) { // up arrow
      SmileyApp.yspeed = -100;
      SmileyApp.xspeed = 0;   
   } else if (event.keyCode === 40) { // right arrow
      SmileyApp.yspeed = 100; 
      SmileyApp.xspeed = 0;
   }
}
document.addEventListener('keydown', arrowkeyCB, true);

JSFiddle : http://jsfiddle.net/X7gz7/

4

1 に答える 1

0

衝突点に接線/垂直な線を見つける必要があります。次に、接線と半径線の交点によって形成される角度を 180 度から引いて、新しい角度を見つけます。

後で詳しく説明する画像を投稿します。

于 2013-11-10T18:42:00.547 に答える