CodingTrain / Suggestion-Box

A repo to track ideas for topics
571 stars 86 forks source link

help me to check the collision #477

Open ICEGAMER opened 7 years ago

ICEGAMER commented 7 years ago

can you guys help me to make the collision(its in function checkBrickCollisions) with the brick so the player jumps jn them and helpe me make so the jumper jumps only once heres the code (JS)

var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d');

var jumperColor = '#660033';; var jumperXSpeed = 10; var gravity = 9.8;

var brickList = [];

var jumper = { width: 30, height: 30, x: 450, y: 50, mass: 100,

speedX: 0,
speedY: 0

}

var brick = createBrick(100, 500, 400, 20); brickList.push(brick); brick = createBrick(400, 300, 200, 20); brickList.push(brick);

registerKeyboard(); setInterval(gameController, 10);

function gameController() { draw(); move(); }

function move () { moveJumper() }

function draw () { clearCanvas(); drawJumper(); drawBricks(); GotoMidGuys(); }

function drawBricks() { for (var i = 0; i < brickList.length; i++) { var brick = brickList[i]; context.fillStyle = "#3E263A"; context.fillRect(brick.x, brick.y, brick.width, brick.height); } }

function moveJumper()
{ jumper.x += jumper.speedX; jumper.y += jumper.speedY;

jumper.speedY += 0.2;
if (jumper.speedY >= 10) {
    jumper.speedY = 10;
}

}

function getRandomCoordinate() { return Math.floor(Math.random() * squareCount + 1); }

function clearCanvas() { context.clearRect(0, 0, 600, 600); }

function drawJumper () { context.fillStyle = jumperColor; context.fillRect(jumper.x, jumper.y, jumper.width, jumper.height);
}

function GotoMidGuys() { document.getElementById("canvas").style.marginLeft = "auto"; document.getElementById("canvas").style.marginRight = "auto"; canvas.style.display = 'block'; }

function registerKeyboard() { document.addEventListener('keydown', function (event) { / key codes W = 119 S = 115 A = 65 D = 68 /

    if(event.keyCode == 87)
    {
        jumper.speedY = -10;
    }
    if(event.keyCode == 65)
    {
        jumper.speedX = -jumperXSpeed;
    }
    else if(event.keyCode == 68)
    {
        jumper.speedX = jumperXSpeed;
    }
}); 

document.addEventListener('keyup', function() {
    console.log('key up')
    if(event.keyCode == 119)
    {
    }
    if(event.keyCode == 65 || event.keyCode == 68)
    {
        jumper.speedX = 0;
    }
});

}

function createBrick(x, y, width, height) { return { width: width, height: height, x: x, y: y } }

function checkCollisions () { checkBrickcollisions(); }

function checkBrickCollisions () { for (var i = 0; i < brickList.length; i++) { var brick = brickList[i]; if (jumper.x + jumper.width >= brick.x && jumper.x <= brick.x + brick.width && jumper.y > brick.y && jumper.y <= brick.y + brick.height) { jumper.speedY -= jumper.speedY ; jumper.speedx -= jumper.speedx ; gravity -= gravity; } } }

Camto commented 7 years ago

Do the bricks have to work like the ones in Mario? Like as in you can push them upwards when you jump? Example: https://github.com/Camto/Brix

ICEGAMER commented 7 years ago

yes pls, and how did you make him jump only once when pressed on W ?

Camto commented 7 years ago

You have to make sure the player only jumps when it's touching the floor. If you look in the code, you might notice that the you object (representing the player) never actually touches anything at the end of it's update cycle. It's always at least one pixel away from everything, if not, it'd be able to jump off anything. In my code, first, the player changes it's y (you.y) position by it's y velocity (you.yv) with this.y += this.yv; and then, I check if it's colliding width any object (touching_world is set to true if it is and false if it isn't). If it's touching a brick with it's top though, push the brick upward (check in Brick.js) and push the player out of the brick, but if the brick can't go any higher, set touching_world = true; and push the player out of the brick.

Sorry the script is so complex, that's just how it is.

(btw, the brick pushing mechanism has room for improvement, but I had to figure out by myself)

Camto commented 7 years ago

Just fyi, there are some things in your code that you should modify:

I know this is a lot at once, but after a while of copy, pasting, and modifying variable names, you'll get the hang of it.

ICEGAMER commented 7 years ago

thank you ill try to understand all the code

Camto commented 7 years ago

Your welcome. Glad I could help!

ICEGAMER commented 7 years ago

hey Camto maybe you can help me ? with collision i have a problem heres my project

https://github.com/ICEGAMER/smoothjump

Camto commented 7 years ago

Hey ICEGAMER, I can see that you use p5.js as another canvas API, but what's Matter.js doing in your libraries?

Camto commented 7 years ago

I think your main problem is in how you make the 'jumper' move in moveJumper().

