So I need to make items jumping. I have array with 6 elements (items). I need to make that they randomly jumped, but if any item jumping, other should stay.
I have code for jumping, on EnterFrame for 1 item it working normally - jumping non stop.
But here is problem that If I try to use this function once (for example as MouseEvent.CLICK), item decrease item's y by 15px. If I use this function 2nd time It decrease It's y by 15px again. So at all I need to launch this function 19 times to make full jump.
//whether or not the main guy is jumping
var mainJumping:Boolean = false;
//how quickly should the jump start off
var jumpSpeedLimit:int = 15;
//the current speed of the jump;
var jumpSpeed:Number = jumpSpeedLimit;
function updateItems(e:Event):void {
var j:Number = Math.round(Math.random()*5);
if(!mainJumping){
//then start jumping
mainJumping = true;
jumpSpeed = jumpSpeedLimit*-1;
item1[j].y += jumpSpeed;
} else {
//then continue jumping if already in the air
if(jumpSpeed < 0){
jumpSpeed *= 1 - jumpSpeedLimit/75;
if(jumpSpeed > -jumpSpeedLimit/5){
jumpSpeed *= -1;
}
}
if(jumpSpeed > 0 && jumpSpeed <= jumpSpeedLimit){
jumpSpeed *= 1 + jumpSpeedLimit/50;
}
item1.y += jumpSpeed;
//if main hits the floor, then stop jumping
//of course, we'll change this once we create the level
if(item1[j].y <= 450){
mainJumping = false;
item1[j].y = 0;
}
}
I've tried to make for loop to use function 19 times (var i = 0; i <19; i++){ ... ,but after It item not jumping at all. Have you any ideas how to make that I used function once I made full jump?
After I created var j:Number = Math.round(Math.random()*5); It working in bad case, because It starting to jump 2nd items, till 1st not completed jump.
//whether or not the main guy is jumping
var mainJumping:Boolean = false;
//how quickly should the jump start off
var jumpSpeedLimit:int = 15;
//the current speed of the jump;
var jumpSpeed:Number = jumpSpeedLimit;
// we declare the variable that will hold the random number
var randomItem:Number;
// this function will select a random number and make the item corresponding
// to that number to jump. You call it once and it continues running.
function selectRandom():void
{
randomItem = Math.round(Math.random() * 5);
this.addEventListener(Event.ENTER_FRAME, updateItems);
}
function updateItems(e:Event):void {
if(!mainJumping){
//then start jumping
mainJumping = true;
jumpSpeed = jumpSpeedLimit*-1;
item1[randomItem].y += jumpSpeed;
} else {
//then continue jumping if already in the air
if(jumpSpeed < 0){
jumpSpeed *= 1 - jumpSpeedLimit/75;
if(jumpSpeed > -jumpSpeedLimit/5){
jumpSpeed *= -1;
}
}
if(jumpSpeed > 0 && jumpSpeed <= jumpSpeedLimit){
jumpSpeed *= 1 + jumpSpeedLimit/50;
}
item1.y += jumpSpeed;
//if main hits the floor, then stop jumping
//of course, we'll change this once we create the level
if(item1[randomItem].y <= 450){
mainJumping = false;
item1[randomItem].y = 0;
// after the item is finished jumping, we remove the listener
// and make it select another number. It is basically a loop.
this.removeEventListener(Event.ENTER_FRAME, updateItems);
selectRandom();
}
}
I just copy/pasted your code and made some modifications. I believe you missed some curly braces somewhere. That aside, the idea is to declare a variable outside of the updateItems method, so the number of the item doesn't randomly change every frame. Hope this solved your problem.
Related
I'm trying to do a sort of a multi element carousel:
I implemented left and right but I have problems with auto:
function addCarouselListener() {
data.forEach(function (carousel) {
carousel.previous.addEventListener('click', moveLeft);
carousel.next.addEventListener('click', moveRight);
});
}
function autoslide() {
var max =10, visible=6, count=visible;
max = 10
while (count < max) {
moveRight();
count +=1;
}
if (count=max) // go back
while(count > visible) {
moveLeft( )
count -=1;
}
First this is not really working always, I need to always work and have a timer.
Second, I need to pause if the user click on left,right(previous/next).
Please don't send me links to already done scripts, because I want to understand, plus I need something more custom.
I can clearly tell you that this line doesn't work as you'd expect :
if (count = max)
To compare equality between two variables you must use == or === if you'd like to also compare their type.
Also if you just do that like this, the slider will loop so fast that your browser will probably crash.
You want to use setInterval()
Here is a simple not-tested example :
var direction = 'right'
var current_position = 0
var max = 10
var delay = 500
var timer = false
function move_slider(){
if(direction == 'right')
current_position += 1
if(direction == 'left')
current_position -= 1
// move the slider
}
function auto_slide(){
console.log(current_position, direction)
move_slider()
if(current_position <= 0)
direction = 'right'
if(current_position >= max)
direction = 'left'
}
function set_auto_mode(){
timer = window.setInterval(auto_slide, delay)
}
function unset_auto_mode(){
window.clearInterval(timer)
timer = false
}
My simple JavaScript game is a Space Invaders clone.
I am using the p5.js client-side library.
I have tried many things to attempt at speeding up the game.
It start off fast, and then over time it get slower, and slower, it isn't as enjoyable.
I do not mean to show every bit of code I have. I am not showing every class, but I will show the main class where everything is happening.
Could someone eyeball this and tell me if you see anything major?
I am new to JS and new to making games, I know there is something called update()
that people use in scripting but I am not familiar with it.
Thank you.
var ship;
var flowers = []; // flowers === aliens
var drops = [];
var drops2 = [];
function setup() {
createCanvas(600, 600);
ship = new Ship();
for (var i = 0; i < 6; i ++) {
flowers[i] = new Flower(i * 80 + 80, 60);
}
flower = new Flower();
}
function draw() {
background(51);
ship.show();
ship.move();
shipDrops();
alienDrops();
dropsAndAliens();
dropDelete();
drop2Delete();
}
// if 0 drops, show and move none, if 5, etc..
function shipDrops() {
for (var i = 0; i < drops.length; i ++) {
drops[i].show();
drops[i].move();
for (var j = 0; j < flowers.length; j++) {
if(drops[i].hits(flowers[j]) ) {
flowers[j].shrink();
if (flowers[j].r === 0) {
flowers[j].destroy();
}
// get rid of drops after it encounters ship
drops[i].evaporate();
}
if(flowers[j].toDelete) {
// if this drop remove, use splice function to splice out of array
flowers.splice(j, 1); // splice out i, at 1
}
}
}
}
function alienDrops() {
// below is for alien/flower fire drops 2
for (var i = 0; i < drops2.length; i ++) {
drops2[i].show();
drops2[i].move();
if(drops2[i].hits(ship) ) {
ship.shrink();
drops2[i].evaporate(); // must evap after shrink
ship.destroy();
if (ship.toDelete) {
delete ship.x;
delete ship.y;
} // above is in progress, deletes after ten hits?
}
}
}
function dropsAndAliens() {
var randomNumber; // for aliens to shoot
var edge = false;
// loop to show multiple flowers
for (var i = 0; i < flowers.length; i ++) {
flowers[i].show();
flowers[i].move();
// ******************************************
randomNumber = Math.floor(Math.random() * (100) );
if(randomNumber === 5) {
var drop2 = new Drop2(flowers[i].x, flowers[i].y, flowers[i].r);
drops2.push(drop2);
}
//**************** above aliens shooting
// below could be method, this will ensure the flowers dont
//go offscreen and they move
//makes whtever flower hits this space become the farther most
//right flower,
if (flowers[i].x > width || flowers[i]. x < 0 ) {
edge = true;
}
}
// so if right is true, loop thru them all again and reset x
if (edge) {
for (var i = 0; i < flowers.length; i ++) {
// if any flower hits edge, all will shift down
// and start moving to the left
flowers[i].shiftDown();
}
}
}
function dropDelete() {
for (var i = drops.length - 1; i >= 0; i--) {
if(drops[i].toDelete) {
// if this drop remove, use splice function to splice out of array
drops.splice(i, 1); // splice out i, at 1
}
}
}
function drop2Delete() {
for (var i = drops2.length - 1; i >= 0; i--) {
if(drops2[i].toDelete) {
// if this drop remove, use splice function to splice out of array
drops2.splice(i, 1); // splice out i, at 1
}
}
}
function keyReleased() {
if (key != ' ') {
ship.setDir(0); // when i lift the key, stop moving
}
}
function keyPressed() {
// event triggered when user presses key, check keycode
if(key === ' ') {
var drop = new Drop(ship.x, height); // start ship x and bottom of screen
drops.push(drop); // when user hits space, add this event to array
}
if (keyCode === RIGHT_ARROW) {
// +1 move right
ship.setDir(1);
} else if (keyCode === LEFT_ARROW) {
// -1 move left
ship.setDir(-1);
} // setir only when pressing key, want continuous movement
}
Please post a MCVE instead of a disconnected snippet that we can't run. Note that this should not be your entire project. It should be a small example sketch that just shows the problem without any extra code.
But to figure out what's going on, you need to debug your program. You need to find out stuff like this:
What is the length of every array? Are they continuously growing over time?
What is the actual framerate? Is the framerate dropping, or does it just appear to be slower?
At what point does it become slower? Try hard-coding different values to see what's going on.
Please note that I'm not asking you to tell me the answers to these questions. These are the questions you need to be asking yourself. (In fact, you should have all of these answers before you post a question on Stack Overflow!)
If you still can't figure it out, then please post a MCVE in a new question post and we'll go from there. Good luck.
I'm trying to increment a number until it reaches a value (say 100), then make it decrement until it reaches 0, and have all this run in a while loop.
The code seems correct, but the browser is freezing, so I can't check in the console if there's a flaw in the algorithm.
var ceiling = 100;
var floor = 1;
var x = 1;
var step = 1;
setInterval(function(){
while(1) {
while(x + step <= ceiling) {
x += step;
document.write(x + ' ');
}
while(x - step >= floor) {
x -= step;
document.write(x + ' ');
}
}
}, 1500);
I've used setInterval here to slow down execution and avoid some buffering issue with the browser. It shouldn't be a problem since I have 16GB of RAM, but it might depend on how the browser can use/access that too in one tab.
I've also tried wrapping the setInterval function inside another function and execute it, with the same result.
You have a while(1) loop which basically is a infinite loop, even if no code is executed, it will freeze the browser.
The other answers have already pointed out the problems with your endless loop and with using document.write.
I think this does what you want:
var ceiling = 100;
var floor = 1;
var x = 1;
var step = 1;
setInterval(function() {
console.log(x);
x += step;
if (x === ceiling || x === floor) {
step = -step;
}
}, 1500);
setInterval is essentially your while(1) loop.
document.write is only intended to be used on the first rendering of the document. since you are doing an interval, then the doc is already rendered, and you can't use document.write. instead, you need to append your text to the body or a div
I'm a total javascript noob and I'm just trying to bludgeon my way through this simple project. Whats supposed to happen is the script is only meant to run while y <= 3. Each time that it runs the second IF statement, it's meant to add one to y's count and if it runs the ELIF, it's meant to subtract one from y's count. The goal is so that you can only have 3 "selected" pictures at any one time. My y does definitely change, but the IF (y <= 3) does not seem to stop the program from running. Thanks in advance, Jack
<SCRIPT type="text/javascript">
var y = 4; //this is a counter
function swapRoast() { //This defines the function
var x=document.images; //this automatically creates an array of all the images in the document starting with image0 and assigns them to variable'x'
if (y <= 3); { //this should check that y <= 3 before running
if (x[0].src.match('Roast_Vegetables.png')) //This tests if the source of image0 in the array matches the script
{
x[0].src=('Roast_Vegetables_Selected.png'); //If the source matches, then it is changed
y ++; //should add 1 to the y count
}
else if (x[0].src.match('Roast_Vegetables_Selected.png')) //If the source doesn't match, then it tests a different source
{
x[0].src=('Roast_Vegetables.png'); //If the different source matches, then the script operates in reverse to the original IF
y --; //should subtract 1 from the y count
}
}
}
function swapVege(obj) {
var x=document.images;
if (y <= 3); {
if (x[1].src.match('Vegetables.png'))
{
x[1].src=('Vegetables_Selected.png');
y ++;
document.getElementById("demo").innerHTML = y;
}
else if (x[1].src.match('Vegetables_Selected.png'))
{
x[1].src=('Vegetables.png');
y --;
document.getElementById("demo").innerHTML = y;
}
}
}
The semicolon is unfortunate and terminates the if block immediately. Change (in both places)
if (y <= 3); {
to something like
if (y <= 3) {
if (y <= 3); {
take out the ";" here
I'm trying to create a simple game with kineticJS on my canvas(Just some practice) and managed to get my player to shoot bullets. The same goes for the enemies that are spawned. They shoot a bullet each time the last bullet leaves the stage.
However: I'd like all the enemies(Variable number) to shoot 3 bullets at a 2 seconds interval. But i'm stuck completely and can't figure a way how to get it done.
Could anyone please look at my fiddle and see what's up?
http://jsfiddle.net/eRQ3P/6/
Note: line 573 is the function that loops(And draws the bullets and such every 30FPS)
Here's the code where i create a new bullet object:(Line 406 in fiddle)
function Enemybullet(destinationX, destinationY, enemySprite) {
this.id = 'bullet';
this.x = enemySprite.getX()+(enemySprite.getWidth()/2);
this.y = enemySprite.getY()+(enemySprite.getHeight()/2);
var targetX = destinationX - this.x,
targetY = destinationY - this.y,
distance = Math.sqrt(targetX * targetX + targetY * targetY);
this.velX = (targetX / distance) * 5;
this.velY = (targetY / distance) * 5;
this.finished = false;
this.sprite = new Kinetic.Circle({
x: this.x,
y: this.y,
radius: 3,
fill: 'black',
name: 'enemyProjectile'
});
this.draw = function(index) {
var mayDelete = false;
this.x += this.velX;
this.y += this.velY;
this.sprite.setAbsolutePosition(this.x, this.y);
//console.log(this.sprite.getX());
/*
if(enemyCollision(this) == true) {
mayDelete = true;
}*/
if (bulletLeftField(this.sprite) == true) {
mayDelete = true;
}
if (mayDelete == true) {
this.sprite.remove();
enemies[index].bullets.splice(0, 1);
createEnemyBullet(enemies[index]);
}
ammoLayer.draw();
}
}
And the function providing a new bullet: (line 247 in fiddle)
function createEnemyBullet(enemy) {
var blt = new Enemybullet(player.sprite.getX(), player.sprite.getY(), enemy.sprite);
ammoLayer.add(blt.sprite);
enemy.bullets.push(blt);
}
Probably the hardest part of this problem is figuring out when to draw each bullet to make three be fired in every 2-second interval. To make the bullets fire evenly, you want to divide the number of frames in the interval by the number of bullets to fire in that interval.
Because you're running the game at 30 frames per second, 2 seconds equals 60 frames.
60 frames / 3 bullets = 20 frames/bullet
So, we're going to create a new bullet for each enemy every 20 frames, or every 20th time refreshLoop() is called, and inside refreshLoop(), you now have to loop through all of the bullets each enemy has in its bullets array, because there can now be more than just one.
The fact that there can be more than one bullet in the bullets array introduces a new problem to the way bullets are removed from the array. Previously, you relied on the fact that one bullet at a time means it will always be the first one in the array, thus your code called bullets.splice(0, 1);. However, when the player is moving around and the enemies fire at the different locations, it is completely possible to have a bullet leave the screen and be removed sooner than one that was fired before it. This would cause the correct bullet sprite to be removed, but the first bullet in the array would be removed from bullets, so it wouldn't be updated anymore in refreshLoop(), and it would just sit on the screen doing nothing.
In order to avoid this, it is necessary to pass to the enemy bullets' draw() function the index in bullets at which the bullet being drawn is located. Since you need to loop through the array anyway, the index is already at hand in refreshLoop(), so just pass this to draw(). Now, every time a bullet needs to be removed, you can just call bullets.splice(bulletIndex, 1);
I hope you don't mind; I forked your fiddle to update it with the changes listed below.
EDIT: A new fiddle for burst-fire instead of sustained fire.
// Inside your Enemybullet definition
// One simple change to draw(), pass in the index of the bullet in the array
this.draw = function(indexEnemy, indexBullet) {
var mayDelete = false;
...
if (bulletLeftField(this.sprite) == true) {
mayDelete = true;
}
if (mayDelete == true) {
this.sprite.remove();
// Since you now have multiple bullets, you'll have to make
// sure you're removing the correct one from the array
enemies[indexEnemy].bullets.splice(indexBullet, 1);
}
ammoLayer.draw();
}
...
// Inside your refreshLoop function
// If there are enemies they should be checked
if (enemies.length > 0) {
for (var i = 0; i < enemies.length; i++) {
enemies[i].draw();
// At 30 frames per second, 3 bullets in 2 seconds would be
// one bullet for every 20 frames. So, every 20 frames,
// create a new bullet for each enemy
if ((enemyShootTimer % 20) == 0) {
createEnemyBullet(enemies[i]);
}
// The same way you draw all of the player's bullets,
// loop through the array of bullets for this enemy,
// and draw each one, passing in the new parameters
if (enemies[i].bullets.length > 0) {
for (var j = 0; j < enemies[i].bullets.length; j++) {
enemies[i].bullets[j].draw(i, j);
}
}
}
}
// Update loop for burst-fire instead of sustained fire
var burstTime = 10; // 10 frames between bullets, 3 per second
var needToShoot = ((enemyShootTimer % burstTime) == 0);
if (enemies.length > 0) {
for (var i = 0; i < enemies.length; i++) {
enemies[i].draw();
// if the enemies still have bullets to shoot this burst
// and if 10 frames have passed since the last shot
// ( enemyBurstCounter is declared outside refreshLoop() )
if (enemyBurstCounter < 3 && needToShoot) {
createEnemyBullet(enemies[i]);
}
if (enemies[i].bullets.length > 0) {
for (var j = 0; j < enemies[i].bullets.length; j++) {
enemies[i].bullets[j].draw(i, j);
}
}
}
if ((enemyShootTimer % 60) == 0) {
enemyBurstCounter = 0; // if 2 seconds have passed, reset burst counter
} else if (needToShoot) {
enemyBurstCounter++; // if the enemies shot, update burst counter
}
}