In js/script.js the function initEntity im trying to use the function to make a new object from the class Entity in js/classes.js but im not sure how I would do that and what I have right now doesnt work. I also want to be able to access the object created from the function. If I forgot any information that you would need then let me know because im not sure if I got everything but I think I did.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/classes.js" defer></script>
<script src="js/script.js" defer></script>
<style>
#cvs {
border: solid 1px black;
}
</style>
</head>
<body>
<canvas width="0" height="0" id="cvs"></canvas>
</body>
</html>
js/classes.js
class Entity {
constructor(x, y, w, h, velX, velY, grav, img) {
this.x = this.x || 0;
this.y = this.y || 0;
this.w = this.w || 0;
this.h = this.h || 0;
this.velX = this.velX || 0;
this.velY = this.velY || 0;
this.grav = this.grav || 0;
this.img = this.img || null;
}
}
class Blocks {
constructor(x, y, w, h, img) {
this.x = this.x || 0;
this.y = this.y || 0;
this.w = this.w || 0;
this.h = this.h || 0;
this.img = this.img || null;
}
}
js/script.js
let cvs, ctx;
let entities = {};
function initEntity(name, x, y , w, h, velX, velY, grav, img) {
name = new Entity(x,y,w,h,velX,velY,grav,img);
entities.push(name);
}
function renderEntities() {
initEntity(player, 300, 300, 5, 5, null, null, 0.95, null);//figure out how to fix this
if(entities.player.img != null || entities.player.img != undefined) {
ctx.drawImage(entities.player.img, entities.player.x, entities.player.y, entities.player.w, entities.player.h);
} else {
ctx.fillStyle = '#FF0000';
ctx.fillRect(entities.player.x, entities.player.y, entities.player.w, entities.player.h);
}
}
function render() {
ctx.clearRect(0,0,cvs.width,cvs.height);
renderEntities();
requestAnimationFrame(render);
};
function mechanics() {
}
window.addEventListener('DOMContentLoaded', function() {
cvs = document.getElementById('cvs');
ctx = cvs.getContext('2d');
cvs.height = 600;
cvs.width = 600;
render();
});
CodePudding user response:
You have the entities variable defined as an object ( = { }), therefore you cannot use the 'push' method. It is a method for arrays, so the solution would be:
let entities = [];
CodePudding user response:
Here a working skeleton to get you up and running with quite a lot of the errors you made removed. Let me explain a few of them.
- As mentioned in my comment
entities
has to be an array aspush()
is not defined on an object, so useentities = []
instead this.x
andx
are two totally unrelated variables. You need to use the value ofx
and assign it tothis.x
otherwisethis.x
will always be initialized to0
asthis.x = this.x || 0
evaluates to0
becausethis.x
isundefined
.- You cannot access your array
entities
like an object. You have to loop over the array to be able to access the the objects within it. See theforEach()
in your functionrenderEntities()
- Your animation is not working because you call
requestAnimationFrame()
with the render function which renders the same values over and over again. You need to change some values in order to see some changes on the screen. I've implemented your methodmechanics()
now which will change some values, so the rectangles get wider until they reach the end of the canvas. When you are done changing values and drawing them to the screen you will then have to callrequestAnimationFrame()
again. This signals the browser you are done animating this frame and it should re-render the canvas so the changes you have made become visible. Additionally this will call your methodmechanics()
again so you can animate the next frame. Last but not least: Be specific, so callwindow.requestAnimationFrame()
not justrequestAnimationFrame()
. You should probably familiarize yourself with howrequestAnimationFrame()
works
You will have to click on Full page
when running the snippet to properly see what's going on
class Entity {
constructor(x, y, w, h, velX, velY, grav, img) {
// don't use this here this.x is undefined,
// so this.x = this.x || 0 will always set to 0
// you have to use the parameters that you provide!
// Notice: this.x is not the same as x. These are two totally different variables
this.x = x || 0;
this.y = y || 0;
this.w = w || 0;
this.h = h || 0;
this.velX = velX || 0;
this.velY = velY || 0;
this.grav = grav || 0;
this.img = img || null;
}
}
class Blocks {
constructor(x, y, w, h, img) {
this.x = x || 0;
this.y = y || 0;
this.w = w || 0;
this.h = h || 0;
this.img = img || null;
}
}
let cvs, ctx;
// entities has to be an array
let entities = [];
// name is not a parameter that you should pass to this function as it is not required to create an instance of entity.
// create a local variable instead and push that onto the array
function initEntity(x, y, w, h, velX, velY, grav, img) {
const newEntity = new Entity(x, y, w, h, velX, velY, grav, img);
entities.push(newEntity);
}
function renderEntities() {
// create 3 entities with different positions
initEntity(300, 300, 5, 5, null, null, 0.95, null); //figure out how to fix this
initEntity(200, 200, 5, 5, null, null, 0.95, null);
initEntity(100, 100, 5, 5, null, null, 0.95, null);
// now entities is an array so you can't access it like an object, you will have to loop over it to draw each and every entity to the screen
entities.forEach((entity) => {
// this logs the entity to the console so you can see what's going on
console.log(entity);
if (entity.img != null || entity.img != undefined) {
ctx.drawImage(entity.img, entity.x, entity.y, entity.w, entity.h);
} else {
ctx.fillStyle = "#FF0000";
ctx.fillRect(entity.x, entity.y, entity.w, entity.h);
}
});
}
function render() {
ctx.clearRect(0, 0, cvs.width, cvs.height);
renderEntities();
// explicitly use the window object here and you need to pass a function that actually does something
// not just re-renders the same objects again and again
window.requestAnimationFrame(mechanics);
}
function mechanics() {
// this is where the animation happens
// loop over all entities
entities.forEach((entity) => {
// for each entity check whether it's x value is smaller than the width of the canvas
// if not increase the width by one and draw it to the screen
if (entity.x < cvs.width) {
entity.x ;
if (entity.img != null || entity.img != undefined) {
ctx.drawImage(entity.img, entity.x, entity.y, entity.w, entity.h);
} else {
ctx.fillStyle = "#FF0000";
ctx.fillRect(entity.x, entity.y, entity.w, entity.h);
}
}
});
// tell the browser that we have finished animating this frame and it should re-render to display our changes
// and call mechanics again to animate the next frame
window.requestAnimationFrame(mechanics);
}
window.addEventListener("DOMContentLoaded", function () {
cvs = document.getElementById("cvs");
ctx = cvs.getContext("2d");
cvs.height = 600;
cvs.width = 600;
render();
});
<canvas width="0" height="0" id="cvs"></canvas>
Please note: this is not a perfect implementation but just to give you an idea on how it works conceptually.