Stop Player Movement After Collision Detection In Canvas - javascript

I basically made two walls in the canvas. One in the top and one at the bottom. My player is controlled by the MOUSE and I wanted to know how to make the player not go through the walls.
Here's the function for the general collision between two objects:
function collides(a, b) {
var val = false;
val = (a.x < b.x + b.width) &&
(a.x + a.width > b.x) &&
(a.y < b.y + b.height) &&
(a.y + a.height > b.y);
return val;
}
Here's the code that detects collision detection:
if (collides(player, block)){
//I don't know what goes here.
}
Any help would be appreciated.

Reposition the player as you already do and also clamp the player's y position to always be between the top and bottom walls.
In your mousemove handler (or wherever the player is repositioned by the mouse):
// reposition the player as you already do
...
// and clamp the player to stay below the top wall
if( player.y < wall.y+wall.height ){ player.y = wall.y+wall.height);
// and clamp the player to stay above the bottom wall
if( player.y+player.height > wall.y ){ player.y = wall.y-player.height);

Related

How to make better movement for game objects in JavaScript?

I'm making pong with HTML canvas and JavaScript, and I am having trouble with the movement of the ball. If you position the paddles in a way that they hit the ball, and then you just leave them there, the ball will just continue in an infinite loop bouncing between the paddles, and the top and bottom of the screen. How can I implement a random number to make the ball move in the opposite direction but slightly differently? If you need any more code than this, let me know. Thx
// Ball to paddles collision detection
function ballToPaddlesCollisionDetection(a,b) {
if(a.X < b.X + b.width && a.X + a.width > b.X && a.Y < b.Y + b.height && a.Y + a.height > b.Y) {
ballDX = -ballDX;
ballDY = - ballDY;
}

How to change angle when a ball collides with a rectangle?

If a circle hits a rectangle and needs to bounce, I need to calculate its new direction.
This is what I have
function tick() {
var dx = Math.cos(ball.direction * (Math.PI / 180))*ball_md.speed;
var dy = Math.sin(ball.direction * (Math.PI / 180))*ball_md.speed;
ball.x += dx;
ball.y -= dy;
drawGame(); // refresh board
//console.log(ball);
paddles.some(function(paddle) {
var circle={x:ball.x+ball_md.radius, y:ball.y+ball_md.radius, r:ball_md.radius};
var rect={x:paddle.x, y:paddle.y, w:game_md.paddle.width, h:game_md.paddle.height};
var hit = RectCircleColliding(circle, rect);
if (hit) {
if (Math.floor(ball.y) + ball_md.radius*2 <= paddle.y || Math.ceil(ball.y) >= paddle.y + game_md.paddle.height) { // hit on top or below paddle
ball.direction = 360 - ball.direction;
} else { // hit left or right side
ball.direction = 180 - ball.direction;
}
return true;
}
});
if (ball.y < 0 || ball.y+ball_md.radius*2 >= game_md.height) { // hit top or bottom wall
ball.direction = 360 - ball.direction;
}
if (ball.x < 0 || ball.x+ball_md.radius*2 >= game_md.width) { // hit left or right wall
ball.direction = 180 - ball.direction;
}
}
but it doesn't seem to always work. Does anyone know why?
Cases when it fails. In this case, it zigzags really fast on the paddle surface.
DEMO: https://jsfiddle.net/3ok2farw/2/
You need to treat the corner collision separately. When it hits the corner the velocity of the ball doesn't change perpendicular to either the horizontal or vertical axis, but along the line connecting the center of the ball and the corner. I'm adding a drawing to make it a bit clearer. If the collision is perfectly elastic (no energy loss), then the v_normal component gets replaced by its negative, -v_normal. If the collision is perfectly plastic (maximum energy loss), the exit velocity is just v_tangential. Hope this helps!

Player facing away from the wall should not collide

I'm working on my first Javascript game. It is a top down 2D view (think GTA 1/2). Now I'm having trouble with collision detection. I have multiple entities where one is the player and the other is a static object (let's say a wall for simplicity).
Each object has X/Y coordinates and the player also has a velocity and an angle (which way the player is facing from 0-360 degrees). The collision detection against the wall works fine and I stop velocity on one of the axis if the player collide having as result the player can "slide" agains the wall.
Now to the issue: Once the player collides agains the wall the movement on one of the axis is stopped. If the player after that turns around and facing away from the wall the movement of that axis is still stopped since ha collided.
I would like the player, if facing away from the object, is free to move how he want's how do I achieve this? I guess I need to figure out which way the player is facing and if he is facing against or away from the object?
for( var i = 0; i < GAME.entities.length; i++ ) {
if( this._collision( GAME.entities[i] ) ) {
var distanceX = GAME.entities[i].x - this.x;
var distanceY = GAME.entities[i].y - this.y;
if( distanceX < 0 )
distanceX *= -1;
if( distanceY < 0 )
distanceY *= -1;
if( !stopX ) {
stopX = ( distanceX > distanceY );
}
if( !stopY ) {
stopY = ( distanceX < distanceY );
}
}
}
I figured out how to do this:
var degrees = ( Math.atan2( GAME.entities[i].x - this.x, GAME.entities[i].y - this.y ) * 180 / Math.PI ) + this.angle

CreateJS: Collision implementing problems

So I have this little javascript labyrinth game I've been working on. The player controls a character using the mouse cursor.
I have a semi-transparent .png bitmap for walls (all in one file), and the player.
The problem here is that I can't seem to make a working collision system.
Here's the essential part of the code:
// Calculate the distances between the cursor and the player
var xDistance = stage.getStage().mouseX - player.x;
var yDistance = stage.getStage().mouseY - player.y;
// Move the player
if (distance > 1) {
player.x += xDistance * easingAmount;
player.y += yDistance * easingAmount;
}
// Check collision for player (bounds)
var mapCollision = collisionMethod(bounds, mapLines, 1);
if (mapCollision) {
if (xDistance > 0 || xDistance < 0)
player.x -= xDistance * easingAmount;
else if (yDistance > 0 || yDistance < 0)
player.y -= yDistance * easingAmount;
}
CollisionMethod is actually ndgmr.checkPixelCollision.
The collision should slide along the walls. This collision only works when the player collides with Y-axis walls.
I am still pretty new with JS, and there's probably a better way to create collision for this kind of situation, so any kind of help or information would be greatly appreciated.
Thanks!

Collision response issue - basic circle within rectangle

I have an animation using JS and Fabric.js whereby circles more around the screen. I'm trying to contain them to a specific area but having some issues.
After some reading yesterday I thought that testing to see if the circle was inside the rectangle (their container) would be quite simple but I've yet to get it working properly.
The circles are created at the bottom of the screen which is also where their container is. With the code that I have they 'float' to the top and stay there in one spot.
The console logs that I have indicate that they are outside the rectangle immediately so I'm assuming that something is wrong with my collision function.
My aim is for them to stay within the containing moving about and when they hit the edges they should change direction so that they will stay inside again.
Thanks for any help.
EDIT : EDITED TO ENABLE A TOUCH OF CLARITY AND USING THE COLSIOSN DETECTION FROM BELOW ANSWER AS NOW THINK THE PROBLEM IS WITH THE RESPONSE INSTEAD OF THE DETECTION.
Collision function:
function testCollision(circle, rectangle) {
return circle.left + circle.radius < rectangle.left + rectangle.width/2 //right side
&& circle.left - circle.radius < rectangle.left - rectangle.width/2 //left side
&& circle.top + circle.radius < rectangle.top + rectangle.height/2 //top
&& circle.top - circle.radius < rectangle.top - rectangle.height/2;
}
left = x & top = y
There are maxX and maxY values which is the width and height of the container.
this is the test:
if(testCollision(circle, rect) == false){
var r = Math.atan2(y - maxY / 2, x - maxX / 2);
vx = -Math.cos(r);
vy = -Math.sin(r);
}
any help is hugely appreciated, thanks!
The way i see it, a circle defined by (x,y,r) coordinates of the center and radius is inside a n axis-aligned rectangle defined by (x,y,w,h) coordinates of the center, the width and the height if the 4 points top,right,bottom,left of the circle are inside the rectangle:
function testCollision(circle, rectangle) {
return circle.x + circle.r < rectangle.x + rectangle.w/2
&& circle.x - circle.r > rectangle.x - rectangle.w/2
&& circle.y + circle.r < rectangle.y + rectangle.h/2
&& circle.y - circle.r > rectangle.y - rectangle.h/2
}
I considered the positive direction of y to be towards the bottom, as is usual in coordinate systems on the web.

Categories

Resources