JavaScript - 2d Polygon Collision And Reaction
I am having troubles getting two polygons to collide and react properly. For now, I just have two boxes. One box is stationary in the center of my canvas while another one is controlled by the keypad arrow keys and flies around. I have no problem detecting when my flying box intersects the stationary box. However, what I am having troubles with is getting the flying box to hit the stationary box and react as if it was an actual object blocking it's path. For now I just need to have my flying box be able to hit the stationary box on any side and have the stationary box block the flying box's motion. At some point, however, I will likely need to do this same kind of reaction between multiple edged 2d polygons. Can anyone help me with this simple box example and also help me track down a more complex scenario similar to this:
http://www.codeproject.com/Articles/...sion-Detection This article seems to be exactly what I am looking for but it is in C#. The way the flying object just slides along the edge of the intersecting polygon is all I need my flying object to do. However, I need an example in javascript so that I can incorporate it into an HTML5 canvas object. Similar TutorialsHello, I'm making a simple javascript game. There is a square stage with a bouncing ball in it. The user can move a paddle along the bottom of the square using the arrow keys to hit the ball, and make it continue bouncing. If the user's paddle doesn't reach the ball in time, it falls to ground, game over. However, my collision isn't working. The ball falls right through my paddle. What am I doing wrong? Code is he <!DOCTYPE HTML PUBLIC> <html> <head> <title>Bask-A-Bounce!</title> <style> #stage{ position: absolute; top: 100; left: 100; border: 3px solid black; width: 500; height: 500; background-color: #E0FFFF; } #paddle{ position: absolute; top: 470; left: 228; width: 64; height: 16; } #ball{ position: absolute; top: 4; left: 200; width: 16; height: 16; } #score{ position: absolute; top: 486; left: 0; width: 500; height: 14; background-color: rgb(32,128,64); } </style> <script language="JavaScript"> //get info, process data, update screen objects //instance vars var ball; var paddle; var score; //initial speeds var dx = 5; var dy = 5; var currentScore = 0; var timer; //set initial conditions for ball and paddle var paddleLeft = 228; var ballLeft = 300; var ballTop = 4; function init(){ //instantiate HTML object instance vars ball = document.getElementById('ball'); paddle = document.getElementById('paddle'); score = document.getElementById('score'); //register key listener with document object document.onkeydown = keyListener; //start the game loop start(); } function keyListener(e){ if(!e){ //for IE e = window.event; } if(e.keyCode==37 && paddleLeft > 0){ //keyCode 37 is left arrow paddleLeft -= 4; paddle.style.left = paddleLeft + 'px'; } if(e.keyCode==39 && paddleLeft < 436){ //keyCode 39 is right arrow paddleLeft += 4; paddle.style.left = paddleLeft + 'px'; } } function start(){ //game loop detectCollisions(); render(); //end conditions if(ballTop < 470){ //still in play - keep the loop going timer = setTimeout('start()',50); } else{ gameOver(); } } function detectCollisions(){ //just reflect the ball on a collision //a more robust engine could change trajectory of ball based //on where the ball hits the paddle if(collisionX()) dx = dx * -1; if(collisionY()) dy = dy * -1; } function collisionX(){ //check left and right boundaries if(ballLeft < 4 || ballLeft > 462) return true; return false; } function collisionY(){ //check if at top of playing area if(ballTop < 4) return true; //check to see if ball collided with paddle if(ballTop > 470){ if(ballLeft > paddleLeft && ballLeft < paddleLeft + 64) return true; } return false; } function render(){ moveBall(); updateScore(); } function moveBall(){ ballLeft += dx; ballTop += dy; ball.style.left = ballLeft; ball.style.top = ballTop; } function updateScore(){ currentScore += 5; score.innerHTML = 'Sco ' + currentScore; } function difficulty(){ //as the game progresses, increase magnitude of the vertical speed if(currentScore % 1000 == 0){ if(dy > 0) dy += 1; else dy -= 1; } } function gameOver(){ //end the game by clearing the timer, modifying the score label clearTimeout(timer); score.innerHTML += " Game Over"; score.style.backgroundColor = 'rgb(128,0,0)'; } </script> </head> <body onLoad="init()"> <h1>Bask-A-Bounce</h1> <div id="stage"> <div id="paddle"> <img src="paddle1.gif"> </div> <div id="ball"> <img src="ball.gif"> </div> <div id="score"> Sco 0 </div> </div> <embed name="SJT" src="SJT.mp3" loop="false" hidden="true" autostart="true"> </embed> </body> </html> im making a sniper game where you shoot apples, and i need to check when the crosshairs are on the apple whenever the user clicks the canvas (note that the onclick listener is in the html, thats why you dont see it, and ive checked that it works). This code doesnt work Code: var crosshair = [250, 200]; var appley = [-100,-400,0,-250]; var applex = [0,200,400,500]; var canvas = document.getElementById("game"); function getMousePos(canvas, evt) { var rect = canvas.getBoundingClientRect(); return { x: evt.clientX - rect.left, y: evt.clientY - rect.top }; } var context = canvas.getContext('2d'); canvas.addEventListener('mousemove', function(evt) { var mousePos = getMousePos(canvas, evt); crosshair[0] = mousePos.x; crosshair[1] = mousePos.y; }, false); function draw(x, y, image){ var context = canvas.getContext("2d"); var imageObj = new Image(); imageObj.onload = function() { context.drawImage(imageObj, x, y); }; imageObj.src = image; } function shoot(){ for(i = 0; i < 4; i++){ if(crosshair[0]-400 > applex[i] && crosshair[0]-400 < applex[i]+80 && // THIS IS THE COLLISION crosshair[1]-300 > appley[i] && crosshair[1]-300 < appley[i]+80){ appley = 500; alert("hit"); } } } function main(){ draw(0,0,"background.jpg"); for(i = 0; i < 4; i++){ draw(applex[i],appley[i],"apple.png"); appley[i] = appley[i]+10; if(appley[i] > 450){ appley[i] = -50; applex[i] = Math.floor((Math.random() * 5) + 1)*100; } } draw(crosshair[0]-400, crosshair[1]-300, "crosshair.png"); } var mainint = setInterval(function(){main();}, 100); help plz i cant get collission detection to work. i tryed but it always caused an infinite loop. heres the code. Code: <html> <!-- main file.--> <head> <title>lightning generator</title> </head> <body> <canvas id='world' width='500' height='500' style='border: 1px solid black; padding:0;'></canvas> <script type="text/javascript" src='world.js'></script> <script type='text/javascript' src='eC.js'></script> <script type='text/javascript' src='world.ground.js'></script> <script type='text/javascript'> world.bolt = { } ; world.bolt.paths = []; // main obj inits world.bolt.draw = function(){ var x, y; for( var id = 0; id <= world.bolt.draw.num; id ++ ){ world.ctx.moveTo( world.bolt.paths[id].x[world.bolt.paths[id].x.length-1], world.bolt.paths[id].y[world.bolt.paths[id].y.length-1] ); var mdx=Math.floor(Math.random()*world.bolt.paths[id].mdx); x = world.bolt.paths[id].x[world.bolt.paths[id].iters] + ((Math.random()<Math.random())?mdx:-mdx); y = ++ world.bolt.paths[id].iters; world.bolt.paths[id].x.push( x ); world.bolt.paths[id].y.push( y ); world.ctx.strokeStyle = world.bolt.paths[id].color; world.ctx.lineTo( x, y ); world.ctx.stroke(); //world.ctx.beginPath(); } if(x%3==0){ world.ctx.fillStyle=world.skyColor; world.ctx.fillRect(0,0,world.w,world.h);} } world.bolt.draw.num=-1; world.bolt.cpath = function( x, y, mdx, srate, id, color ){ world.bolt.paths[id] = { } ; world.bolt.paths[id].iters = 0; world.bolt.paths[id].x = []; world.bolt.paths[id].y = []; world.bolt.paths[id].x[0] = x; world.bolt.paths[id].y[0] = y; world.bolt.paths[id].mdx = mdx; world.bolt.paths[id].srate = srate; world.bolt.paths[id].color = color; world.bolt.draw.num += 1; } world.bolt.cpath(250,0, 5,5,0,'rgba(255,255,150,.5)'); window.setInterval(world.bolt.draw,100) window.setTimeout('world.bolt.cpath(125,0,5,5,1,"rgba(255,10,0,.5)")',1000); </script> </body> </html> Code: //world.js var world = { skyColor:'rgba(0,0,100,.009)' } ; world.canvas = document.getElementById( 'world' ) world.canvas.cstyle = document.defaultView.getComputedStyle( world.canvas, null ) world.w = parseInt( world.canvas.cstyle.width, 10 ); world.h = parseInt( world.canvas.cstyle.height, 10 ); world.ctx = world.canvas.getContext( '2d' ); finally, Code: // world.ground.js world.ground = { } ; world.ground.level = []; world.ground.make = function( GArray, length ){ world.ctx.strokeStyle = '#000000'; world.ground.level = []; world.ctx.fillStyle = '#FFF'; world.ctx.fillRect( 0, 0, world.w, world.h ); world.ground.level = GArray; for ( world.ground.make.i = 0; world.ground.make.i <= length; world.ground.make.i ++ ){ if ( GArray[world.ground.make.i + 1] === undefined ){ GArray[world.ground.make.i + 1] = GArray[world.ground.make.i]; } world.ctx.moveTo( world.ground.make.i, ( world.h ) ); world.ctx.lineTo( world.ground.make.i, ( world.h - GArray[world.ground.make.i] ) ); } world.ctx.stroke(); world.ctx.beginPath(); } ; world.ground.create = function( func, width ){ func = ec( func ); if( func === false ){ alert( 'Pass equation as a string without the "y=", "f(x)=", "g(x)=" or similar.' ); return world; } if( func == 'perspicaciousness' ){ return world; } var temp = []; for( var x = 0; x <= width; x ++ ){ temp[x] = eval( func ); } world.ground.make( temp, width ); } ; world.ground.create.test='4'; world.ground.create( world.ground.create.test, 500 ); in the end of world.bolt.cpath,there should be a way to use the local varis X and Y, and world.ground.js's world.ground.level[] to detect it. sorry for the gigantic length. thanks in advanced. the jsnerd hey guys i'm making a lunar lander game using javascript.i want the player to land the spaceship on a black line i've drawn. but i have problems getting it right.when the player lands it properly in the line i want it to display a dialogue box which says u landed it perfectly.but the problem is even if i land it outside the line it gives me that message.so after spending sometime with it i figured out that my if statement is not working properly.it doesn't take the value from my x axis and only considers the value from my y axis.for eg lets say i drew the line from 560px to 600px on the x axis and its located at 700px on the y axis and this is my if statement if((TopPos>695)&&(rightPos>560)&&(rightPos<600)) { alert('you landed perfectly') } this is supposed to work but if i go above 600px but still maintains the height above 695 it says i have won.i have included the code could some point me out where i'm making the mistake thank you . Code: <html> <head> <title>Lunar lander</title> <script language="JavaScript"> var TopPos=100; var fuel = 300; var gravity = 0.0001; var speed = 0.0005; var moveBy = 366; var Xpix = 1000; function animation(){ TopPos +=gravity document.getElementById("divlander").style.top = TopPos + "px"; if ((TopPos>604)&&(Xpix<526)){ alert('win'); } else if ((moveBy<100)&&(moveBy>500)){ alert('crashed'); } if(TopPos<610) window.setTimeout("animation()",30); gravity +=0.03; gravity += speed; var f = document.game.fuel.value; f--; document.game.fuel.value = f; if (f<=0){ document.game.fuel.value ="0"; gravity=10; gr=0; speed=10; f=1; alert('out of fuel'); } } function moveObj(name, Xpix, Ypix) { obj = document.getElementById(name); px = parseInt(obj.style.left) + Xpix; py = parseInt(obj.style.top) + Ypix; obj.style.left = px; obj.style.top = py; } function ProcessKeypress(e) { var myObj = "divlander"; var moveBy = 10; if (e.keyCode) keycode=e.keyCode; else keycode=e.which; ch=String.fromCharCode(keycode); if(ch=='a') moveObj(myObj, -moveBy, 0); else if(ch=='d') moveObj(myObj, moveBy, 0); else if(ch=='w') gravity = -1; } </script> <form name='game'> <body onKeyPress="ProcessKeypress(event);"> <body onload ="animation();"> <input type=button value='200' name="fuel"> <p><img id="divlander" style="z-index: 0; left: 1000px; position: absolute; top: 100px" img src="lunar_lander_72dpi2.png"></p> <img src="Serenity2.jpg";> <p><<body> </body> </form> </html> i have a simple collision if statement in the main interval in a javascript game. The problem is, it only sometime works, as in i have to shoot at zombies multiple times for them to disappear, when it should only take 1 bullet. i have arrays for the players bullets x and y values, and 5 zombies x and y values(4 total arrays). The collision code is at the bottom of the main() function. here is the code: Code: var missed = 0; var score = 0; var on = 1; var bulletx = []; var bullety = []; var zombiex = [700,600,800,1000,900]; var zombiey = [0,100,300,200,50]; function draw(image, x, y){ var canvas = document.getElementById("game"); var context = canvas.getContext("2d"); var imageObj = new Image(); imageObj.onload = function() { context.drawImage(imageObj, x, y); }; imageObj.src = image; } document.onkeydown = checkKey; function checkKey(e) { if(on === 1){ if(on === 1){ e = e || window.event; if (e.keyCode == '40') { down(); }else if (e.keyCode == '38') { up(); }else if(e.keyCode == '32'){ bullety.push(y+50); bulletx.push(100); score = score - 1; } } } } var y = 300; function down(){ y = y+50; draw("player.png", 0, y); } function up(){ y = y-50; draw("player.png", 0, y); } draw("player.png",0,y); function main(){ draw("background.png",0,0); draw("player.png",0,y); for(i = 0; i < 5; i++){ draw("zombie.png",zombiex[i],zombiey[i]); zombiex[i] = zombiex[i] - 5; if(zombiex[i] < -100){ zombiex[i] = 600; zombiey[i] = Math.random()*450 missed = missed+1; } } if(missed === 5){ clearInterval(mainint); alert("5 zombies passed you, and America has fallen"); alert("sco "+score); on = 0; } for(i = 0; i < bulletx.length; i++){ draw("background.png",0,0); draw("bullet.png",bulletx[i],bullety[i]); bulletx[i] = bulletx[i]+30; if(bulletx[i] > 700){ bulletx.splice(i,1); bullety.splice(i,1); } if(bulletx[i] > zombiex[i] && bullety[i] > zombiey[i]-20 && bullety[i] < zombiey[i]+70){ zombiex[i] = 600; zombiey[i] = Math.random()*450 score = score + 10; } } } var mainint = setInterval(function(){main();}, 50); so basically I have a div that contains the image of a circle and I need to check if the mouse is touching the circle. what approach should I take to this? I need to call another function when the mouse leaves the circle (which will be a square speaking physically) I would assume it has to do with radius, but I am not really sure how to do this with a circle shape. thanks a ton! |