0

Using the setInterval function, I'm trying to create a sprite once every second on code.org using javascript, so my first version of the code looks like

setInterval( function() {
  createSprite(200,200,20,20)
}, 1000)

My problem is that putting setInterval inside of the Draw function causes it to not work properly and a sprite is created every tick after one second has passed, and when the setInterval is not put into function Draw it does not draw the sprite like I want it too.

One solution I have tried is putting the Draw function inside of setInterval but it is not recognized and gives the error message "Draw is defined, but it is not called in your program".

Is there a different version of setInterval that works inside of Draw function, a way to put Draw inside of setInterval successfully, a way to make the sprite show up even though it is outside Draw, or a different way to solve this problem?

Specifically what I'm looking for is to create a sprite once every second, have it show up on screen, be able to choose different velocities for each sprite each time a new one is spawned, and being able to put this function inside of an if function and still have it work as intended.

a piece of code showing something that partially works is shown here:

https://studio.code.org/projects/gamelab/ApXezLpMzV3TfEfHx1CrhFyuteYDSKWe_6Hx0NdJgnc

It works in the regards that it spawns a sprite every second, but if I try to assign one of the sprites that got spawned a velocity, It only works for the first one, as shown here:

https://studio.code.org/projects/gamelab/ApXezLpMzV3TfEfHx1CrhFyuteYDSKWe_6Hx0NdJgnc

the only way I think a solution could be made would be by declaring a class, and then creating a sprite of this class inside the setInterval function, but I do not know exactly how to do this.

Qwerty
  • 23
  • 5
  • 1
    Try This - https://stackoverflow.com/questions/28456898/javascript-setinterval-function-not-working-in-drawing-to-canvas – Onic Team Aug 02 '20 at 14:18
  • 1
    @VedPrakash I don't understand, my coding isn't very advanced. – Qwerty Aug 02 '20 at 14:28
  • so do you want them to start spawning from the start, or on a key press? what kind of event? i'll try to create it – Menawer Aug 10 '20 at 21:24
  • 2
    Could you please share all the relevant code? – Daniele Ricci Aug 10 '20 at 21:46
  • you reference your `Draw` function no fewer than 7 times inside your question - so it (both its implementation and how it interacts with the rest of your code) is likely quite important to knowing what the problem is. Yet you do not share the function, or anything about your code beyond a simple `setInterval` call. Please give more detail as it will help us understand the problem and hopefully allow someone to answer your question well. – Robin Zigmond Aug 11 '20 at 18:51
  • @Menawer I want to start spawning once a certain variable is greater than or equal to 2, this variable will always be an integer greater than or equal to one, and starts at the value of 1. – Qwerty Aug 12 '20 at 02:21
  • @DanieleRicci I added the relevant code – Qwerty Aug 12 '20 at 02:22
  • @RobinZigmond The solution does not necessarily involve the draw function, that is just one way of solving this problem that I have tried. – Qwerty Aug 12 '20 at 02:23

2 Answers2

3

So i think that your problem is that the sprite generates only after a second, right?

If so, please try this:

createSprite(200,200,20,20);
setInterval( function(){ createSprite(200,200,20,20)},1000);
Qwerty
  • 23
  • 5
  • 1
    Thank you, this works perfectly except for the fact that when I add a velocity only the first instance will move. Also, if I copy&paste the code into an if function it does not work – Qwerty Aug 02 '20 at 14:38
  • what do you mean by "velocity"?? – Rick Aug 12 '20 at 02:28
  • @Rick what i mean by velocity is that when i use velocity.x on the sprite only the first sprite that gets spawned moves. – Qwerty Aug 12 '20 at 20:35
  • you need to have a way to reference each sprite. but without seeing any code, no one is going to be able to help much. – Rick Aug 13 '20 at 00:33
0

See comments:

// just a helper function to generate random velocities
function random_in_range(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min }

var monster = createSprite(200,200,20,20);
monster.velocityX = 5;

setInterval(function() {
  // as you needed to set velocity for a newly created sprite
  // you need to have this sprite as a variable
  var fireball = createSprite(monster.x,monster.y,4,4);
  // now you can set it's velocity
  fireball.velocityX = random_in_range(1,6);
  // basically that's it.
  // as you don't do anything else with a "fireball"
  // you can just forget about it, and you don't need to save it anywhere
}, 1000);

function draw() {
  background("white");
  createEdgeSprites();
  monster.bounceOff(edges);
  drawSprites();
}

The link with the working code


Looking at your original code and your question I think that you may have some basic misconseptions about JS (sorry if I misjudged). Explained them in the comments to your code. I also added some lines to illustrate my points:

var spawner = createSprite(200,200,20,20);
var remember_spawner = spawner // ADDED
// After a new sprite created it does't change 'spawner' variable
createSprite(150,200,15,15).velocityY = 3; // ADDED
console.log(remember_spawner === spawner) // ADDED // you see it's the same

// you need to assign the newly created sprite to a variable
// you can think of this as:
// I need give them different names so that they can understand to whom am I taking to
// and if you don't name them they won't listen to you at all
var spawner2 = createSprite(100,200,10,10);  // ADDED
spawner2.velocityY = 1  // ADDED // now you cat change velocity of another sprite
console.log(spawner !== spawner2) // ADDED // and it is another sprite

// var thing_to_be_spawned = createSprite(spawner.x,spawner.y,4,4);
  // You probably don't need this. And you don't use the variable anyway.
  // This sprite created at the same time as the spawner.
  // But if you need it, and you want it to move - change it's velocity (thing_to_be_spawned.velocityX = something) not the velocity of spawner
  // And it would be better if you'll name the function passed to setInterval
  // and call it instead of repeating it. Like so:
  // function fire() { ... } // define the function
  // fire() // call the function
  // setInterval(fire, 1000) // call the function every second

setInterval(function(){
  console.log("This function executed every second") // ADDED
  console.log("Fire!") // ADDED
  createSprite(spawner.x,spawner.y,4,4);
  console.log("Done") // ADDED
},1000);

console.log("Next line executed only once") // ADDED
spawner.velocityX=5;
// The fact that it's placed after setInterval() does mean that
// it will be executed after call to setInterval()
// but it doesn't mean that it will be executed after the function passed to setInterval(). Let's call it fire(), shall we?
// Actually, the fire() function will be called only after all the code in this file
// And setInterval() is also called only once, only the fire() passed to it called every second

function draw() { // Here you don't call draw() you only define it, so that code.org can call it whenever it wants
  // looking at the code draw function we can't tell when or how often it's called
  // it depends on the implementation details of code.org.
  // We can add console.log to find out
  console.log("Draw called") // ADDED
  background("white");
  createEdgeSprites();
  spawner.bounceOff(edges);
  drawSprites();
}
console.log("'fire()' not called yet") // ADDED

Console logs can be seeing in Debug Console of studio.code.org. It opens with a click on Debug Commands. Use it! I mean console.log(). I could also say "use Debug Commands!" but debug is poorly implemented in studio.code.org and can be misleading... You should definitely give it a try, but your trust you should put in console.log().

x00
  • 13,643
  • 3
  • 16
  • 40