By the way, in jumperCollisions() (line 230) you have to replace if (jumper.y > canvas.width) by if (jumper.x > canvas.width) because the jumper can wrap around the screen to the left, but not to the right. Seriously, try it.

ICEGAMER commented 7 years ago

thank you it way a typo with a jumper and th libraries is was thinking that matter.js will make my jumps better but p5.js and matter.js make another canvas so to use then i needed to rec0de my game

Camto commented 7 years ago

The way I understand your code is:

Move cactus's x by his x velocity.
Move cactus's y by his y velocity.
If he's touching a brick:
    Stop his up or down velocity.

I can see that you put the controls in another function, but you shouldn't do that. If the controls are separate from the physics, they can de-synchronize, and that can lead to glitches. Instead, you can do that when a key event is triggered, a variable is switched on or off, but that the physics still controls the player's speed. The correct version is:

// The cactus's x movement.
If the player is pressing left:
    Change the cactus's x velocity by -1. // Go left!
If the player is pressing right:
    Change the cactus's x velocity by 1. // Go right!
Change the cactus's x velocity to itself times friction. // Slow down over time.
Move his x by his x velocity. // Actually do the moving.

If he's touching a brick:
    Move him back. // Move the cactus's x position by the negative x velocity.
    Set his x velocity to 0. // Stop his movement.
// End of the cactus's x movement.

// The cactus's y movement.
Move the cactus's y by his y velocity. // Move up or down.
If he's touching a brick:

    Move him back. // Move the cactus's y position by the negative y velocity.
    Set his y velocity to 0. // Stop his movement.

    Move the cactus down one pixel. // If he got forced out of the floor, force him back in, but if he got forced out of the ceiling, going down won't get him back into the ceiling.
    If he's touching a brick AND pressing up: // If he got forced back into the floor.
        Set his y velocity up to his maximum jump speed. // JUMP!
    Move the cactus back up one pixel.

else: // If he was never touching a brick in the FIRST place.

    Change the cactus's y velocity by the fall speed. // Make him fall.
    If he's going faster than the maximum fall speed:
        Make him go at the maximum fall speed instead.

// End of the cactus's y movement.

I use that pseudocode (words that can easily be translated to code: WikiPedia's article on pseudocode) in EVERY platformer I make that uses normal physics.

In your game, it would be:

function moveJumper() {
    // The cactus's x movement.
    if(keys[key_codes.a]) {
        jumper.speedX -= 1; // Go left!
    }
    if(keys[key_codes.d]) {
        jumper.speedX +=1; // Go right!
    }
    jumper.speedX *= 0.95; // Slow down over time.
    jumper.x += jumper.speedX; // Actually do the moving.

    var touching_brick = false;
    for(var i = 0; i < brickList.length; i++) {
        let brick = brickList[i];
        if(jumper.x < brick.x + brick.width && jumper.x + jumper.width > brick.x && jumper.y < brick.y + brick.height && jumper.y + jumper.height > brick.y) {
            touching_brick = true;
        }
    }
    if(touching_brick) {
        jumper.x -= jumper.speedX; // Move the cactus's x position by the negative x velocity.
        jumper.speedX = 0; // Stop his movement.
    }
    // End of the cactus's x movement.

    // The cactus's y movement.
    jumper.y += jumper.speedY; // Move up or down.

    var touching_brick = false;
    for(var i = 0; i < brickList.length; i++) {
        let brick = brickList[i];
        if(jumper.x < brick.x + brick.width && jumper.x + jumper.width > brick.x && jumper.y < brick.y + brick.height && jumper.y + jumper.height > brick.y) {
            touching_brick = true;
        }
    }

    if(touching_brick) {

        jumper.y -= jumper.speedY; // Move the cactus's y position by the negative y velocity.
        Set his y velocity to 0. // Stop his movement.

        jumper.y++; // If he got forced out of the floor, force him back in, but if he got forced out of the ceiling, going down won't get him back into the ceiling.

        var touching_brick = false;
        for(var i = 0; i < brickList.length; i++) {
            let brick = brickList[i];
            if(jumper.x < brick.x + brick.width && jumper.x + jumper.width > brick.x && jumper.y < brick.y + brick.height && jumper.y + jumper.height > brick.y) {
                touching_brick = true;
            }
        }

        if(touching_brick && keys[key_codes.w]) { // If he got forced back into the floor.
            jumper.speedY = 10; // JUMP!
        }
        jumper.y--;

    } else { // If he was never touching a brick in the FIRST place.

        jumper.speedY += 0.2; // Make him fall.
        if(jumper.speedY > 10) {
            jumper.speedY = 10;
        }

    }

    // End of the cactus's y movement.
}

I used the same commets in the pseudocode as in the JavaScript alternative. By the way, this script assumes you've defined keys. So you still have to do that. (Check previous answers)