I have problem with canvas animation. I created a character (black-evil box) that can be moved. After it touch another box (red) it stops.
The animation is simple - the player.x deducted from boxes[i].x makes the blocks (and the camera) moving.
The problem is that "camera" (or viewport - don't know how to call it) should also stop.
I tried to change the variable left to 0 after a collision, but it's not working
Live example: http://jsfiddle.net/wA73R/
How to fix that? How to stop all things after collision?
Related
I make the game "bugs killer" with mouse pointer, and I use the bottle image on a cursor that spray on bugs,
but the problem is that spray not kill the bugs, when bottle goes on bugs that kill with onclick.
so can any one tell me how can i solve this problem?
how can I increase mouse pointer area in javascript ????
This is the code of spray animation:
<script type="text/javascript">
// for Spray Animation
function clickEffect(e){
var d=document.createElement("div");
d.className="clickEffect";
d.style.top=e.clientY+"px";d.style.left=e.clientX+"px";
document.body.appendChild(d);
d.addEventListener('animationend',function(){d.parentElement.removeChild(a);}.bind(this));}
document.addEventListener('click',clickEffect);
</script>
You can't "increase" the mouse pointer.
What you need to do is implement basic collision detection.
We can't tell you how to do it because there are whole books about this, but here are the steps i'd go through if i wanted a super-simple collision detection.
1) Register a click event and store the mouse position
2) Extend the mouse coordinates to cover a larger surface (for example leftLimit = mouseposition x - 10)
3) Loop through all your bugs or whatever you need to be able to click on. Calculate the space and position they occupy on your screen. If the bug's limit are within the range of the mouse click, destroy it
Alright, so I have a good deal of experience with HTML and CSS, and some experience with Javascript (I can write basic functions and have coded in similar languages).
I'm looking to start some visual projects and am specifically interested in getting into particle systems. I have an idea for something similar to Codecademy's name generator here (https://www.codecademy.com/courses/animate-your-name/0/1) where particles are mapped to a word and move if hovered over. It seems as though alphabet.js is what's really behind Codecademy's demo however I can't understand exactly how they mapped the particles to a word, etc.
I've done some basic tutorials just creating rudimentary particles in a canvas but I'm not sure a canvas is the best way to go - demos that utilize one of the many libraries available (such as http://soulwire.github.io/sketch.js/examples/particles.html) don't use a canvas.
So my question is - what is the best way for a beginner/intermediate in Javascript to start with particle systems? Specifically to accomplish the Codecademy name effect or similar? Should I try to use canvas or which library would be best to start with and how would you recommend starting?
The code for this project is achievable for your intermediate JS programmer status.
How the CodeAcademy project works ...
Start by building each letter out of circles and saving each circle's centerpoint in an array. The alphabet.js script holds that array of circle centerpoints.
On mousemove events, test which circles are within a specified radius of the mouse position. Then animate each of those discovered circles radially outward from the mouse position using simple trigonometry.
When the mouse moves again, test which circles are no longer within the specified radius of the current mouse position. Then animate each of those "outside" circles back towards their original positions.
You can also use native html5 canvas without any libraries...
Another approach allowing any text to be "dissolved" and reassembled
Start by drawing the text on the canvas. BTW, this approach will "dissolve" any drawing, not just text.
Use context.getImageData to fetch the opacity value of every pixel on the canvas. Determine which pixels on the canvas contain parts of the text. You can tell if a pixel is part of the text because it will be opaque rather than transparent.
Now do the same procedure that CodeAcademy did with their circles -- but use your pixels:
On mousemove events, test which pixels are within a specified radius of the mouse position. Then animate each of those discovered pixels radially outward from the mouse position using simple trigonometry.
When the mouse moves again, test which pixels are no longer within the specified radius of the current mouse position. Then animate each of those "outside" pixels back towards their original positions.
[Addition: mousemove event to test if circles are within mouse distance]
Note: You probably want to keep an animation frame running that moves circles closer or further from their original positions based on a flag (isInside) for each circle.
function handleMouseMove(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// calc the current mouse position
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// test each circle to see if it's inside or outside
// radius of 40px to current mouse position
// circles[] is an array of circle objects shaped like this
// {x:,y:,r:,originalX:,originalY:,isInside:}
var radius=40;
for(var i=0;i<circles.length;i++){
var c=circles[i];
var dx=c.x-mouseX;
var dy=c.y-mouseY;
if(dx*dx+dy*dy<radius*radius){
c.isInside=true;
// move c.x & c.y away from its originalX & originalY
}else{
c.isInside=false;
// if the circle is not already back at it's originalX, originalY
// then move c.x & c.y back towards its originalX, originalY
}
}
}
I would like to start off with a note. I tried using a jsfiddle but for some reason HTML5 canvas does not work. So as a workaround I used http://jsbin.com/gugihuwegopa/1/. To edit with this site, click the edit button at the top right corner of the window. Anyway, my problem is, when the paddle is not moving, the ball bounces correctly off all sides (The nomove variable has nothing to do with that, its just to make it disappear with the "w" key). However, when I move the paddle with the mouse towards the ball, it gets stuck inside the paddle. I think this is because it is not updating the location of the paddle fast enough so that the ball ends up inside of it, and my code continues to cause the ball to bounce even while inside. (until moving the paddle rapidly away and it gets unstuck). Yes I have tried putting the cxt.fillRect before the cxt.arc(). Sometimes the ball will travel through the paddle as well. I figure a way to fix this would be factoring in the direction of the ball in my two if statements:
if(y+ymove>=w && y+ymove<=w+h && x>=s && x<=s+l ) ymove*=-1; //top and bottom
if(x+xmove>=s && x+xmove<=s+l && y+ymove<=w+h && y+ymove>=w ) xmove*=-1; //left and right
Some other methods I have tried include:
if(y+ymove>=w && y+ymove<=w+h && x>=s && x<=s+l && centerY+17.5 < y+ymove+5 && centerX+12.5 < x+xmove+5) ymove*=-1; //top and bottom, extra +5 for radius
if(x+xmove>=s && x+xmove<=s+l && y+ymove<=w+h && y+ymove>=w && centerX+12.5 < x+xmove+5 && centerY+17.5 < y+ymove+5) xmove*=-1; //left and right
So basically I just need the ball to bounce correctly no matter how I move the paddle. Feel free to edit all you want, even if it means adding more if statements. All I ask is absolutely NO JQuery. Thanks in advance.
I would recommend to do your code more friendly in order to get help, removing comments and keep only the parts you need to fix.
About your problem one thing you could do is to use a flag, if the ball is hitting the paddle set the flag to True, do the redirection once and stop checking for the collision until the flag is false.
For sure there should be a better workaround but that's a start.
You must think of collision handling as having (at least) two phases : Collision detection and Collision resolution. Here you solve the collision only by changing speed, but both objects might still intersect if one speed is very high : one object might well be inside the other : So you have also to solve position, or, if you prefer 'push' the ligthest object out of the heaviest. You can do this by using a few min/max on the x,y,w,h of both objects.
OR, There's another 'dynamic' method to avoid object overlap : Have the collision handling time-driven. Split the collision handling into time sub-steps, making a stop on each collision. You must compute the time when the next collision will happen, then move everyone to that time, then update only the speeds, and do this again until enough time elapsed. So there not even a chance an overlap can happen : you 'stop the watch' on collision, then change speed, then restart time again. And several collision can happen in one frame, a case that won't be handled properly by a single-pass algorithm (case when a ball hit near a corner).
An example : Say your game frame time, 'dt' is 16 ms, now you detect the ball hits paddle at 10.2ms -> you make both object moves for 10.2ms (x+=vx*10.2/y...), solve their speed (only), then you ask your collision engine to iterate a further 5.8ms.
It's a little work but i did it in my game engine, it works fine.
(Hope i've been more helping than confusing... :-) )
I'm making a canvas game where you travel in a spaceship over an endless repreating background. Right now I'm drawing four instances of the background at different positions based off of the player's x/y position, so they will move with the player.
ctx.translate(ax,ay);
ctx.drawImage(Ibg,Math.round(x/1080)*1080,Math.round(y/720)*720,1080,720);
ctx.drawImage(Ibg,(Math.round(x/1080)*1080)-1080,Math.round(y/720)*720,1080,720);
ctx.drawImage(Ibg,Math.round(x/1080)*1080,(Math.round(y/720)*720)-720,1080,720);
ctx.drawImage(Ibg,(Math.round(x/1080)*1080)-1080,(Math.round(y/720)*720)-720,1080,720);
Translating to ax and ay basically allows objects to scroll with the cameras the player moves, since ax and ay are relative to the player's position. I can create a parallax effect by doing this instead:
ctx.translate(ax*.5,ay*.5);
This makes the background scroll slower than other game objects, like I'd like it to. But I still haven't figured out how to adjust the rest of the code to compensate. As the player moves farther from (0,0) he sees less and less of the background, because it seems to go beyond him at a faster rate. How can I fix this?
As an option to markE's answer you don't need to use a second canvas at all (which is a good option to this).
You can simply use CSS for background image and adjust background position with the amount you need.
Demo here
The essential part is simply these lines:
Background X position where -1 can be replaced with the value you want to move it at.
bgx -= 1;
Then for each loop the background position is updated (Y position is fixed in this example):
canvas.style.backgroundPosition = bgx + 'px -30px'; // set X and Y position
When bgx somehow equals the max width of the image you just reset it to the beginning.
Use 2 canvases -- one placed directly on top of the other
A "background" canvas is on the bottom and animates more slowly.
A "game objects" canvas is on the top and animates more quickly.
That way you can create a parallax effect using different animation speeds for each canvas.
Using canvas and mousemove I create a masking effect.
Example: FIDDLE
The masking effect works but on fast scrolling performance isn't ideal.
How can I improve the framerate?
I fixed it simply by using the window mouse coordinates, instead of the listener on the canvas (assuming you want the picture to just be black).
http://jsfiddle.net/gfZ5C/166/
I also changed to requestAnimationFrame, you'll notice a complete FPS difference in the movement of the circle, instead of it moving according to the listener.
window.onmousemove = function (e) {
circle.posX = e.pageX-can.offsetLeft;
circle.posY = e.pageY-can.offsetTop;
circle.hide = (circle.posX >= 550 || circle.posY >= 550) ? true : false;
}
if (!circle.hide) ctx.arc(circle.posX, circle.posY, 70, 0, Math.PI * 2, true);
I left it at 550, so that you could see it actually disappear, you can change it to a big number if you want the circle to just drag right off the canvas.
Also there is no lag on the circle following the mouse now.
Update:
Fixed the fiddle so that the circle adjusts for window offset too.
The offset is relevant to its parent element, so depending on how far deep your canvas is, you will have to subtract each elements offset that it is inside.
Update:
Switched to handle 'onmouse' events, this will work much better on a real site, because mousing over the iFrame doesn't work well, but it still works. Will work 100% as intended on a real site.