Simple Falling Sand Toy Lag - javascript

Well, after looking this problem up three times and finding nothing really relevant to my question, I will now ask.
I got curious and decided to experiment to see if I could make a very basic falling sand toy in canvas.
I did successfully do it, as the "sand" builds up on the ground like it should, but it slows down very quickly because of the hit detection between airborne particles and ground particles.
See for yourself Edit: Possibly dead link, here's a JsFiddle instead.
Particles are spawned by clicking and holding the mouse button. And after you've spawned approximately 200 particles, it gets brought to its knees.
for(i in P){
if(P[i].Y<canvas.height-1){
P[i].Y++
for(j in G){//This loop seems to cause the lag
if(P[i].X==G[j].X&&P[i].Y==G[j].Y-1){
G[G.length]={X:P[i].X,Y:P[i].Y}
}
}
}else{
G[G.length]={X:P[i].X,Y:P[i].Y}
}
}
I'm just wondering if there's something I'm doing horribly wrong; I'm pretty sure it's not supposed to lag that badly. I'm also wondering if there's a way to do it without nested loops, but it seems the only way I've been able to make this work is by checking every individual airborne particle against every individual ground particle, which makes it lag.
If the link is broken, say the word and I'll post the entire code here.
Thanks

It is easier to remember the height of each pile of sand (eg for each column or x-coordinate in the canvas) and check against that. You can directly use the index (should be the same as the x-coordinate), so you do not require to loop through all ground positions to find the correct one.
You need only one check for each airborne sand piece, namely the check with the height of the pile of the corresponding column.
Additionally when the sand has hit the pile, remove it from the 'active particle' list, so you do not need to check it each time, keeping the outer for-loop as small/short as possible.
Redraw each pile using the height of the pile (does not work well when the sand grains have separate colors...) or put the sand that is not falling anymore in a separate memory structure to redraw the piles properly.

Related

Is it possible to make a viewport that follows the player using vanilla javascript?

I'm wondering how to make a viewport that follows the player such as in sidescrolling games. I have a semi-working version, but it requires me to move everything except the player.
ctx.translate(canvX,canvY);
drawBlocks();
ctx.restore()
This works for now, but I will have to draw enemies and other objects, and I don't want to constantly have to redo the process. I'm looking for a simple solution that basically involves a camera that follows the player. Is this possible?
Use something like three.js for games. Because you have to draw as many frames per second, and canvas just isn't great for that (if you don't believe me now, wait until you have to draw more things on the screen).
However, for your current code, one thing I notice is you're missing a save.
If that's not the problem, which I dont think it is, based on your question, you don't want to re-draw everything, only the background? You could actually use multiple layers, so that each enemy is an HTML element, and you only redraw the enemy when their animation frame changes. Then you just move their element ( a little cheaper than re-drawing in terms of performance ).
THREE.JS is what you should learn.. it will really help you out.

Feathered edge Ellipse p5.js

Im looking to create an ellipse with a feathered or soft edge, as if it has been drawn with a spray can. I cant get my head around it...?? :-i
Any Help will be truly appreciated.
You have to break this down further. Pretend you have a friend who has never seen anything drawn with a spray can, so they have no idea what that looks like. Your goal is to give your friend a piece of paper, a pencil, and a list of steps they can follow to create the effect even though they've never seen it before.
Write down a series of steps (in English, not in code) that your friend could follow using the pen and paper. Remember that your friend has never seen the effect before, so you have to be as specific as possible. Try to break steps down into smaller sub-steps whenever possible. Maybe try watching videos of the effect in slow motion to figure out exactly what's going on.
When you have the list of steps written down, that's an algorithm that you can think about implementing with code.
Even though this doesn't feel like programming, this process of breaking your main goal down into several smaller steps is at the core of programming (especially creative coding).
That being said, I can help you get started by offering several approaches you might want to play with.
Just use an image stamp. Draw the effect beforehand and then just draw that image to the canvas, optionally randomly rotating and coloring it.
Or draw a series of circles, maybe getting more transparent as they get further from the center.
Or draw a random dot within a random range at a random angle. Do this several times per frame.

Best approach for collision detection with HTML5 and JavaScript?

