0

So I've been working on a running stick man game. Unfortunately I've come across this one problem I just can't seem to figure out. I want an alert to appear and say "Game Over" if a drawing named obstacle passes through my stick man. However if my stickman kicks (which he turns red) and the obstacle touches the drawings right foot then it will say "You win". Any help would be well appreciated!

The following is what I have so far: Btw I considered checking if a given pixel that the obstacle passes is red, then say "You win", but that seems not to work.

$(document).ready(function(e){

//get canvas from drawcanvas div
var canvas = document.getElementById("drawCanvas"),

//utilize 2D canvas
context = canvas.getContext('2d'),

//get width of canvas
width = canvas.width,

//get height of canvas
height = canvas.height,

//create stickman to keep track of body parts
stickman = {head: [200, 200, 10,0,  2*Math.PI ],
body: [195, 210, 178, 250],
rightArm: [192,215,200,230,210,230],
leftArm: [192,215,178 ,222,178,230],
rightLeg: [178, 250,190,260,185,275,192, 275],
leftLeg: [178, 250, 168, 260, 155, 262,153, 268]
} ;

//create obstacle 1
obstacle1  = { circle: [450,200, 8, 0, 2* Math.PI],
ob1_mv1:  [455, 200],
ob1_l1: [470, 200],
ob1_mv2:  [445, 200],
ob1_l2: [430, 200] };
var ob1Distance = 0;


var id = context.createImageData(1,1);
var d = id.data;
d[0] = 0;
d[1] = 0;
d[2] = 0;
d[3] = 0;

/function to render normal obstacle
function obstacle1_norm(ob1Distance) {
context.strokeStyle =  "rgb(0,0,0)";

context.beginPath();
//obstacle core
context.arc(obstacle1.circle[0] +ob1Distance,
obstacle1.circle[1],
obstacle1.circle[2],
obstacle1.circle[3],
obstacle1.circle[4],
obstacle1.circle[5]) ;
context.moveTo(obstacle1.ob1_mv1[0] + ob1Distance,obstacle1.ob1_mv1[1]);
context.lineTo(obstacle1.ob1_l1[0] + ob1Distance,obstacle1.ob1_l1[1]);
context.moveTo(obstacle1.ob1_mv2[0] +ob1Distance, obstacle1.ob1_mv2[1]);
context.lineTo(obstacle1.ob1_l2[0] +ob1Distance, obstacle1.ob1_l2[1]);
context.stroke();
}

//function render normal obstacle spin
function obstacle1_spin(ob1Distance){
context.strokeStyle =  "rgb(0,0,0)";

context.beginPath();
context.arc(obstacle1.circle[0] +ob1Distance,
obstacle1.circle[1],
obstacle1.circle[2],
obstacle1.circle[3],
obstacle1.circle[4],
obstacle1.circle[5]) ;
context.moveTo(obstacle1.ob1_mv1[0] - 5  + ob1Distance ,obstacle1.ob1_mv1[1]);
context.lineTo(obstacle1.ob1_l1[0] - 18 + ob1Distance ,obstacle1.ob1_l1[1]);
context.moveTo(obstacle1.ob1_mv2[0] - 5 + ob1Distance  ,obstacle1.ob1_mv2[1]);
context.lineTo(obstacle1.ob1_l2[0] - 20 + ob1Distance,obstacle1.ob1_l2[1]);
context.stroke();
}

function costume1(){
context.strokeStyle =  "rgb(0,0,0)";
context.beginPath();
//head
context.arc(stickman.head[0], stickman.head[1], stickman.head[2], stickman.head[3], stickman.head[4]);
//body
context.moveTo(stickman.body[0],stickman.body[1]);
context.lineTo(stickman.body[2],stickman.body[3]);

//right arm
context.moveTo(stickman.leftArm[0],stickman.leftArm[1]);
context.lineTo(stickman.leftArm[2] ,stickman.leftArm[3]);
context.lineTo(stickman.leftArm[4], stickman.leftArm[5]);

//left arm
context.moveTo(stickman.rightArm[0], stickman.rightArm[1]);
context.lineTo(stickman.rightArm[2], stickman.rightArm[3]);
context.lineTo(stickman.rightArm[4] , stickman.rightArm[5]);

//left leg
context.moveTo(stickman.rightLeg[0], stickman.rightLeg[1]);
context.lineTo(stickman.rightLeg[2],stickman.rightLeg[3]);
context.lineTo(stickman.rightLeg[4] , stickman.rightLeg[5]);
context.lineTo(stickman.rightLeg[6], stickman.rightLeg[7]);


//right leg
context.moveTo(stickman.leftLeg[0], stickman.leftLeg[1]);
context.lineTo(stickman.leftLeg[2], stickman.leftLeg[3]);
context.lineTo(stickman.leftLeg[4], stickman.leftLeg[5]);
context.lineTo(stickman.leftLeg[6] , stickman.leftLeg[7]);
context.stroke();
}

//stick figure costume 2
function costume2(){
context.strokeStyle =  "rgb(0,0,0)";

context.beginPath();
//head
context.arc(stickman.head[0], stickman.head[1], stickman.head[2], stickman.head[3], stickman.head[4]);
//body
context.moveTo(stickman.body[0],stickman.body[1]);
context.lineTo(stickman.body[2],stickman.body[3]);
//left arm
context.moveTo(stickman.leftArm[0],stickman.leftArm[1]);
context.lineTo(stickman.leftArm[2] +10 ,stickman.leftArm[3]+5);
context.lineTo(stickman.leftArm[4] +20, stickman.leftArm[5]-8);
//right arm
context.moveTo(stickman.rightArm[0]    ,  stickman.rightArm[1]);
context.lineTo(stickman.rightArm[2] -20 , stickman.rightArm[3] -5);
context.lineTo(stickman.rightArm[4] -20, stickman.rightArm[5]-5);
//right leg
context.moveTo(stickman.rightLeg[0], stickman.rightLeg[1]);
context.lineTo(stickman.rightLeg[2] - 8 ,stickman.rightLeg[3]);
context.lineTo(stickman.rightLeg[4] -20, stickman.rightLeg[5]);
context.lineTo(stickman.rightLeg[6] -20, stickman.rightLeg[7]);
//left leg
context.moveTo(stickman.leftLeg[0], stickman.leftLeg[1]);
context.lineTo(stickman.leftLeg[2] + 20 , stickman.leftLeg[3]);
context.lineTo(stickman.leftLeg[4] +8, stickman.leftLeg[5] + 8 );
context.lineTo(stickman.leftLeg[6] +15 , stickman.leftLeg[7] + 4);
context.stroke();
}

function fight_kick(){
context.strokeStyle =  "rgba(255,0,0,255)";

context.beginPath();
//head
context.arc(stickman.head[0] - 20, stickman.head[1], stickman.head[2], stickman.head[3], stickman.head[4]);
//body
context.moveTo(stickman.body[0] - 15,stickman.body[1]);
context.lineTo(stickman.body[2],stickman.body[3]);
//left arm
context.moveTo(stickman.leftArm[0] - 13,stickman.leftArm[1]);
context.lineTo(stickman.leftArm[2] - 15 ,stickman.leftArm[3]+5);
context.lineTo(stickman.leftArm[4] - 20, stickman.leftArm[5]-15);
//right arm
context.moveTo(stickman.rightArm[0] - 13    ,  stickman.rightArm[1]+1);
context.lineTo(stickman.rightArm[2]  , stickman.rightArm[3] - 22);
context.lineTo(stickman.rightArm[4] , stickman.rightArm[5] - 35);
//right leg
context.moveTo(stickman.rightLeg[0], stickman.rightLeg[1]);
context.lineTo(stickman.rightLeg[2] - 20 ,stickman.rightLeg[3]);
context.lineTo(stickman.rightLeg[4] -20, stickman.rightLeg[5]);
context.lineTo(stickman.rightLeg[6] -30, stickman.rightLeg[7]);
//left leg
context.moveTo(stickman.leftLeg[0], stickman.leftLeg[1]);
context.lineTo(stickman.leftLeg[2] + 25 , stickman.leftLeg[3]-18);
context.lineTo(stickman.leftLeg[4] + 55, stickman.leftLeg[5] -30 );
context.lineTo(stickman.leftLeg[6] +60, stickman.leftLeg[7] - 40);

context.stroke();
}

var ob1_flag = true ;
function ob1_spinning(){
 if (ob1_flag == true  ) {

   obstacle1_spin(ob1Distance);
   ob1_flag = false;
  }else  if (ob1_flag == false ) {

   obstacle1_norm(ob1Distance) ;
   ob1_flag = true;
  }
 ob1Distance -= 20;

}


//create board
function board(){
context.fillStyle="#FFF";
context.fill();
context.beginPath();
context.moveTo(0,276);
context.lineTo(width,276);
context.stroke();
context.strokeStyle="#000";
context.strokeRect(0,0,width,height);
//setInterval(function(){ob1_spinning();}, 100);

}


function collision() {

var dataPixel = context.getImageData(stickman.rightLeg[4] -20, stickman.rightLeg[5],
canvas.width, canvas.height).data;
if ( obstacle1.circle[0] + ob1Distance - 30  < stickman.head[0] + 10      )  {
}
 if (dataPixel[0] + dataPixel[1]  + dataPixel[2]  <  255 && dataPixel[0] + dataPixel[1]  + dataPixel[2] >= 241 ){
 alert("red") 
}
// context.putImageData(id,stickman.rightLeg[4] -20, stickman.rightLeg[5]);

 }




timer =  setInterval(function(){running();} , 200);
//function check  space key press if so kick
function check(e) {
    var code = e.keyCode;
    //Up arrow pressed
     if (code == 32 ) {
       context.clearRect(150,125.25, 70, 150);
       board();
       clearInterval(timer);
       setTimeout(fight_kick(), 250);
 }
 timer = setInterval(function() { running();}, 250);
}

//check for event keydown
window.addEventListener('keydown',check,false);

//flag for switching costumes
flag = true;

//running function to switch between all costumes
function running(){
if (flag == true) {
 context.clearRect(150,125.25, 70, 150);
 board();
 costume2();
 flag = false;
}else if(flag == false) {
 context.clearRect(150,125.25, 70, 150);
 board();
 costume1();
 flag = true;
}
 }
setInterval(function(){collision();}, 5);
setInterval(function(){
context.clearRect(400+ob1Distance,162, 90 , 50 );
ob1_spinning()
;} , 300);

});
acampbe222
  • 73
  • 1
  • 12

