This is my JSFiddle: http://jsfiddle.net/Au6br/13/
The problem is when I keep pressing keydown.up the player jump multiple times. What I want is to define a variable called JumpCount so when the player jump if the jump variable is greater than this value the jumping stop.
Character.prototype.Jump = function () { // Jumping
character.MaxJump += gravity;
character.y += character.MaxJump;
if (keydown.up) {
if (!character.jumping) {
character.jumping = true;
character.Pos = 4;
character.Row = 2;
character.h = 23;
character.MaxJump = -character.sp * 2.5;
}
}
if (character.y >= ch - character.h) { // if the character is under the bottom
character.y = ch - character.h;
character.jumping = false;
}
};
The first problem is that you can jump when you're not on the ground. It's because of the Onground function.
Replace this :
return this.y <= ch - this.h;
With this :
return this.y >= ch - this.h;
You should also use this function in Jump to avoid duplicate code :
if (character.Onground()) { // if the character is under the bottom
character.y = ch - character.h;
character.jumping = false;
}
Counting the jumps (I assume you want to make double jumps) can't work as long as you test if(keydown.up). When you press the UP key, this value will be true for more than one frame (depending on the duration the player presses it), so you'll never be able to correctly count the number of jumps. You must bind the jump on the onkeydown event, which is called once. After that, it will be simple to replace character.jumping with an integer.
I'd do it like this:
Character.prototype.Jump = function () {
character.MaxJump += gravity;
character.y += character.MaxJump;
if (keydown.up) {
if (character.CurrentJumps < character.JumpCount) {
character.CurrentJumps++
character.Pos = 4;
character.Row = 2;
character.h = 23;
character.MaxJump = -character.sp * 2.5;
}
}
if (character.y >= ch - character.h) {
character.y = ch - character.h;
character.CurrentJumps = 0
}
};
Were JumpCount is the max jumps, and CurrentJumps is the currently done jumps
And an example to set to double jump:
character.JumpCount = 2 // 2 Jumps
How about you add a variable called jumpCount or something that you increase every time the character jumps. Only allow the character to jump if jumpCount is smaller or equal to the number of jumps you like the character to be able to do. Then just set jumpCount to zero when the player touches the floor. This also gets rid of your jumping variable since this would mean the same thing as jumpCount === 0.
Related
I am using the Zdog library to create 3d objects in javascript. In the function that controls my animations I am trying to have a particle move around randomly and then after an interval return back to its original point. Here is my code:
if (radioOn == true){
radio.zoom = size;
path = [Math.floor((Math.random() * 3 - 1)),Math.floor((Math.random() * 2)),Math.floor((Math.random() * 2 - 1))];
origin[0] += path[0];
origin[1] += path[1];
origin[2] += path[2];
lightning.translate.x += path[0];
lightning.translate.y -= path[1];
lightning.translate.z += path[2];
timer++;
}
if (timer == 20){
timer = 0;
lightning.translate.x -= origin[0];
lightning.translate.y += origin[1];
lightning.translate.z -= origin[2];
origin = [0,0,0];
}
I have put alerts in the second if statement and timer is getting reset but origin is not. Also the particle initially does what I need but after it gets reset it will no longer move.
This is a simple test case from a game in phaser.js. The ball moves to top of screen, collides, bounces down and stops because of a conditional, I set the sprite's y value and velocity to stop it falling further.
However, in the next update loop, the y value increases again, and count increases to 2.
From console.log - as ball descends y is 437,442,445, then remains on 440. I don't understand how ball.y goes beyond 440 twice, this is the entire running code. Setting bounce to 0 in conditional has no effect. It's not that console.log in the browser is out of sync with phaser update, because the count variable reports the conditional is entered twice.
var mainState = {
preload: function() {
game.load.image('ball', 'assets/ball.png');
},
create: function() {
game.physics.startSystem(Phaser.Physics.ARCADE);
game.world.enableBody = true;
ball = game.add.sprite(180, 440, 'ball');
ball.body.bounce.setTo(1);
ball.body.allowGravity = false;
ball.body.collideWorldBounds = true;
game.physics.arcade.moveToXY(ball, 160,10,350); ballstop = false;
count = 0;
},
update: function() {
console.log("ball.y " + ball.y);
if (ball.y > 440) {
ball.body.bounce.setTo(0);
ball.body.velocity.x = 0;
ball.body.velocity.y = 0;
ball.y = 440;
count = count + 1;
}
},
};
var game = new Phaser.Game(360, 640);
game.state.add('main', mainState);
game.state.start('main');
Try reseting the body.
The relevant block would look something like this:
if (ball.y > 440) {
ball.body.bounce.setTo(0);
ball.body.reset(0, 0);
//ball.body.velocity.x = 0;
//ball.body.velocity.y = 0;
ball.y = 440;
count = count + 1;
}
I've also saved a JSFiddle with this change.
I'm trying to make a basic FPS view using CSS.
Here's a demo of what I have so far: https://jsfiddle.net/w8q7xtmL/
In particular, movement is as simple as detecting keypresses, then:
// "self" is if the player object
requestAnimationFrame(step);
function step() {
if( keys[37]) self.direction += 2;
if( keys[39]) self.direction -= 2;
if( keys[38]) {
self.x += Math.cos(self.direction/180*Math.PI) * 4;
self.y -= Math.sin(self.direction/180*Math.PI) * 4;
}
if( keys[40]) {
self.x -= Math.cos(self.direction/180*Math.PI) * 4;
self.y += Math.sin(self.direction/180*Math.PI) * 4;
}
self.camera.style.transform = "rotateX(90deg) rotateZ("+(self.direction-90)+"deg) translate(-"+self.x+"px,-"+self.y+"px)";
requestAnimationFrame(step);
}
This works quite well, but there are a couple of issues.
Sometimes, elements don't stack correctly. The floor will be visible when walls should be blocking it from view, for instance.
Other times, the view will freeze completely, despite there being no errors in the console or anything that would indicate failure. It just... stops. Sometimes I can get it un-stuck by trying to move around a bit to "unstick" it, but other times I just have to reload the page.
Are there any discernible errors in my approach, or is the state of 3D transforms just not there yet for this kind of thing?
For the record, in case it matters, I'm developing with Google Chrome 49.
I can't believe I missed this.
Before:
self.camera.style.transform = "rotateX(90deg) rotateZ("+(self.direction-90)+"deg)
translate(-"+self.x+"px,-"+self.y+"px)";
After:
self.camera.style.transform = "rotateX(90deg) rotateZ("+(self.direction-90)+"deg)
translate("+(-self.x)+"px,"+(-self.y)+"px)";
Because, funnily enough, when self.x is negative, you get translate(--12px,0px) which is invalid.
I believe it is because you are detecting keys in a loop.
Instead, use this:
var rotval = 0;
window.addEventListener('keydown', function(e) {
key = e.keyCode
if(key === "left")
{
rotval = 1;
}
}, true);
window.addEventListener('keyup', function(e) {
key = e.keyCode
if(key === "left")
{
rotval = 0;
}
}, true);
then just add a variable to the loop function and when it is more or less than 0, it moves or rotates the camera!
function loop()
{
camera.rotation.y += rotval
camera.position.x //and so on
}
setInterval(loop,30)
Hope this helps :)
I don't know a lot about JS, but i have to do assignments with it. right now i have a ball that bounces from one side of the screen to the other. with every bounce the colour of the screen and the ball change. but i'd like a slight increase of speed with every bounce as well(or a random speed every time it bounces if that's easier). this is the code I have for moving, the bouncing and the colour changing now:
fill(r,g,b);
ellipse(circleX, circleY, circleSize, circleSize);
circleX += moveX;
if (circleX > width - circleSize / 2 || circleX < circleSize / 2) {
moveX = -moveX;
r = random(255);
g = random(255);
b = random(255);
}
moveX is always 5 now and changes to -5 when turning back. but i'd like it if it turned into -6 and then +7 when going forward again. or something like that at least.
I thank you guys in advance for helping me and please explain it like you're explaining it to a child.
First, lets make a function which takes a number and returns +1 for non-negative numbers (positive or 0) and -1 for negative numbers, i.e. it's sign
function sign(x) {
if (x < 0) return -1;
return 1;
}
A full implementation of sign would have a special case for 0, and is available natively in ES6
Next, when it becomes time to change moveX separate it's magnitude (absolute value) and sign, increment it's magnitude and put the two pieces back together again before flipping the sign over
moveX = -sign(moveX) * (Math.abs(moveX) + 1);
You'll want to add another test inside your collision detection code to increase the speed. If the velocity is positive, then you want to add 1. If the velocity is negative, you want to subtract 1. Your code would look something like this...
...
moveX = -moveX
if (moveX < 0) {
--moveX;
} else {
++moveX;
}
...
Keep track of how many times the circle has "bounced" and add it to the speed.
var base_speed = 5;
var bounces = 0;
var direction = 1; //positive for moving right, negative for moving left
var moveX = base_speed + bounces * direction;
circleX += moveX;
if (circleX > width - circleSize / 2 || circleX < circleSize / 2) {
direction = -direction;
bounces++;
r = random(255);
g = random(255);
b = random(255);
}
I'm making a game where you control your character with the arrow keys and attack with 'A'. My problem is that the attack has no delay so when I hold 'A' the enemy's hp depletes rapidly. How do I add delay? I tried adding delay, here is my code:
var DELAY = 2;
var cooldown = 0;
function update(time) {
// UP
if (38 in keysDown) {
player.y -= player.speed * time;
}
// DOWN
if (40 in keysDown) {
player.y += player.speed * time;
}
// LEFT
if (37 in keysDown) {
player.x -= player.speed * time;
}
// RIGHT
if (39 in keysDown) {
player.x += player.speed * time;
}
// 'A'
if(65 in keysDown) {
player.attacking = true;
cooldown -= time;
}
else
player.attacking = false;
// Collision
if( (player.x + pImage.width-5) >= monster.x &&
(player.x + pImage.width-5) < monster.x + enImage.width &&
player.y >= monster.y && player.y < (monster.y + enImage.height) &&
player.attacking)
{
if(cooldown <= 0) {
monster.hp -= player.dmg;
cooldown = DELAY;
}
if(monster.hp <= 0) {
relocEn();
}
}
}
The problem is that the cooldown counts only when I'm holding 'A' and resets only when the player is touching the monster. I want something like when I press 'A' the cooldown timer sets off. Also, I want the sprite(in attacking state) to go along with the delay and goes back to "standing" state. Thanks in advance
Here's what I would do:
I would create a variable for the time of the last attack and move all your code relevant to attacking to another function. I'm assuming time is measured in milliseconds so you're probably going to want your delay to be in the hundreds.
var DELAY = 400; //Change this to a higher value if it's not long enough.
var timeSinceLastAttack = -400; // The opposite of the DELAY if you want to attack at the start.
function update(time) {
...
// 'A'
if(65 in keysDown
&& time > (timeSinceLastAttack + DELAY) ) {
player.attack();
timeSinceLastAttack = time;
}
Then in your attack() function you can do your collision detection.
Okay,
1- Try assigning a larger value for the DELAY
2- Print the "time" value to see how much you add each loop to the DELAY if it was a big value - larger than 0.00x - divide it
Another thing:
Place the "cooldown -= time" outside the "A pressed" parentheses
It's not good, to force the user to hold the A button for a certain amount of time each time he want to shoot