Little simulation of gravity in JS using canvas - javascript

So, I am trying to create a few circles and then I want them to fall down. Here is the code and demo: demo FireBug tells me that the method "move" is not defined for undefined objects, so something must be wrong when I want to create an array of obects. Correct my mistakes and take into consideration that I have just started learning object oriented programming in JS.

Instead of creating multiple events, create one event and loop in there:
setInterval(function(){
ctx.clearRect(0,0,1000,1000); //Clear the canvas here
for (i = 0;i<bubble.length;++i)
{
bubble[i].move();
bubble[i].redraw();
}
},32);
The problem was a scope problem.
The way you had written it i had the value of 10 in all events where they where executing.
Working fiddle: http://jsfiddle.net/some/fGChQ/16/
Your other problem is that you clear the canvas in your redraw... For every circle.

I've made a fork of this that addresses the looping issues, there also appears to have been a problem with the clearing of the canvas rectangle that was causing some interference

for (i = 0;i<bubble.length - 1; ++i)
{
console.log(bubble[i].y)
setInterval(function(){
bubble[i].move();
bubble[i].redraw();
},32);
}
bubble.length is 10, array is index 0-9. bubble[10] is undefined, so you can't call the method move on it.

Related

Parse shape movement from createjs tween?

I'm trying to pre-calculate the bounding boxes of objects in a createjs file.
I have a simple recursive loop that loops over the tween.
I'm having trouble understanding how the data is stored.
My understanding is so far:
tween._stephead - the start of the tween
tween._stephead.next - the next tween target, with multiple .next objects
and mixed in between there seem to be some ease objects.
For each of the tween targets, I read the props, and move the bounding box of my shape according to the values x and y.
This seems to work okay for single objects on a tween, but as soon as there are multiple objects in a tween, this falls apart, due to the fact that its stored in an array, and objects not in the array are still visible on screen.
Ive looked over the API and haven't found any other way to do pre-calculation of objects movements... Am I going about this right?
I ended up using a simpler method, just play the demo though without displaying it to the user.
for (var f=0; f<totalFrames; f++) {
stage.update();
var c = exportRoot.numChildren;
while(c--) {
var child = exportRoot.children[c];
...
}
}

How would I go about making a variable that allows me to toggle an object's visibility in Javascript