1 Answers1

1

You can use a line intersection algorithm. Feed the two lines you want to check, if non-null result they intersect. Then determine based on which lines you fed or the position on the line in the result, which part was hit and provide action accordingly.

To optimize you could first check against a bounding box, then if bounding box is hit check each line part of the shapes.

Here is one line intersection function (source):

Line 1 is given as p0x, p0y, p1x, p1y, line 2 as p2x, p2y, p3x, p3y. If intersect an object is returned with properties x and y.

var intPoint = intersection( .... );
if (intPoint) {
  ... some action here...
}

function intersection(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) {

    var d1x = p1x - p0x,
        d1y = p1y - p0y,
        d2x = p3x - p2x,
        d2y = p3y - p2y,

        // determinator
        d = d1x * d2y - d2x * d1y,
        px, py, s, t;

    // continue if intersecting/is not parallel
    if (d) {

      px = p0x - p2x;
      py = p0y - p2y;

      s = (d1x * py - d1y * px) / d;
      if (s >= 0 && s <= 1) {

        // if s was in range, calc t
        t = (d2x * py - d2y * px) / d;
        if (t >= 0 && t <= 1) {
          return {x: p0x + (t * d1x),
                  y: p0y + (t * d1y)}
        }
      }
    }
    return null
}
  • So I understand the line intersection algorithm, however how can I check what space a drawing takes up on the canvas. I assume you'd do so with checking whether a particular plots pixel is transparent or not. Am I right? – acampbe222 May 10 '16 at 16:06
  • You don't have to check using pixels. The way to use this is to feed it all the lines you want to check, e.g. all the parts of the stickman, and then compare each part against each line segment of the obstacle. Of course, the stickman and obstacle had to be defined as objects so you can track their line positions. –  May 10 '16 at 16:16
  • 1
    I thought I declared my stickman as an object here `stickman = {head: [200, 200, 10,0, 2*Math.PI ], body: [195, 210, 178, 250], rightArm: [192,215,200,230,210,230], leftArm: [192,215,178 ,222,178,230], rightLeg: [178, 250,190,260,185,275,192, 275], leftLeg: [178, 250, 168, 260, 155, 262,153, 268] } ;` – acampbe222 May 10 '16 at 17:51