I'm trying to make a little platform game with pure HTML5 and JavaScript. No frameworks.
So in order to make my character jump on top of enemies and floors/walls etc., it needs some proper collision detection algorithms.
Since I'm not usually into doing this. I really have no clue on how to approach the problem.
Should I do a re-check in every frame (it runs in 30 FPS) for all obstacles in the Canvas and see if it collides with my player, or is there a better and faster way to do so?
I even thought of making dynamic maps. So the width, height, x- and y coordinates of the obstacle are stored in an object. Would that make it faster to check if it's colliding with the player?
1. Should I re-check in every frame (it runs on 30 FPS)?
Who says it runs in 30 FPS? I found no such thing in the HTML5 specification. Closest you'll get to have anything to say about the framerate at all is to programmatically call setInterval or the newish, more preferred, requestAnimationFrame function.
However, back to the story. You should always look for collisions as much as you can. Usually, writing games on other platforms where one have a greater ability to measure CPU load, this could be one of those things you might find favorable to scale back some if the CPU has a hard time to follow suit. In JavaScript though, you're out of luck trying to implement advanced solutions like this one.
I don't think there's a shortcut here. The computer has no way of knowing what collided, how, when- and where, if you don't make that computation yourself. And yes, this is usually, if not at all times even, done just before each new frame is painted.
2. A dynamic map?
If by "map" you mean an array-like object or multidimensional array that maps coordinates to objects, then the short answer has to be no. But please do have an array of all objects on the scene. The width, height and coordinates of the object should be stored in variables in the object. Leaking these things would quickly become a burden; rendering the code complex and introduce bugs (please see separation of concerns and cohesion).
Do note that I just said "array of all objects on the scene" =) There is a subtle but most important point in this quote:
Whenever you walk through objects to determine their position and whether they have collided with someone or not. Also have a look at your viewport boundaries and determine whether the object are still "on the scene" or not. For instance, if you have a space craft simulator of some kind and a star just passed the player's viewport from one side to the other and then of the screen, and there is no way for the star to return and become visible again, then there is no reason for the star to be left behind in the system any more. He should be deleted and removed. He should definitely not be stored in an array and become part of a future collision detection with the player's avatar! Such things could dramatically slow down your game.
Bonus: Collision quick tips
Divide the screen into parts. There is no reason for you to look for a collision between two objects if one of them are on left side of the screen, and the other one is on the right side. You could split up the screen into more logical units than just left and right too.
Always strive to have a cheap computation made first. We kind of already did that in the last tip. But even if you now know that two objects just might be in collision with each other, draw two logical squares around your objects. For instance, say you have two 2D airplanes, then there is no reason for you to first look if some part of their wings collide. Draw a square around each airplane, effectively capturing their largest width and their largest height. If these two squares do not overlap, then just like in the last tip, you know they cannot be in collision with each other. But, if your first-phase cheap computation hinted that they might be in collision, pass those two airplanes to another more expensive computation to really look into the matter a bit more.
I am still working on something i wanted to make lots of divs and make them act on physics. I will share somethings that weren't obvious to me at first.
Detect collisions in data first. I was reading the x and y of boxes on screen then checking against other divs. After a week it occurred to me how stupid this was. I mean first i would assign a new value to div, then read it from div. Accessing divs is expensive. Think dom as a rendering stage.
Use webworkers if possible easy.
Use canvas if possible.
And if possible make elements carry a list of elements they should be checked against for collision.(this would be helpful in only certain cases).
I learned that interactive collisions are way more expensive. Because you have to check for changes in environment while in normal interaction you simulate what is going to happen in future, and therefore your animation would be more fluid and more cpu available.
i made something very very early stage just for fun: http://www.lastnoob.com/

Clone object with random rotation and position

I have one white line, behind a mask that is in the shape of my logo. And behind that a black background.
I want this line to duplicate once every 5 frames in a completely new 'position' and 'rotation' under the mask, until the whole thing becomes white with lines. I am a complete beginner to expressions and I don't even know exactly where to put the code. I think this is kind of what I am looking for:
seedRandom(1, true);
x=random(minvalue, maxvalue);
y=random(minvalue, maxvalue);
z=random(minvalue, maxvalue);
[x,y,z]
But this doesn't clone the line.
Any help would be great
Max
Unfortunately you cannot clone an object with an After Effects expression. I think you will probably want to add the random position/rotation expression to one layer, then duplicate that layer (command+d on Mac) many times, and then use an After Effects script like this one:
http://aescripts.com/pt_shiftlayers/
(Copy it to Adobe After Effects CS#/Scripts/ScriptUI Panels/, restart AE, and then open it from Window > Scripts > pt_shiftlayers.jsx or something like that).
It will offset your layers the number of frames you specify, 5 in your case. (The script is pay-what-you-want, so you can set the price to $0 and give it a try for free, or pay for it if you really appreciate the developer's work.)
If that doesn't suit your needs, you may be able to use a particle system plugin like Trapcode Particular or CC Particle World to generate a particle every 5 frames with no movement, random rotation, random position.
Let me know if this works for you.

HTML5 Canvas game has bug where first puzzle piece changes to a different piece when clicked on?

I think I just need a fresh set of eyes on this game I'm working on.
It's a sliding image puzzle (where you split an image into pieces and display them back in a random order, I then remove a single piece of the puzzle and the user has to click on each puzzle piece to move it around and thus put the image back together)
The full code is here: https://github.com/Integralist/HTML5-Image-Slider-Game
The bug I'm having is on the first puzzle piece you move, if you click it again - when it moves back to the position it just came from - the puzzle piece changes to a different piece (in one instance I noticed that it was changing to the puzzle piece that is removed to initiate the game, but that might just be coincidence).
At first I thought the issue was with the setInterval method which is asynchronous (I was thinking that because I'm inside a loop maybe the reference loop iteration was getting messed up, but I'm now passing in the relevant iteration into the setInterval and the issue still occurs so it can't be that).
UPDATE:
I still think the problem is something to do with the setInterval. The main issue is when we start drawing the image onto the canvas the original x/y co-ordinates obviously have changed from what we expect them to be. I've noticed that the object which holds the co-ordinates for the puzzle piece we want to move is incorrect when we click on the same puzzle piece to move it back into the position it was just in. I noticed the drawnOnCanvasX/Y properties are different to what they should be, and that they now match the x/y co-ordinates of the empty_space variable? The fact that this doesn't happen all the time makes me think that the setInterval is not passing through the correct object from the loop into the function that executes on the interval?
Any help appreciated.
The problem was because I hadn't removed a particular item from the randomised Array.
For the game to work I needed to remove 1 puzzle piece, this allows the other pieces to have a space they can be moved into. Problem was that I had clearRect the piece I wanted but not actually removed it from the Array. So when I was looping through to find an item in the Array that had those exact X/Y co-ordinates it was finding the puzzle piece item that should have been removed (and because the piece that is removed is chosen randomly that's why sometimes that piece would be found via the loop first, and other times the correct piece would be found).
Christ that was painful.

Categories