Bouncing off a circular Boundary with multiple balls?

Posted by Anarkie on Game Development See other posts from Game Development or by Anarkie
Published on 2013-11-10T20:44:51Z Indexed on 2013/11/10 22:24 UTC
Read the original article Hit count: 241

Filed under:
|
|
|

I am making a game like this :

Smiley Game

Yellow Smiley has to escape from red smileys, when yellow smiley hits the boundary game is over, when red smileys hit the boundary they should bounce back with the same angle they came, like shown below:

Bounce angle

Every 10 seconds a new red smiley comes in the big circle, when red smiley hits yellow, game is over, speed and starting angle of red smileys should be random. I control the yellow smiley with arrow keys. The biggest problem I have reflecting the red smileys from the boundary with the angle they came. I don't know how I can give a starting angle to a red smiley and bouncing it with the angle it came. I would be glad for any tips!

My js source code :

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
};

var SmileyReds = new Array();

 for (var i=0; i<5; i++){
 SmileyReds[i] =  {
   radius: 15,
   xspeed: 0,
   yspeed: 0,
   xpos:350,  // x-position of smiley
   ypos: 67  // y-position of smiley
};
 SmileyReds[i].xspeed = Math.floor((Math.random()*50)+1);
 SmileyReds[i].yspeed = Math.floor((Math.random()*50)+1);
 }

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

    for (var i=0; i<SmileyReds.length; i++){
   SmileyReds[i].xpos += SmileyReds[i].xspeed * h/1000;  // update position according to constant speed
   SmileyReds[i].ypos += SmileyReds[i].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);

   for (var i=0; i<SmileyReds.length; i++){
   drawSmileyRed(SmileyReds[i].xpos, SmileyReds[i].ypos, SmileyReds[i].radius);
   }
}
// uncomment these two lines to get every going
// SmileyApp.speed = 100; 
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/gj4Q7/

© Game Development or respective owner

Related posts about math

Related posts about JavaScript