Why is my collision code not working at all? - javascript

I am relatively new to JavaScript, and am looking to create a platformer game for a class project. I have tried multiple ways to make a player rectangle collide with an obstacle rectangle but none have worked the way I intended. This method that I wrote myself is not functioning at all, and I have no clue why.
var ctx = myCanvas.getContext("2d");
var fps = 50
var level = 1
var gravity = 0.5
var player = {
x: 0,
y: 0,
x_v: 0,
y_v: 0,
width: 20,
height: 20,
speed: 3,
jump: 10,
color: "blue"
}
const obstacle = {
x: 0,
y: 550,
width: 600,
height: 100,
color: "black"
}
function MyKeyUpHandler(MyEvent) {
if (MyEvent.keyCode == 37 || MyEvent.keyCode == 39) {
player.x_v = 0
}; // not left or right
if (MyEvent.keyCode == 38 || MyEvent.keyCode == 40) {
player.y_v = 0
}; // not up or down
}
function MyKeyDownHandler(MyEvent) {
if (MyEvent.keyCode == 37) {
player.x_v = -player.speed
}; // left
if (MyEvent.keyCode == 38) {
player.y_v = -player.jump
}; // up
if (MyEvent.keyCode == 39) {
player.x_v = player.speed
}; // right
MyEvent.preventDefault();
}
function renderplayer() {
player.y_v = player.y_v + gravity
player.x = player.x + player.x_v
player.y = player.y + player.y_v
ctx.fillStyle = player.color
ctx.fillRect(player.x, player.y, player.width, player.height)
}
function renderobstacle() {
ctx.fillStyle = obstacle.color
ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height)
}
function collision() {
if (player.y == obstacle.y - player.height) {
player.y_v = 0
}
}
function frameyshit() {
ctx.clearRect(0, 0, 600, 600)
renderplayer();
renderobstacle();
collision();
if (player.y >= 600) {
player.y = 1
player.x = 1
player.y_v = 0
}
}
setInterval(frameyshit, 1000 / fps)
addEventListener("keydown", MyKeyDownHandler)
addEventListener("keyup", MyKeyUpHandler)
<canvas id=myCanvas width=600 height=600 style="background-color: transparent;"> </canvas>

Related

Make an object (image) move using WASD keys

I have the code below. What I want to do is instead of a small square to move around the canvas, I want to use an image instead. In my snippet, I tried to use the drawImage function so that I could display the image I want to use. I was able to display the image but when I try to use the WASD keys, it does not move. Instead, the black square is still the one that is being controlled by the keys. Is there a way on how I can control the image using WASD keys and not the black square?
var canvas;
var context;
var ctx;
var xaxis = 10;
var yaxis = 10;
var obstacle = [];
window.onload = function() {
canvas = document.getElementById("textbox");
context = canvas.getContext("2d");
ctx = canvas.getContext("2d");
player.img.src = 'https://64.media.tumblr.com/tumblr_lkl5spPdno1qfamg6.gif'; //
canvas.width = 400;
canvas.height = 400;
drawCanv();
}
/* obstacle object */
var object = {
height: 50,
width: 50,
x: 100,
y: 100,
}
/* player object */
var player = {
height: 10,
width: 10,
img: new Image() //
};
function drawCanv() {
/* canvas */
context.beginPath();
context.fillStyle = "#ffffff";
context.fillRect(0, 0, canvas.width, canvas.height);
/* player */
context.beginPath();
context.fillStyle = "black";
context.drawImage(player.img, player.height, player.width, 10, 10); //
context.fillRect(xaxis, yaxis, player.width, player.height);
/* obstacle object */
var ndx = obstacle.push({
x: object.x,
y: object.y,
width: object.width,
height: object.height,
}) - 1;
ctx.beginPath();
ctx.fillStyle = "red";
ctx.fillRect(obstacle[ndx].x, obstacle[ndx].y, obstacle[ndx].width, obstacle[ndx].height);
}
function hitObsta(player, array) {
for (var value of array) {
if ((player.x + player.width > value.x && player.x < value.x + value.width)
&& (player.y + player.height > value.y && player.y < value.y + value.height)) {
return true;
}
}
return false;
}
function onkeydown(e) {
/* Going right*/
if (e.keyCode == 68 && xaxis + 10 < canvas.width) {
xaxis++;
var updatedCoords = (Object.assign({
x: xaxis,
y: yaxis,
}, player));
if (hitObsta(updatedCoords, obstacle)) {
xaxis--;
}
}
/* Going left*/
else if (e.keyCode == 65 && xaxis > 0) {
xaxis--;
var updatedCoords = (Object.assign({
x: xaxis,
y: yaxis,
}, player));
if (hitObsta(updatedCoords, obstacle)) {
xaxis++;
}
}
/* Going up*/
else if (e.keyCode == 87 && yaxis > 0) {
yaxis--;
var updatedCoords = (Object.assign({
x: xaxis,
y: yaxis,
}, player));
if (hitObsta(updatedCoords, obstacle)) {
yaxis++;
}
}
/* Going down*/
else if (e.keyCode == 83 && yaxis + 10 < canvas.height) {
yaxis++;
var updatedCoords = (Object.assign({
x: xaxis,
y: yaxis,
}, player));
if (hitObsta(updatedCoords, obstacle)) {
yaxis--;
}
}
//render();
drawCanv();
}
function render()
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(player.img, player.height, player.width, 10, 10); //
}
window.addEventListener("keydown", onkeydown);
<html>
<head>
<title>Canvas</title>
<style>
</style>
</head>
<body>
<canvas id="textbox" style="border: 1px solid black"></canvas>
<script src="js/app.js"></script>
</body>
</html>
You don't need the black square at all. You can just do something like this:
const image = new Image(10, 10)
image.src = 'https://64.media.tumblr.com/tumblr_lkl5spPdno1qfamg6.gif';
/* player object */
var player = {
height: 10,
width: 10,
img: image
};
function drawCanv() {
// ...
/* player */
context.beginPath();
context.drawImage(player.img, xaxis, yaxis, 10, 10); //
// ...
}

