Transferred from GitHub
This commit is contained in:
parent
d8ab855bd1
commit
5b0863d2c4
5 changed files with 495 additions and 0 deletions
BIN
data/icons.png
Normal file
BIN
data/icons.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 849 B |
25
index.html
Normal file
25
index.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="Stylesheet" href="styles/styles.css">
|
||||||
|
<title>MINESWEEPER</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Grid -->
|
||||||
|
<div id="grid">
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="grid_head">
|
||||||
|
<h2 id="flags" style="display:inline-block;">010</h2>
|
||||||
|
<button id="restart">Restart</button>
|
||||||
|
<h2 id="time" style="display:inline-block;">000</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Grid -->
|
||||||
|
<canvas width="700" height="600"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Scripts -->
|
||||||
|
<script src="scripts/script.js"></script>
|
||||||
|
<script src="scripts/game.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
392
scripts/game.js
Normal file
392
scripts/game.js
Normal file
|
@ -0,0 +1,392 @@
|
||||||
|
// Variables
|
||||||
|
/// Game
|
||||||
|
var tilesGrid = [];
|
||||||
|
var tilesShown = [];
|
||||||
|
var flagsGrid = [];
|
||||||
|
var playing = true;
|
||||||
|
/// For loops
|
||||||
|
var rippling = false;
|
||||||
|
/// Games
|
||||||
|
var flags = gridBombs;
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
/// Private
|
||||||
|
function _checkWin(){
|
||||||
|
// Matches
|
||||||
|
var matches = 0;
|
||||||
|
|
||||||
|
for(var y = 0; y < gridHeight; y++){
|
||||||
|
for(var x = 0; x < gridWidth; x++){
|
||||||
|
if(flagsGrid[y*gridHeight+x]
|
||||||
|
&& tilesGrid[y*gridHeight+x]){
|
||||||
|
matches++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(matches >= gridBombs){
|
||||||
|
_winGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _updateScreen(){
|
||||||
|
// Mode of tile?
|
||||||
|
var tileMode = 0;
|
||||||
|
|
||||||
|
// Thing
|
||||||
|
for(var y = 0; y < gridHeight; y++){
|
||||||
|
for(var x = 0; x < gridWidth; x++){
|
||||||
|
// Drawing with CANVAS
|
||||||
|
let _tileWidth = UI_Canvas.width / gridWidth;
|
||||||
|
let _tileHeight = UI_Canvas.height / gridHeight;
|
||||||
|
|
||||||
|
// Drawing
|
||||||
|
/// New Object
|
||||||
|
ctx.beginPath();
|
||||||
|
|
||||||
|
/// Color?
|
||||||
|
ctx.fillStyle = "#ffffff";
|
||||||
|
|
||||||
|
// Game over, show mines
|
||||||
|
if(!playing
|
||||||
|
&& tilesGrid[y*gridHeight+x] == 1){
|
||||||
|
tileMode = 0;
|
||||||
|
}
|
||||||
|
// Numbered tiles
|
||||||
|
else if(!tilesGrid[y*gridHeight+x]
|
||||||
|
&& tilesShown[y*gridHeight+x]){
|
||||||
|
tileMode = 1;
|
||||||
|
}
|
||||||
|
// Flag tiles
|
||||||
|
else if(flagsGrid[y*gridHeight+x]){
|
||||||
|
tileMode = 2;
|
||||||
|
}
|
||||||
|
// Standard tiles
|
||||||
|
else{
|
||||||
|
tileMode = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// What tile mode do we use?
|
||||||
|
switch(tileMode){
|
||||||
|
case 0:
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 2,0, 16,16);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
|
||||||
|
// Todo: Add numbered tiles support
|
||||||
|
switch(_getNumber(x,y)){
|
||||||
|
case "":
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 3,0, 16,16);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 0,1, 16,16);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 1,1, 16,16);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 2,1, 16,16);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 3,1, 16,16);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 0,2, 16,16);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 1,2, 16,16);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 2,2, 16,16);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 3,2, 16,16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 1,0, 16,16);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
drawTileMap("data/icons.png", x, y, _tileWidth, _tileHeight, 0,0, 16,16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Win check
|
||||||
|
_checkWin();
|
||||||
|
|
||||||
|
// UI
|
||||||
|
UI_Flags.textContent = flags;
|
||||||
|
console.log(flags);
|
||||||
|
}
|
||||||
|
function _startGrid(){
|
||||||
|
/*
|
||||||
|
This is different from _createGrid
|
||||||
|
|
||||||
|
this will just start up the systems.
|
||||||
|
_createGrid will be triggered when you first click
|
||||||
|
making the grid spawn
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Reset grid
|
||||||
|
tilesGrid = [];
|
||||||
|
tilesShown = [];
|
||||||
|
|
||||||
|
// Loops for Grids
|
||||||
|
for(var y = 0; y < gridHeight; y++){
|
||||||
|
for(var x = 0; x < gridWidth; x++){
|
||||||
|
// Add to shown
|
||||||
|
tilesGrid.push(0);
|
||||||
|
tilesShown.push(0);
|
||||||
|
flagsGrid.push(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _createGrid(){
|
||||||
|
// Mouse to cursor pos
|
||||||
|
// Get mouse position
|
||||||
|
var _mx = mousePosition[0];
|
||||||
|
var _my = mousePosition[1];
|
||||||
|
|
||||||
|
// Convert it to local grid space
|
||||||
|
_mx -= UI_Canvas.offsetLeft;
|
||||||
|
_my -= UI_Canvas.offsetTop;
|
||||||
|
|
||||||
|
// Convert _mx and _my to be able to be used to find the tile the user wants
|
||||||
|
let _x = Math.floor(_mx / (UI_Canvas.width / gridWidth));
|
||||||
|
let _y = Math.floor(_my / (UI_Canvas.height / gridHeight));
|
||||||
|
|
||||||
|
// Random Bombs
|
||||||
|
for(var i = 0; i < gridBombs; i++){
|
||||||
|
// Placeholder positions
|
||||||
|
var _bx = 0;
|
||||||
|
var _by = 0;
|
||||||
|
|
||||||
|
// Checking for an unused space
|
||||||
|
while(true){
|
||||||
|
_bx = parseInt(Math.random() * 10);
|
||||||
|
_by = parseInt(Math.random() * 10);
|
||||||
|
|
||||||
|
if(tilesGrid[_by*gridHeight+_bx] == 0
|
||||||
|
&& _bx != _x && _by != _y){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply position
|
||||||
|
tilesGrid[_by*gridHeight+_bx] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _chkTile(x,y){
|
||||||
|
return tilesGrid[y*gridHeight+x];
|
||||||
|
}
|
||||||
|
function _setTile(x,y, val){
|
||||||
|
tilesShown[y*gridHeight+x] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getNumber(x,y){
|
||||||
|
// Result number
|
||||||
|
var result = 0;
|
||||||
|
|
||||||
|
// Go through all tiles
|
||||||
|
for(var _y = y-1; _y < y+2; _y++){
|
||||||
|
for(var _x = x-1; _x < x+2; _x++){
|
||||||
|
if((_y >= 0 && _y < gridHeight)
|
||||||
|
&& (_x >= 0 && _x < gridWidth)){
|
||||||
|
if(_chkTile(_x,_y) > 0){
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result == 0){
|
||||||
|
result = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return result
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function spawnRipple(x, y) {
|
||||||
|
// Tile with bombs near?
|
||||||
|
if(_getNumber(x,y) != ""){
|
||||||
|
rippling = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checking if this is a bad tile..
|
||||||
|
for (var _y = -1; _y < 2; _y++) {
|
||||||
|
for (var _x = -1; _x < 2; _x++) {
|
||||||
|
// Checking for things that will cause it to fail
|
||||||
|
if (_x == 0 && _y == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (x + _x < 0 || x + _x >= gridWidth || y + _y < 0 || y + _y >= gridHeight) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No diagonal
|
||||||
|
if((_x == -1 && _y == -1)
|
||||||
|
|| (_x == -1 && _y == 1)
|
||||||
|
|| (_x == 1 && _y == -1)
|
||||||
|
|| (_x == 1 && _y == 1)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bombs near?
|
||||||
|
if(_getNumber(x+_x, y+_y) != ""){
|
||||||
|
tilesShown[(y + _y) * gridWidth + (x + _x)] = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The beef and potatoes!
|
||||||
|
if (!tilesShown[(y + _y) * gridWidth + (x + _x)] && !_chkTile(x + _x, y + _y)) {
|
||||||
|
tilesShown[(y + _y) * gridWidth + (x + _x)] = 1;
|
||||||
|
spawnRipple(x + _x, y + _y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checking for a fail
|
||||||
|
for (var _y = -1; _y < 2; _y++) {
|
||||||
|
for (var _x = -1; _x < 2; _x++) {
|
||||||
|
// Checking for things that will cause it to fail
|
||||||
|
if (_x == 0 && _y == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (x + _x < 0 || x + _x >= gridWidth || y + _y < 0 || y + _y >= gridHeight) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The beef and potatoes!
|
||||||
|
if (!tilesShown[(y + _y) * gridWidth + (x + _x)] && !_chkTile(x + _x, y + _y)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failing..
|
||||||
|
rippling = false;
|
||||||
|
}
|
||||||
|
function _revealTiles(x, y) {
|
||||||
|
// Are we clicking on a flag?
|
||||||
|
if(flagsGrid[y*gridHeight+x] != 0){return};
|
||||||
|
|
||||||
|
// Set clicked tile
|
||||||
|
_setTile(x, y, 1);
|
||||||
|
|
||||||
|
// RIPPLE EFFECT METHOD
|
||||||
|
rippling = true;
|
||||||
|
// Force ripple ending if things carry on forever
|
||||||
|
setTimeout(function(){
|
||||||
|
rippling = false;
|
||||||
|
}, 1500);
|
||||||
|
|
||||||
|
// Ripple!
|
||||||
|
while(rippling){
|
||||||
|
spawnRipple(x,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// You messed up..
|
||||||
|
if (tilesGrid[y * gridWidth + x]) {
|
||||||
|
_endGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _clickTile(){
|
||||||
|
// The whole reason I was going to use Divs is because
|
||||||
|
// It would have been easier but.. No.. Of course not
|
||||||
|
// Javascript is Never simple or it never works like C/C++ does.
|
||||||
|
|
||||||
|
// Get mouse position
|
||||||
|
var _mx = mousePosition[0];
|
||||||
|
var _my = mousePosition[1];
|
||||||
|
|
||||||
|
// Convert it to local grid space
|
||||||
|
_mx -= UI_Canvas.offsetLeft;
|
||||||
|
_my -= UI_Canvas.offsetTop;
|
||||||
|
|
||||||
|
// Convert _mx and _my to be able to be used to find the tile the user wants
|
||||||
|
let _x = Math.floor(_mx / (UI_Canvas.width / gridWidth));
|
||||||
|
let _y = Math.floor(_my / (UI_Canvas.height / gridHeight));
|
||||||
|
|
||||||
|
console.log(_x, _y);
|
||||||
|
|
||||||
|
// Check if we need to init the grid
|
||||||
|
let sum = 0;
|
||||||
|
for(var i = 0; i < tilesGrid.length; i++){
|
||||||
|
sum += tilesGrid[i];
|
||||||
|
}
|
||||||
|
if(sum == 0){
|
||||||
|
_createGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update
|
||||||
|
_revealTiles(_x, _y);
|
||||||
|
}
|
||||||
|
function _addFlag(event){
|
||||||
|
// Prevent default
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// Too many flags?
|
||||||
|
if(flags <= 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get mouse position
|
||||||
|
var _mx = mousePosition[0];
|
||||||
|
var _my = mousePosition[1];
|
||||||
|
|
||||||
|
// Convert it to local grid space
|
||||||
|
_mx -= UI_Canvas.offsetLeft;
|
||||||
|
_my -= UI_Canvas.offsetTop;
|
||||||
|
|
||||||
|
// Convert _mx and _my to be able to be used to find the tile the user wants
|
||||||
|
let _x = Math.floor(_mx / (UI_Canvas.width / gridWidth));
|
||||||
|
let _y = Math.floor(_my / (UI_Canvas.height / gridHeight));
|
||||||
|
|
||||||
|
// Now, let's add the flag!
|
||||||
|
flagsGrid[_y*gridHeight+_x] = !flagsGrid[_y*gridHeight+_x];
|
||||||
|
|
||||||
|
console.log("New Flag: " + flagsGrid[_y*gridHeight+_x]);
|
||||||
|
}
|
||||||
|
function _getFlags(){
|
||||||
|
flags = gridBombs;
|
||||||
|
for(var y = 0; y < gridHeight; y++){
|
||||||
|
for(var x = 0; x < gridWidth; x++){
|
||||||
|
if(flagsGrid[y*gridHeight+x] == 1){
|
||||||
|
flags--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Public
|
||||||
|
function _endGame(){
|
||||||
|
alert("YOU HIT A MINE!");
|
||||||
|
playing = false;
|
||||||
|
}
|
||||||
|
function _winGame(){
|
||||||
|
alert("You Won!");
|
||||||
|
}
|
||||||
|
function _onUpdate(){
|
||||||
|
// Drawing:
|
||||||
|
_getFlags();
|
||||||
|
_updateScreen();
|
||||||
|
}
|
||||||
|
function _onStart(){
|
||||||
|
// Init
|
||||||
|
_startGrid();
|
||||||
|
|
||||||
|
// Start loop
|
||||||
|
thread = window.setInterval(_onUpdate, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Events
|
||||||
|
window.addEventListener("load", _onStart);
|
||||||
|
UI_Canvas.addEventListener("click", _clickTile);
|
||||||
|
UI_Canvas.addEventListener("contextmenu", _addFlag);
|
36
scripts/script.js
Normal file
36
scripts/script.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Variables
|
||||||
|
/// Constants
|
||||||
|
var gridWidth = 10;
|
||||||
|
var gridHeight = 10;
|
||||||
|
var gridBombs = 10;
|
||||||
|
/// DOM
|
||||||
|
const UI_Grid = document.getElementById("grid");
|
||||||
|
const UI_Canvas = document.querySelector("canvas");
|
||||||
|
const UI_Flags = document.getElementById("flags");
|
||||||
|
/// Canvas
|
||||||
|
const ctx = UI_Canvas.getContext("2d");
|
||||||
|
/// Debug
|
||||||
|
const DBG_SHOWMINES = true;
|
||||||
|
/// Thread
|
||||||
|
var thread = null;
|
||||||
|
/// UI
|
||||||
|
var mousePosition = [];
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
function moveMouse(event){
|
||||||
|
mousePosition = [
|
||||||
|
event.clientX,
|
||||||
|
event.clientY
|
||||||
|
];
|
||||||
|
}
|
||||||
|
function drawTileMap(tilepath, x,y, w,h, tx,ty, tw,th){
|
||||||
|
ctx.imageSmoothingEnabled = false;
|
||||||
|
|
||||||
|
var tileset = new Image();
|
||||||
|
tileset.src = tilepath;
|
||||||
|
ctx.fillStyle = "#ffffff";
|
||||||
|
ctx.drawImage(tileset, tx*tw,ty*th, tw,th, x * w, y * h, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Events
|
||||||
|
window.addEventListener("mousemove", moveMouse);
|
42
styles/styles.css
Normal file
42
styles/styles.css
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/* Elements */
|
||||||
|
body{
|
||||||
|
background-color: #0A0A0A;
|
||||||
|
color: #FFFFFF
|
||||||
|
}
|
||||||
|
button{
|
||||||
|
background: #bbbbbb;
|
||||||
|
color: #2A2A2A;
|
||||||
|
|
||||||
|
border: 0px solid black;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
padding: 5px;
|
||||||
|
margin: 10px;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
canvas{
|
||||||
|
background: none;
|
||||||
|
color: #FFFFFF;
|
||||||
|
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Classes */
|
||||||
|
.grid_head{
|
||||||
|
background-color: #888888;
|
||||||
|
color: #aa0000;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Objects */
|
||||||
|
#grid{
|
||||||
|
background-color: #2A2A2A;
|
||||||
|
color: #FFFFFF;
|
||||||
|
|
||||||
|
width: 700px;
|
||||||
|
margin-left: 25%;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
Loading…
Reference in a new issue