I am using the p5.js library to create Tetris. When someone gets a line clear (that is, a full line has been filled with Tetris blocks) then the tiles that made that line fill up should be removed/turned off.
What would be the best way to do this? For all visibility aspects of a tile, I use a show() function that draws a rectangle to show the tile. Should I add a variable to the object and check if that is true because executing the show function? Or is there a built-in method or function that makes removing an object easy? I can't seem to find anything like this online
It is hard to answer if we do not know how your tiles are represented in your program.
The method I recommend is to remove the tile from it's container structure altogether.
For example, if the state of your game is stored in a matrix, simply empty the cells that constitute a line. This way, your show() function should not be called at all.
Removing the tile from the container will work, but if its difficult then there is another way.
Have a variable to track whether the tile is being used and have its default be true e.g this.inPlay = true
Only update and show a tile if its inplay is true:
if (tile.inPlay == true) {
tile.update()
tile.show()
}
'''
If you want to remove it, just set its inplay to false
PS. a great tutorial for p5.js is on youtube (made by the coding train)
PPS. just search 'coding train p5.js tutorial' on youtube

draw function not looping as expected

I'm a beginner on here, so apologies in advance for naivety. I've made a simple image on Brackets using Javascript, trying to generate circles with random x and y values, and random colours. There are no issues showing when I open the browser console in Developer Tools, and when I save and refresh, it works. But I was expecting the refresh to happen on a loop through the draw function. Any clues as to where I've gone wrong?
Thanks so much
var r_x
var r_y
var r_width
var r_height
var x
var y
var z
function setup()
{
r_x = random()*500;
r_y = random()*500;
r_width = random()*200;
r_height = r_width;
x = random(1,255);
y= random(1,255);
z= random(1,255);
createCanvas(512,512);
background(255);
}
function draw()
{
ellipse(r_x, r_y, r_width, r_height);
fill(x, y, z);
}
Brackets.io is just your text editor (or IDE if you want to be technical) - so we can remove that from the equation. The next thing that baffles me is that something has to explicitly call your draw() method as well as the setup() method -
I'm thinking that you're working in some sort of library created to simplify working with the Canvas API because in the setup() method you're calling createCanvas(xcord,ycord) and that doesn't exist on it's own. If you want to rabbit hole on that task check out this medium article, it walks you thru all the requirements for creating a canvas element and then drawing on that canvas
Your also confirming that you're drawing at least 1 circle on browser refresh so i think all you need to focus on is 1)initiating your code on load and 2)a loop, and we'll just accept there is magic running in the background that will handle everything else.
At the bottom of the file you're working in add this:
// when the page loads call drawCircles(),
// i changed the name to be more descriptive and i'm passing in the number of circles i want to draw,
// the Boolean pertains to event bubbling
window.addEventListener("load", drawCircles(73), false);
In your drawCircles() method you're going to need to add the loop:
// im using a basic for loop that requires 3 things:
// initialization, condition, evaluation
// also adding a parameter that will let you determine how many circles you want to draw
function drawCircles(numCircles) {
for (let i = 0; i < numCircles; i++) {
ellipse(r_x, r_y, r_width, r_height);
fill(x, y, z);
}
}
here's a link to a codepen that i was tinkering with a while back that does a lot of the same things you are
I hope that helps - good luck on your new learning venture, it's well worth the climb!
Thank you so much for your help! What you say makes sense - I basically deleted the equivalent amount of code from a little training exercise downloaded through coursera, thinking that I could then essentially use it as an empty sandpit to play in. But there's clearly far more going on under the hood!
Thanks again!

Box2dWeb call function when objects collide

I'm fairly new to javascript and box2d, i was wondering if someone knows how i can call a custom function when two objects collide. I tried using some examples that uses the b2ContactListener without any succes. I've placed an object above another and let the standard Box2d physics do it's thing.
I recieve two console outputs, the first is null and the second is Ball with the following code:
var listener = new Box2D.Dynamics.b2ContactListener;
listener.BeginContact = function(contact) {
console.log(contact.GetFixtureA().GetBody().GetUserData());
console.log(contact.GetFixtureB().GetBody().GetUserData());
};.
The two objects that need to collide are a b2_dynamicbody (ball) and a b2PolygonShape. (rectangle). Using bodyDef.userData = "Ball"; in my Ball.js and bodyDef.userData = "Mouse"; in my Mouse.js i try to identify if they are hit. Instead only the ball is displayed.
Next to that i'm sure this is not the correct way for detecting collision :P I hope i've explained it well enough, could somebody steer me in the right direction?
Ok I solved it myself, apparently I had to add my custom event to the world I create with box2d. So, the issue was solved by me reading big chunks of box2d documentation/manual which can be found here:
I started with adding a String as UserData() to every object which can collide and has to do something else next to just colliding. Using the following code:
bodyDef.userData = "Car";
note: every object has to have it's own unique string.
Then I created a new contact listener (formulated in my question above) and listened for fixtures colliding with each other. When that happens, I 'save' the fixtures UserData() in variables which I can then use to look what objects collide with each other.
var contactListener = new Box2D.Dynamics.b2ContactListener;
contactListener.BeginContact = function(contact) {
var fixA = contact.GetFixtureA().GetBody().GetUserData();
var fixB = contact.GetFixtureB().GetBody().GetUserData();
// if else statement here...
};
world.SetContactListener(contactListener);
Finally, I added the last statement world.SetContactListener(contactListener); to add the event to the world, making it possible for it to listen to collisions, which I forgot to add and thus was my problem.
Hope someone finds this usefull!

Detecting collisions between two moving objects

I've got a basic Space Invaders type game going, and I can't get it to recognise when the shot from the player hits the alien. (I'm only checking Alien2 atm, the one second from the left). Since they're both moving, I've decided the only way to check for collisions is with either a range-based if statement (with 2 top coordinates and one left coordinate), or directly comparing the positions along the Y axis with Jquery.
I'm using the range-based solution at the moment, but so far it hasn't worked (not sure why).
My code so far:
if (key == "87"/*&& document.getElementById('BarrelOne').id=='BarrelOne'*/){
var Invader2 = document.getElementById('Alien2');
var Shot1 = document.getElementById('ShortShot');
Shot1.style.webkitAnimationPlayState="running";
setTimeout(function(){
Shot1.style.webkitAnimationPlayState="paused";
}, 1200);
if(document.elementFromPoint(625.5, 265.5) == Shot1){
Invader2.style.visibility="hidden";
}
};
Jsfiddle:
http://jsfiddle.net/ZJxgT/2/
I did something similar, and i found that it was much easier to achieve using gameQuery.
to test for collisions:
var collided = $("#div1").collision("#div2");
you can see full working example here
EDIT
If you're having trouble check out the API. For example, to find out how to use collisions check this part of the API.
the collision works in the following way:
This method returns the list of elements collisioning with the selected one but only those that match with the filter given as parameter. It takes two optional arguments (their order is not important). The filter is a string filtering element used to detect collision, it should contain all the elements the function should search collision into. For example if you look for collision with element of the class ‘foo’ that may be contained in a group you will use the filter ".group,.foo".
So, write something like this:
$("#ShortShot").collision("#Alien2").hide();
// will return the alien if it collides with ShortShot
or, to hide them both:
if (($("#ShortShot").collision("#Alien2")).length) {
$("#ShortShot").remove();
$("#Alien2").remove();
}
Instead of losing hours reinventing the wheel, I would suggest to switch (if still possible, depending on your time deadline) to a real 2D game engine for Javascript, with easy collision detection.
Check as well: 2D Engines for Javascript

Categories