fix bomb and explode position
This commit is contained in:
parent
2f7df02f61
commit
78b94d300c
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules
|
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.0 KiB |
28
index.html
Normal file
28
index.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>ReactGirls Akademie Algoritmy</title>
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<script src="p5.js"></script>
|
||||||
|
<script src="p5.sound.js"></script>
|
||||||
|
<script src="src/index.js"></script>
|
||||||
|
<script src="src/ai.js"></script>
|
||||||
|
<script src="src/game.js"></script>
|
||||||
|
<script src="src/player.js"></script>
|
||||||
|
<script src="src/physics.js"></script>
|
||||||
|
<script src="src/obstacle.js"></script>
|
||||||
|
<script src="src/bomb.js"></script>
|
||||||
|
<script src="src/utils.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body
|
||||||
|
class="bg-slate-900 min-h-screen max-w-screen max-h-screen overflow-hidden m-0 p-0"
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
></body>
|
||||||
|
</html>
|
12268
p5.sound.js
Normal file
12268
p5.sound.js
Normal file
File diff suppressed because one or more lines are too long
6
package-lock.json
generated
Normal file
6
package-lock.json
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "OctopusBomb",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {}
|
||||||
|
}
|
BIN
sound/explosion.mp3
Normal file
BIN
sound/explosion.mp3
Normal file
Binary file not shown.
274
src/ai.js
Normal file
274
src/ai.js
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
function makeEnemy(x, y) {
|
||||||
|
return {
|
||||||
|
t: "enemy",
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
lastMove: millis(),
|
||||||
|
isAlive: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawEnemies() {
|
||||||
|
for (let enemi of enemies) {
|
||||||
|
let dampingX = 0;
|
||||||
|
let dampingY = 0;
|
||||||
|
if (enemi.isMoving || !enemi.isAlive) {
|
||||||
|
dampingX = Math.sin(millis() / (1800 / gameFrameRate)) * damping;
|
||||||
|
dampingY = Math.cos(millis() / (1800 / gameFrameRate)) * damping;
|
||||||
|
}
|
||||||
|
textSize(cellSize / 1.2);
|
||||||
|
|
||||||
|
if (enemi.isAlive) {
|
||||||
|
text(
|
||||||
|
"🦈",
|
||||||
|
enemi.x + dampingX - halfCellSize,
|
||||||
|
enemi.y + dampingY + yOffsetDraw - halfCellSize
|
||||||
|
);
|
||||||
|
if(debug){fill(255, 0, 0);
|
||||||
|
circle(enemi.x + dampingX, enemi.y + dampingY, 8);}
|
||||||
|
} else {
|
||||||
|
text(
|
||||||
|
"💀",
|
||||||
|
enemi.x - halfCellSize,
|
||||||
|
enemi.y + dampingY + yOffsetDraw - halfCellSize
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveEnemies() {
|
||||||
|
const playerPosition = positionsToCellsIdx({
|
||||||
|
x: player1.x,
|
||||||
|
y: player1.y,
|
||||||
|
});
|
||||||
|
|
||||||
|
const playerReversPosition = [playerPosition.yi, playerPosition.xi];
|
||||||
|
|
||||||
|
for (let enemi of enemies) {
|
||||||
|
const enemiPosition = positionsToCellsIdx({
|
||||||
|
x: enemi.x,
|
||||||
|
y: enemi.y,
|
||||||
|
});
|
||||||
|
|
||||||
|
const enemiReversPosition = [enemiPosition.yi, enemiPosition.xi];
|
||||||
|
|
||||||
|
let pathFindTimer = Math.floor(millis() / 100);
|
||||||
|
pathFindTimer = pathFindTimer % 2;
|
||||||
|
if (pathFindTimer === 0) {
|
||||||
|
//const path = bfs(grid, enemiReversPosition, playerReversPosition);
|
||||||
|
// fix this
|
||||||
|
////const path = findPath(grid, enemiReversPosition, playerReversPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//function to judge if a cell is safe or not
|
||||||
|
safeNeighbor = function (r, c) {
|
||||||
|
if (r < 0 || r >= rows) return false;
|
||||||
|
if (c < 0 || c >= cols) return false;
|
||||||
|
if (grid[r][c] !== freePlace) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
//function to identify neighbors of current location
|
||||||
|
exploreLocation = function (location) {
|
||||||
|
let r = location.r;
|
||||||
|
let c = location.c;
|
||||||
|
let allNeighbors = [];
|
||||||
|
|
||||||
|
//left
|
||||||
|
if (safeNeighbor(r, c - 1)) allNeighbors.push({ r: r, c: c - 1 });
|
||||||
|
//right
|
||||||
|
if (safeNeighbor(r, c + 1)) allNeighbors.push({ r: r, c: c + 1 });
|
||||||
|
//top
|
||||||
|
if (safeNeighbor(r - 1, c)) allNeighbors.push({ r: r - 1, c: c });
|
||||||
|
//bottom
|
||||||
|
if (safeNeighbor(r + 1, c)) allNeighbors.push({ r: r + 1, c: c });
|
||||||
|
|
||||||
|
return allNeighbors;
|
||||||
|
};
|
||||||
|
|
||||||
|
//find path between two cells
|
||||||
|
findPath = function (grid, start, end) {
|
||||||
|
let gridMap = [];
|
||||||
|
//var row = grid.length;
|
||||||
|
//var col = grid[0].length;
|
||||||
|
var location = {
|
||||||
|
r: start[0],
|
||||||
|
c: start[1],
|
||||||
|
};
|
||||||
|
var queue = [];
|
||||||
|
queue.push(location);
|
||||||
|
while (queue.length) {
|
||||||
|
var currentLocation = queue.shift();
|
||||||
|
if (currentLocation.r == end[0] && currentLocation.c == end[1]) {
|
||||||
|
//return currentLocation;
|
||||||
|
let paths = [currentLocation];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
let r = currentLocation.r;
|
||||||
|
let c = currentLocation.c;
|
||||||
|
let parent = grid[r][c].parent;
|
||||||
|
if (parent == undefined) break;
|
||||||
|
paths.push(parent);
|
||||||
|
currentLocation = { r: parent.r, c: parent.c };
|
||||||
|
}
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
grid[currentLocation.r][currentLocation.c].state = "visited";
|
||||||
|
var neighbors = exploreLocation(currentLocation);
|
||||||
|
for (neighbor of neighbors) {
|
||||||
|
if (grid[neighbor.r][neighbor.c].state != "visited") {
|
||||||
|
queue.push(neighbor);
|
||||||
|
grid[neighbor.r][neighbor.c]["parent"] = currentLocation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Code to traverse, and print path of route
|
||||||
|
printPath = function (path) {
|
||||||
|
let paths = [path];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
let r = path.r;
|
||||||
|
let c = path.c;
|
||||||
|
let parent = grid[r][c].parent;
|
||||||
|
if (parent == undefined) break;
|
||||||
|
paths.push(parent);
|
||||||
|
path = { r: parent.r, c: parent.c };
|
||||||
|
}
|
||||||
|
console.log(paths);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
// openAI:
|
||||||
|
// Sure, here's an implementation of the breadth-first search algorithm in JavaScript for finding a
|
||||||
|
// path between two points in a grid:
|
||||||
|
// */
|
||||||
|
|
||||||
|
// function bfs(grid, start, end) {
|
||||||
|
// //debugger;
|
||||||
|
// const queue = [start]; // Initialize the queue with the starting point
|
||||||
|
// const visited = new Set(); // Keep track of visited cells
|
||||||
|
// const parent = new Map(); // Map each cell to its parent in the search tree
|
||||||
|
|
||||||
|
// while (queue.length > 0) {
|
||||||
|
// let curr = queue.shift(); // Take the first cell from the queue
|
||||||
|
// visited.add(curr); // Mark it as visited
|
||||||
|
|
||||||
|
// // Check if we've reached the end
|
||||||
|
// if (curr[0] === end[0] && curr[1] === end[1]) {
|
||||||
|
// // Trace back the path from the end to the start by following the parent pointers
|
||||||
|
// let path = [];
|
||||||
|
// let currParent = curr;
|
||||||
|
// while (currParent !== undefined && currParent !== null) {
|
||||||
|
// // test on undefined?
|
||||||
|
// path.unshift(currParent);
|
||||||
|
// currParent = parent.get(currParent);
|
||||||
|
// }
|
||||||
|
// return path;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Add unvisited neighbors to the queue
|
||||||
|
// let neighbors = getNeighbors(grid, curr[0], curr[1]);
|
||||||
|
// for (const neighbor of neighbors) {
|
||||||
|
// if (!visited.has(neighbor)) {
|
||||||
|
// queue.push(neighbor);
|
||||||
|
// parent.set(neighbor, curr);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // If we didn't find a path, return null
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Returns an array of unblocked neighbor cells of the given cell
|
||||||
|
// function getNeighbors(grid, row, col) {
|
||||||
|
// const numRows = grid.length;
|
||||||
|
// const numCols = grid[0].length;
|
||||||
|
// let neighbors = [];
|
||||||
|
|
||||||
|
// if (row > 0 && grid[row - 1][col] === freePlace) {
|
||||||
|
// neighbors.push([row - 1, col]);
|
||||||
|
// }
|
||||||
|
// if (col > 0 && grid[row][col - 1] === freePlace) {
|
||||||
|
// neighbors.push([row, col - 1]);
|
||||||
|
// }
|
||||||
|
// if (row < numRows - 1 && grid[row + 1][col] === freePlace) {
|
||||||
|
// neighbors.push([row + 1, col]);
|
||||||
|
// }
|
||||||
|
// if (col < numCols - 1 && grid[row][col + 1] === freePlace) {
|
||||||
|
// neighbors.push([row, col + 1]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return neighbors;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/*
|
||||||
|
Here, `grid` is a 2D array of objects representing the cells in the grid.
|
||||||
|
Each object has a `blocked` property that is `true` if the cell is blocked and `false` otherwise.
|
||||||
|
`start` and `end` are arrays representing the coordinates of the starting and ending cells, respectively.
|
||||||
|
The function returns an array of cell coordinates representing the shortest path between the starting
|
||||||
|
and ending cells, or `null` if no path exists.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
To use the breadth-first search algorithm to move an object in a grid to a target, you can follow these steps:
|
||||||
|
|
||||||
|
1. Create a grid object that represents the state of the grid. Each cell in the grid can be either empty or blocked. You can represent the grid as a 2D array of objects, where each object has a `blocked` property that is `true` if the cell is blocked and `false` otherwise.
|
||||||
|
|
||||||
|
2. Create an object that represents the state of the moving object. The object should have a `position` property that is a two-element array representing the current position of the object in the grid.
|
||||||
|
|
||||||
|
3. Define a target position that the object needs to reach.
|
||||||
|
|
||||||
|
4. Call the `bfs` function with the grid, the starting position of the object, and the target position. This will return an array of cell coordinates representing the shortest path between the starting position and the target position.
|
||||||
|
|
||||||
|
5. Move the object one step along the path at a time. For example, you can use `setInterval` to move the object every few milliseconds. The object should move to the next cell in the path until it reaches the target position.
|
||||||
|
|
||||||
|
Here's some example code that demonstrates these steps:
|
||||||
|
|
||||||
|
javascript
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Define the grid
|
||||||
|
// const grid = [
|
||||||
|
// [{ blocked: false }, { blocked: false }, { blocked: false }],
|
||||||
|
// [{ blocked: false }, { blocked: true }, { blocked: false }],
|
||||||
|
// [{ blocked: false }, { blocked: false }, { blocked: false }],
|
||||||
|
// ];
|
||||||
|
|
||||||
|
// // Define the moving object
|
||||||
|
// const object = {
|
||||||
|
// position: [0, 0], // Starting position
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Define the target position
|
||||||
|
// const target = [2, 2];
|
||||||
|
|
||||||
|
// Find the shortest path from the object's position to the target
|
||||||
|
//const path = bfs(grid, object.position, target);
|
||||||
|
|
||||||
|
// Move the object along the path
|
||||||
|
/*
|
||||||
|
let i = 0;
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (i < path.length - 1) {
|
||||||
|
// Move the object to the next cell in the path
|
||||||
|
object.position = path[i + 1];
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
// Stop the interval if the object has reached the target
|
||||||
|
clearInterval(interval);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
/*
|
||||||
|
In this example, the `setInterval` function is called every 1000 milliseconds, or 1 second. You can adjust this value to make the object move faster or slower.
|
||||||
|
Also, note that this example assumes that the object can only move to adjacent cells that are not blocked.
|
||||||
|
If you want to allow the object to move diagonally or through blocked cells, you'll need to modify the `getNeighbors` function to include those cases.
|
||||||
|
*/
|
87
src/bomb.js
Normal file
87
src/bomb.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
let bombs = [];
|
||||||
|
let explosions = [];
|
||||||
|
//let bomb = {x: 0, y: 0}
|
||||||
|
|
||||||
|
function placeBomb(x, y) {
|
||||||
|
let lastBomb = bombs.slice(-1); // return last element
|
||||||
|
if (lastBomb.length === 0 || lastBomb[0].placeAt < millis() - nextBombTime) {
|
||||||
|
//snap bomb on grid
|
||||||
|
if (snapBomb) {
|
||||||
|
x = Math.round(x / cellSize) * cellSize;
|
||||||
|
y = Math.round(y / cellSize) * cellSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
let bomb = { x, y, placeAt: millis() };
|
||||||
|
bombs.push(bomb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawBombs() {
|
||||||
|
textSize(cellSize / 1.6);
|
||||||
|
for (let bomb of bombs) {
|
||||||
|
text("💣", bomb.x - halfCellSize, bomb.y + yOffsetDraw - halfCellSize);
|
||||||
|
if(debug){
|
||||||
|
fill(255, 0, 0);
|
||||||
|
circle(bomb.x, bomb.y, 8);}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function detonateBomb() {
|
||||||
|
for (let bomb of bombs) {
|
||||||
|
if (bomb && bomb.placeAt < millis() - bombDelay) {
|
||||||
|
//console.log(bombs.length);
|
||||||
|
placeMultiExplosion(bomb.x, bomb.y);
|
||||||
|
bombs.splice(bombs.indexOf(bomb), 1);
|
||||||
|
explosionSound.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function placeMultiExplosion(x, y) {
|
||||||
|
for (let ix = -explodeSize; ix <= explodeSize; ix++) {
|
||||||
|
for (let iy = -explodeSize; iy <= explodeSize; iy++) {
|
||||||
|
const exlodesOverBorder = overBorder({ x: x, y: y });
|
||||||
|
|
||||||
|
x = exlodesOverBorder.x;
|
||||||
|
y = exlodesOverBorder.y;
|
||||||
|
|
||||||
|
placeExplosion(ix * cellSize + x, iy * cellSize + y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function placeExplosion(x, y) {
|
||||||
|
const exlodeOverBorder = overBorder({ x: x, y: y });
|
||||||
|
console.log(exlodeOverBorder);
|
||||||
|
console.log(x);
|
||||||
|
x = exlodeOverBorder.x;
|
||||||
|
y = exlodeOverBorder.y;
|
||||||
|
|
||||||
|
let explosion = { x, y, placeAt: millis() };
|
||||||
|
explosions.push(explosion);
|
||||||
|
const explodePosition = positionsToCellsIdx({
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
});
|
||||||
|
if (grid[explodePosition.yi][explodePosition.xi] === softItem) {
|
||||||
|
grid[explodePosition.yi][explodePosition.xi] = freePlace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawExplosions() {
|
||||||
|
textSize(cellSize / 1);
|
||||||
|
for (let explosion of explosions) {
|
||||||
|
text(
|
||||||
|
"💥",
|
||||||
|
explosion.x - halfCellSize - 4,
|
||||||
|
explosion.y + yOffsetDraw - halfCellSize + 4
|
||||||
|
);
|
||||||
|
if(debug){fill(255, 0, 0);
|
||||||
|
circle(explosion.x, explosion.y, 8);}/* */
|
||||||
|
|
||||||
|
if (explosion && explosion.placeAt < millis() - expodeDelay) {
|
||||||
|
//console.log(explosions.lengh);
|
||||||
|
explosions.splice(explosions.indexOf(explosion), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
src/game.js
Normal file
120
src/game.js
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
const debug = false;
|
||||||
|
const cellSize = 40;
|
||||||
|
const halfCellSize = cellSize / 2;
|
||||||
|
const rows = Math.floor(window.innerHeight / cellSize - 1);
|
||||||
|
const cols = Math.floor(window.innerWidth / cellSize - 1);
|
||||||
|
const ypx = rows * cellSize;
|
||||||
|
const xpx = cols * cellSize;
|
||||||
|
const bombDelay = 1500;
|
||||||
|
const expodeDelay = 500;
|
||||||
|
const nextBombTime = 500;
|
||||||
|
//const overlappedBorder = -Math.floor(halfCellSize); // px
|
||||||
|
const gameFrameRate = 60;
|
||||||
|
const steppOnStart = 1;
|
||||||
|
const yOffsetDraw = cellSize - cellSize / 4;
|
||||||
|
const offsetCollision = cellSize / 4;
|
||||||
|
const grid = []; // grid[iy][ix]
|
||||||
|
const explodeSize = 2;
|
||||||
|
const softItemRandomFactor = 0.8;
|
||||||
|
const hardItemRandomFactor = 0.95;
|
||||||
|
const softItem = 2;
|
||||||
|
const hardItem = 3;
|
||||||
|
const freePlace = 0;
|
||||||
|
const enemies = [];
|
||||||
|
const damping = 2;
|
||||||
|
const enemiSpeed = 4;
|
||||||
|
|
||||||
|
const snapBomb = false;
|
||||||
|
|
||||||
|
let explosionSound;
|
||||||
|
|
||||||
|
function setup() {
|
||||||
|
createCanvas(windowWidth, windowHeight);
|
||||||
|
//createCanvas(cols * cellSize, rows * cellSize);
|
||||||
|
explosionSound = loadSound("sound/explosion.mp3");
|
||||||
|
frameRate(gameFrameRate); // Attempt to refresh at starting FPS
|
||||||
|
|
||||||
|
for (let iy = 0; iy < rows; iy++) {
|
||||||
|
const row = [];
|
||||||
|
for (let ix = 0; ix < cols; ix++) {
|
||||||
|
rect(ix * cellSize, iy * cellSize, cellSize);
|
||||||
|
if (Math.random() > softItemRandomFactor) {
|
||||||
|
row.push(softItem); // push soft item
|
||||||
|
//text("🌿", ix * cellSize, iy * cellSize + cellSize - cellSize / 4);
|
||||||
|
} else if (Math.random() > hardItemRandomFactor) {
|
||||||
|
row.push(hardItem);
|
||||||
|
} else {
|
||||||
|
row.push(freePlace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grid.push(row);
|
||||||
|
}
|
||||||
|
grid.push([]); // add one free row
|
||||||
|
|
||||||
|
// put player on free place
|
||||||
|
let randPosition; // proc nelze deklarovat uvnitr while???
|
||||||
|
do {
|
||||||
|
player1.x = (Math.floor(Math.random() * cols) * cellSize) + cellSize / 2;
|
||||||
|
player1.y = (Math.floor(Math.random() * rows) * cellSize) + cellSize / 2;
|
||||||
|
|
||||||
|
randPosition = positionsToCellsIdx({
|
||||||
|
x: player1.x,
|
||||||
|
y: player1.y,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(randPosition);
|
||||||
|
} while (grid[randPosition.yi][randPosition.xi] !== freePlace);
|
||||||
|
|
||||||
|
// put enemy on free place
|
||||||
|
let enemi = { x: 0, y: 0 };
|
||||||
|
|
||||||
|
do {
|
||||||
|
enemi.x = (Math.floor(Math.random() * cols) * cellSize) + cellSize / 2;
|
||||||
|
enemi.y = (Math.floor(Math.random() * rows) * cellSize) + cellSize / 2;
|
||||||
|
|
||||||
|
randPosition = positionsToCellsIdx({
|
||||||
|
x: enemi.x,
|
||||||
|
y: enemi.y,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(randPosition);
|
||||||
|
} while (grid[randPosition.yi][randPosition.xi] !== freePlace);
|
||||||
|
enemies.push(makeEnemy(enemi.x, enemi.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
background(0, 255);
|
||||||
|
fill(0, 90, 255);
|
||||||
|
textSize(cellSize / 1.2);
|
||||||
|
|
||||||
|
for (let iy = 0; iy < rows; iy++) {
|
||||||
|
for (let ix = 0; ix < cols; ix++) {
|
||||||
|
rect(ix * cellSize, iy * cellSize, cellSize);
|
||||||
|
text(iy, ix);
|
||||||
|
if (grid[iy][ix] === softItem) {
|
||||||
|
text("🌿", ix * cellSize, iy * cellSize + yOffsetDraw);
|
||||||
|
} else if (grid[iy][ix] === hardItem) {
|
||||||
|
text("🪨", ix * cellSize, iy * cellSize + yOffsetDraw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//debugger;
|
||||||
|
|
||||||
|
// draw bomb
|
||||||
|
drawBombs();
|
||||||
|
|
||||||
|
detonateBomb();
|
||||||
|
|
||||||
|
drawExplosions();
|
||||||
|
|
||||||
|
// draw
|
||||||
|
|
||||||
|
movePlayer();
|
||||||
|
|
||||||
|
moveEnemies();
|
||||||
|
|
||||||
|
drawPlayer();
|
||||||
|
|
||||||
|
drawEnemies();
|
||||||
|
}
|
0
src/index.js
Normal file
0
src/index.js
Normal file
0
src/obstacle.js
Normal file
0
src/obstacle.js
Normal file
26
src/physics.js
Normal file
26
src/physics.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
function isCollidingWithObstractle(destination) {
|
||||||
|
let xi = destination.xi;
|
||||||
|
let yi = destination.yi;
|
||||||
|
|
||||||
|
|
||||||
|
const modDestination = overBordFix({x: xi,y: yi});
|
||||||
|
|
||||||
|
xi = modDestination.x;
|
||||||
|
yi = modDestination.y;
|
||||||
|
|
||||||
|
|
||||||
|
//overBorder({x: xi, y: yi}); // error - pixel vs grid input
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//console.log(yi, xi);
|
||||||
|
|
||||||
|
const content = grid[yi][xi];
|
||||||
|
if (content === freePlace || content === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
118
src/player.js
Normal file
118
src/player.js
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
const player1 = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
isMoving: false,
|
||||||
|
isAlive: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
function movePlayer() {
|
||||||
|
let isMoving = false;
|
||||||
|
let stepp = Math.floor(deltaTime / 16 + steppOnStart - 1) + 1;
|
||||||
|
|
||||||
|
let dx = 0;
|
||||||
|
let dy = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 88 - x key - kill player
|
||||||
|
if (keyIsDown(88)) {
|
||||||
|
player1.isAlive = false;
|
||||||
|
let isMoving = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player1.isAlive) {
|
||||||
|
// ENTER key - drop bomb - space malfunction on any, dell, keyboard
|
||||||
|
if (keyIsDown(ENTER)) {
|
||||||
|
placeBomb(player1.x, player1.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyIsDown(RIGHT_ARROW)) {
|
||||||
|
dx += 1;
|
||||||
|
isMoving = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyIsDown(LEFT_ARROW)) {
|
||||||
|
dx -= 1;
|
||||||
|
isMoving = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyIsDown(DOWN_ARROW)) {
|
||||||
|
dy += 1;
|
||||||
|
isMoving = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyIsDown(UP_ARROW)) {
|
||||||
|
dy -= 1;
|
||||||
|
isMoving = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < stepp; i++) {
|
||||||
|
const destinationLeftTop = positionsToCellsIdx({
|
||||||
|
x: player1.x + dx + offsetCollision - halfCellSize,
|
||||||
|
y: player1.y + dy + offsetCollision - halfCellSize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const destinationRightTop = positionsToCellsIdx({
|
||||||
|
x: player1.x + dx - offsetCollision + halfCellSize,
|
||||||
|
y: player1.y + dy + offsetCollision - halfCellSize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const destinationLeftBottom = positionsToCellsIdx({
|
||||||
|
x: player1.x + dx + offsetCollision - halfCellSize,
|
||||||
|
y: player1.y + dy - offsetCollision + halfCellSize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const destinationRightBottom = positionsToCellsIdx({
|
||||||
|
x: player1.x + dx - offsetCollision + halfCellSize,
|
||||||
|
y: player1.y + dy - offsetCollision + halfCellSize,
|
||||||
|
});
|
||||||
|
|
||||||
|
player1.isMoving = isMoving;
|
||||||
|
|
||||||
|
//console.log(destinationLeftTop);
|
||||||
|
|
||||||
|
if (
|
||||||
|
//true
|
||||||
|
isCollidingWithObstractle(destinationLeftTop) ||
|
||||||
|
isCollidingWithObstractle(destinationRightTop) ||
|
||||||
|
isCollidingWithObstractle(destinationLeftBottom) ||
|
||||||
|
isCollidingWithObstractle(destinationRightBottom)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
//console.log(positionsToCellsIdx(player1));
|
||||||
|
}
|
||||||
|
|
||||||
|
player1.x += dx;
|
||||||
|
player1.y += dy;
|
||||||
|
|
||||||
|
const player1overBorder = overBorder({ x: player1.x, y: player1.y });
|
||||||
|
|
||||||
|
player1.x = player1overBorder.x;
|
||||||
|
player1.y = player1overBorder.y;
|
||||||
|
//console.log(positionsToCellsIdx({
|
||||||
|
// x: player1.x,
|
||||||
|
// y: player1.y,
|
||||||
|
//}))
|
||||||
|
//console.log(player1overBorder);
|
||||||
|
console.log([player1.x, player1.y]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawPlayer() {
|
||||||
|
let dampingX = 0;
|
||||||
|
let dampingY = 0;
|
||||||
|
if (player1.isMoving || !player1.isAlive) {
|
||||||
|
dampingX = Math.sin(millis() / (1800 / gameFrameRate)) * damping;
|
||||||
|
dampingY = Math.cos(millis() / (1800 / gameFrameRate)) * damping;
|
||||||
|
}
|
||||||
|
textSize(cellSize / 1.2);
|
||||||
|
|
||||||
|
if (player1.isAlive) {
|
||||||
|
text("🐙", player1.x + dampingX - halfCellSize, player1.y + dampingY + yOffsetDraw - halfCellSize);
|
||||||
|
if(debug){fill(0, 255, 0);
|
||||||
|
circle(player1.x + dampingX, player1.y + dampingY, 8);}
|
||||||
|
} else {
|
||||||
|
text("💀", player1.x - halfCellSize, player1.y + dampingY + yOffsetDraw - halfCellSize);
|
||||||
|
}
|
||||||
|
}
|
54
src/utils.js
Normal file
54
src/utils.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
function positionsToCellsIdx(position) {
|
||||||
|
const colIdx = Math.floor(position.x / cellSize);
|
||||||
|
const rowIdx = Math.floor(position.y / cellSize);
|
||||||
|
return { xi: colIdx, yi: rowIdx };
|
||||||
|
}
|
||||||
|
|
||||||
|
function overBorder(position) {
|
||||||
|
let xi = position.x;
|
||||||
|
let yi = position.y;
|
||||||
|
|
||||||
|
|
||||||
|
if (xi >= xpx) {
|
||||||
|
xi = xi - xpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xi < 0) {
|
||||||
|
xi = xpx + xi - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yi >= ypx) {
|
||||||
|
yi = yi - ypx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yi < 0) {
|
||||||
|
yi = ypx + yi - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { x: xi, y: yi };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function overBordFix(position){
|
||||||
|
|
||||||
|
let xi = position.x;
|
||||||
|
let yi = position.y;
|
||||||
|
|
||||||
|
if (yi < 0) {
|
||||||
|
yi = rows - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xi < 0) {
|
||||||
|
xi = cols - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yi >= rows) {
|
||||||
|
yi = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xi >= cols) {
|
||||||
|
xi = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { x: xi, y: yi };
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user