handling the intersection of two rectangles in a platformer - javascript

I am working on a simple platform game in HTML5/Canvas/Javascript/jQuery. You can see it here.
I'm aware of how to check the intersection of two rectangles (there are several questions on here regarding that), and my game checks and handles the intersection of the two rectangles, but only under very specific circumstances, and only because the character is not wider than my block.
My question: how do I calculate the intersection of two rectangles in a way which I can tell which direction the intersection occurs from? The only way I can think of includes 20+ if statements (this cannot be the proper way?).
I need to know the direction of intersection because I "peek" ahead to see if my sprite coordinates (x + dx, y + dy) will intersect a rectangle, and if they will, set the sprite's new coordinates to just the edge of the rectangle on the next tick.

To get the position of a rectangle relatively to an other, you could use the center the sprite rectangle and get its position to the block.
The following function is to get position of a point to another. It should help you. Just need to adapt to verify the position of your sprite to your block using the center of the sprite and the center of the block (or verify the position of the sprite center to the top left and bottom right corners of the block)
function positionOf(point, relativeTo) {
var dx = point.x - relativeTo.x; // diff on x axis
var dy = point.y - relativeTo.y; // diff on y axis
if(dx >= dy) { // point is on top right half from relativeTo
return dx >= - dy ? 'EAST' : 'NORTH';
}
else { // point is on bottom left half from relativeTo
return dx >= - dy ? 'SOUTH' : 'WEST';
}
}
EDIT : all of this is good when considering x and y axis origin is at top left corner of viewport

Related

Css Transform Effect in MongoDB site

