Unable to create a new instance in javascript - javascript

the following is my code,
function hostile(x, y) {
this.speed = 1;
this.health = 100;
this.x = x;
this.y = y;
this.height = 32;
this.width = 32;
this.isDead = false;
this.direction = 0;
this.move = function(){
context.clearRect(0,0,canvas1.width,canvas1.height);
if (this.x > canvas.width - 64) {
this.y += 10;
this.direction = 0;
}
if (this.x < 0) {
this.y += 10;
}
if (this.direction === 1) {
this.x += this.speed;
} else {
this.x -= this.speed;
}
if (this.x < 0) {
this.direction = 1;
}
if (this.y > 420) {
//this might have to be changed
this.x = 600;
}
}
};
//CREATING AN INSTANCE OF HOSTILE, THIS ISN'T WORKING FOR MULTIPLE INSTANCES, BUT WHY?
var hostile = new hostile(20,20);
var hostileA = new hostile(20,20);
I have hostile created and I have this instance being called in the update method, hostile.move() however the var hostile works, the var hostile does not, I have checked the code hostile is the only reference in the file.

var hostile = new hostile(20,20);
You just overwrote the hostile variable to refer to that instance rather than the constructor.
This is one of the reasons that constructors are UpperCamelCase by convention

You're erasing your constructor with
var hostile = new hostile(20,20);
Then you can't create other hostile objects.

Related

Prototype function calling an object undefined

I am trying to make a collision function for my new platformer game and I came across an error when making my collision prototype function.
platforms = [];
var newPlatform = function(x, y) {
this.x = x,
this.y = y,
this.width = 50,
this.height
}
var platform1 = new newPlatform(10, 100);
var platform2 = new newPlatform(50, 50);
platforms.push(platform1);
platforms.push(platform2);
var player = {
x:100,
y:305,
width:80,
height:120,
velocity_y:4
}
platforms.prototype.collision = function(player) {
return (this.x < player.x + player.width && this.x + this.width > player.x && this.y
< player.y + player.height && this.y + this.height > player.y);
}
for (let i = 0; i < platforms.length; i++) {
if (platforms[i].collision(player)) {
player.velocity_y = 0 ;
}
}
This gives out an error that reads "Cannot set property 'collision' of undefined" does anyone know how to fix this?

JavaScript only running when class file contains parenthesis in name

