I am programming collision detection in JS for a platformer. For some reason, when my character touches the ground on the top, it won't jump again. Here's my code:
if (isCollideY(platforms[i].getBoundingClientRect(), document.getElementById('spriteNotReal').getBoundingClientRect()) == true) {
if (falling == true && (jumping == false)) {
moveY = platforms[i].getBoundingClientRect().y + 3;
momentumY = 0;
onSolidGround = true;
}
}
if (event.code == 'KeyW' && (moveY <= 300)) {
moveY += 1;
move (moveX, moveY);
momentumY = momentumY + 20;
onSolidGround = false;
falling = false;
jumping = true;
}
else if (onSolidGround == false) {
if (momentumY < 0) {
falling = true;
}
else if (momentumY > 0) {
jumping = true;
}
else {
jumping = false;
}
moveX += momentumX / 3 + 1;
document.getElementById("spriteNotReal").src = "jumpmain.gif";
}
My problem was somewhat stupid. After checking the input code, I realized that the jump wasn't happening because it would only jump while on the "platform" I set up to test, not while it was actually on a platform. Here's the improved code:
if (event.code == 'KeyW' && (onSolidGround == true)) {
moveY += 1;
move (moveX, moveY);
momentumY = momentumY + 20;
onSolidGround = false;
falling = false;
jumping = true;
}
Related
I am building a platforming game in JavaScript.
For some reason, when my character lands on a platform, the character will then begin alternating between doing a very small jump, and then do a full-sized jump. I want it to do a full-sized jump every time. Why isn't this working?
Here's my code:
if (isCollideY(platforms[i].getBoundingClientRect(), document.getElementById('spriteNotReal').getBoundingClientRect()) == true) {
if (falling == true && (jumping == false)) {
moveY = platforms[i].getBoundingClientRect().y + 3;
momentumY = 0;
onSolidGround = true;
}
}
if (event.code == 'KeyW' && (onSolidGround == true)) {
momentumY = momentumY + 20;
onSolidGround = false;
falling = false;
jumping = true;
}
else if (onSolidGround == false) {
if (momentumY < 0) {
falling = true;
}
else if (momentumY > 0) {
jumping = true;
}
else {
jumping = false;
}
moveX += momentumX / 3 + 1;
document.getElementById("spriteNotReal").src = "jumpmain.gif";
}
This is most likely an issue with your booleans for jumping / falling / onSolidGround. Most likely the character is somehow being flagged as something other than
onSolidGround = true;
jumping = false;
falling = false;
When the first jump is taking place.
I am trying to make a pong like game in html, but every time one player try to move the other movement will stop.
//javaScript
var p1axis = 40;
var p2axis = 40;
function input(event)
{
var x = event.charCode || event.keyCode;
if(x == 115)
{
p1axis += 2;
document.getElementById("p1").style.top = p1axis + "%";
}
if(x == 119)
{
p1axis -= 2;
document.getElementById("p1").style.top = p1axis + "%";
}
if(x == 108)
{
p2axis += 2;
document.getElementById("p2").style.top = p2axis + "%";
}
if(x == 111)
{
p2axis -= 2;
document.getElementById("p2").style.top = p2axis + "%";
}
}
I expect that both players will be able to play freely.
instead only one can move at once.
You can create an array and add keys as they are pressed. You will have to remove them as the key is released. Also, I just used keydown with jQuery, you can also use keydown with JavaScript.
var bKeys = [];
$('body').keydown(function(e) {
if (bKeys.includes(e.which) === false) {
bKeys.push(e.which);
}
});
$('body').keyup(function(e) {
bKeys.pop(e.which);
});
setInterval(() => {
console.log(bKeys);
}, 15);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Remember to click in the body when you run the code
var k1 = false, k2 = false, k3 = false, k4 = false;
var p1axis = 40;
var p2axis = 40;
function input(event)
{
var x = event.charCode || event.keyCode;
if(x == 115 || x == 83)
{
k1 = true;
}
if(x == 119 || x == 87)
{
k2 = true;
}
if(x == 108 || x == 76)
{
k3 = true;
}
if(x == 111 || x == 79)
{
k4 = true;
}
}
function remove(event)
{
var x = event.charCode || event.keyCode;
if(x == 115 || x == 83)
{
k1 = false;
}
if(x == 119 || x == 87)
{
k2 = false;
}
if(x == 108 || x == 76)
{
k3 = false;
}
if(x == 111 || x == 79)
{
k4 = false;
}
}
function move()
{
if(k1)
{
p1axis += 1;
document.getElementById("p1").style.top = p1axis + "%";
}
if(k2)
{
p1axis -= 1;
document.getElementById("p1").style.top = p1axis + "%";
}
if(k3)
{
p2axis += 1;
document.getElementById("p2").style.top = p2axis + "%";
}
if(k4)
{
p2axis -= 1;
document.getElementById("p2").style.top = p2axis + "%";
}
setTimeout(move, 20);
}
How should I detect collisions for a sprite that can't have a rectangular hitbox? I am trying to make a platformer, and I'm currently working on collision detections for the level's platforms. Here's my physics:
function onTimerTick() {
if (moveY > 300) {
momentumY = momentumY - 2;
move(moveX, moveY);
} else if (moveY < 300) {
moveY = 300;
momentumY = 0;
move(moveX, moveY);
}
moveY = moveY + momentumY;
move(moveX, moveY);
if (moveY <= 300) {
if (momentumX > 0) {
right = true;
momentumX -= 1;
} else if (momentumX < 0) {
if (document.getElementById("spriteNotReal").getAttribute("scr") != "walkLeft.gif") {
document.getElementById("spriteNotReal").src = "walkLeft.gif";
}
right = false;
momentumX += 1;
} else {
if (right == true) {
document.getElementById("spriteNotReal").src = "amaincharacter.png";
} else {
document.getElementById("spriteNotReal").src = "maincharacterleft.png";
}
}
moveX = moveX + momentumX;
} else {
moveX += momentumX / 3 + 1;
document.getElementById("spriteNotReal").src = "jumpmain.gif";
}
document.getElementById("gold").innerHTML = momentumX;
}
I'm thinking of trying to break up the level into different rectangles, all in the same class, and then test for collisions within that class. Is there any way I could do this? Also, I think I should use boundingClientRect, but I don't know how to use this for collisions.
I have created a maze game where the user must collect all the coins in the maze, however I am trying to make an alert appear once the user has collected all the coins, not in any particular order just in general. The alert is being very troublesome at the moment and not working correctly and I'm not sure where I am going wrong based off my research into the matter. I am new to JavaScript so apologies for any clear mistakes.
EDIT I GOT TOLD TO REPHRASE MY QUESTION MORE DIRECTLY - SO THIS ISN'T A DUPLICATE QUESTION. I ALSO HAVE A MAP DECLARDED BUT CANNOT UPLOAD AS IT'S TOO MUCH CODE.
Also, when I say not working correctly, it will appear at random counts as supposed to when the last reward has been collected.
var el = document.getElementById('game');
function drawWorld(){
el.innerHTML = '';
for(var y = 0; y < map.length ; y = y + 1) {
for(var x = 0; x < map[y].length ; x = x + 1) {
if (map[y][x] === 1) {
el.innerHTML += "<div class='borders'></div>";
} else if (map[y][x] === 2) {
el.innerHTML += "<div class='reward'></div>";
} else if (map[y][x] === 3) {
el.innerHTML += "<div class='ground'></div>";
} else if (map[y][x] === 5) {
el.innerHTML += "<div class='character'></div>";
} else if (map[y][x] === 4) {
el.innerHTML += "<div class='ship'></div>";
}
}
el.innerHTML += "<br>";
}
winGame();
}
function restartGame(){
window.location.reload();
}
function winGame(){
if (!map[5].includes(2) && !map[2].includes(2) &&
!map[3].includes(2) && !map[2].includes(2) && !map[4].includes(2)
&& !map[2].includes(2))
alert("Well done!");
}
drawWorld();
document.onkeydown = function(event){
if (event.keyCode === 37){
if ( map[character.y][character.x-1] !== 1){
map[character.y][character.x] = 3;
character.x = character.x - 1;
map[character.y][character.x] = 5;
drawWorld();
}
} else if (event.keyCode === 38){
if ( map[character.y-1][character.x] !== 1){
map[character.y][character.x] = 3;
character.y = character.y - 1;
map[character.y][character.x] = 5;
drawWorld();
}
} else if (event.keyCode === 39){
if ( map[character.y][character.x+1] !== 1){
map[character.y][character.x] = 3;
character.x = character.x + 1;
map[character.y][character.x] = 5;
drawWorld();
}
} else if (event.keyCode === 40){
if ( map[character.y+1][character.x] !== 1){
map[character.y][character.x] = 3;
character.y = character.y + 1;
map[character.y][character.x] = 5;
drawWorld();
}
}
console.log(map)
}
I am working on a javascript game that involves building, destroying, and survival.
It has been working fine but after adding trees the game would randomly freeze after breaking blocks.
The code is here:
for (var bl in blocks) {
if (mouse.x >= blocks[bl].x-camera.x && mouse.y >= camera.y+blocks[bl].y && mouse.x <= blocks[bl].x-camera.x+64 && mouse.y <= camera.y+blocks[bl].y+64) {
document.body.style.cursor = "pointer";
if (mouse.down) {
if (!blocks[bl].d && blocks[bl].d !== 0) {
blocks[bl].d = 32;
} else if (blocks[bl].d > 0) {
blocks[bl].d -= 0.5;
if (tools[player.tool].n === 'axe') {
blocks[bl].d -= 1;
}
} else {
var fb = false;
for (var i in inventory) {
if (inventory[i].n === blocks[bl].n) {
inventory[i].a ++;
fb = true;
}
}
if (!fb) {
inventory.push({n: blocks[bl].n, a: 1});
}
blocks.splice(bl, 1);
}
}
}
}
I don't see any way there could be an infinite loop and no errors show up when it happens.
EDIT
I changed the code to
var spliceblock = {bl: 0, s: false};
for (var bl in blocks) {
if (mouse.x >= blocks[bl].x-camera.x && mouse.y >= camera.y+blocks[bl].y && mouse.x <= blocks[bl].x-camera.x+64 && mouse.y <= camera.y+blocks[bl].y+64) {
document.body.style.cursor = "pointer";
if (mouse.down) {
if (!blocks[bl].d && blocks[bl].d !== 0) {
blocks[bl].d = 32;
} else if (blocks[bl].d > 0) {
blocks[bl].d -= 0.5;
if (tools[player.tool].n === 'axe') {
blocks[bl].d -= 1;
}
} else {
var fb = false;
for (var i in inventory) {
if (inventory[i].n === blocks[bl].n) {
inventory[i].a ++;
fb = true;
}
}
if (!fb) {
inventory.push({n: blocks[bl].n, a: 1});
}
spliceblock.s = true;
spliceblock.bl = bl;
//blocks.splice(bl, 1);
}
}
}
}
if (spliceblock.s) {
blocks.splice(spliceblock.bl, 1);
}
but it still freezes randomly when trying to break blocks.
Modifying an array (using splice) while you're iterating through it is bound to cause problems. If you remove the block bl from the array and then continue to run through it, the counter will probably be off.
Instead, store the index of the block you're removing, then remove it after you're done looping through the blocks.