I am making a Physics engine that utilizes JavaScript to create boxes that have the properties of physics applied to them in scale of the window size. However, the class called box that contains all the physical properties of these boxes cannot be found by the function document.getElementByClassName("box")
.
I am trying to assign a variable boxelem
to contain the location properties of each individual box so that I can integrate mouse manipulation into my program in the future. I have tried doing this through the code:
var boxelem = document.getElementsByClassName("box");
and then adding a mouse over event listener to boxelem.
Necessary Code:
var canvas;
var ctx;
var box = [];
var boxelem;
//Startup Code
window.onload = function(e) {
canvas = document.getElementById("c");
ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
box = [new box(10, 20, "cyan"), new box(299, 40, "red"), new box(90, 50,
"black"), new box(29, 20, "turquoise")];
boxelem = document.getElementsByClassName("box");
noscroll();
update();
}
//Physic Clock (For real-time physics)
var clock = {
lasttick: 0,
tick: function() {
var td = performance.now() - this.lasttick;
this.lasttick = performance.now();
return td / 1000;
},
reset: function() {
}
}
//Box objects be created here (Box Class)
var box = function(x, y, color) {
var _this = this;
//First Spawn Physics and Settings
_this.x = Math.random() * (canvas.width - 50);
_this.y = Math.random() * (canvas.height - 50);
_this.vx = 0;
_this.vy = Math.random() * 150;
_this.ax = 0;
_this.ay = 440;
_this.color = color;
_this.draw = function() {
ctx.fillStyle = _this.color;
ctx.fillRect(_this.x, _this.y, 50, 50);
}
//Normal Physics
_this.update = function(t, mX, mY) {
if (mX != 0) {
_this.x += _this.vx * t;
_this.vx += mX * t;
} else {
_this.x += _this.vx * t;
_this.vx += _this.ax * t;
}
_this.y += _this.vy * t;
_this.vy += _this.ay * t;
//Boundary Creation
if ((_this.y + 55) > canvas.height) {
_this.vy -= _this.ay * t;
_this.vy = 0;
}
if ((_this.x + 55) > canvas.width) {
_this.vx -= _this.ax * t;
_this.vx = 0;
}
if ((_this.y) < 0) {
_this.vy -= _this.ay * t;
_this.vy = 0;
_this.y = (canvas.height + 20);
}
if ((_this.x) < 0) {
_this.vx -= _this.ax * t;
_this.vx = 0;
}
}
}
//Get mouse position if over a box
var pageX = 0;
var pageY = 0;
for (var z = 0; z < box.length; z++) {
boxelem.addEventListener("mouse", mPos, false);
}
The event listener at the bottom gives an error because boxelem
is not defined due to the elements not being found by getElementsByClassName
.
HTML Code:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type=text/javascript src="Physics.js"></script>
<meta charset="utf-8" />
<title>Physics Engine of Boxes</title>
</head>
<body>
<canvas id="c"></canvas>
</body>
</html>
I have looked at (Unobtrusive Javascript-Basic Implementation: How do I bind all elements of a particular class to a function in Javascript?) and (Change an element's class with JavaScript) but am unsure how to apply it to my issue.
This body of your loop is not accessing the index. Also, the .length
you're using is from the box
function instead of the boxelem
collection.
This:
for (var z = 0; z < box.length; z++)
{
boxelem.addEventListener("mouse", mPos, false);
}
should be this:
for (var z = 0; z < boxelem.length; z++)
{
boxelem[z].addEventListener("mouse", mPos, false);
}
As D Simon pointed out below, boxelem
is undefined
because you're not populating that variable until after the DOM loads. You should be sure to fetch those items before trying to use that variable.
If you move all the code to window.onload
, it should work. Note that window.onload
doesn't run until all resources are loaded. You may want to use a different event that fires sooner, but that's another topic.
//Startup Code
window.onload = function(e) {
var canvas = document.getElementById("c");
var ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var box = [new box(10, 20, "cyan"), new box(299, 40, "red"), new box(90, 50,
"black"), new box(29, 20, "turquoise")];
var boxelem = document.getElementsByClassName("box");
noscroll();
update();
//Physic Clock (For real-time physics)
var clock = {
lasttick: 0,
tick: function() {
var td = performance.now() - this.lasttick;
this.lasttick = performance.now();
return td / 1000;
},
reset: function() {
}
}
//Box objects be created here (Box Class)
var box = function(x, y, color) {
// ...implementation...
}
//Get mouse position if over a box
var pageX = 0;
var pageY = 0;
for (var z = 0; z < boxelem.length; z++) {
boxelem[z].addEventListener("mouse", mPos, false);
}
}