Camera movement in a 2d game

I really wanna know how to make 2d camera movement in html and javascript, so i wrote this code which is just a character and a block so i can test if the camera movement is working. This is my code:
var c = document.getElementById("screen");
var ctx = c.getContext("2d");
var rightPressed;
var leftPressed;
var x = (c.width - 75) / 2;
var speed = 10;
function block() {
ctx.fillStyle = "#fff";
ctx.fillRect(390, 225, 80, 25);
}
function character() {
ctx.fillStyle = "#00f"
ctx.fillRect(x, 250, 50, 50);
}
function keyUpHandler(event) {
if (event.keyCode == 37) {
leftPressed = false;
} else if (event.keyCode == 39) {
rightPressed = false;
}
}
function keyDownHandler(event) {
if (event.keyCode == 37) {
leftPressed = true;
} else if (event.keyCode == 39) {
rightPressed = true;
}
}
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("keydown", keyDownHandler, false);
function draw() {
ctx.clearRect(0, 0, c.width, c.height);
block();
character();
if (rightPressed && (x + 50) < c.width) {
x += speed;
} else if (leftPressed && x > 0) {
x -= speed;
}
requestAnimationFrame(draw);
}
requestAnimationFrame(draw);
#screen {
display: block;
margin: auto;
background-color: #0f0;
border: 2px solid black;
}
#headline {
text-align: center;
}
<h1 id="headline">2d Camera movement</h1>
<canvas id="screen" width="500" height="300"></canvas>
Is there anyone who knows how to do this then please tell me, also it would be nice if you could put it into this code :)
I created two classes, a Game and a Ball. The balls will move when a player presses the left or right key.
The balls know their own position and speed, the game does not care.
Just tell the ball to update according to the game's current state.
I adapted a good portion of code from here:
"Quick Tip: How to Make a Game Loop in JavaScript"
I added ES6 classes, vector support and dynamic game element support.
Demo
const canvasTxt = window.canvasTxt.default;
const KeyCodeMap = {
37: 'left',
38: 'up',
39: 'right',
40: 'down',
65: 'left',
68: 'right',
83: 'down',
87: 'up'
};
Object.assign(canvasTxt, {
align: 'left',
vAlign: 'top',
font: 'monospace',
fontSize: 24
});
const main = () => {
Game.DEBUG = true; // Enable global DEBUG mode.
const ctx = document.getElementById('screen').getContext('2d');
const game = new Game(ctx);
game.gameElements.push(...[
new Ball({
speed: new Victor(10, 0),
position: new Victor(game.getWidth() / 2, game.getHeight() / 2),
color: 'red',
size: 20
}),
new Ball({
speed: new Victor(20, 0),
position: new Victor(game.getWidth() / 2, game.getHeight() / 4),
color: 'green',
size: 30
}),
new Ball({
speed: new Victor(20, 50),
position: new Victor(100, 140),
color: 'cyan',
size: 25
}),
]);
game.redraw();
};
class Ball {
constructor(options) {
let opts = Object.assign({}, Ball.defaultOptions, options);
this.position = opts.position;
this.speed = opts.speed;
this.size = opts.size;
this.color = opts.color;
}
update(container, state) {
if (state.pressedKeys.left && !state.pressedKeys.right) {
this.position.subtract(this.speed);
}
if (state.pressedKeys.right && !state.pressedKeys.left) {
this.position.add(this.speed);
}
this.checkBounds(container); // Make sure object is in-bounds...
}
checkBounds(container) {
if (this.position.x > container.width) {
this.position.x = 0;
}
if (this.position.x < 0) {
this.position.x = container.width;
}
if (this.position.y > container.height) {
this.position.y = 0;
}
if (this.position.y < 0) {
this.position.y = container.height;
}
}
draw(ctx) {
ctx.save();
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.size / 2, 0, 2 * Math.PI, false);
ctx.fillStyle = this.color;
ctx.fill();
//ctx.lineWidth = 1;
//ctx.strokeStyle = '#000000';
ctx.stroke();
ctx.restore();
}
}
Ball.defaultOptions = {
position: new Victor(0, 0),
speed: new Victor(0, 0),
size: 1,
color: '#FFFFFF'
};
class Game {
constructor(ctx) {
this.ctx = ctx;
this.gameElements = [];
this.resize();
this.state = {
pressedKeys: {} // Capture key pressed
};
this.__lastRender = 0;
this.__animationId = null;
window.onresize = (e) => this.resize(e);
document.addEventListener('click', (e) => this.clickHandler(e), false);
document.addEventListener('keyup', (e) => this.keyUpHandler(e), false);
document.addEventListener('keydown', (e) => this.keyDownHandler(e), false);
}
clickHandler(e) {
this.isRunning() ? this.pause() : this.run(); // Pause, if running
}
keyUpHandler(event) {
let key = KeyCodeMap[event.keyCode];
delete this.state.pressedKeys[key];
}
keyDownHandler(event) {
let key = KeyCodeMap[event.keyCode];
if (key) this.state.pressedKeys[key] = true;
}
getWidth() {
return this.ctx.canvas.width;
}
getHeight() {
return this.ctx.canvas.height;
}
resize(event) {
this.ctx.canvas.width = window.innerWidth * 2
this.ctx.canvas.height = window.innerHeight * 2
}
update(progress) {
this.gameElements.forEach(gameElement => gameElement.update(this.ctx.canvas, this.state));
}
redraw() {
this.ctx.clearRect(0, 0, this.getWidth(), this.getHeight());
this.gameElements.forEach(gameElement => gameElement.draw(this.ctx));
if (Game.DEBUG) {
this.__renderDebugText(this.ctx);
}
}
/* #private */ __renderDebugText(ctx) {
ctx.save();
let text = 'DEBUG OUTPUT:\n\n' + JSON.stringify(Object.assign({
running: this.isRunning()
}, this.state), null, 2);
let offset = { x: 16, y: 16 };
let bounds = { width: 280, height: 320 };
ctx.fillStyle = 'rgba(16, 16, 16, 0.8)';
ctx.fillRect(offset.x, offset.y, bounds.width, bounds.height);
ctx.lineWidth = 1;
ctx.strokeStyle = '#333';
ctx.strokeRect(offset.x, offset.y, bounds.width, bounds.height);
ctx.fillStyle = '#FFF';
canvasTxt.drawText(ctx, text, offset.x + 4, offset.y + 4, bounds.width, bounds.height);
ctx.restore();
}
loop(timestamp) {
this.update(timestamp - this.__lastRender);
this.redraw();
this.__lastRender = timestamp;
this.__animationId = window.requestAnimationFrame((ts) => this.loop(ts));
}
isRunning() {
return this.__animationId != null;
}
run() {
this.__animationId = window.requestAnimationFrame((ts) => this.loop(ts));
}
pause() {
cancelAnimationFrame(this.__animationId);
this.__animationId = null;
this.redraw();
}
}
Game.DEBUG = false; // Default is off
main();
html,
body {
margin: 0;
padding: 0;
}
canvas {
background: #000;
height: 100%;
width: 100%;
display: block
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/victor/1.1.0/victor.min.js"></script>
<script src="https://unpkg.com/canvas-txt#2.0.6/build/index.js"></script>
<canvas id="screen" />

How to stop key input from blocking the movement of an object drawn on the canvas?

So i have a simple html5 canvas render loop and I'm handling keydown and keyup.
A rectangle drawn on the screen can move left,right, up and down.
The problem is when you move left and right in succession, the rectangle seems to stop for a very long time, like it's being interrupted and I just want it to have a more smooth transition towards the opposite direction.
Even just changing any direction causes the rectangle to stop.
here's the Jsfiddle: https://jsfiddle.net/NeuroTypicalCure/sq6czebr/39/
let canvas = document.getElementById('c');
let ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 600;
let input = {
key: null,
directions: {
up: 1.5,
down: 0.5,
left: 1,
right: 2
}
}
let player = {
x: 0,
y: 0,
direction: null,
speed: 5
}
// start
draw();
function draw(){
ctx.clearRect(0,0,canvas.width,canvas.height);
if(input.key === 'w'){
player.direction = input.directions.up;
}
if(input.key === 's'){
player.direction = input.directions.down;
}
if(input.key === 'a'){
player.direction = input.directions.left;
}
if(input.key === 'd'){
player.direction = input.directions.right;
}
// keyup -> speed 0 // else -> speed 5
if(input.key === null){
player.speed = 0;
}else{
player.speed = 5;
}
player.x += Math.cos(player.direction*Math.PI)*player.speed;
player.y += Math.sin(player.direction*Math.PI)*player.speed;
ctx.fillRect(player.x,player.y,50,50);
requestAnimationFrame(draw);
}
function handleKeyDown(e){
e.preventDefault();
input.key = e.key
}
function handleKeyUp(e){
e.preventDefault();
input.key = null;
}
window.addEventListener('keydown',handleKeyDown);
window.addEventListener('keyup',handleKeyUp);
Your problem lies with the fact that you can hold multiple keys at the same time, your logic should reflect that. i.e.:
https://jsfiddle.net/danfoord1/cr84xh2n/19/
let canvas = document.getElementById('c');
let ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 600;
let input = {
keys: [],
directions: {
up: 1.5,
down: 0.5,
left: 1,
right: 2
}
}
let player = {
x: 0,
y: 0,
directions: [],
speed: 5
}
const directions = {
'w': 1.5,
's': 0.5,
'a': 1,
'd': 2
};
// start
draw();
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// keyup -> speed 0 // else -> speed 5
if (input.keys.length === 0) {
player.speed = 0;
} else {
player.speed = 5;
}
player.directions = input.keys.map(k => directions[k]);
player.directions.forEach(d => {
player.x += Math.cos(d * Math.PI) * player.speed;
player.y += Math.sin(d * Math.PI) * player.speed;
});
ctx.fillRect(player.x, player.y, 50, 50);
requestAnimationFrame(draw);
}
function handleKeyDown(e) {
e.preventDefault();
if (input.keys.indexOf(e.key) === -1) {
input.keys.push(e.key);
}
}
function handleKeyUp(e) {
e.preventDefault();
if (input.keys.indexOf(e.key) > -1) {
input.keys.splice(input.keys.indexOf(e.key), 1);
}
}
window.addEventListener('keydown', handleKeyDown);
window.addEventListener('keyup', handleKeyUp);
The problem with your code lies in your handling of keyup events:
function handleKeyUp(e){
e.preventDefault();
input.key = null;
}
You're basically reseting input.key whenever a key is released, no matter if it's a different key than the one that initiated the move. So if you press two keys and then release one, it will reset input.key (until your computer sent another keydown event - if you're still holding down the key). This can be fixed with a simple check if the keyup event belongs to the current input.key.
function handleKeyUp(e){
e.preventDefault();
if (e.key === input.key) input.key = null;
}
Here's a code snippet:
let canvas = document.getElementById('c');
let ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 600;
let input = {
key: null,
directions: {
up: 1.5,
down: 0.5,
left: 1,
right: 2
}
}
let player = {
x: 0,
y: 0,
direction: null,
speed: 5
}
// start
draw();
function draw(){
ctx.clearRect(0,0,canvas.width,canvas.height);
if(input.key === 'w'){
player.direction = input.directions.up;
}
if(input.key === 's'){
player.direction = input.directions.down;
}
if(input.key === 'a'){
player.direction = input.directions.left;
}
if(input.key === 'd'){
player.direction = input.directions.right;
}
// keyup -> speed 0 // else -> speed 5
if(input.key === null){
player.speed = 0;
}else{
player.speed = 5;
}
player.x += Math.cos(player.direction*Math.PI)*player.speed;
player.y += Math.sin(player.direction*Math.PI)*player.speed;
ctx.fillRect(player.x,player.y,50,50);
requestAnimationFrame(draw);
}
function handleKeyDown(e){
e.preventDefault();
input.key = e.key
}
function handleKeyUp(e){
e.preventDefault();
if (e.key === input.key) input.key = null;
}
window.addEventListener('keydown',handleKeyDown);
window.addEventListener('keyup',handleKeyUp);
canvas{
border: 1px solid aqua;
}
<!DOCTYPE html>
<html>
<body>
<canvas id="c"></canvas>
</body>
</html>

2D Platform shooter Canvas game | Creating the shooting function

So I'm making this pretty basic game I would say for a school project. I have all the basic controllers working, jumping, navigating left and right, but I'm struggling to find a way to make the character be able to shoot. I would also like to make it so it's like a break between each shoot, like a bolt action. The collision part shouldn't be a problem, so no need for help there.
(function() {
var requestAnimationFrame =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
})();
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
width = 640,
height = 480,
player = {
x: width / 2,
y: height - 140,
width: 35,
height: 90,
speed: 3,
velX: 0,
velY: 0,
jumping: false,
grounded: false
},
keys = [],
friction = 0.8,
gravity = 0.3;
var hovedkarakterBilde = new Image();
hovedkarakterBilde.src = "mc1.png";
var boxes = [];
// dimensions
boxes.push({
// venstre vegg
x: 0,
y: 0,
width: 10,
height: height
});
boxes.push({
// gulv
x: 0,
y: height - 68,
width: width,
height: 1
});
boxes.push({
x: 120,
y: 250,
width: 80,
height: 80
});
boxes.push({
x: 170,
y: 275,
width: 80,
height: 80
});
boxes.push({
x: 220,
y: 325,
width: 80,
height: 80
});
boxes.push({
x: 270,
y: 225,
width: 40,
height: 40
});
canvas.width = width;
canvas.height = height;
function update() {
// check keys
if (keys[38]) {
// up arrow or space
if (!player.jumping && player.grounded) {
player.jumping = true;
player.grounded = false;
player.velY = -player.speed * 2;
}
}
if (keys[39]) {
// right arrow
if (player.velX < player.speed) {
player.velX++;
}
}
if (keys[37]) {
// left arrow
if (player.velX > -player.speed) {
player.velX--;
}
}
player.velX *= friction;
player.velY += gravity;
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = "black";
ctx.beginPath();
player.grounded = false;
for (var i = 0; i < boxes.length; i++) {
ctx.rect(boxes[i].x, boxes[i].y, boxes[i].width, boxes[i].height);
var dir = colCheck(player, boxes[i]);
if (dir === "l" || dir === "r") {
player.velX = 0;
player.jumping = false;
} else if (dir === "b") {
player.grounded = true;
player.jumping = false;
} else if (dir === "t") {
player.velY *= -1;
}
}
if (player.grounded) {
player.velY = 0;
}
player.x += player.velX;
player.y += player.velY;
ctx.fill();
ctx.drawImage(
hovedkarakterBilde,
player.x,
player.y,
player.width,
player.height
);
requestAnimationFrame(update);
}
function colCheck(shapeA, shapeB) {
// get the vectors to check against
var vX = shapeA.x + shapeA.width / 2 - (shapeB.x + shapeB.width / 2),
vY = shapeA.y + shapeA.height / 2 - (shapeB.y + shapeB.height / 2),
// add the half widths and half heights of the objects
hWidths = shapeA.width / 2 + shapeB.width / 2,
hHeights = shapeA.height / 2 + shapeB.height / 2,
colDir = null;
// if the x and y vector are less than the half width or half height, they
we must be inside the object, causing a collision
if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) {
// figures out on which side we are colliding (top, bottom, left, or right)
var oX = hWidths - Math.abs(vX),
oY = hHeights - Math.abs(vY);
if (oX >= oY) {
if (vY > 0) {
colDir = "t";
shapeA.y += oY;
} else {
colDir = "b";
shapeA.y -= oY;
}
} else {
if (vX > 0) {
colDir = "l";
shapeA.x += oX;
} else {
colDir = "r";
shapeA.x -= oX;
}
}
}
return colDir;
}
document.body.addEventListener("keydown", function(e) {
keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function(e) {
keys[e.keyCode] = false;
});
window.addEventListener("load", function() {
update();
});
HTML:
</head>
<body>
<canvas id="canvas" style="background: url('bakgrunn1.png')"></canvas>
</body>
<script src="spillv2.js"></script>
First thing you have to consider is if the bullet is hit-scan or projectile. Hit-scan means when the bullet is shot, the bullet instantly hits the target. This can be done by using a ray-cast to check if it hits an object. Projectile based bullets are when the user points in a direction, the bullet actually "moves". This can be implemented by adding an array of "bullets" to the player. So when the player clicks, a bullet object is added the array. This bullet object will be drawn on it's own in the draw loop and will move from the user to the direction it's pointed at.
Adding a delay is simple, you can have a "cooldown" variable that is a counter that lasts for n milliseconds. When the user fires, the counter is set to n and starts to count down to 0. When it reaches 0, you are able to fire again.
Well, you could make a shoot(e) function, which will be called when user presses (keydown) space for example and then make a new array, lets say ammo[]. Then, inside shoot() you will do something like:
const ammo = [];
let shooting = false;
function shoot(e) {
e = e || event;
const key = e.keyCode;
if(shooting) return; // This will prevent from shooting more bullets while holding space
// So you'd need to press space for each time you want to shoot.
if(key == 32) { // Key code 32 is SPACE
shooting = true;
// You get the coordinates from your player, from which the bullet will shoot
ammo.push({
x: player.x,
y: player.y + (player.height / 2)
// Player.height / 2 is basically setting the ammo at the middle of the character
});
}
}
And then, I presume you do all the updates in the update() function (yea, logically :D), you'll do something like:
function update() {
// Insert it somewhere
for(let i = 0; i < ammo.length; i++) {
// The "theBullet" part refers to either your image for the bullet
ctx.drawImage(theBullet, ammo[i].x, ammo[i].y;
ammo[i].x++ // Or however fast you'd like it to go.
}
}
Hope its somewhat clear, I am working myself on a spaceshooter type of game, almost finished, so shared some of my code here :) Not implying that its the best, but it does the work :)