I'm new to JavaScript and wanted to code a game I had previously coded in Java. I was coding with the p5.js library, and using the Atom text editor. The game I was making was Asteroids and it was working fine. I had figured out how to add the ship and the lasers. Then I added the code for the actual asteroids. (I'm not sure if this is relevant or not, but as I said before, I was copying the code from a Java project and when I went to add the asteroids I basically copied the whole thing over, without saving it until I was done.) After I added them, I tried to run it, and I said "asteroid is not defined", because I forgot to add a reference to it in the HTML. However, after I ran it again, the page stopped loading and eventually crashed (I got the "Aw, Snap! Something went wrong when displaying this webpage" error). I thought it was the HTML at first, but when I added the class to the main script, it still crashed. After an hour, I realized that if I added parenthesis to the class name (class ship(){}) then the page would load. However, I would get a syntax error as expected. The same thing would happen if I declared the object as the class like you would do in Java (Ship ship;), it would run but it would say "Uncaught SyntaxError: Unexpected identifier". I'm not sure how to get around this, or why not adding parenthesis to a class name would cause the program not to run.
Attached are the first part of my main script, the constructor of my ship class, and my asteroid class because the problems only started after adding it.
Any help or solutions to this problem would be greatly appreciated.
Main Script:
let ship;
let bullets = [];
let asteroids = [];
// Left Right Boost Slow Shoot
let keyDown = [false, false, false, false, false];
function setup(){
window.canvas = createCanvas(800, 600);
ship = new Ship(width/2, height/2);
for(let i = 0; i = 4; i++){
asteroids.push(new asteroid(random(width), random(height), 100));
}
frameRate(60);
}
function draw(){
background(0);
checkKeys();
ship.update();
ship.show();
for(let i = bullets.length-1; i >= 0; i--){
bullets[i].update();
bullets[i].show();
if(!bullets[i].alive){
bullets.splice(i, 1);
}
}
for(let i = asteroids.length-1; i >= 0; i--){
asteroids[i].update();
asteroids[i].show();
}
}
Ship Class:
class Ship{
constructor(x, y){
this.x = x;
this.y = y;
this.velX = 0;
this.velY = 0;
this.midX = this.x + 15;
this.midY = this.y + 20;
this.heading = 0;
this.rotation = 0;
this.boosting = false;
}
Asteroid Class:
class asteroid{
constructor(x, y, size){
this.x = x;
this.y = y;
this.size = size;
this.velX = random(-2, 3);
this.velY = random(-2, 3);
if(this.velX == 0){
this.velX++;
}
if(this.velY == 0){
this.velY++;
}
this.points = random(4, 12);
this.xPoints = [];
this.yPoints = [];
this.offsets = [];
for(let i = 0; i < this.points; i++){
this.offsets[i] = random(-size/5, (size/5)+1);
}
}
update(){
this.x += this.velX;
this.y += this.velY;
}
show(){
stroke(255);
beginShape();
for(let i; i < this.points; i++){
let angle = i*(360/this.points);
let px = (this.size/2 + this.offsets[i]) * cos(angle);
let py = (this.size/2 + this.offsets[i]) * sin(angle);
this.xPoints[i] = px + this.x;
this.yPoints[i] = py + this.y;
vertex(px, py);
}
endShape(CLOSE);
}
}
Running the code, I got the same error. Turns out your ship class has no closing bracket } for the class, only for the constructor. Adding that and now I get no errors
let ship;
let bullets = [];
let asteroids = [];
// Left Right Boost Slow Shoot
let keyDown = [false, false, false, false, false];
function setup(){
window.canvas = createCanvas(800, 600);
ship = new Ship(width/2, height/2);
for(let i = 0; i = 4; i++){
asteroids.push(new asteroid(random(width), random(height), 100));
}
frameRate(60);
}
function draw(){
background(0);
checkKeys();
ship.update();
ship.show();
for(let i = bullets.length-1; i >= 0; i--){
bullets[i].update();
bullets[i].show();
if(!bullets[i].alive){
bullets.splice(i, 1);
}
}
for(let i = asteroids.length-1; i >= 0; i--){
asteroids[i].update();
asteroids[i].show();
}
}
class Ship{
constructor(x, y){
this.x = x;
this.y = y;
this.velX = 0;
this.velY = 0;
this.midX = this.x + 15;
this.midY = this.y + 20;
this.heading = 0;
this.rotation = 0;
this.boosting = false;
}
} //<--- I added this bracket
class asteroid{
constructor(x, y, size){
this.x = x;
this.y = y;
this.size = size;
this.velX = random(-2, 3);
this.velY = random(-2, 3);
if(this.velX == 0){
this.velX++;
}
if(this.velY == 0){
this.velY++;
}
this.points = random(4, 12);
this.xPoints = [];
this.yPoints = [];
this.offsets = [];
for(let i = 0; i < this.points; i++){
this.offsets[i] = random(-size/5, (size/5)+1);
}
}
update(){
this.x += this.velX;
this.y += this.velY;
}
show(){
stroke(255);
beginShape();
for(let i; i < this.points; i++){
let angle = i*(360/this.points);
let px = (this.size/2 + this.offsets[i]) * cos(angle);
let py = (this.size/2 + this.offsets[i]) * sin(angle);
this.xPoints[i] = px + this.x;
this.yPoints[i] = py + this.y;
vertex(px, py);
}
endShape(CLOSE);
}
}

Is there a way to optimisate a particle generating algorythm to work with many objects?

