how do i make an objects continuously spawn on kaboom.js - game-development

When I shoot the asteriod they disapear which is what i want however I want more asteriods to spawn instead of them just disapearing forever.Im not sure what to add in this code to make more spawn into the game.
any help is appreciated
i thought making the number of asteriods a constant would make sure that 5 asteriods are on screen at all times however that didnt seem to work
// the asteroids
const NUM_ASTERIODS = 3;
for (let i = 0; i < NUM_ASTERIODS; i++) {
var spawnPoint = asteroidSpawnPoint();
var a = add([
sprite("asteroid"),
pos(spawnPoint),
rotate(rand(1,90)),
origin("center"),
area(),
scale(0.2),
solid(),
"asteroid",
"mobile",
"wraps",
{
speed: rand(5, 10),
initializing: true
}
]);
while (a.isColliding("mobile")) {
spawnPoint = asteroidSpawnPoint();
a.pos = spawnPoint;
a.pushOutAll();
}
a.initializing = false;
a.pushOutAll();
}
function asteroidSpawnPoint() {
// spawn randomly at the edge of the scene
return choose([rand(vec2(0), vec2(width(), 0)),
rand(vec2(0), vec2(0, height())),
rand(vec2(0, height()), vec2(width(), height())),
rand(vec2(width(), 0), vec2(width(), height()))]);
}

I had a similar problem when trying to spawn continuous sprites from the top of the screen. I found the following code worked to spawn my sprites at random positions (x-axis) across the top of the screen (y-axis).
Kaboom suggests using the wait() method within a recursive function in their tutorial, which avoids using a loop and allows you to control the frequency of spawning.
function spawnAsteroid() {
add([sprite('asteroid'),
pos(rand(width()), 0),
origin(),
body(),
'dangerous'
])
wait(rand(0.5, 1), spawnAsteroid);
}
spawnAsteroid();

Related

How can one dynamically update a progress indicator while a calculation started by changing an InputField value is running?