Canvas Rectangle & Ball Collision Not working

I'm making a html5 canvas game and I have a problem with the collision.
The problem is when the ball collides with any platform, the ball gravity should be -1 and go up as the same velocity as the platforms but it only works with the last platform and the left one. How can I fix it? Thanks!
HTML:
<html>
<head>
<title>Falldown</title>
</head>
<body>
<canvas id="canvas" width = "380" height= "640"></canvas>
<script src="beta.js"></script>
</body>
</html>
JS Code:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var isMenu = true;
var isPlaying = false;
var testing = true;
var pressingLeft = false;
var pressingRight = false;
var Platforms = [];
var difficulty = 1;
var gravity = 1;
var Player = {
color: "red",
radius: 7.5,
stepY: 1.5,
x: 175,
y: 75
};
function RectCircleColliding(circle, rect) {
var distX = Math.abs(circle.x - rect.x - rect.width / 2);
var distY = Math.abs(circle.y - rect.y - 20 / 2);
if (distX > (rect.width / 2 + circle.radius)) return false;
if (distY > (20 / 2 + circle.radius)) return false;
if (distX <= (rect.width / 2)) return true;
if (distY <= (20 / 2)) return true;
var dx = distX - rect.width / 2;
var dy = distY - 20 / 2;
return (dx * dx + dy * dy <= (circle.radius * circle.radius));
}
function drawBackground() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
if (isMenu && !isPlaying) {
createText("60px monospace", "white", "FallDown", 45, 130);
createText("34px Arial", "white", "PLAY", 130, 260);
createText("34px Arial", "white", "LEADERBOARD", 50, 340);
createText("34px Arial", "white", "SETTINGS", 90, 420);
} else {
if (testing) {
Platforms = [];
for (var i = 0; i < 13; i++) {
Platforms.push({
"x": 10,
"y": 160 + (i * 70),
"width": (Math.random() * canvas.width) - 60
});
}
testing = false;
}
for (var i in Platforms) {
ctx.fillStyle = "#00ffff";
ctx.fillRect(10, Platforms[i].y, Platforms[i].width, 20);
var totalTest = Platforms[i].width + 60;
ctx.fillRect(totalTest + 30, Platforms[i].y, canvas.width - totalTest, 20);
Platforms[i].y -= 1;
if (RectCircleColliding(Player, Platforms[i])) {
gravity = -1;
} else {
gravity = 1;
}
}
detectBorderCollision();
detectPlayerCollision();
drawPlayer();
drawBorder();
if (Platforms.length === 7) Platforms = [];
}
}
function detectBorderCollision() {
if (Player.x > 370 - Player.radius) {
Player.x = 370 - Player.radius;
} else if (Player.x < 3.8 + Player.radius * 2) {
Player.x = 3.8 + Player.radius * 2
}
}
function detectPlayerCollision() {
}
function drawPlayer() {
ctx.beginPath();
ctx.fillStyle = Player.color;
ctx.arc(Player.x, Player.y, Player.radius, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
Player.y += gravity;
if (pressingRight) {
Player.x += 2;
} else if (pressingLeft) {
Player.x -= 2;
}
/*
ctx.fillStyle = "#00ffff";
ctx.fillRect(10, 160, 300, 20);
*/
}
function drawBorder() {
ctx.beginPath();
ctx.strokeStyle = "#00ffff";
ctx.lineWidth = 10;
ctx.moveTo(5, 0);
ctx.lineTo(5, 640);
ctx.moveTo(375, 0);
ctx.lineTo(375, 640);
ctx.stroke();
ctx.closePath();
}
function createText(font, color, value, posX, posY) {
ctx.font = font;
ctx.fillStyle = color;
ctx.fillText(value, posX, posY)
}
function isInside(realX, realY, x1, x2, y1, y2) {
return (realX > x1 && realX < x2) && (realY > y1 && realY < y2)
}
function drawGame() {
drawBackground();
}
function startDrawing() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawGame();
requestAnimationFrame(startDrawing);
}
function Init() {
requestAnimationFrame(startDrawing);
canvas.addEventListener("click", function(evt) {
var rect = canvas.getBoundingClientRect();
var mouseX = evt.clientX - rect.left;
var mouseY = evt.clientY - rect.top;
if (isMenu && !isPlaying) {
if (isInside(mouseX, mouseY, 115, 230, 220, 270)) {
isPlaying = true;
isMenu = false;
} else if (isInside(mouseX, mouseY, 35, 320, 300, 345)) {
console.log("Leaderboard");
} else if (isInside(mouseX, mouseY, 75, 270, 380, 430)) {
console.log("Settings");
}
}
});
window.addEventListener("keydown", function(evt) {
if (!isMenu && isPlaying) {
if (evt.keyCode === 39) { // right
pressingRight = true;
} else if (evt.keyCode === 37) { // left
pressingLeft = true;
}
}
});
window.addEventListener("keyup", function(evt) {
if (!isMenu && isPlaying) {
if (evt.keyCode === 39) { // right
pressingRight = false;
} else if (evt.keyCode === 37) { // left
pressingLeft = false;
}
}
});
}
Init();
There are so many magic numbers in your code that debugging it is difficult and tedious. Replace all the number literals with identifiers which describe what the values represent.
The following amendment to part of the drawBackground function causes all the collisions with left hand platforms to work, but not perfectly.
var hasCollided;
for (var i in Platforms) {
ctx.fillStyle = "#00ffff";
ctx.fillRect(10, Platforms[i].y, Platforms[i].width, 20);
var totalTest = Platforms[i].width + 60;
ctx.fillRect(totalTest + 30, Platforms[i].y, canvas.width - totalTest, 20);
Platforms[i].y -= 1;
if (!hasCollided) {
if (RectCircleColliding(Player, Platforms[i])) {
gravity = -1;
hasCollided = true;
} else {
gravity = 1;
}
}
}

Categories

Resources