I am trying to make my cursor be a PNG image that I have already preloaded in an art game I am designing on P5.js.
I have tried so many things, but it still won't work!
Can someone please let me know where to put the cursor function as well as what to put inside the parentheses? Thanks so much!
function preload() {
uImg = loadImage('assets/ufo.png');
rImg = loadImage('assets/asteroid.png');
bImg3 = loadImage('assets/bimg3.jpg');
}
function setup() {
createCanvas(1200, 600);
mode = 3; //level 3 in game
noCursor();
}
// END OF SET UP
function draw() {
levelThree();
}
// END OF DRAW
function levelThree() {
clear();
if (mode == 3) {
lost = false;
score = 0;
background(bImg3);
cursor(uImg,mouseX,mouseY);
}
}
I think simply using image() instead of cursor() will do what you want. I don't know why, but I think that when using cursor() you can't input a p5.Image, you have to put a string of a URL to an image that exists on the internet.
Also, when using cursor(), the other two parameters should be between 0 and 31. They describe where the "active point" of the cursor is, relative to where the actual mouse point is.
You could just do something like this:
let img
function preload(){
img = loadImage('cursor.png')
}
function setup() {
createCanvas(400, 400);
imageMode(CENTER)
noCursor()
}
function draw() {
background(20);
image(img,mouseX,mouseY)
}
And you should put the option stuff in setup() so the imageMode() and fill() and idk rectMode()... in setup, though what ever you're going to draw multiple times in draw() and you should load images in preload, cause javascript doesn't reallly care if images are loaded in or not and callback functions are meh, preload is good in my opinion. I also don't think that you really need the assets in assets/image.png
And also why exactly do you have mouseX and mouseY in the cursor() at the end of your code snippet???
hope this is actually answering the right question...
Related
I am trying to draw hundreds of images onto a canvas, but only when I reference the specific image variable. I encountered a function created by someone responding to another one of these posts that I was using. It was something like map = createImage("images/Global/Map.png") and it would return the value I was able to draw like this: ctx.drawImage(map, 0, 0, 224, 292) instead of me having to do it in the onload function.
I guess what I am trying to ask is how would I create an object that would allow me to do this?
I tried something along the line of this:
const createImage = function(src) {
image = newImage();
image.src = src;
image.onload = function() {
return(image);
}
}
// Other code creating images...
var map = createImage("images/map.png");
// Code to draw map
ctx.drawImage(map, 0, 0, 224, 292);
Thanks in advance. I'm hoping its a simple problem.
I was an idiot and should not have been allowed to post this question.
I was trying to do animations using canvas on javascript.
The thing that would have solved my problem (while it was never a problem to begin with) was the window.requestAnimationFrame(function()). As it kept animating, sooner or later the images would load and be drawn. To my eyes, it appeared as if it were instant, hence my wanting the program to wait until everything was loaded.
There was never a problem to begin with. Oops.
I am a beginner at p5js, and I was learning how to upload an image. This is my code:
PImage img;
function setup() {
size(1400, 1400)
img = loadImage("india-map.gif");
}
function draw() {
background(0)
image(img, 100, 100);
}
When I run it, it says that there is a problem with line 1. The error message reads:
SyntaxError: Expected ;but found img.
I don't know what this means and what I should do. Can anyone help me?
Edit:
I changed the code to
var image1;
function preload(){
image1= loadImage("india-map.jpg");
}
function setup(){
creatCanvas(1350,600)
}
function draw(){
image(image1, 100, 100);
}
My page just says ...loading without loading any image.
In addition to kemicofa great answer, I think it is also important to note the loadImage is asynchronous. This means that when we call loadImage it will take some time for the method to retrieve and load the image data into memory. As a result of this, loadImage doesn't happen instantly like the rest of your code.
Thus, while your image is being loaded, the rest of your code is still able to run, including the draw method. This means that if your draw method only runs once (you can make it run only once by using noLoop(), your image will not be displayed because it hasn't yet been loaded in.
There are a couple of solutions to this issue such as using a callback. However, p5js offers another method which runs before setup called preload. In this function, you can load your image to make sure that it is ready for setup and draw to use.
Using all these ideas you will end up with code which looks somewhat like:
let img;
function preload() {
img = loadImage('india-map.gif'); // load media and other data
}
function setup() { // only executed once preload is has finished loading data
createCanvas(400, 400);
}
function draw() { // only executed once preload is has finished loading data
image(img, 0, 0, width, height);
noLoop(); // stop draw from looping (to show img has been loaded)
}
You can find a working example here
Explanation:
PImage is a type coming from the Processing3 library.
In javascript, when declaring a variable use const, let or var.
Additionally, the size method comes from Processing3 as well. Instead use createCanvas method and pass the size as a parameter.
Go over the documentation and make sure the methods you wish to use exist.
Solution:
let img;
function setup() {
createCanvas(100, 50);
img = loadImage("india-map.gif");
}
function draw() {
background(0);
image(img, 100, 100);
}
I have the following code:
var posX1 = 0, posY1 = 100;
var speedX1 = random(1,3), speedY1 = random(1,3);
var posX2 = 0, posY2 = 200;
var speedX2 = 2, speedY2 = 0;
function setup()
{
createCanvas(640, 480);
}
function draw()
{
// redraw the background so you blank the screen
background(255);
if(posX1 > width)
{
speedX1 = -speedX1;
}
// update the position based on the speed
posX1 += speedX1;
posY1 += speedY1;
// draw a ball
strokeWeight(20);
point(posX1, posY1);
//
posX2 += speedX2;
posY2 += speedY2;
//draw a ball
strokeWeight(20);
point(posX2, posY2);
}
Its in P5. I basically want the two circles to race each other at random speeds between 1 and 3 but instead they dont even appear on the screen. Can anyone point out where I'm going wrong?
You can't use P5.js functions before setup() is called.
If you run this code and look at the JavaScript console (which should always be your first step) you'll see that you're getting an error saying that random() is not defined. If you then Google that error, you'll get a ton of results explaining what's going on.
From the P5.js FAQ:
Why can't I assign variables using p5 functions and variables before setup()?
The explanation for this is a little complicated, but it has to do
with the way the library is setup in order to support both global and
instance mode. To understand what's happening, let's first look at the
order things happen when a page with p5 is loaded (in global mode).
Scripts in <head> are loaded.
<body> of HTML page loads (when this is complete, the onload event fires, which then triggers step 3).
p5 is started, all functions are added to the global namespace.
So the issue is that the scripts are loaded and evaluated before p5 is
started, when it's not yet aware of the p5 variables. If we try to
call them here, they will cause an error. However, when we use p5
function calls inside setup() and draw() this is ok, because the
browser doesn't look inside functions when the scripts are first
loaded. This is because the setup() and draw() functions are not
called in the user code, they are only defined, so the stuff inside of
them isn't run or evaluated yet.
It's not until p5 is started up that the setup() function is actually
run (p5 calls it for you), and at this point, the p5 functions exist
in the global namespace.
In other words, you have to define your variables at the top of your sketch, but only assign them inside the setup() function:
var speedX1;
var speedY1;
function setup()
{
createCanvas(640, 480);
speedX1 = random(1,3);
speedY1 = random(1,3);
}
I've recently made the leap from using Khan Academy's processing.js environment to the real deal and am getting a little confused.
I have a simple processing.js program that basically draws a circle, and I want the size of this circle to be determined by the width of the canvas.
If I print the width within a processing.js function, like setup, I'm shown the correct 500px width. Unfortunately, whenever I try to access the width property outside of a processing.js function, it shows the default 100px size, even though the canvas itself is 500px wide.
I think I might be using a fairly ugly mix of processing and javascript, which could be the root of my problems. Your help would be much appreciated!
Processing.js
///* PROCESSING.JS SETUP *///
void setup() {
size(500, 500);
println(width); // WORKS! :)
}
println(width); // DOESN'T WORK... :(
///* GLOBAL VARIABLES *///
var moleculeQuantity = 1;
///* OBJECT CONSTUCTORS *///
var Molecule = function(x, y) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
};
Molecule.prototype.draw = function() {
noStroke();
fill(88, 91, 183);
ellipse(this.x, this.y, 70, 70);
fill(225, 227, 228);
ellipse(this.x, this.y, 40, 40);
};
// Fill array with molecule objects
var molecules = [];
for (var i = 0; i < moleculeQuantity; i++) {
molecules[i] = new Molecule(200, 100);
}
///* DRAW FUNCTION *///
void draw() {
background(225, 227, 228);
molecules[0].draw();
}
Your problem has nothing to do with mixing Processing and JavaScript, and it has nothing to do with asynchronous execution. It's much simpler than that.
Think of the order your code executes in. Anything outside of a method will execute before your setup() function is called. In your case, that means you're accessing the width variable before you've changed it by calling the size() function.
You have to change your code so that your code is triggered after setup() is called. The simplest way to do that is to just move your code to the end of your setup() function, or into a function that's called after setup(), such as the draw() or event methods.
You might think that because your function call is below the setup() function in your code that the setup() call happens first, but it doesn't. You've simply defined the setup() function- it hasn't been called (by Processing) yet! Try moving any code that's outside of a function to the top of your sketch to make it more obvious:
println(width); // this happens first, so width is still 100
void setup() {
size(500, 500);
println(width); //now that size() has been called, the width is 500
}
Edit: I'll try to explain the order of events. Here is what happens when you load a page that contains a Processing.js sketch:
The page is loaded.
Processing.js itself is loaded.
Processing.js compiles your Processing code into JavaScript code.
Your code (which is now JavaScript code) is loaded. Functions like setup() and draw() are defined at this step, but not called yet. Code outside of your functions is called. This is when you see 100 being printed out.
Processing.js calls the setup() function that was defined in step 4. This is when the width is set.
Processing.js starts calling the draw() function 60 times per second.
As for where you should place your variables and functions, that completely depends on what you want to do with them. But you might place a variable's declaration at the top of your sketch and its initialization inside the setup() function. That way you can access its value anywhere, but you know it won't be set until setup() has run. Something like this:
float middleX;
void setup(){
size(500, 500);
middleX = width/2;
}
void draw(){
background(0);
ellipse(middleX, mouseY, 10, 10);
}
I am making a javascript canvas drawing program and I want the user to be able to choose between the pencil tool, circle tool and clearing screen on keypress.
In the following code the variable key_press holds the users selection. The whole program does not work when I don't assign anything to the variable, so I made the default value = pencil(). But now I cant use anything but pencil.
I post only relevant code here, but it is full in this jsfiddle
var canvas, context, tool, key_press;
// check for key press
window.addEventListener('keydown',function(event){
key_press= String.fromCharCode(event.keyCode);
},false);
function init () {
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
//check user selection
if (key_press === "1") {
tool = new Pencil();
} else if (key_press === "2") {
tool = new Circle();
} else if (key_press === "3") {
canvas.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
tool = new Pencil();
} else tool = new Pencil(); //this part is probably causing the problem, but clear screen (selection 3) does not work either so it could be something different.
//onmouse calls and end of init()
}
//basically just two functions after init for the tools
function Pencil () {
//...
}
function Circle() {
//...
}
//calling main function init()
init();
Obviously the way I handle user input is bad. Could you point me in the right direction as to what I am doing wrong?
Your distance calculation wasn't working because you left off a , 2 in the second Math.pow call.
Your jsfiddle wasn't working because the default on a new fiddle is to run in window.load, but you then added another load event listener that never fired.
I've changed the code to reflect these changes (and make the context.arc call use the distance rather than z) and it appears to work:
http://jsfiddle.net/rWV5h/1/