In fact, I'm making a background which has to kinda illustrate "influence".
I tried to make this with particles, generated from a given point on the screen, which are moving toward a random direction, and which blast after some lifetime they have. So the problem is, I succeeded some way to do it, but it's really slow. about 400 generators placed, and the browser starts to lag, and the thing is i need at least 400 of these. So is there anyway to optimise what I did?
Link on this pen.
my particle:
class Particle {
constructor(radius,speed,lifetime,aoe) {
this.speed = speed;
this.life = lifetime;
this.aoe = aoe;
}
throw() {
var r = random(TWO_PI);
var dx = cos(r);
var dy = sin(r);
var speedX = this.speed*dx;
var speedY = this.speed*dy;
return [speedX,speedY];
}
display(rootX,rootY,x,y) {
line(rootX,rootY,x,y);
}
blast(rootX,rootY,x,y) {
line(rootX,rootY,x,y);
ellipse(x,y,this.aoe,this.aoe);
}
}
and here's the generator:
class ParticleGenerator {
constructor(x,y,frequency, particle) {
this.x = x;
this.y = y;
this.f = frequency;
this.p = particle;
this.pX = this.x;
this.pY = this.y;
this.state = 0;
this.wait = 0;
this.dir = this.p.throw();
}
travel(sX,sY) {
this.pX += sX;
this.pY += sY;
}
activate() {
var d = (dist(this.x,this.y,this.pX,this.pY)/this.p.speed)/this.p.life;
if(this.state == 0)
this.dir = this.p.throw();
if (this.state < this.p.life) {
stroke(255,0,0);
fill(11)
this.travel(this.dir[0],this.dir[1]);
this.p.display(this.x,this.y,this.pX,this.pY);
this.state++;
}
if (this.state == this.p.life && this.wait < this.f) {
stroke(255,0,0,255-(this.wait*255)/this.f)
fill(255,0,0,255-(this.wait*255)/this.f);
this.p.blast(this.x,this.y,this.pX,this.pY);
this.wait++;
}
if (this.wait == this.f) {
this.state = 0;
this.wait = 0;
this.pX = this.x;
this.pY = this.y;
}
}
}

p5 js "can't read property 'show()' of undefined"

What I am trying to do in this code is to take one dead particle, and make live ones cling to it and become dead in the process. At the end I would wish to have something that looks nice and is just a pleasurable program to watch.
But I have a problem...
My code will freeze at seemingly random points while running it and say "can't read property 'show()' of undefined."
The error is on line 18 when it tries to run the "live[i].show();"
sometimes it happens right away and sometimes it takes awhile but it always happens. Any help is appreciated.
Thank you in advance.
var live = [];
var dead = [];
function setup() {
createCanvas(windowWidth, windowHeight);
background(255);
for (var i = 0; i < 100; i++) {
live.push(new particle(random(width), random(height), 1));
}
dead.push(new particle(width / 2, height / 2, 0))
}
function draw() {
background(255);
if (live.length > 0) {
for (var i = 0; i < live.length; i++) {
live[i].update(i);
live[i].show();
}
}
for (var i = 0; i < dead.length; i++) {
dead[i].show();
}
}
function particle(x, y, l) {
this.x = x;
this.y = y;
this.l = l;
this.speed = 5;
this.c = 200;
this.s = 50;
}
particle.prototype.update = function(dex) {
this.speed *= this.l;
this.x += random(-this.speed, this.speed)
this.y += random(-this.speed, this.speed)
if (this.x < 0) {
this.x = width;
} else if (this.x > width) {
this.x = 0;
}
if (this.y < 0) {
this.y = height;
} else if (this.y > height) {
this.y = 0;
}
for (var i = 0; i < dead.length; i++) {
if (dist(dead[i].x, dead[i].y, this.x, this.y) < this.s && dist(dead[i].x, dead[i].y, this.x, this.y) > 0) {
dead.push(new particle(this.x, this.y, 0));
live.splice(dex, 1);
}
}
}
particle.prototype.show = function() {
this.c *= this.l;
strokeWeight(this.s);
stroke(this.c);
point(this.x, this.y);
}
If you replace loop in the draw method with map it will solve your problem.
function draw() {
background(255);
live.map(function(curr,i){
curr.update(i);
curr.show();
})
dead.map(function(curr){
curr.show();
})
}
here is the plunkr of the updated code https://plnkr.co/edit/j5ueccmK4o7kbNKfeYQJ The error was caused because it was trying to access array larger than the maximum index of the array.
This is caused because you are mutating the array using splice in update method and it reduces its length while the for loop with previous length tries to loop the array beyond its length causing undefined.
Edit:
It is better to reduce the mutation in the code to avoid these errors.