I have a Mathematica notebook that employs a fairly complicated user interface for controlling a long-running calculation. Among other things, the interface takes liberal advantage of Button, RadioButtonBar, Checkbox, and InputField.
When the effect of clicking a Button is an intermediate calculation that may take more than a couple seconds to complete, I like to provide a visual indication that the code hasn't crashed and is, in fact, doing something useful. A good way to do this is to start up a ProgressIndicator just before the intermediate calculation starts and then turn it off once the calculation is done. I have found this to be straightforward for calculations started by a Button click.
The same method does not work, however, for calculations that are initiated by changes to an InputField value. The simplified code below was written to do this but fails. The last two rows of the Grid are supposed to change automatically when updatingQ changes to True in the inner Dynamic command and then change back when updatingQ reverts to True, but it never happens. It appears that the outer Dynamic code is being blocked while the inner Dynamic code runs so it never even notices the changes to updatingQ.
On the other hand, the last two lines of the Grid respond as expected if one manually sets updatingQ=True on a separate input line.
(BTW, i) Pause[2] is just a stand-in for the intermediate calculation and ii) I multiply the input value by Pi is just to make it more obvious when the stand-in calculation is done.)
Apparently, the action portion of a Button behaves differently. Other pieces of code within the same Dynamic block can see and quickly respond when flags are changed there. It may be notable that I use Method->"Queued" in such cases. I tried the same with InputField (for which it is not a documented option) but to no effect.
I've tried various other things not shown here also without success.
A way to make this work would be much appreciated.
Clear[ProgressIndicatorTest]
updatingQ = False;
ProgressIndicatorTest = {
TextCell["ProgressIndicatorTest", "Subsubsection", Background -> LightBlue],
DynamicModule[
{filterTypes = {"Max energy", "Max length"}, filterValue, workingOn = "", iter = 0},
Scan[(filterValue[#[[1]]] = #[[2]]) &, Transpose#{filterTypes, {0.1, 100.}}];
Dynamic[
Grid[
Join[
Map[
Function[
filterType,
{filterType,
Dynamic#
InputField[
Dynamic[
filterValue[filterType],
Function[
value,
If[value > 0,
updatingQ = True;
Pause[2];
filterValue[filterType] = \[Pi] value;
updatingQ = False
]
]
], FieldSize -> 5, Alignment -> Right
]
}
], filterTypes
],
{{updatingQ, "-------"}},
{If[updatingQ,
{"Updating ... ",
ProgressIndicator[Appearance -> "Indeterminate"]},
Nothing
]}
], Alignment -> Left,
Background -> {None, {LightGreen, LightGreen, LightYellow, LightYellow}}
]
]
]
};
CellGroup[ProgressIndicatorTest]
As Forrest Gump never said, "Stackoverflow/Stackexchange is like a box of chocolates ... you never know what you'll get". And so today I found this answer which solves my problem.
Adapted to my particular case, the resulting code is as follows:
Clear[ProgressIndicatorTest]
calculation[n_] := Module[{a = .3}, Do[a = a (1 - a), {i, n 10^6}]]
updatingQ = False;
ProgressIndicatorTest = {
TextCell["ProgressIndicatorTest", "Subsubsection", Background -> LightBlue],
DynamicModule[{filterTypes = {"Max energy", "Max length"}, filterValue, upToDateQ = True},
Scan[(filterValue[#[[1]]] = #[[2]]) &, Transpose#{filterTypes, {0.1, 100.}}];
Dynamic[
Grid[
Join[
Map[
Function[
filterType,
{filterType,
DynamicWrapper[
InputField[
Dynamic[
filterValue[filterType],
Function[
value,
If[value > 0,
upToDateQ = False;
filterValue[filterType] = value
]
]
], FieldSize -> 5, Alignment -> Right
],
If[! upToDateQ,
Refresh[
updatingQ = True; calculation[2]; updatingQ = False;
upToDateQ = True,
None
]
],
SynchronousUpdating -> False
]
}
], filterTypes
],
{
If[updatingQ,
{"Updating ... ",
ProgressIndicator[Appearance -> "Indeterminate", ImageSize -> 80]},
Nothing
]
}
], Alignment -> Left,
Background -> {None, {LightGreen, LightGreen, LightYellow,}}]
]]
};
CellGroup[ProgressIndicatorTest]
This code does exactly what I want.
The key to success is wrapping DynamicWrapper around InputField and inserting a cleverly constructed second argument that performs the flag reset (upToDate=False in my case) that triggers the ProgressIndicator located elsewhere.
A couple more points.
Pause turns out not to be a good stand-in for a calculation. You may observe that the code behaves differently with a real function such as calculation.
It is interesting to note that upToDateQ can be a local variable whereas updatingQ cannot.
Kudos to Albert Retey for providing the code back in 2013.
The documentation for InputField says
"An InputField of type Expression [the default] replaces its
contents with the fully evaluated form every time the contents are
updated".
This seems to mean that InputField privately evaluates its content and all connected dynamics before releasing value changes, probably to prevent circular evaluations.
The following example condenses the problem. The first part works ok ...
changed = processing = False;
Column[{InputField[Dynamic[x, (changed = True; x = 2 #) &], FieldSize -> 5],
Dynamic[changed],
Dynamic[processing]}]
... until the dynamic below is also evaluated. Then changed never shows True because it is changed back to False before the update concludes.
Dynamic[If[changed,
processing = True;
Pause[2];
changed = processing = False]]
A alternative strategy would be to use a Button, e.g.
changed = False;
processing = Spacer[0];
Column[{InputField[Dynamic[y, (changed = True; y = #) &], FieldSize -> 5],
Button["Enter",
If[changed,
processing = ProgressIndicator[Appearance -> "Indeterminate", ImageSize -> 120];
Pause[2];
y = 2 y;
changed = False;
processing = Spacer[0]], Method -> "Queued", Enabled -> Dynamic[changed]],
Dynamic[changed],
Dynamic[processing]}]
This shorter version avoids the need to tab out of the input field.
changed = False;
processing = Spacer[0];
Column[{InputField[Dynamic[y], FieldSize -> 5],
Button["Enter",
processing = ProgressIndicator[Appearance -> "Indeterminate", ImageSize -> 120];
Pause[2];
y = 2 y;
processing = Spacer[0], Method -> "Queued"], Dynamic[processing]}]
Note the use of Method -> "Queued" gives Button the advantage over InputField. Without it Button appears to have the same problem.

"Parsing error: Unexpected token )" with bot

I'm making a discord bot and I'm trying to make a timer that every second it edits the message to time + 1 second like a real clock (Like 0:00). I'm a noob at this. This is my script:
const Discord = require("discord.js");
exports.run = async(bot, message, args) => {
let timerMessage = await message.channel.send('0');
for (i = 0, 10000000000) {
setTimeout(function() {
timerMessage.edit(timerMessage + 1);
}, 1000);
}
}
module.exports.help = {
name: "timer"
}
I have an error and it says: "Parsing error: Unexpected token )"
I would really appreciate it if you would help me with my problem, Thanks!
(Btw I'm using it in Glitch on Google Chrome)
It says that there's an unexpected token ) because you wrote your loop like this:
for (i = 0, 10000000000) {...}
You forgot to add the third argument (usually i++). Also, if you want it to run 10000000000 times you should write a comparison:
for (let i = 0; i < 10000000000; i++) {...}
I see what you're trying to achieve, but I would do it in a simpler way, using setInterval() instead of setTimeout().
setInterval(() => {
timerMessage.edit(timerMessage + 1);
}, 1000);
You seem to be missing a right parenthesis after the setTimeout function. I am not entirely familiar with what you are doing, but I would try something like this :
const Discord = require("discord.js");
exports.run = async (bot, message, args) => {
let timerMessage = await message.channel.send('0');
for (i = 0, 10000000000) {
setTimeout(function()) {
timerMessage.edit(timerMessage + 1);
}, 1000);
}
}
module.exports.help = {
name: "timer";
}
Although this should (maybe) replace the missing parenthesis in your code, it seems to have many other issues. For example, your for loop does not make much sense. Normally a for loop would look something like this (to repeat a certain number of times in java) :
for (int i = 0; i < 10; i++) {
System.out.println(i);
} // will print numbers 0-9, repeat 10 times
The whole chunk of code with the setTimeout bit seems to be messed up... It would help to have a little more context on what you are trying to do / some commenting in your code.
If you are trying to get into coding, I'd recommend something much more basic or some tutorials. CodingTrain has great coding videos on youtube and you will learn a ton no matter what language you go with. Hope this helped...

Createjs. Line follow element fiddle

I created this jsfiddle.
A line i connecting two elements, and I want the line to stay connected to both elements no matter where they go.
I've sort of succeeded, but with one pretty obvious error. It keeps drawing new lines instead of redrawing the existing line. Please help me on how to make it update the line position instead.
var stage = new createjs.Stage("canvas");
createjs.Ticker.setFPS(60);
createjs.Ticker.addEventListener("tick", tick);
var arrDots = [];
var arrLines = [];
var circle1 = new createjs.Shape().set({
x: stage.canvas.width/2,
y: 50,
cursor: "pointer",
name:"target"
});
circle1.graphics.f(createjs.Graphics.getRGB(Math.random()*0xFFFFFF))
.dc(0,0,20);
stage.addChild(circle1);
arrDots.push(circle1);
var circle2 = new createjs.Shape().set({
x: stage.canvas.width/2,
y: stage.canvas.height - 50,
cursor: "pointer",
name:"target"
});
circle2.graphics.f(createjs.Graphics.getRGB(Math.random()*0xFFFFFF))
.dc(0,0,20);
stage.addChild(circle2);
arrDots.push(circle2);
var line = new createjs.Shape().set({
graphics: new createjs.Graphics().s("#00f").mt(arrDots[0].x,
arrDots[0].y).lt(arrDots[1].x, arrDots[1].y)
});
stage.addChild(line);
arrLines.push([arrDots[0], arrDots[1], line]);
createjs.Tween.get(circle1, {loop: true}).to({x:50},
3000).to({x:stage.canvas.width/2}, 3000);
function tick(event) {
keepLineConnection();
stage.update();
}
function keepLineConnection() {
for(var i = 0; i < arrLines.length; i++) {
arrLines[i][2].graphics.mt(arrLines[i][0].x, arrLines[i][0].y).lt(arrLines[i][1].x, arrLines[i][1].y);
}
}
The reason it keeps drawing is because you keep adding commmands to the graphics. Basically, you are doing this:
graphics.mt().lt().mt().lt().mt().lt().mt().etc();
Since you are just adding new instrucitons, they will pile up over time,
and will eventually kill your processor.
An easy fix for that is to clear the graphics first before adding new ones:
graphics.clear().mt().lt();
A better approach is to use commands. Since EaselJS 0.7.0, all graphics commands are objects, and at any time you can update properties of those objects directly. For example, the MoveTo and LineTo commands both have an x and y property. Here is more info on Commands: http://blog.createjs.com/update-width-height-in-easeljs/
Here is a modified fiddle that stores of commands on the line, and then updates them on tick. I also made a few other updates, such as changing the timing mode to RAF, which is smoother than using interval-based timers at 60FPS.
https://jsfiddle.net/tck7x8u2/
// Store commands:
line.cmd1 = line.graphics.mt(0,0).command;
line.cmd2 = line.graphics.lt(0,0).command;
// Update commands:
var instr = arrLines[i],
line = instr[2];
line.cmd1.x = instr[0].x;
line.cmd1.y = instr[0].y;
line.cmd2.x = instr[1].x;
line.cmd2.y = instr[1].y;
Cheers!
Edit: Here is are some demos using that idea that I made a while back:
https://lab.gskinner.com/connections
http://jsfiddle.net/lannymcnie/2xoL08bx/
http://jsfiddle.net/lannymcnie/6rh7P/

Collision Physics P2 and Arcade not working as desired

Hi all so I have a small problem, basically I'm trying to kill a moving sprite, it does not matters if it comes from left to right or right to left, but all I want to kill is the one colliding and not the whole group, so to test go to the far right and shoot the block, you will see the new block disappear but not the one that collided is this possible I'm providing my game.js below but I created a demo that you can download and test to get a better feel of my problem please help, thanks.
Link to Demo
BasicGame.Game = function (game) {
// When a State is added to Phaser it automatically has the following properties set on it, even if they already exist:
this.game; // a reference to the currently running game (Phaser.Game)
this.add; // used to add sprites, text, groups, etc (Phaser.GameObjectFactory)
this.camera; // a reference to the game camera (Phaser.Camera)
this.cache; // the game cache (Phaser.Cache)
this.input; // the global input manager. You can access this.input.keyboard, this.input.mouse, as well from it. (Phaser.Input)
this.load; // for preloading assets (Phaser.Loader)
this.math; // lots of useful common math operations (Phaser.Math)
this.sound; // the sound manager - add a sound, play one, set-up markers, etc (Phaser.SoundManager)
this.stage; // the game stage (Phaser.Stage)
this.time; // the clock (Phaser.Time)
this.tweens; // the tween manager (Phaser.TweenManager)
this.state; // the state manager (Phaser.StateManager)
this.world; // the game world (Phaser.World)
this.particles; // the particle manager (Phaser.Particles)
this.physics; // the physics manager (Phaser.Physics)
this.rnd; // the repeatable random number generator (Phaser.RandomDataGenerator)
// You can use any of these from any function within this State.
// But do consider them as being 'reserved words', i.e. don't create a property for your own game called "world" or you'll over-write the world reference.
this.bulletTimer = 0;
};
BasicGame.Game.prototype = {
create: function () {
//Enable physics
// Set the physics system
this.game.physics.startSystem(Phaser.Physics.ARCADE);
//End of physics
// Honestly, just about anything could go here. It's YOUR game after all. Eat your heart out!
this.createBullets();
this.createTanque();
this.makeOneBloque();
this.timerBloques = this.time.events.loop(1500, this.makeBloques, this);
},
update: function () {
if(this.game.input.activePointer.isDown){
this.fireBullet();
}
this.game.physics.arcade.overlap(this.bullets, this.bloque, this.collisionBulletBloque, null, this);
},
createBullets: function() {
this.bullets = this.game.add.group();
this.bullets.enableBody = true;
this.bullets.physicsBodyType = Phaser.Physics.ARCADE;
this.bullets.createMultiple(100, 'bulletSprite');
this.bullets.setAll('anchor.x', 0.5);
this.bullets.setAll('anchor.y', 1);
this.bullets.setAll('outOfBoundsKill', true);
this.bullets.setAll('checkWorldBounds', true);
},
fireBullet: function(){
if (this.bulletTimer < this.game.time.time) {
this.bulletTimer = this.game.time.time + 1400;
this.bullet = this.bullets.getFirstExists(false);
if (this.bullet) {
this.bullet.reset(this.tanque.x, this.tanque.y - 20);
this.bullet.body.velocity.y = -800;
}
}
},
makeOneBloque: function(){
this.bloquecs = ["bloqueSprite","bloquelSprite"];
this.bloque = this.game.add.group();
for (var i = 0; i < 4; i++){
this.bloque.createMultiple(5, this.bloquecs[Math.floor(Math.random()*this.bloquecs.length)], 0, false);
}
this.bloque.enableBody = true;
this.game.physics.arcade.enable(this.bloque);
this.bloque.setAll('anchor.x', 0.5);
this.bloque.setAll('anchor.y', 0.5);
this.bloque.setAll('outOfBoundsKill', true);
this.bloque.setAll('checkWorldBounds', true);
},
makeBloques: function(){
this.bloques = this.bloque.getFirstExists(false);
if (this.bloques) {
this.bloques.reset(0, 300);
this.bloques.body.kinematic = true;
this.bloques.body.velocity.x = 500;
}
},
createTanque: function() {
this.tanqueBounds = new Phaser.Rectangle(0, 600, 1024, 150);
this.tanque = this.add.sprite(500, 700, 'tanqueSprite');
this.tanque.inputEnabled = true;
this.tanque.input.enableDrag(true);
this.tanque.anchor.setTo(0.5,0.5);
this.tanque.input.boundsRect = this.tanqueBounds;
},
collisionBulletBloque: function(bullet, bloques) {
this.bloques.kill();
this.bullet.kill();
},
quitGame: function (pointer) {
// Here you should destroy anything you no longer need.
// Stop music, delete sprites, purge caches, free resources, all that good stuff.
// Then let's go back to the main menu.
this.state.start('MainMenu');
}
};

actionscript-how to stop movieclip

I made a movie clip object namely "ball" with this script and it works!
onClipEvent(enterFrame){
var a=1.2 //it's an acceleration
totalTime = getTimer()/1000;
hours = Math.floor(totalTime/3600);
minutes = Math.floor((totalTime/3600-hours)*60);
seconds = Math.floor(((totalTime/3600-hours)*60-minutes)*60);
milli = Math.floor((totalTime-(seconds+(minutes*60)+(hours*3600)))*100);
stopwatch = seconds+(milli/100)+(minutes*60)+(hours*3600);
t= stopwatch;
v=a*t;
this._x=this._x+v;
}
but I failed to stop with button contains this script,
on (press) {
_root.ball.stop();
}
Anyone can help me please? I want to stop the object and the timer also. Thank you in advance.
You can't just stop the using stop(), read Marty's comment.
First of all, change the code within your ball movieclip to this:
onClipEvent(load){
_stopped = false;
}
onClipEvent(enterFrame){
var a=1.2 //it's an acceleration
if(_stopped == false){
totalTime = getTimer()/1000;
hours = Math.floor(totalTime/3600);
minutes = Math.floor((totalTime/3600-hours)*60);
seconds = Math.floor(((totalTime/3600-hours)*60-minutes)*60);
milli = Math.floor((totalTime-(seconds+(minutes*60)+(hours*3600)))*100);
stopwatch = seconds+(milli/100)+(minutes*60)+(hours*3600);
t= stopwatch;
v=a*t;
this._x=this._x+v;
}
}
This wraps the code which does all the calculation and movement of your ball, inside an if statement, which is only true when the variable _stopped is equals to FALSE. As long as _stopped = false;, your ball will be moving, and so will the time.
Now, change your button's actionscript to this:
on (press) {
_root.ball._stopped = true;
}
This will turn _stopped's value from FALSE to TRUE, and thus stopping all the calculation and movement of your ball, since the condition that _stopped should be equals to FALSE, is then no longer true.
Hope this works :)