I'm having trouble blocking the player's path they already went through. I have the player leave a trail of slime that there are not suppose to go through. I'm using sublime text
// Put your global variables after this line
var GRIDWIDTH, GRIDHEIGHT;
GRIDWIDTH = 11;
GRIDHEIGHT = 13;
var player = new Object();
player.x = 0;
player.y = 0;
var reset = 0x0052;
var GAME_WON = false;
var foodValue = 1;
var PlayerInventory = {
key: 0,
food: 0,
foodLeft: 0,
}
// Put your function definitions after this line
function drawPlayer(x, y) {
PS.color(x, y, PS.COLOR_GREEN);
PS.glyphColor(x, y, PS.COLOR_WHITE);
PS.glyph(x, y, "ඬ");
player.x = x;
player.y = y;
}
function drawSlime(x, y, dir) {
PS.color(x, y, PS.COLOR_GREEN);
PS.data(x, y, dir);
PS.data(x, y, "wall")
}
function PlaceKey(x, y) {
PS.color(x, y, PS.COLOR_YELLOW);
PS.glyphColor(x, y, PS.COLOR_ORANGE);
PS.glyph(x, y, "K")
PS.data(x, y, "key");
}
function removePlayer(x, y) {
PS.glyph(x, y, 0);
}
function isInGrid(x, y) {
if (x < 0) return false;
else if (x >= GRIDWIDTH) return false;
else if (y < 0) return false;
else if (y >= GRIDHEIGHT) return false;
else return true;
}
function CreateButtons() {
PS.glyph(5, 12, reset);
PS.data(5, 12, "resetbutton");
}
function DrawInventory() {
PS.statusText(" key: " + PlayerInventory.key + "food: " + PlayerInventory.food);
}
function PlaceFood(x, y) {
PS.glyph(x, y, 0x25CE);
PS.glyphColor(x, y, 0xBA9A19);
PS.data(x, y, "food");
PlayerInventory.foodLeft += foodValue;
}
// PS.keyDown ( key, shift, ctrl, options )
// Called when a key on the keyboard is pressed
PS.keyDown = function(key, shift, ctrl, options) {
"use strict";
// Uncomment the following line to inspect parameters
// PS.debug( "PS.keyDown(): key = " + key + ", shift = " + shift + ", ctrl = " + ctrl + "\n" );
// Add code here for when a key is pressed
if (GAME_WON) {
GameSetup();
} else {
var oldX = player.x;
var oldY = player.y;
// Moves the player in the game with the key arrow
if (key == PS.KEY_ARROW_RIGHT && (player.x < (GRIDWIDTH - 1)))
player.x += 1;
else if (key == PS.KEY_ARROW_LEFT && (player.x > 0))
player.x -= 1;
else if (key == PS.KEY_ARROW_UP && (player.y > 0))
player.y -= 1;
else if (key == PS.KEY_ARROW_DOWN && (player.y < (GRIDHEIGHT - 1)))
player.y += 1;
var dataAtPlayer = PS.data(player.x, player.y);
if (dataAtPlayer == "wall") {
player.x = oldX;
player.y = oldY;
}
if (dataAtPlayer == "drawSlime") {
player.x = oldX;
player.y = oldY;
}
if (dataAtPlayer == "leaf") {
if (PlayerInventory.key > -0) {
PS.audioPlay("fx_blast4");
DrawInventory();
} else {
player.x = oldX;
player.y = oldY;
}
}
if (dataAtPlayer == "key") {
PlayerInventory.key += 1;
DrawInventory();
PS.audioPlay("fx_pop");
}
if (dataAtPlayer == "food") {
PlayerInventory.foodLeft -= foodValue;
PlayerInventory.foods += foodValue;
DrawInventory();
PS.audioPlay("fx_tada");
if (PlayerInventory.foodLeft == 0) {
GAME_WON = true;
PS.statusText("Click R to restar!");
}
}
drawPlayer(player.x, player.y);
}
};
I tried to fix this issue by changing the code to this:
// WASD keys to move The Snail
if (key == 119) {
//Check that up isn’t a wall
//Check that up isn’t off the screen
if (player.y - 1 >= 0) {
if (PS.data(player.x, player.y - 1) != "wall") {
//If both are true, remove player from current position
//If both are true, draw player in new position
removePlayer(player.x, player.y);
drawPlayer(player.x, player.y - 1);
drawSlime(player.x, player.y);
}
}
}
if (key == 115) {
//Check that down isn’t a wall
//Check that down isn’t off the screen
if (player.y + 1 < GRIDHEIGHT) {
if (PS.data(player.x, player.y + 1) != "wall") {
//If both are true, remove player from current position
//If both are true, draw player in new position
removePlayer(player.x, player.y);
drawPlayer(player.x, player.y + 1);
drawSlime(player.x, player.y);
}
}
}
if (key == 97) {
//Check that left isn’t a wall
//Check that left isn’t off the screen
if (player.x - 1 >= 0) {
if (PS.data(player.x - 1, player.y) != "wall") {
//If both are true, remove player from current position
//If both are true, draw player in new position
removePlayer(player.x, player.y);
drawPlayer(player.x - 1, player.y);
drawSlime(player.x, player.y);
}
}
}
if (key == 100) {
//Check that right isn’t a wall
//Check that right isn’t off the screen
if (player.x + 1 < GRIDWIDTH) {
if (PS.data(player.x + 1, player.y) != "wall") {
//If both are true, remove player from current position
//If both are true, draw player in new position
removePlayer(player.x, player.y);
drawPlayer(player.x + 1, player.y);
drawSlime(player.x, player.y);
}
}
}
And while this worked, I wasn't able to interact with the items in the game,
Related
I'm trying to make a program where the user moves with a circle using the keyboard to collect coins. What I tried so far is using an if statement to see if they collide and if they do, the user gets 1 coin and the image disappears. When I try this method, the code runs normally, but the collision doesn't happen.
/* Credit: https://openprocessing.org/sketch/525131
*/
var left, right, up, down;
var coin = [];
var player, posX, posY, radius, speed, colour, gameScreen, coins;
function setup() {
createCanvas(400, 400);
left = right = up = down = false;
gameScreen = "game";
coins = 0;
for (var i = 0; i < 10; i++) {
coin[i] = new Coin(random(width), random(height), 20, 20);
}
player = new Player();
}
function game() {
background(0);
if (left == true) {
player.moveLeft();
}
if (right == true) {
player.moveRight();
}
if (up == true) {
player.moveUp();
}
if (down == true) {
player.moveDown();
}
for (var i = 0; i < 10; i++) {
coin[i].display();
}
player.display();
//player.collision();
fill(255);
textSize(20);
text("Coins: " + coins, 10, 30);
}
function draw() {
game();
}
function keyPressed() {
// if (keyPressed) { For Processing add this line
if (keyCode == LEFT_ARROW || key == 'a') {
left = true;
}
if (keyCode == RIGHT_ARROW || key == 'd') {
right = true;
}
if (keyCode == UP_ARROW || key == 'w') {
up = true;
}
if (keyCode == DOWN_ARROW || key == 's') {
down = true;
}
// }
}
function keyReleased() {
if (keyCode == LEFT_ARROW || key == 'a') {
left = false;
}
if (keyCode == RIGHT_ARROW || key == 'd') {
right = false;
}
if (keyCode == UP_ARROW || key == 'w') {
up = false;
}
if (keyCode == DOWN_ARROW || key == 's') {
down = false;
}
}
function Coin(coinX, coinY, coinR) {
this.img = loadImage("https://www.paulwheeler.us/files/Coin120.png");
this.coinX = coinX;
this.coinY = coinY;
this.coinR = coinR;
this.display = function() {
image(this.img, this.coinX, this.coinY, this.coinR, this.coinR);
}
}
function Player() {
this.posX = width / 2;
this.posY = height / 2;
this.radius = 10;
this.speed = 4;
this.colour = "blue";
this.display = function() {
fill(this.colour);
ellipse(this.posX, this.posY, this.radius * 2, this.radius * 2);
}
this.moveLeft = function() {
// posX = posX - speed;
this.posX = constrain(this.posX - this.speed, this.radius, width - this.radius);
}
this.moveRight = function() {
// posX = posX + speed;
this.posX = constrain(this.posX + this.speed, this.radius, width - this.radius);
}
this.moveUp = function() {
// posY = posY-speed;
this.posY = constrain(this.posY - this.speed, this.radius, height - this.radius);
}
this.moveDown = function() {
// posY = posY+speed;
this.posY = constrain(this.posY + this.speed, this.radius, height - this.radius);
}
/*this.collision = function(){
if (this.posX > this.coinX && this.posX < this.coinX + this.coinR && this.posY > this.coinY && this.posY < this.coinY + this.coinR){
coins+=1;
//Coin disappears
}
}
*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
You can use dist() in p5 to determine the distance between the center of the two circles and then see if it smaller than the two radi combined. Once you have that you can execute whatever code is needed.
for (let i = 0; i < coin.length; i++) {
if (
dist(player.posX, player.posY, coin[i].coinX, coin[i].coinY) <
player.radius + coin[i].coinR
) {
coin.splice(i, 1);
coins++;
i--;
}
}
Snippet
/* Credit: https://openprocessing.org/sketch/525131
*/
var left, right, up, down;
var coin = [];
var player, posX, posY, radius, speed, colour, gameScreen, coins;
function setup() {
createCanvas(400, 400);
left = right = up = down = false;
gameScreen = "game";
coins = 0;
for (var i = 0; i < 10; i++) {
coin[i] = new Coin(random(400), random(400), 20);
}
player = new Player();
}
function game() {
background(0);
if (left == true) {
player.moveLeft();
}
if (right == true) {
player.moveRight();
}
if (up == true) {
player.moveUp();
}
if (down == true) {
player.moveDown();
}
//change to coin.length to prevent error
for (var i = 0; i < coin.length; i++) {
coin[i].display();
}
player.display();
//player.collision();
fill(255);
textSize(20);
text("Coins: " + coins, 10, 30);
for (let i = 0; i < coin.length; i++) {
if (
dist(player.posX, player.posY, coin[i].coinX, coin[i].coinY) <
player.radius + coin[i].coinR
) {
coin.splice(i, 1);
coins++;
i--;
}
}
}
function draw() {
game();
}
function keyPressed() {
// if (keyPressed) { For Processing add this line
if (keyCode == LEFT_ARROW || key == "a") {
left = true;
}
if (keyCode == RIGHT_ARROW || key == "d") {
right = true;
}
if (keyCode == UP_ARROW || key == "w") {
up = true;
}
if (keyCode == DOWN_ARROW || key == "s") {
down = true;
}
// }
}
function keyReleased() {
if (keyCode == LEFT_ARROW || key == "a") {
left = false;
}
if (keyCode == RIGHT_ARROW || key == "d") {
right = false;
}
if (keyCode == UP_ARROW || key == "w") {
up = false;
}
if (keyCode == DOWN_ARROW || key == "s") {
down = false;
}
}
function Coin(coinX, coinY, coinR) {
/*this.img = loadImage(
"https://www.searchpng.com/wp-content/uploads/2019/04/Game-Coins-PNG-jpeg-715x715.png"
);*/
this.coinX = coinX;
this.coinY = coinY;
this.coinR = coinR;
this.colour = "yellow";
this.display = function () {
fill(this.colour);
ellipse(this.coinX, this.coinY, this.coinR * 2, this.coinR * 2);
};
}
function Player() {
this.posX = width / 2;
this.posY = height / 2;
this.radius = 10;
this.speed = 4;
this.colour = "blue";
this.display = function () {
fill(this.colour);
ellipse(this.posX, this.posY, this.radius * 2, this.radius * 2);
};
this.moveLeft = function () {
// posX = posX - speed;
this.posX = constrain(
this.posX - this.speed,
this.radius,
width - this.radius
);
};
this.moveRight = function () {
// posX = posX + speed;
this.posX = constrain(
this.posX + this.speed,
this.radius,
width - this.radius
);
};
this.moveUp = function () {
// posY = posY-speed;
this.posY = constrain(
this.posY - this.speed,
this.radius,
height - this.radius
);
};
this.moveDown = function () {
// posY = posY+speed;
this.posY = constrain(
this.posY + this.speed,
this.radius,
height - this.radius
);
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js" integrity="sha512-N4kV7GkNv7QR7RX9YF/olywyIgIwNvfEe2nZtfyj73HdjCUkAfOBDbcuJ/cTaN04JKRnw1YG1wnUyNKMsNgg3g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
Your collision function was trying to access this.coinX, this.coinY, and this.coinR but it was defined on Player which doesn't have any of those properties. You need to use a loop to check each coin for collision:
this.collision = function() {
for (let ix = 0; ix < coin.length; ix++) {
const currentCoin = coin[ix];
if (this.posX > currentCoin.coinX &&
this.posX < currentCoin.coinX + currentCoin.coinR &&
this.posY > currentCoin.coinY &&
this.posY < currentCoin.coinY + currentCoin.coinR) {
coins += 1;
// Coin disappears:
// delete the current coin from the array
coin.splice(ix, 1);
// Since the coin that was at ix + 1 is now at position ix in
// the coin array, we need to set ix back by one.
ix--;
}
}
}
/* Credit: https://openprocessing.org/sketch/525131
*/
var left, right, up, down;
var coin = [];
var player, posX, posY, radius, speed, colour, gameScreen, coins;
function setup() {
createCanvas(400, 400);
left = right = up = down = false;
gameScreen = "game";
coins = 0;
for (var i = 0; i < 10; i++) {
coin[i] = new Coin(random(width), random(height), 20, 20);
}
player = new Player();
}
function game() {
background(0);
if (left == true) {
player.moveLeft();
}
if (right == true) {
player.moveRight();
}
if (up == true) {
player.moveUp();
}
if (down == true) {
player.moveDown();
}
for (var i = 0; i < coin.length; i++) {
coin[i].display();
}
player.display();
player.collision();
fill(255);
textSize(20);
text("Coins: " + coins, 10, 30);
}
function draw() {
game();
}
function keyPressed() {
// if (keyPressed) { For Processing add this line
if (keyCode == LEFT_ARROW || key == 'a') {
left = true;
}
if (keyCode == RIGHT_ARROW || key == 'd') {
right = true;
}
if (keyCode == UP_ARROW || key == 'w') {
up = true;
}
if (keyCode == DOWN_ARROW || key == 's') {
down = true;
}
// }
}
function keyReleased() {
if (keyCode == LEFT_ARROW || key == 'a') {
left = false;
}
if (keyCode == RIGHT_ARROW || key == 'd') {
right = false;
}
if (keyCode == UP_ARROW || key == 'w') {
up = false;
}
if (keyCode == DOWN_ARROW || key == 's') {
down = false;
}
}
function Coin(coinX, coinY, coinR) {
this.img = loadImage("https://www.paulwheeler.us/files/Coin120.png");
this.coinX = coinX;
this.coinY = coinY;
this.coinR = coinR;
this.display = function() {
image(this.img, this.coinX, this.coinY, this.coinR, this.coinR);
}
}
function Player() {
this.posX = width / 2;
this.posY = height / 2;
this.radius = 10;
this.speed = 4;
this.colour = "blue";
this.display = function() {
fill(this.colour);
ellipse(this.posX, this.posY, this.radius * 2, this.radius * 2);
}
this.moveLeft = function() {
// posX = posX - speed;
this.posX = constrain(this.posX - this.speed, this.radius, width - this.radius);
}
this.moveRight = function() {
// posX = posX + speed;
this.posX = constrain(this.posX + this.speed, this.radius, width - this.radius);
}
this.moveUp = function() {
// posY = posY-speed;
this.posY = constrain(this.posY - this.speed, this.radius, height - this.radius);
}
this.moveDown = function() {
// posY = posY+speed;
this.posY = constrain(this.posY + this.speed, this.radius, height - this.radius);
}
this.collision = function() {
for (let ix = 0; ix < coin.length; ix++) {
const currentCoin = coin[ix];
if (this.posX > currentCoin.coinX &&
this.posX < currentCoin.coinX + currentCoin.coinR &&
this.posY > currentCoin.coinY &&
this.posY < currentCoin.coinY + currentCoin.coinR) {
coins += 1;
// Coin disappears:
// delete the current coin from the array
coin.splice(ix, 1);
// Since the coin that was at ix + 1 is now at position ix in
// the coin array, we need to set ix back by one.
ix--;
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
I've been experementing with 2d rectangular collision but i stumbled into an error i can't fix, even after over an hour of tweaking.
Collision works fine up, down and left. but the right causes the player to go up to the y value of the collision. The code is the exact same as the left site (correctly mirrored. I think)
var player = new Player(50,50,100,0.3,false,0,0)
var playerCollision = new Collision(player.x,player.y,64,64);
var ground = new Collision(0,500,300,100);
var wall = new Collision(200,400,100,100);
var wall2 = new Collision(0,400,100,100);
var collisions = [ground,wall,wall2];
for (i=0;i<collisions.length;i++) {
if (collisions[i].checkCollision(playerCollision)) {
if (collisions[i].x - playerCollision.x > 0 && playerCollision.x + playerCollision.width > collisions[i].x-1 && playerCollision.y+playerCollision.height-20 > collisions[i].y) {
player.dx = 0;
player.x = collisions[i].x-64;
} else if ((collisions[i].x + collisions[i].width)- playerCollision.x < 0 && playerCollision.x < collisions[i].x+collisions[i].width+1 && playerCollision.y+playerCollision.height-20 > collisions[i].y) {
player.dx = 0;
player.x = collisions[i].x+collisions[i].width;
} else if (collisions[i].y - playerCollision.y+playerCollision.height > 0) {
player.dy = 0;
player.y = collisions[i].y-64;
} else if ((collisions[i].y+collisions[i].height) - playerCollision.y < 0) {
player.dy = 0;
player.y = collisions[i].y+collisions[i].height;
}
}
}
Collision.js:
function Collision(x,y,width,height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.checkCollision = function(other) {
if (this.x < other.x + other.width &&
this.x + this.width > other.x &&
this.y < other.y + other.height &&
this.height + this.y > other.y) {
return true
} else {
return false;
}
}
this.show = function() {
ctx.strokeStyle = "#38ff35";
ctx.strokeRect(this.x,this.y,this.width,this.height);
}
}
EDIT:
changed some code (didn't fix the problem tho)
obj1
position = (0, 0)
dimensions = (2, 0)
obj2
position = (2, 0)
dimensions = (2, 0)
0 < 2 + 2 = true
0 + 2 > 2 = false
this already shows that your check doesn't mathematically make sense. These two blocks should be overlapping but return false
Try:
if (this.x + this.width < other.x - other.width ||
this.x - this.width > other.y + other.width ||
this.y + this.height < other.y - other.height ||
this.y - this.height > other.y + other.height)
{
no collisions
}
I made this basic game where I drew a map and a player, the player can move anywhere but how can I make so that it wont move when its on the tile[1] in the map?
also when I try to check if the player.x is greater than 50 it could go left it works but than if I click 2 keys at once it goes through
const context = document.querySelector("canvas").getContext("2d");
var rgb = 'rgb(' + Math.random()*256 + ',' + Math.random()*256 + ',' + Math.random()*256 + ','+Math.random() + ')';
document.onload = Loop();
var width = 1500;
var height = 800;
function Loop(){
var width = 1500;
var height = 800;
context.canvas.height = height;
context.canvas.width = width;
this.interval = setInterval(Update, 1000/100);
}
const Player = function(x, y, w, h, color) {
this.x = x; this.y = y; this.w = w; this.h = h;
this.speedY = 0; this.speedX = 0;
this.Draw = function(){
context.fillStyle = this.color;
context.fillRect(this.x, this.y, this.w, this.h);
};
this.Move = function(){
this.x += this.speedX;
this.y += this.speedY;
};
};<code>
var player = new Player(100,100,50, 50, rgb);
var Key = {};
function Update(){
context.clearRect(0, 0, width, height);
Map();
player.Draw();
player.Move();
onkeydown = onkeyup = function(e){
player.speedX = 0;
player.speedY = 0;
e = e || event;
Key[e.keyCode] = e.type == 'keydown';
if(Key[37] || Key[65]) {player.speedX -= 2}
if(Key[38] || Key[87]) {player.speedY -= 2}
if(Key[39] || Key[68]) {player.speedX += 2}
if(Key[40] || Key[83]) {player.speedY += 2}
if(Key[32]) {player.color = 'rgb(' + Math.random()*256 + ',' + Math.random()*256 + ',' + Math.random()*256 + ','+Math.random()*1 + ')';}
};
}
var map = [
1, 1, 1, 1, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1
];
var row = 5;
var column = 5;
function Map(){
for(let y = -1; y < column; y++){
for(let x = -1; x < row; x++){
switch(map[((y*row) + x)]) {
case 0: context.fillStyle = player.color;
break;
case 1: context.fillStyle = "#ffffff";
break;
default: context.fillStyle = "#000000";
}
context.fillRect(x*50, y*50, 50, 50);
}
}
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: black;
}
canvas {
display: block;
margin: auto;
border: solid 1px white;
border-radius: 10px;
}
script {
display: none;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="application/javascript">
void function() {
"use strict";
// Classes
function Camera(x,y) {
this.x = x || 0.0;
this.y = y || 0.0;
}
Camera.prototype = {
set: function(x,y) {
this.x = x || 0.0;
this.y = y || 0.0;
},
pan: function(x,y) {
this.x += x || 0.0;
this.y += y || 0.0;
}
};
var nextID = 0;
function Tile(colour) {
this.id = nextID++;
this.colour = colour || "black";
}
function Map(width,height) {
this.width = width || 1;
this.height = height || 1;
this.map = [];
this.map.length = this.height;
for (var y = 0; y < this.height; ++y) {
this.map[y] = [];
this.map[y].length = width;
for (var x = 0; x < this.width; ++x) {
this.map[y][x] = Math.random() < 0.2 ?
this.TILE_WALL:
this.TILE_GRASS;
}
this.map[y][0] = this.TILE_WALL;
this.map[y][this.width - 1] = this.TILE_WALL;
}
for (var x = 0; x < this.width; ++x) {
this.map[0][x] = this.TILE_WALL;
this.map[this.height - 1][x] = this.TILE_WALL;
}
}
Map.prototype = {
TILE_WIDTH: 32.0,
TILE_HEIGHT: 32.0,
INV_TILE_WIDTH: 0.0,
INV_TILE_HEIGHT: 0.0,
TILE_AIR: new Tile("#00000000"),
TILE_GRASS: new Tile("#00AA00FF"),
TILE_WALL: new Tile("#555555FF"),
set: function(x,y,tile) {
this.map[y][x] = tile;
},
scaleX: function(x) {
return (x * this.INV_TILE_WIDTH) | 0;
},
scaleY: function(y) {
return (y * this.INV_TILE_HEIGHT) | 0;
},
isColliding: function(x,y) {
return x > -1 && x < this.width
&& y > -1 && y < this.height
&& this.map[y][x].id > 1;
},
render: function(ctx,camera) {
for (var y = 0; y < this.height; ++y) {
for (var x = 0; x < this.width; ++x) {
var tile = this.map[y][x];
var _x = x * this.TILE_WIDTH - camera.x;
var _y = y * this.TILE_HEIGHT - camera.y;
ctx.fillStyle = tile.colour;
ctx.fillRect(_x,_y,this.TILE_WIDTH - 1,this.TILE_HEIGHT - 1);
}
}
}
};
Map.prototype.INV_TILE_WIDTH = 1.0 / Map.prototype.TILE_WIDTH;
Map.prototype.INV_TILE_HEIGHT = 1.0 / Map.prototype.TILE_HEIGHT;
function Player(x,y) {
this.x = x || 0.0;
this.y = y || 0.0;
this.dx = 0.0;
this.dy = 0.0;
this.isUp = false;
this.isDown = false;
this.isLeft = false;
this.isRight = false;
}
Player.prototype = {
WIDTH: 20.0,
HEIGHT: 20.0,
ACCELERATION: 1.0,
DEACCELERATION: 0.5,
MAX_SPEED: 3.0,
tick: function(map) {
// Movement
if (this.isUp) {
this.dy -= this.ACCELERATION;
if (this.dy < -this.MAX_SPEED) {
this.dy = -this.MAX_SPEED;
}
} else if (this.dy < 0.0) {
this.dy += this.DEACCELERATION;
if (this.dy > 0.0) {
this.dy = 0.0;
}
}
if (this.isDown) {
this.dy += this.ACCELERATION;
if (this.dy > this.MAX_SPEED) {
this.dy = this.MAX_SPEED;
}
} else if (this.dy > 0.0) {
this.dy -= this.DEACCELERATION;
if (this.dy < 0.0) {
this.dy = 0.0;
}
}
if (this.isLeft) {
this.dx -= this.ACCELERATION;
if (this.dx < -this.MAX_SPEED) {
this.dx = -this.MAX_SPEED;
}
} else if (this.dx < 0.0) {
this.dx += this.DEACCELERATION;
if (this.dx > 0.0) {
this.dx = 0.0;
}
}
if (this.isRight) {
this.dx += this.ACCELERATION;
if (this.dx > this.MAX_SPEED) {
this.dx = this.MAX_SPEED;
}
} else if (this.dx > 0.0) {
this.dx -= this.DEACCELERATION;
if (this.dx < 0.0) {
this.dx = 0.0;
}
}
// Collision
if (this.dx !== 0.0) {
var minY = map.scaleY(this.y);
var maxY = map.scaleY(this.y + this.HEIGHT);
var minX = 0;
var maxX = 0;
if (this.dx < 0.0) {
minX = map.scaleX(this.x + this.dx);
maxX = map.scaleX(this.x);
} else {
minX = map.scaleX(this.x + this.WIDTH);
maxX = map.scaleX(this.x + this.WIDTH + this.dx);
}
loop:
for (var y = minY; y <= maxY; ++y) {
for (var x = minX; x <= maxX; ++x) {
if (map.isColliding(x,y)) {
this.x = this.dx < 0.0 ?
(x + 1) * map.TILE_WIDTH:
x * map.TILE_WIDTH - this.WIDTH - 1;
this.dx = 0.0;
break loop;
}
}
}
}
if (this.dy !== 0.0) {
var minX = map.scaleX(this.x);
var maxX = map.scaleX(this.x + this.WIDTH);
var minY = 0;
var maxY = 0;
if (this.dy < 0.0) {
minY = map.scaleY(this.y + this.dy);
maxY = map.scaleY(this.y);
} else {
minY = map.scaleY(this.y + this.HEIGHT);
maxY = map.scaleY(this.y + this.HEIGHT + this.dy);
}
loop:
for (var y = minY; y <= maxY; ++y) {
for (var x = minX; x <= maxX; ++x) {
if (map.isColliding(x,y)) {
this.y = this.dy < 0.0 ?
(y + 1) * map.TILE_HEIGHT:
y * map.TILE_HEIGHT - this.HEIGHT - 1;
this.dy = 0.0;
break loop;
}
}
}
}
this.x += this.dx;
this.y += this.dy;
},
render: function(ctx,camera) {
camera.set(this.x,this.y);
ctx.lineWidth = 1;
ctx.strokeStyle = "black";
ctx.fillStyle = "darkred";
ctx.beginPath();
ctx.rect(this.x - camera.x,this.y - camera.y,this.WIDTH,this.HEIGHT);
ctx.fill();
ctx.stroke();
}
};
// Variables
var canvasWidth = 180;
var canvasHeight = 160;
var canvas = null;
var ctx = null;
var camera = null;
var map = null;
var player = null;
// Functions
function onKeyDown(e) {
switch(e.key.toUpperCase()) {
case "W": player.isUp = true; break;
case "S": player.isDown = true; break;
case "A": player.isLeft = true; break;
case "D": player.isRight = true; break;
}
}
function onKeyUp(e) {
switch(e.key.toUpperCase()) {
case "W": player.isUp = false; break;
case "S": player.isDown = false; break;
case "A": player.isLeft = false; break;
case "D": player.isRight = false; break;
}
}
function loop() {
// Tick
player.tick(map);
// Render
ctx.fillStyle = "gray";
ctx.fillRect(-canvasWidth >> 1,-canvasHeight >> 1,canvasWidth,canvasHeight);
map.render(ctx,camera);
player.render(ctx,camera);
//
requestAnimationFrame(loop);
}
// Entry point (first to execute)
onload = function() {
canvas = document.getElementById("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
ctx = canvas.getContext("2d");
ctx.translate(canvasWidth >> 1,canvasHeight >> 1);
camera = new Camera(0.0,0.0);
map = new Map(10,10);
player = new Player(40.0,40.0);
map.set(1,1,map.TILE_GRASS);
addEventListener("keydown",onKeyDown);
addEventListener("keyup",onKeyUp);
loop();
}
}();
</script>
</body>
</html>
Firstly, looking at your code, there are some things that are missing which is required to implement basic collision detection and those are:
The player's current direction that he/she is moving in. This is important because it allows the function determining the collision detection to distinguish which side it is checking for the collision (Up, down, left, or right) since a player can only collide with one side at a time.
The tile's position and size. This is also very important because like the first point, there is only one side of the tile that the player can collide with and knowing the size and position can determine if it is a collision or not based on the players size and position.
Also, since you mentioned it is a basic game, the implementation below is a basic collision detection. If you were to make a more complex and bigger game, you should try looking into quad trees for more efficient collision detection:
https://gamedevelopment.tutsplus.com/tutorials/quick-tip-use-quadtrees-to-detect-likely-collisions-in-2d-space--gamedev-374
Now this is the function for detecting collision, for the sake of readability and shortness, p will represent the player object and t would represent the tile object. This function returns whether or not the player is colliding with a tile based on their direction of movement.
function isColliding(p, t){
if (p.direction == 'up') {
return p.y +(p.height/2)-p.speedY< t.y + t.height && p.y > t.y
&& p.x + p.width > t.x && p.x < t.x + t.width;
}
if (p.direction == 'down') {
return p.y + (p.height/2)+p.speedY > t.y && p.y < t.y
&& p.x + p.width > t.x && p.x < t.x + t.width;
}
if (p.direction == 'right') {
return p.x + p.width+p.speedX > t.x && p.x < t.x
&& p.y +(p.height/2)> t.y && p.y + p.height < t.y +t.height+ (p.height / 2);
}
if (p.direction == 'left') {
return p.x -p.speedX< t.x + t.width && p.x > t.x
&& p.y +(p.height/2)> t.y && p.y + p.height < t.y +t.height+ (p.height / 2);
}
return false;
}
You would probably want to put this in the player move function to constantly detect for tiles as it is moving. To do that, you'd want to modify your keydown detection so that with each different keydown, it would update the player's direction, here's a simple example:
document.onkeydown = function(event){
if (event.keyCode == 87)
player.up = true;
else if (event.keyCode == 65)
player.left = true;
else if (event.keyCode == 83)
player.down = true;
else if (event.keyCode == 68)
player.right = true;
}
and another simple example for every time the player moves (user presses a keydown):
const Player= function(/*Param stuff*/){
/*Property stuff*/
//tileArray is the array (or object, your choice) of all the current tiles in the map
this.move=function(tileArray){
//Go through all tiles to see if player is colliding with any of them
for(var t in tileArray){
if(this.up){
if(isColliding(this, tileArray[t]){
//functionality for when player collides
}else{
//functionality for when player doesn't collide
}
}
//check if player is going down, left, etc
}
}
}
These are just examples of how to implement the detection. You should use it as a reference to implement it relatively to how your code function because I didn't write it based on what you posted.
PS.
Make sure to also convert the directions to false after the user stops pressing the key.
I am trying to make a 2d top view javascript game and i want to make my map using program "tiled" i have made my map and have the exported json but dont know how to parse it into a canvas html tag and i dont know were to start here is my crazy game code
<html>
<body>
</body>
</html>
<script>
// Create the canvas
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);
// Background image
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function() {
bgReady = true;
};
bgImage.src = "images/newbackground.png";
//hp box
var hpBoxReady = false;
var hpBoxImage = new Image();
hpBoxImage.onload = function() {
hpBoxReady = true;
};
hpBoxImage.src = "images/hpbox.png";
// player image
var playerReady = false;
var playerImage = new Image();
playerImage.onload = function() {
playerReady = true;
};
playerImage.src = "images/char.png";
// enemy image
var enemyReady = false;
var enemyImage = new Image();
enemyImage.onload = function() {
enemyReady = true;
};
enemyImage.src = "images/enemy_idle01.png";
// Game objects
var hpBox = {
restoreHealth: 34,
x: 300,
y: 300
}
var player = {
stamina: 7,
health: 100,
sprintSpeed: 400,
weakSpeed: 150,
speed: 300 // movement in pixels per second
};
var enemy = {
speed: 250,
viewDistance: 40
};
var enemysCaught = 0;
// Handle keyboard controls
var keysDown = {};
addEventListener("keydown", function(e) {
keysDown[e.keyCode] = true;
}, false);
addEventListener("keyup", function(e) {
delete keysDown[e.keyCode];
}, false);
// Reset the game when the player catches a enemy
var reset = function() {
player.x = canvas.width / 2;
player.y = canvas.height / 2;
// Throw the enemy somewhere on the screen randomly
enemy.x = 32 + (Math.random() * (canvas.width - 64));
enemy.y = 32 + (Math.random() * (canvas.height - 64));
};
//w is 87
//a is 65
//s is 83
//d is 68
// Update game objects
var update = function(modifier) {
if (87 in keysDown) { // Player holding up
player.y -= player.speed * modifier;
}
if (83 in keysDown) { // Player holding down
player.y += player.speed * modifier;
}
if (65 in keysDown) { // Player holding left
player.x -= player.speed * modifier;
}
if (68 in keysDown) { // Player holding right
player.x += player.speed * modifier;
}
if (
player.x <= (0)) {
player.health -= 1;
console.log('health decreasing');
}
}
if (
player.y <= (0)) {
player.health -= 1;
console.log('health decreasing');
};
// Are they touching?
if (
player.x <= (enemy.x + 32) &&
enemy.x <= (player.x + 32) &&
player.y <= (enemy.y + 32) &&
enemy.y <= (player.y + 32)
) {
++enemysCaught;
reset();
}
// Draw everything
var render = function() {
if (bgReady) {
context.drawImage(bgImage, 0, 0);
}
if (hpBoxReady) {
context.drawImage(hpBoxImage, hpBox.x, hpBox.y);
}
if (playerReady) {
context.drawImage(playerImage, player.x, player.y);
}
if (enemyReady) {
context.drawImage(enemyImage, enemy.x, enemy.y);
}
// Score
context.fillStyle = "rgb(250, 250, 250)";
context.font = "24px Helvetica";
context.textAlign = "left";
context.textBaseline = "top";
context.fillText("enemys killed: " + enemysCaught, canvas.width / 2, 32);
};
function dieEvent() {
player.health = 100;
}
function updateHealth() {
context.fillStyle = "rgb(255 ,0 ,0)";
context.textAlign = "right";
context.fillText("Health: " + player.health, 1000, 32)
}
function isNearHPBox() {
if (
player.y <= (hpBox.y + enemy.viewDistance + 64) &&
player.y >= (hpBox.y - enemy.viewDistance - 64) &&
player.x <= (hpBox.x + enemy.viewDistance + 64) &&
player.x >= (hpBox.x - enemy.viewDistance - 64)) {
console.log("healing!");
if (player.health <= 100) {
hpBox.restoreHealth = player.health - 100;
player.health += hpBox.restoreHealth;
}
}
}
function moveEnemy() {
if (
player.y <= (enemy.y + enemy.viewDistance + 64) &&
player.y >= (enemy.y - enemy.viewDistance - 64) &&
player.x <= (enemy.x + enemy.viewDistance + 64) &&
player.x >= (enemy.x - enemy.viewDistance - 64)) {
console.log("seen on enemys Y");
var audio = new Audio('sounds/theWanderer_Scream.m4a');
audio.play();
if (player.x >= (enemy.x)) {
enemy.x -= enemy.speed;
}
if (player.x >= (enemy.x)) {
enemy.x -= enemy.speed;
}
}
}
function checkWallCollision() {
if (player.y <= 0) {
console.log("y")
player.y += 64;
}
if (player.x <= 0) {
console.log("x")
player.x += 64;
}
if (enemy.y <= 0) {
console.log("y")
enemy.y += 64;
}
if (enemy.x <= 0) {
console.log("x")
enemy.x += 64;
}
}
function reducedSpeed() {
player.speed = player.weakSpeed;
}
// The main game loop
var main = function() {
var now = Date.now();
var delta = now - then;
update(delta / 1000);
context.clearRect(0, 0, canvas.width, canvas.height);
render();
updateHealth();
moveEnemy();
if (player.health <= 20) {
reducedSpeed();
} else {
player.speed = 300;
}
if (player.health <= 0) {
dieEvent();
}
checkWallCollision();
isNearHPBox();
then = now;
// Request to do this again ASAP
requestAnimationFrame(main);
};
// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
// Let's play this game!
var then = Date.now();
reset();
main();
</script>
<style>
body {
margin: 0;
padding: 0;
}
</style>
i have tried all the tutorials but cant seem to get it to work so for now i just have a small little background image could sombody please help?
Your question is a bit general. I recommand to enroll Udacity's HTML5 Game Development course I think many part of your question should be answered after watching that course.
I am coding a Pacman clone. The steps that I have accomplished are the floor, the maze, as also the pacman and the movement of pacman through wall paths.
The maze is in array format where the walls are represented as "x". Also the movement should go with wasd keys from the keyboard. Currently the movement of the object is smooth and can walk in the path and change directions correctly only if I have the good timing with the hit.
I have also read this post Relevant Post and I followed some of these techniques so that I can store the key presses. After I did that I don't think that something changed from the previous design. Also when I change to a direction that is not allowed it rotates to that direction and stops moving. I want to implement this like classic Pac-man game. Below is the code of my issue.
That's the handleKeyDown function where i check for key press.
function handleKeyDown(event) {
currentlyPressedKeys[event.keyCode] = true;
if (String.fromCharCode(event.keyCode) == "A") {
curr_key=temp;
curr_key="A";
memory_key = temp;
pacRot = 0;
}
if (String.fromCharCode(event.keyCode) == "D") {
curr_key=temp;
curr_key="D";
memory_key = temp;
pacRot = 180;
}
if (String.fromCharCode(event.keyCode) == "W") {
curr_key=temp;
curr_key="W";
memory_key = temp;
pacRot = 270;
}
if (String.fromCharCode(event.keyCode) == "S") {
curr_key=temp;
curr_key="S";
memory_key = temp;
pacRot = 90;
}
}
Now the function can_move(key) that checks if the object can move to a direction
function can_move(key){
if (key == "W") {
if (stage[Math.round(y) - 1][x] == "x") {
y = Math.round(y);
return false;
} else {
return true;
}
}
if (key == "A") {
if (stage[y][Math.round(x) - 1] == "x") {
x = Math.round(x);
return false;
} else {
return true;
}
}
if (key == "S") {
if (stage[Math.round(y) + 1][x] == "x") {
y = Math.round(y);
return false;
} else {
return true;
}
}
if (key == "D") {
if (stage[y][Math.round(x) + 1] == "x") {
x = Math.round(x);
return false;
} else {
return true;
}
}
}
And finally the main moving function move_conditions that is called inside tick() after drawScene()
function move_conditions(elapsed) {
if(can_move(curr_key)==true){
if(curr_key=="W"){
ySpeed = 5;
xSpeed = 0;
y -= (ySpeed * 25) / 1000.0;
x = Math.round(x);
}
if(curr_key=="A"){
ySpeed = 0;
xSpeed = 5;
x -= (xSpeed * 25) / 1000.0;
y = Math.round(y);
}
if(curr_key=="S"){
ySpeed = 5;
xSpeed = 0;
y += (ySpeed * 25) / 1000.0;
x = Math.round(x);
}
if(curr_key=="D"){
ySpeed = 0;
xSpeed = 5;
x += (xSpeed * 25) / 1000.0;
y = Math.round(y);
}
}else if(can_move(memory_key)==true){
if(memory_key=="W"){
ySpeed = 5;
xSpeed = 0;
y -= (ySpeed * 25) / 1000.0;
x = Math.round(x);
}
if(memory_key=="A"){
ySpeed = 0;
xSpeed = 5;
x -= (xSpeed * 25) / 1000.0;
y = Math.round(y);
}
if(memory_key=="S"){
ySpeed = 5;
xSpeed = 0;
y += (ySpeed * 25) / 1000.0;
x = Math.round(x);
}
if(memory_key=="D"){
ySpeed = 0;
xSpeed = 5;
x += (xSpeed * 25) / 1000.0;
y = Math.round(y);
}
}