I am new to css and learning different type of css styles. I want to learn how the effect used in official MongoDb website. The effect which tracks the mouse position and transforms the boxes. I know how to do the transform in css. But, how can it be done with the mouse position. Thanks for the help.
General overview of how to do it:
Register a mousemove-handler and track your mouse-screen location (see link)
translate mouse screenlocation, to mouse location relative to rectangle:
e.target in mousemove event gives you the rectangle (or some descendent which allows you to get to the rectangle.
given the target element get it's position (top + left using getBoundingClientRect) as well as width and height. These should be easy to lookup
Notice that the mouse at the center of the rectangle doesn't rotate the rectangle. Only when moving to the edges, the rotation starts to get going. This rotational rate-of-change seems to be linear. So:
determine the max rotation that seems nice to have in degrees. Simply test with different numbers in the chrome dev tools or similar: transform: rotateY(0.01deg) rotateX(0.01deg); Say you want to have a max rotation of 25 degrees.
say the rectangle is 100px in width. It's clear to see that each pixel movement from the center to the edge (50 px in total) adds 0.5 degree to the rotation due to the linear rate of change: 25 deg / 50px. So for example moving 20px to the left of the center translates to rotateY(10deg);. Moving 20px to the right results in the mirror rotation (rotateY(-10deg);). NOTE: the positive and negative may need to be flipped.
similarly, moving along the Y-axis changes the rotateX-property.
Once calculated, set the css-property and you're done
I believe this must be done with Javascript. The general idea is when the mouse enter/move on the element, you compare it's coordinate with the position and width/height of the element to decide the rotation values. When the mouse leave the element, you reset the values of the rotation back to normal.
You can get the coordinate of the mouse from event by using:
const mouseX = event.clientX; // Get the horizontal coordinate
const mouseY = event.clientY; // Get the vertical coordinate
And the position of the element:
const eleLoc = event.target.getBoundingClientRect();
From there you calculate the center and the width/height of the element:
const centerX = (eleLoc.right + eleLoc.left) / 2
const centerY = (eleLoc.bottom + eleLoc.top) / 2
const halfWidth = (eleLoc.right - eleLoc.left) / 2
const halfHeight = (eleLoc.bottom- eleLoc.top) / 2
Then you calculate the distance between the mouse and the center in percent. In the center, the distance is 0, at the border, it's 1 (or -1).
const percentX = (mouseX - centerX) / halfWidth
const percentY = (mouseY - centerY) / halfHeight
Now you only need to rotate X/Y based on the distance percent:
const degX = percentX * maxDegX
const defY = percentY * maxDegY
event.target.style.transform = `perspective(${yourPerspective}px) rotateX(${degX}deg) rotateY(${degY}deg)`
Remember to reset the transform when your mouse move out.
There are some libraries for this, ie: tilt.js

How can I add a point to a relative position on a canvas graph?

I have a bit of code (involving "canvas"), which generates a graph on a four-quadrant cartesian plane. (Please see the JsFiddle link in the comment below.)
I want to create a bit of code that adds a point to a specific position on the plane. However, I want the point to get plotted based on the intervals on the x- & y-axes rather than pixels. In other words, I don't want to have to guess and check where each coordinate is on the graph and then adjust accordingly. If I move the graph 200 pixels down on the page, I want the point to likewise move 200 pixels down.
Coding novice, here (if you couldn't tell already). It took me forever to get to this point, so I would greatly appreciate any help anyone is willing to offer.
Thanks!
The 2D canvas context provides a transformation to all rendering.
You can set the matrix with ctx.setTransform and you can multiply the existing transformation with ctx.transform, ctx.scale, ctx.rotate, ctx.translate
Personally I am a big fan of ctx.setTransform(a,b,c,d,e,f); where
a,b is the unit length and direction of the X axis in pixels
c,d is the unit length and direction of the Y axis in pixels
e,f is the location of the origin relative to the top left and is in
pixels.
Basicly 2 vectors defining the size (scale) and direction of a pixel x and y axis, and a coordinate defining where on the canvas the origin is. The coordinate is not effected by the scale or rotation.
So if you want the X axis to point down and the scale to be two then
a = 0, b = 2 the Y axis is then b = -2, c = 0 to be 90deg clockwise from the X axis.
If you want the axis to remain the same but the scale scale = 2 changed then
a = scale,b = 0, c= 0, d = scale. And to have the origin at the center of the canvas e = canvas.width/2, f = canvas.height/2
Now if you draw an arc ctx.arc(0,0,100,0,Math.PI*2) you will see a circle in the center of the canvas with a radius = 100*scale
Hope that makes sense....

How do I rotate div to specific coordinates?

I have two (or 3) coordinates.
They are the 2 upper coordinates: left and right
How do I create a div where the left corner has the coordinate of the left one and the right corner the coordinate of the right one.
The rotation should be created from these coordinates or this height difference between these 2 points
How can I achieve this?
To get the angle between the two coordinates, you could use Math.atan2
var angle = Math.atan2(Y2 - Y1, X2 - X1);
you could then use a CSS3 property to set the correct angle on the div.

How does one rotate a HTML canvas object around a fixed point using mouse action?

For example it may be used in the application of manually adjusting the hands of the clock. I guess it probably involves translating the needle (to make the end point of the needle the centre of rotation) then rotating it, then translating the needle again.
But since the needle listens to the mouse event all the time, the 1st mouse event will be captured. The result is that the needle ends up being translated and not rotated at all. Mouse event is impossible to debug too...
Any idea or code snippets that I can refer to? Using Javascript or CSS to rotate both fine.
In your example, you will want to calculate the angle between the centre of the clock face (black dot), and the current mouse position (red dot), relative to the Y axis (cardinal north if you imagine a compass).
If I remember my trig correctly, you can calculate this by using the following:
var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
// alter the angle to be relative to Y axis instead of X
angle += 90;
if(angle < 0) { angle = 360 + angle; }
In the formula, x and y are the coordinates of the two points, one of which you will know (it is the centre of the clock face), and the other you can get from the mouse move event.
Once you have the angle, you can simply translate to the the centre of the circle, rotate the canvas by the calculated amount, and draw the hand.
Update: I created a jsfiddle to illustrate the angle calculation:
http://jsfiddle.net/DAEpy/1/

About equal to function in Javascript?

Alright, I have a HTML canvas with a bunch of circles on it. I want mouseclick events on circles to trigger some Javascript function. I already have the basics, but the coordinates are obviously so precise that it takes me like 30 times to hit the exact coordinates of a certain circle.
Is there a way I could implement an "about equal to"; in other words, I would like the x and y of the mouseclick to trigger a function when it's pretty close to (let's say 10px) the coordinates of something on canvas?
Thanks
Alex
You can use something like this to test if one point is within a certain radius of another point:
function withinRadius (x1, y1, x2, y2, radius) {
var dX = x1 - x2, dY = y1 - y2;
return ((dX*dX) + (dY*dY) < radius*radius);
}
First thoughts:
if ((mouselocx >= (corodinatex - 10)) && (mouselocx <= (corodinatex + 10)) {
if ((mouselocy >= (corodinatey - 10)) && (mouselocy <= (corodinatey + 10)) {
Do something...
}
}
General case, you want to check if you have clicked within a polygon created by expanding your curve outward in both left and right directions. Calculation of this polygon in the case of bezier curves, general conic sections, etc. is tricky. Most graphic libraries allow you to set a stroke-width parameter and do it for you. Draw a wide curve in background color below your 1px curve and check for hits on the wide one. Just make sure you draw all the background color ones before any of the foreground color ones.
In your specific case of circles, if you don't have such a graphic library, it will suffice to see if you have clicked within your tolerance of a distance from the circle center. If you have a very small number of circles you can go through the whole list. If you have more than a half dozen (gut feel for when to cut over to better algorithm) divide the screen up into quarters with a list of which circles a hit in one of the rectangles might have hit, then divide into quarters within that rectangle and check with circles it might be until you have just a half dozen or so possibilities. Then go down the list of possibilities checking if you are within your delta for any of the circles.

Categories

Resources