Node Socket.io object trouble

I'm having some trouble with Node Socket.IO
I have put all my code in pastebins
Server file
var io = require("socket.io").listen(1337);
io.set("log level", "0");
var particles = [];
var players = [];
var remove_loop;
var particle;
io.sockets.on("connection", function(socket) {
//connection
socket.emit("hello");
console.log("A new connection has been established");
//new player
socket.on("new_player", function() {
players.push(socket.id);
console.log("New player connected.");
console.log("ID: " + socket.id);
});
//new particle
socket.on("new_particle", function(data) {
particle = data;
socket.broadcast.emit("particles_data", particle);
});
});
Game file
window.onload = function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//display settings
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
setInterval(function() {
if(canvas.width != window.innerWidth || canvas.height != window.innerHeight) {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
}, 1000);
//remove cursor
document.getElementById("canvas").style.cursor = "none";
//server connection
var socket = io.connect("http://localhost:1337");
//variables
var update_loop;
var draw_loop;
var local_player;
var mouse_x;
var mouse_y;
var remote_players;
var particles;
var remove_loop;
var explosion;
var background_color;
init();
function init() {
//initialize
local_player = new Player();
background_color = "000000";
explosion = true;
remote_players = [];
particles = [];
draw_loop = setInterval(function() { draw(); }, 10);
update_loop = setInterval(function() { update(); }, 10);
//server
socket.on("hello", function() {
socket.emit("new_player");
});
socket.on("particles_data", function(data) {
particles.push(data);
});
};
function update() {
for(var i = 0; i < particles.length; i++) {
particles[i].move();
}
};
function draw() {
//background_color
ctx.fillStyle = "#" + background_color;
ctx.fillRect(0, 0, canvas.width, canvas.height);
//remove particles
setInterval(function() {
if(!remove_loop) remove_loop = setInterval(function() {
setTimeout(function() {
if(particles.length > 0) {
particles.shift();
}
}, 1);
}, 20);
}, 10);
//particles
for(var i = 0; i < particles.length; i++) {
if(particles[i].x < canvas.width &&
particles[i].y < canvas.width) {
if(particles[i].x < canvas.width &&
particles[i].y < canvas.height) {
particles[i].draw(ctx);
}
}
}
}
function newParticle() {
socket.emit("new_particle", new Particle(local_player.x, local_player.y, local_player.color));
particles.push(new Particle(local_player.x, local_player.y, local_player.color));
};
//move mouse
canvas.onmousemove = function(event) {
if(!event) event = window.event;
local_player.x = event.pageX;
local_player.y = event.pageY;
newParticle();
};
//touch mouse (phones/tables)
canvas.onmousedown = function(event) {
if(!event) event = window.event;
local_player.x = event.pageX;
local_player.y = event.pageY;
newParticle();
}
};
Player file
function Player() {
this.x = 0;
this.y = 0;
this.color = Math.floor(Math.random() * 999999);
while (this.color < 100000) {
this.color = Math.floor(Math.random() * 999999);
}
};
Particle file
function Particle(x, y, color) {
this.start_x = x;
this.start_y = y;
this.speed = Math.floor(Math.random() * 3 + 1);
this.x = x;
this.y = y;
this.size = Math.floor(Math.random() * 3 + 1);
this.color = "#" + color;
this.direction = Math.floor(Math.random() * 8);
this.move = function() {
this.speedDecreaseChance = Math.random(Math.random() * 100);
//Chance that the particle loses it's velocity like you would
//see with real particles
if(this.speedDecreaseChance > 3) { this.speed -= 0.5 };
//It's important that they move -AWAY- from X and Y.
this.subDirection = Math.floor(Math.random() * 2);
if(this.direction == 0) { //upper left
if(this.subDirection == 0) {
this.x -= this.speed;
} else if(this.subDirection == 1) {
this.y -= this.speed;
}
} else if(this.direction == 1) { //bottom right
if(this.subDirection == 0) {
this.x += this.speed;
} else if(this.subDirection == 1) {
this.y += this.speed;
}
} else if(this.direction == 2) { //upper right
if(this.subDirection == 0) {
this.x += this.speed;
} else if(this.subDirection == 1) {
this.y -= this.speed;
}
} else if(this.direction == 3) { //bottom left
if(this.subDirection == 0) {
this.x -= this.speed;
} else if(this.subDirection == 1) {
this.y += this.speed;
}
} else if(this.direction == 4) { //left
this.x -= this.speed/1.5;
if(this.subDirection == 0) {
this.y -= this.speed;
} else if(this.subDirection == 1) {
this.y += this.speed;
}
} else if(this.direction == 5) { //up
this.y -= this.speed/1.5;
if(this.subDirection == 0) {
this.x -= this.speed;
} else if(this.subDirection == 1) {
this.x += this.speed;
}
} else if(this.direction == 6) { //right
this.x += this.speed/1.5;
if(this.subDirection == 0) {
this.y -= this.speed;
} else if(this.subDirection == 1) {
this.y += this.speed;
}
} else if(this.direction == 7) { //down
this.y += this.speed/1.5;
if(this.subDirection == 0) {
this.x -= this.speed;
} else if(this.subDirection == 1) {
this.x += this.speed;
}
}
};
this.draw = function(ctx) {
ctx.beginPath();
ctx.shadowColor = this.color;
ctx.shadowBlur = 8;
ctx.arc(this.x, this.y, this.size ,0 ,2*Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
ctx.shadowBlur = 0;
};
};
Now the problem is that there's an error in my traffic between the server and all sockets.
What I want to do is make it possible that when one has particle objects to send them to the server and the server sends them to everyone except the original sender.
I did this through socket.broadcast.emit();
This went successful.
However when the objects arrive at the other sockets I get this error:
Uncaught TypeError: Object #<Object> has no method 'move'
Uncaught TypeError: Object #<Object> has no method 'draw'
For every particle object that exists at that moment.
If anyone knows why my objects lose their methods and would be so friendly to help a programmer in distress I'd be absolutely delighted :)
Thanks in advance!
From what I know Socket.IO expected JSON data as 2nd parameter for the emit function. JSON data format doesn't support function as values according to http://www.json.org/
You are sending a javascript object and expecting the object to be created from the json on a different client. This is not how Socket.IO communication works.
Instead of doing that you should send the data required to construct the object and use that to construct the object on the client.
You could do some thing like the following
Change this line
socket.emit("new_particle", new Particle(local_player.x, local_player.y, local_player.color));
to
socket.emit("new_particle", {x:local_player.x, y:local_player.y, color:local_player.color});
and then the event listener
socket.on("particles_data", function(data) {
particles.push(data);
});
to handle the creation of object from the data
socket.on("particles_data", function(data) {
particles.push(new Particle(data.x, data.y, data.color));
});
When an object is serialized to JSON, it loses all type information. This is what socket.io is transmitting.
var particle = new Particle(1, 2, 'ccc');
console.log(JSON.stringify(particle)); // {"start_x":1,"start_y":2,"speed":3,"x":1,"y":2,"size":3,"color":"#ccc","direction":5}
You can't tell if it's a particle or a monkey or something else.
When you receive this object, you need to convert it to a Particle first.
socket.on("particles_data", function(data) {
var particle = ...;
particles.push(particle);
});
You could define a constructor and create it again:
var particle = new Particle(data.x, data.y, data.color);
Or you could change its prototype:
var particle = $.extend(new Particle(), data); // here using jQuery helper method

Categories

Resources