So the question is really bad because I don't know what to ask or call what I'm trying to do, but...
I have a game I'm creating and I've added in an array for the lasers. It works fine but I want to limit the number of lasers that can be on the screen at once so the player doesn't just spam the space bar to win.
I tried limiting it by making a set number of bullets which only allows the user to shoot twice but where I tried to add back bullets once it reached the top of the canvas so they could start shooting again but it didn't work.
I assume this is because it is within the spacePressed if and so it considers spacePressed to be false so it won't run where it adds one bullet but when I put the adding bullets if outside the spacePressed it still didn't work.
I'm not sure how to go about doing what I'm trying to do and would appreciate any ideas towards fixing this. I will also have to add in later where the laser disappears upon hitting the meteor and adds back one bullet so I would also like help with figuring that out.
https://jsfiddle.net/200uaqrn/18/ <-before adding any bullets
https://jsfiddle.net/200uaqrn/19/ <-adding in my attempt to create limited bullets
if(spacePressed) {
if(lasers.y<=laserSize) {
bullets+=1;
}
else{
drawLaser();
lasers.forEach(function(laser,index){
laser.y-=laserdY;
})
}
}
Also separate question for the same project I'm going to later make multiple meteors falling at once and I assume I would use an array for that. But I don't know how to use that array to make them fall from random y cords at different times, etc.
For the laser, you can try to just set a function with timeout:
var canFire = true;
function allowFire() {
canFire = true;
}
function newLaser() {
this.x = turretX
this.y = canvas.height - 75
canFire = false;
setTimeout(allowFire, 3000);
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if (e.keyCode === 39) {
rightPressed = true;
} else if (e.keyCode === 37) {
leftPressed = true;
}
if (e.keyCode === 32 && canFire == true) {
spacePressed = true;
lasers.push(new newLaser())
}
}
Note that 3000 is the cooldown there.
This will limit the amount of bullets at the same time in the screen, as the player will only shoot every x milliseconds, if you wanna a exact amount of bullets, you can do a var for them with the desired amount, then remove one every time that the player press space, and do a check for > 0 here: (e.keyCode === 32 && canFire == true)
For the meteors if you're going to use the array, to make them fall random you can use this function(found in Mozilla Developers):
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
So you can use it for the coordinates and for the time you can use a timeout(like above) with a random time too, using this(from the same source):
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
If it's a array you can use it like getRandomArbitrary(i * 1000, i * 3000) as i being the index in a for loop. It depends on how specifically you wanna them to work, there's many ways to do that, a function that call itself, while loop, etc.
"It works fine but I want to limit the number of lasers that can be on the screen at once so the player doesn't just spam the space bar to win."
So it sounds like what you want to do is not limit the amount of bullets, but limit the ability of the player to shoot. You could ensure that some time (a tenth of a second?) must pass before the player can shoot again.
As for random numbers, see the later examples here on how to get random numbers in some range.
Related
I am coding a game that is currently in its very early stages for a project to try to learn more about coding. In my game, objects generate randomly (green squares), and the player (red square), avoids them. I am having trouble trying to get the green squares to generate from a random position on the x-axis. I already have a formula to generate a random number for X, but after it selects a number randomly, all the "projectiles" generate there, rather than all generating from a different area. How would I get all the "projectiles" to generate from different positions on the x-axis randomly?
var randomX = Math.floor(Math.random() * 480) + 15;
function updateGameArea() {
var x, y;
for (i = 0; i < projectiles.length; i += 1) {
if (player.crashWith(projectiles[i])) {
gameArea.stop();
return;
}
}
gameArea.clear();
gameArea.frameNo += 1;
if (gameArea.frameNo == 1 || everyinterval(150)) {
x = randomX;
y = gameArea.canvas.height;
projectiles.push(new component(40, 40, "green", x, y));
}
for (i = 0; i < projectiles.length; i += 1) {
projectiles[i].y += -1; // the shape is using its coordinates to build downward from its y position
projectiles[i].update();
}
player.newPos();
player.update();
}
function everyinterval(n) {
if ((gameArea.frameNo / n) % 1 == 0) {return true;}
return false;
Expected: Green squares generate in random positions on the x- axis every 3 seconds and move upwards
Actual: Green squares all generate from the same random position on the X-axis.
You should reset X every time you're adding a new projectile:
if (gameArea.frameNo == 1 || everyinterval(150)) {
randomX = Math.floor(Math.random() * 480) + 15;
x = randomX;
y = gameArea.canvas.height;
projectiles.push(new component(40, 40, "green", x, y));
}
Otherwise, the randomX value stays constant as the value originally evaluated on line 1 when the interpreter reached it.
Here's your problem:
var randomX = Math.floor(Math.random() * 480) + 15;
// Generates a random number and stores it to randomX
// Called using 'randomX'
You need to turn it into a function if you want it to run each time:
var randomX = function() { Math.floor(Math.random() * 480) + 15 };
// Returns a new number each time
// Called using 'randomX()'
Both shivashriganesh mahato and natelouisdev have, essentially responded to how to fix the issue but since you are learning coding here is a tip. When you code, the code will run in a particular order. If you want something to be reassigned repeatedly, in this case a randomized number being used, and you want it to occur only after an event, you need to make sure that it gets trigger within each event.
natelouisdev has a good approach because, by using it as a function, you can call your randomizer more cleanly in your code and make it reassign the value of x each time.
Since you are building a game, it is also a good idea to compartmentalize your code. It'll make it easier to keep your ideas in order for each event trigger.
Example:
function gameLoss(){} - Define event return upon game loss. You can
then create editable rules to reason for loss without having to edit
the loss
function gameActive(){} - Defines what is normal gameplay. everything that occurs during normal gameplay should be managed here.
function gameArea(){} - Defines game canvas that function more for UI than for gameplay (scores, lifes, size of screen, etc)
Had you created individual functions you'd realize you only need a randomized 'x' value upon regular play thus you'd assign it within the gameActive() function and not as a global variable. Then you'd call the gameActive() function as many times as needed within a time interval to ensure a unique value is created each time.
-Side note: Don't litter unnecessary global variables. It'll make a mess off of your code when debugging. -
I'm trying to make the selector rotate at varying times, I figured I would try a simple if/else statement, to make the first one rotate after 3 seconds, and the following ones after 30 seconds. However, it just keeps rotating it every three seconds. Had I figured how to make this work, I was planning on adding more if/else statements inside the previous one, so that I could add custom times for each slide. Any ideas how I could achieve this?
$(document).ready(function(){
var flipped = false;
if (!flipped)
{
$('#Blog1 > ul').tabs({fx:{opacity: 'toggle'}});
$('#Blog1 > ul').tabs('rotate', 3000, true);
flipped = true;
}
else
{
$('#Blog1 > ul').tabs({fx:{opacity: 'toggle'}});
$('#Blog1 > ul').tabs('rotate', 30000, true);
}
});
You're clearly setting "flipped" to false every time you run the function.
Or rather, your not running it again to check for flipped. (I think)
You need to separate the variable from the function, otherwise it will always be false.
As for time, you can easily use Math.random()
randomNumber = Math.floor((Math.random() * 30) + 1); // Random number between 1 and 30
$('#Blog1 > ul').tabs({fx:{opacity: 'toggle'}});
$('#Blog1 > ul').tabs('rotate', randomNumber, true);
I developing TD game with EaselJS and faced with one problem.
When enemy come to castle he should should to start attack it with uniq delay.(for example witch:3 seconds, elemental:2 seconds e.t.c.)
How to set this delay with enabled ticker?
createjs.Ticker.on("tick", moveTick);
createjs.Ticker.setFPS(20);
console.log(mobs);
function moveTick(event) {
for (var i = 0; i < mobs.length; i++) {
if (mobs[i].y > stage.canvas.height - castle.castleHeight - mobs[i].elemSize) {
setTimeout(console.log("attacking"), 600000);
} else {
mobs[i].y = mobs[i].y + mobs[i].movementSpeed;
}
}
field.update(event);
}
Since you know how many seconds you want to have something wait before performing an action, and you know how many frames per second your program will run at, what you can do is count frames before performing an action.
A good way to count the frames would be to maintain a tick counter, and decrement the counter any time it is a positive number, and then performing an action once the counter hits 0. Here is a code example partially making use of your code of how this might work:
createjs.Ticker.on("tick", moveTick);
createjs.Ticker.setFPS(20);
console.log(mobs);
// note that enemy_ticker would probably be a property of your enemy object:
var enemy_ticker = -1;
function moveTick(event) {
if (event that causes enemy to attack soon) {
enemy_ticker = 60; // this gives us 3 seconds
}
if (enemy_ticker > 0) {
enemy_ticker--;
} else if (enemy_ticker = 0) {
enemy_ticker--;
// put your code to start your enemy's attack here
}
field.update(event);
}
I'm new to html5 games and javascript and I need a little help here.
I'm creating a simple 2D mini-game, but I have a problem. With the positions.
I have 3 different vertical positions (or 3 rows), p_top, p_mid and p_bot. My mission is to move a ball with these positions using just 2 buttons.
My buttons are only the up and down arrow. If I press up I move the red ball one position up, and if I press down I move the red ball one position down.
The problem:
If the ball is at p_bot and I want to press up, it goes to p_top. And if the ball is at p_top and I press down it goes to p_bot.
How can I fix this? This is what I'm doing. I'm not very sure if my algorythm at update(); is not good, or if it is something wrong on they key event listener.
//Keyboard event listener
var keysDown = {};
addEventListener("keydown", function (e) {
keysDown[e.keyCode] = true;
}, false);
addEventListener("keyup", function (e) {
delete keysDown[e.keyCode];
}, false);
var update = function(){
if(38 in keysDown) { //key UP
if(ball.y == p_bot){
ball.y = p_mid;
}
if(gninja.y == p_mid){
ball.y = p_top;
}
}
if(40 in keysDown) { //key DOWN
if(ball.y == p_top){
ball.y = p_mid;
}
if(gninja.y == p_mid){
ball.y = p_bot;
}
}
};
The first problem is your update is called to fast and you don't see middle pos because when you push the key in your keysDown object, it's always in and the update is all ~16ms right ?
First solutions:
If you want the player have to push 2 times on up to go from bot to top you should use only keyup like this
Remove keydown listener, remove delete in the keyup:
addEventListener("keyup", function( e ){ keysDown[ e.keyCode ] = true; }, false );
Then remove the key when update check it
if ( 40 in keysDown )
{
delete keysDown[ 40 ];
// do you old stuff here should work
}
Second solution:
Otherwise if you want to use keydown you can use timestamp to prevent events update faster than what you can see (and it's more comfortable because you can tweak it).
Before your update function
var lastCheck = Date.now();
function update()
{
if ( Date.now() - lastCheck > 200 ) // 200 is 200ms, tweak this
{
// old stuff inside
}
}
And a tip:
Then a tip I can give you it's to not use if if if if like you do and look for better solution in this case you can use array and save the index of your position inside the array just moving this index
var pos = [ 10, 50, 150 ]; // 10 is top pos and 150 bot pos
var currentPosId = 0; // player y is pos[ currentPosId ]
Then in you update function you check keys and do currentPosId++ or -- I let you find how to do it (and if you add other pos later it'll be more comfortable for tweak and adding positions).
I am trying to make a game. There are blocks falling and a main block which the user commands that is trying to avoid them. There is a point system that is supposed to add 10points each time the red cube touches one of the extremities. The problem is that it adds 10 points per each 10 milliseconds that the cube stays in the extremity. How can I solve this??
You just need a flag that you set and then clear whenever you touch the side.
Since the box starts touching the side, i initialized already_touched to true.
var already_touched = true;
Then your logic below becomes:
if (mySprite.x == 450 || mySprite.x == 0) {
if (!already_touched) {
already_touched = true;
count += 10;
}
var alert1 = document.getElementById("score");
alert1.innerHTML = "Score: " + count;
} else {
already_touched = false;
}
Working demo here: http://jsfiddle.net/KrZq9/