when running the p5.js code, it seems to break, it works for 1 frame then breaks and lags no matter what device (ChatGPT and bard were unable to debug) (btw no error message is given)
var player;
var speed = 5;
var HP = 10;
var MaxHP = 10;
var frames = 0;
var VillageX = 0;
var VillageY = 0;
var NPCs = [];
class NPC {
constructor() {
this.x = getRandomInt(VillageX, VillageX + 500);
this.y = getRandomInt(VillageY, VillageY + 500);
this.sprite = new Sprite(this.x, this.y, 15);
this.sprite.img = "Images/npc.png";
this.sprite.collider = "dynamic";
this.sprite.scale = 3;
this.minimapX = 0;
this.minimapY = 0;
NPCs.push(this);
}
}
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min);
}
function preload() {
lexendFont = loadFont("Fonts/lexend.ttf")
}
function setup() {
frameRate(60);
createCanvas(windowWidth, windowHeight);
frames += 1;
console.log(frames);
VillageX = getRandomInt(-4900, 4400);
VillageY = getRandomInt(-4900, 4400);
player = new Sprite(0, 0, 15, "circle");
player.addImage("player", loadImage("Images/player.png"));
player.scale = 3;
player.collider = "dynamic";
topWall = new Sprite(0, -5010, 10000, 10);
topWall.visible = false;
topWall.collider = "kinematic";
leftWall = new Sprite(-5010, 0, 10, 10000);
leftWall.visible = false;
leftWall.collider = "kinematic";
bottomWall = new Sprite(0, 5010, 10000, 10);
bottomWall.visible = false;
bottomWall.collider = "kinematic";
rightWall = new Sprite(5010, 0, 10, 10000);
rightWall.visible = false;
rightWall.collider = "kinematic";
for (var i = 0; i < 3; i++) {
new NPC();
}
textSize(32);
}
function draw() {
clear();
background("green");
stroke(0);
strokeWeight(8);
noFill();
rect(windowWidth - 215, windowHeight - 50, 200, 35, 3);
noStroke();
fill("#00cc44");
rect(windowWidth - 215, windowHeight - 50, map(HP, 0, MaxHP, 0, 200), 35, 3);
fill("black");
rect(15, windowHeight - 215, 200, 200, 12);
var minimapX = map(player.x, -5200, 5200, 15, 215);
var minimapY = map(player.y, -5200, 5200, windowHeight - 215, windowHeight - 15);
fill("white");
circle(minimapX, minimapY, 8);
NPCs.forEach((NP, index) => {
NP.minimapX = map(NP.x, -5200, 5200, 15, 215);
NP.minimapY = map(NP.y, -5200, 5200, windowHeight - 215, windowHeight - 15)
fill("blue");
circle(NP.minimapX, NP.minimapY, 8);
});
camera.x = player.x;
camera.y = player.y;
player.rotation = player.angleTo(mouse) + 90;
if (kb.pressing("left")) player.vel.x = -speed;
else if (kb.pressing("right")) player.vel.x = speed;
else player.vel.x = 0;
if (kb.pressing("up")) player.vel.y = -speed;
else if (kb.pressing("down")) player.vel.y = speed;
else player.vel.y = 0;
fill("white");
textFont(lexendFont)
textSize(18);
text("HEALTH", windowWidth - 205, windowHeight - 27)
}
It breaks and lags extremely. How do i fix this, i have narrowed it down to be something to do with crearing an NPC, but nothing more.
The actual problem was a bug in p5.js
that was solved in version 1.5.0
.
The bug #5816 consisted in the fact that, in certain conditions, an image loaded during setup
resulted in the function setup
being called again (multiple times); in your case, the line this.sprite.img = 'Images/npc.png'
(from NPC
's constructor) resulted in the setup
function being called on an infinite recursion.
So the immediate solution is, if possible, to upgrade the link to p5.js
in your index.html
to the latest version (1.6.0
) -- it took me a while to realise that your replit was using version 1.4.0
.
Regardless of that, it is a good practice to preload images, as you already did with fonts. I'll repeat the steps from my message (adapted from preload reference):
var npcImg;
(or let npcImg
if you change to ES6)preload
function do load the image npcImg = loadImage('Images/npc.png');
setup
function add npcImg.loadPixels();
this.sprite.img = 'Images/npc.png'
with this.sprite.img = npcImg;
(in NPC's constructor)