Good progress on UI and making this thing actually work.
|
@ -4,10 +4,10 @@ import {roomManager} from "./roomManager.mjs"
|
||||||
import { World} from "./world/world.mjs"
|
import { World} from "./world/world.mjs"
|
||||||
|
|
||||||
export class Game {
|
export class Game {
|
||||||
constructor(name) {
|
constructor(id, options) {
|
||||||
this.name = name;
|
this.id = id;
|
||||||
this.players = [];
|
this.players = [];
|
||||||
this.world = new World([16,16])
|
this.world = new World(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
addPlayer(id, name) {
|
addPlayer(id, name) {
|
||||||
|
@ -22,7 +22,7 @@ export class Game {
|
||||||
this.players = this.players.filter(obj => obj.id != id);
|
this.players = this.players.filter(obj => obj.id != id);
|
||||||
log.log("removed player - " + id)
|
log.log("removed player - " + id)
|
||||||
if (this.players.length < 1) {
|
if (this.players.length < 1) {
|
||||||
roomManager.removeGame(this.name);
|
roomManager.removeGameByID(this.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,15 +40,4 @@ export class Game {
|
||||||
}
|
}
|
||||||
return names
|
return names
|
||||||
}
|
}
|
||||||
|
|
||||||
getSettings() {
|
|
||||||
const settings =
|
|
||||||
{
|
|
||||||
mines: this.world.mines,
|
|
||||||
dimensions: this.world.dimensions,
|
|
||||||
name: this.name
|
|
||||||
}
|
|
||||||
return settings
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,31 @@
|
||||||
import {Game} from "./game.mjs"
|
import {Game} from "./game.mjs"
|
||||||
import * as log from "./log.mjs"
|
import * as log from "./log.mjs"
|
||||||
|
import * as util from "./util.mjs"
|
||||||
import {IllegalAction} from "./server/illegalAction.mjs"
|
import {IllegalAction} from "./server/illegalAction.mjs"
|
||||||
class RoomManager {
|
class RoomManager {
|
||||||
constructor(){
|
constructor(){
|
||||||
this.games = [];
|
this.games = [];
|
||||||
}
|
}
|
||||||
getGameByName(name, create) {
|
getGameByID(id) {
|
||||||
const game = this.games.filter(obj => obj.name == name)[0]
|
const game = this.games.filter(obj => obj.id == id)[0]
|
||||||
if (game === undefined && create) {
|
if (game === undefined) {
|
||||||
this.addGame(name);
|
return false
|
||||||
// Oh no.... This cant be good code.
|
|
||||||
// Coming back to it two months later. Horrible, but I don't know how to fix it. Maybe I'll leave it as an ancient artifact.
|
|
||||||
return this.getGameByName(name);
|
|
||||||
}
|
}
|
||||||
return game
|
return game
|
||||||
}
|
}
|
||||||
|
|
||||||
addGame(name, settings) {
|
addGame(id, options) {
|
||||||
const game = new Game(name, settings);
|
const game = new Game(id, options);
|
||||||
this.games.push(game);
|
this.games.push(game);
|
||||||
return game
|
return game
|
||||||
}
|
}
|
||||||
removeGame(name) {
|
removeGameByID(id) {
|
||||||
this.games = this.games.filter(obj => obj.name != name);
|
this.games = this.games.filter(obj => obj.id != id);
|
||||||
log.log("removed game - " + name)
|
log.log("removed game - " + id)
|
||||||
// Broken?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllIDs() {
|
getAllPlayerIDs() {
|
||||||
let ids = []
|
let ids = []
|
||||||
for (let i = 0; i < this.games.length; i++) {
|
for (let i = 0; i < this.games.length; i++) {
|
||||||
for (let j = 0; j < this.games[i].players.length; j++) {
|
for (let j = 0; j < this.games[i].players.length; j++) {
|
||||||
|
@ -37,26 +35,44 @@ class RoomManager {
|
||||||
return ids
|
return ids
|
||||||
}
|
}
|
||||||
|
|
||||||
joinClientToGame(room, nick, id, client) {
|
getAllGameIDs() {
|
||||||
if (this.getAllIDs().includes(id)) {
|
let ids = []
|
||||||
|
for (let i = 0; i < this.games.length; i++) {
|
||||||
|
ids.push(this.games[i].id)
|
||||||
|
}
|
||||||
|
return ids
|
||||||
|
}
|
||||||
|
|
||||||
|
playerJoinGame(roomCode, playerName, playerID) {
|
||||||
|
// See if the client is already in a game
|
||||||
|
console.log(roomCode, playerName)
|
||||||
|
if (this.getAllPlayerIDs().includes(playerID)) {
|
||||||
return new IllegalAction(id, 22)
|
return new IllegalAction(id, 22)
|
||||||
}
|
}
|
||||||
if (nick.length > 9) {
|
if (!this.getAllGameIDs().includes(roomCode)) {
|
||||||
return new IllegalAction(id, 21)
|
return new IllegalAction(id, 30)
|
||||||
}
|
}
|
||||||
const game = this.getGameByName(room, true);
|
const game = this.getGameByID(roomCode);
|
||||||
const player = game.addPlayer(id, nick);
|
const player = game.addPlayer(playerID, playerName);
|
||||||
|
// See if player name is taken already
|
||||||
if (player === false) {
|
if (player === false) {
|
||||||
this.removeGame(game)
|
this.removeGame(game)
|
||||||
return new IllegalAction(id, 20)
|
return new IllegalAction(id, 20)
|
||||||
}
|
}
|
||||||
|
return [game, player]
|
||||||
client.join(game.name)
|
|
||||||
client.game = game;
|
|
||||||
client.player = player
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playerCreateGame(options, playerName, playerID) {
|
||||||
|
if (this.getAllPlayerIDs().includes(playerID)) {
|
||||||
|
return new IllegalAction(id, 22)
|
||||||
|
}
|
||||||
|
console.log(options)
|
||||||
|
const id = util.createCode()
|
||||||
|
const game = this.addGame(id, options)
|
||||||
|
const player = game.addPlayer(playerID, playerName);
|
||||||
|
return [game, player]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import {IllegalAction} from "./illegalAction.mjs"
|
||||||
import * as log from "../log.mjs"
|
import * as log from "../log.mjs"
|
||||||
import {roomManager} from "../roomManager.mjs"
|
import {roomManager} from "../roomManager.mjs"
|
||||||
import {io} from "./io.mjs"
|
import {io} from "./io.mjs"
|
||||||
var oldWorld = 0
|
|
||||||
|
|
||||||
io.on('connection', function(client){
|
io.on('connection', function(client){
|
||||||
connected(client)
|
connected(client)
|
||||||
|
@ -12,34 +11,54 @@ io.on('connection', function(client){
|
||||||
function connected(client) {
|
function connected(client) {
|
||||||
client.sync = function() {
|
client.sync = function() {
|
||||||
const tempWorld = client.game.world.obfuscate();
|
const tempWorld = client.game.world.obfuscate();
|
||||||
io.to(client.game.name).emit('sync',{world: tempWorld})
|
io.to(client.game.id).emit('sync',{world: tempWorld})
|
||||||
}
|
}
|
||||||
|
|
||||||
client.sendMeta = function() {
|
client.sendMeta = function() {
|
||||||
const roomSettings = client.game.getSettings();
|
const roomID = client.game.id
|
||||||
const roomPlayers = client.game.players; // Dont send client id's to everyone, TODO
|
const roomPlayers = client.game.players; // Dont send client id's to everyone, TODO
|
||||||
const metadata = {players: roomPlayers, settings: roomSettings}
|
const metadata = {players: roomPlayers, roomID: roomID}
|
||||||
io.to(client.game.name).emit('metadata', metadata)
|
io.to(client.game.id).emit('metadata', metadata)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const id = client.game.id
|
||||||
|
client.emit('message', id)
|
||||||
}
|
}
|
||||||
|
|
||||||
client.game = "";
|
client.game = "";
|
||||||
client.player = "";
|
client.player = "";
|
||||||
|
|
||||||
client.on('disconnect', function(){
|
client.on('disconnect', function(){
|
||||||
if (!roomManager.getAllIDs().includes(client.id)) return new IllegalAction(client.id, 22)
|
if (!roomManager.getAllPlayerIDs().includes(client.id)) return new IllegalAction(client.id, 22)
|
||||||
log.log(client.id + ' disconnected.', 'FgCyan')
|
log.log(client.id + ' disconnected.', 'FgCyan')
|
||||||
client.game.removePlayerByID(client.id)
|
client.game.removePlayerByID(client.id)
|
||||||
client.sendMeta();
|
client.sendMeta();
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on('joinGame', function(data){
|
client.on('joinGame', function(data){
|
||||||
if(!roomManager.joinClientToGame(data.room, data.name, client.id, client)) return
|
const info = roomManager.playerJoinGame(data.room, data.name, client.id)
|
||||||
|
client.join(info[0].id)
|
||||||
|
client.game = info[0];
|
||||||
|
client.player = info[1]
|
||||||
client.sync()
|
client.sync()
|
||||||
log.log(`${client.id} joined the game as ${data.name} requesting to join room: ${data.room}`, 'FgMagenta');
|
log.log(`${client.id} joined the game as ${data.name} requesting to join room: ${data.room}`, 'FgMagenta');
|
||||||
client.emit('inGame', true)
|
client.emit('inGame', true)
|
||||||
client.sendMeta()
|
client.sendMeta()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
client.on('createGame', function(data){
|
||||||
|
const info = roomManager.playerCreateGame(data.options, data.name, client.id)
|
||||||
|
client.join(info[0].id)
|
||||||
|
client.game = info[0];
|
||||||
|
client.player = info[1]
|
||||||
|
|
||||||
|
log.log(`${client.id} joined the game as ${data.name} `, 'FgMagenta');
|
||||||
|
client.emit('inGame', true)
|
||||||
|
client.sync()
|
||||||
|
client.sendMeta()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
client.on('leaveGame', function(data){
|
client.on('leaveGame', function(data){
|
||||||
log.log(client.id + ' disconnected.')
|
log.log(client.id + ' disconnected.')
|
||||||
|
@ -49,8 +68,8 @@ function connected(client) {
|
||||||
|
|
||||||
|
|
||||||
client.on('clickCanvas', function(data){
|
client.on('clickCanvas', function(data){
|
||||||
if (!roomManager.getAllIDs().includes(client.id)) return new IllegalAction(client.id, 1)
|
if (!roomManager.getAllPlayerIDs().includes(client.id)) return new IllegalAction(client.id, 1)
|
||||||
client.game.world.click([data.tilePosition[0],data.tilePosition[1]], data.mode, client.player)
|
client.game.world.click(data.tilePosition[0],data.tilePosition[1], data.mode, client.player)
|
||||||
|
|
||||||
client.sync()
|
client.sync()
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
|
import crypto from "crypto";
|
||||||
export function randomNumber(min, max) {
|
export function randomNumber(min, max) {
|
||||||
return Math.floor(Math.random() * (max - min) + min);
|
return Math.floor(Math.random() * (max - min) + min);
|
||||||
}
|
}
|
||||||
export function clamp(number, min, max) {
|
export function clamp(number, min, max) {
|
||||||
return Math.max(min, Math.min(number, max));
|
return Math.max(min, Math.min(number, max));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createCode() {
|
||||||
|
const randomString = crypto.randomBytes(3).toString("hex").toUpperCase()
|
||||||
|
return randomString
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
export function flag(data, location, player) {
|
export function flag(x, y, data, player) {
|
||||||
let tile = data[location[0]][location[1]]
|
let tile = data[x][y]
|
||||||
|
|
||||||
if (!tile.mask || tile.color === 0) return data
|
if (!tile.mask || tile.color === 0) return data
|
||||||
const color = player.color * 1
|
const color = player.color * 1
|
||||||
|
@ -17,6 +17,6 @@ export function flag(data, location, player) {
|
||||||
tile.flag = 0;
|
tile.flag = 0;
|
||||||
}
|
}
|
||||||
console.log(tile.flag)
|
console.log(tile.flag)
|
||||||
data[location[0]][location[1]] = tile
|
data[x][y] = tile
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,22 +14,22 @@ const searchLoc =
|
||||||
[-1,-1],[0,-1],[1,-1]
|
[-1,-1],[0,-1],[1,-1]
|
||||||
]
|
]
|
||||||
|
|
||||||
export function generate(world, avoidLocation){
|
export function generate(avoidX, avoidY, world){
|
||||||
var minesPlanted = 0;
|
var minesPlanted = 0;
|
||||||
while (minesPlanted < world.mines || !(minesPlanted <= world.dimensions[0]*world.dimensions[1]-15)) {
|
while (minesPlanted < world.mines || !(minesPlanted <= world.width*world.height-15)) {
|
||||||
const x = util.randomNumber(0,world.dimensions[0])
|
const x = util.randomNumber(0,world.width)
|
||||||
const y = util.randomNumber(0,world.dimensions[1])
|
const y = util.randomNumber(0,world.height)
|
||||||
var suitable = true;
|
var suitable = true;
|
||||||
searchLoc.forEach(loc => {
|
searchLoc.forEach(loc => {
|
||||||
const tempx = x + loc[0]
|
const tempx = x + loc[0]
|
||||||
const tempy = y + loc[1]
|
const tempy = y + loc[1]
|
||||||
if (tempx === avoidLocation[0] && tempy === avoidLocation[1]) {
|
if (tempx === avoidX && tempy === avoidX) {
|
||||||
suitable = false;
|
suitable = false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// console.log([x,y] + ":----:" + avoidLocation)
|
|
||||||
if (x == avoidLocation[0] && y == avoidLocation[1]) { suitable = false }
|
if (x == avoidX && y == avoidY) { suitable = false }
|
||||||
if (world.data[x][y].type == 5) { suitable = false }
|
if (world.data[x][y].type == 5) { suitable = false }
|
||||||
|
|
||||||
if (suitable) {
|
if (suitable) {
|
||||||
world.data[x][y].type = 5
|
world.data[x][y].type = 5
|
||||||
|
|
|
@ -7,14 +7,14 @@ const searchLoc =
|
||||||
// Place Numbers
|
// Place Numbers
|
||||||
export function mark(world) {
|
export function mark(world) {
|
||||||
|
|
||||||
for(let x = 0; x < world.dimensions[0]; x++){
|
for(let x = 0; x < world.width; x++){
|
||||||
for(let y = 0; y < world.dimensions[1]; y++){
|
for(let y = 0; y < world.height; y++){
|
||||||
if (world.data[x][y].type === 1) {
|
if (world.data[x][y].type === 1) {
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
searchLoc.forEach(location => {
|
searchLoc.forEach(location => {
|
||||||
const tempx = x + location[0]
|
const tempx = x + location[0]
|
||||||
const tempy = y + location[1]
|
const tempy = y + location[1]
|
||||||
if (tempx >= 0 && tempy >= 0 && tempx < world.dimensions[0] && tempy < world.dimensions[1]) {
|
if (tempx >= 0 && tempy >= 0 && tempx < world.width && tempy < world.height) {
|
||||||
if (world.data[tempx][tempy].type === 5) {
|
if (world.data[tempx][tempy].type === 5) {
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
export function obfuscate(world) {
|
export function obfuscate(world) {
|
||||||
let tempWorld = world;
|
let tempWorld = world;
|
||||||
for(let x = 0; x < tempWorld.dimensions[0]; x++){
|
for(let x = 0; x < tempWorld.width; x++){
|
||||||
for(let y = 0; y < tempWorld.dimensions[1]; y++){
|
for(let y = 0; y < tempWorld.height; y++){
|
||||||
|
|
||||||
if (tempWorld.data[x][y].mask === true) {
|
if (tempWorld.data[x][y].mask === true) {
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import * as log from "../log.mjs"
|
import * as log from "../log.mjs"
|
||||||
import * as revealer from "./revealer.mjs"
|
import * as revealer from "./revealer.mjs"
|
||||||
export function place(data, location, id) {
|
export function place(x, y, data) {
|
||||||
let tile = data[location[0]][location[1]];
|
let tile = data[x][y];
|
||||||
if (tile.mask === true) {
|
if (tile.mask === true) {
|
||||||
if (tile.mask && tile.flag === 0) {
|
if (tile.mask && tile.flag === 0) {
|
||||||
tile.mask = false;
|
tile.mask = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
data[location[0]][location[1]] = tile;
|
data[x][y] = tile;
|
||||||
revealer.reveal(data, location)
|
revealer.reveal(x, y, data)
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,16 @@ const searchLoc =
|
||||||
[-1,-1],[0,-1],[1,-1]
|
[-1,-1],[0,-1],[1,-1]
|
||||||
]
|
]
|
||||||
|
|
||||||
export function reveal(data, location) {
|
export function reveal(x, y, data) {
|
||||||
if (data[location[0]][location[1]].type !== 5) {
|
if (data[x][y].type !== 5) {
|
||||||
|
|
||||||
var toSearch = [];
|
var toSearch = [];
|
||||||
var searchedLocations = [];
|
var searchedLocations = [];
|
||||||
toSearch.push(location)
|
toSearch.push([x, y])
|
||||||
|
|
||||||
if (data[location[0]][location[1]].type === 1) {
|
if (data[x][y].type === 1) {
|
||||||
while (toSearch.length > 0) {
|
while (toSearch.length > 0) {
|
||||||
|
console.log("LoopReveal")
|
||||||
const x = toSearch[0][0]
|
const x = toSearch[0][0]
|
||||||
const y = toSearch[0][1]
|
const y = toSearch[0][1]
|
||||||
searchedLocations.push(toSearch[0])
|
searchedLocations.push(toSearch[0])
|
||||||
|
|
|
@ -6,39 +6,40 @@ import * as flagger from "./flagger.mjs"
|
||||||
import * as placer from "./placer.mjs"
|
import * as placer from "./placer.mjs"
|
||||||
|
|
||||||
export class World {
|
export class World {
|
||||||
constructor(dimensions = [32,32], mines = 30) {
|
constructor(options) {
|
||||||
this.mines = 200
|
this.mines = options.mines
|
||||||
this.dimensions = dimensions;
|
this.width = options.width*1
|
||||||
|
this.height = options.height*1
|
||||||
this.isGenerated = false;
|
this.isGenerated = false;
|
||||||
this.isObfuscated = false;
|
this.isObfuscated = false;
|
||||||
this.isMarked = false;
|
this.isMarked = false;
|
||||||
this.data = Array.from(Array(this.dimensions[0]), () => new Array(this.dimensions[1]));
|
this.data = Array.from(Array(this.width), () => new Array(this.height));
|
||||||
for (let x = 0; x < this.dimensions[0]; x++){
|
for (let x = 0; x < this.width; x++){
|
||||||
for (let y = 0; y < this.dimensions[1]; y++){
|
for (let y = 0; y < this.height; y++){
|
||||||
this.data[x][y] = {type: 1, flag: 0, mask: true}
|
this.data[x][y] = {type: 1, flag: 0, mask: true}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
click (location, mode, player) {
|
click (x, y, mode, player) {
|
||||||
if (this.isGenerated) {
|
if (this.isGenerated) {
|
||||||
if (mode === 2) {
|
if (mode === 2) {
|
||||||
this.data = flagger.flag(this.data, location, player)
|
this.data = flagger.flag(x, y, this.data, player)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode === 0) {
|
if (mode === 0) {
|
||||||
this.data = placer.place(this.data, location, player)
|
this.data = placer.place(x, y, this.data, player)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.generate(location).mark();
|
this.generate(x, y).mark();
|
||||||
this.data = placer.place(this.data, location, player)
|
this.data = placer.place(x, y, this.data, player)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
generate(location) {
|
generate(x, y) {
|
||||||
if (this.isGenerated) return log.log("Already Generated");
|
if (this.isGenerated) return log.log("Already Generated");
|
||||||
return generator.generate(this, location);
|
return generator.generate(x, y, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
mark() {
|
mark() {
|
||||||
|
|
3
test.mjs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import * as util from "./scripts/util.mjs"
|
||||||
|
|
||||||
|
console.log(util.createCode())
|
BIN
www/fonts/moderndos.ttf
Normal file
BIN
www/fonts/moderndos.woff2
Normal file
87
www/game.html
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
<script src="http://localhost:35729/livereload.js" charset="utf-8"></script>
|
||||||
|
<script type="text/javascript" src="socket.io.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script src='scripts/script.js' type="module"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Canvas used to generate individual sprites off one sprite atlas -->
|
||||||
|
|
||||||
|
<canvas class="hidden" id="spriteJank" width=24 height=24></canvas>
|
||||||
|
<main>
|
||||||
|
<p id="message"></p>
|
||||||
|
<div id="game" style="display: none;">
|
||||||
|
<span id="leftBar">
|
||||||
|
<p id="status">Connection Status</p>
|
||||||
|
</span>
|
||||||
|
<span id="rightBar">
|
||||||
|
<div class="canvasContainer">
|
||||||
|
<canvas oncontextmenu="return false;" id="canvas" width=0 height=0></canvas>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="menu" id="menu">
|
||||||
|
<div id="joinType">
|
||||||
|
<h2>Create Room Or Join with code?</h2>
|
||||||
|
<button type="button" id="gotoCreate">create game</button>
|
||||||
|
<button type="button" id="gotoJoin">Join game</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="joinGame" style="display: none;">
|
||||||
|
<input type="text" id="joinGameCode" value="">
|
||||||
|
<input type="text" id="joinGameUsername" value="bob">
|
||||||
|
<button type="button" id="joinGameButton">Join</button>
|
||||||
|
</div>
|
||||||
|
<div id="createGame" >
|
||||||
|
<h2>Create Room</h2>
|
||||||
|
<hr>
|
||||||
|
<div class="leftRight">
|
||||||
|
<div class="left">
|
||||||
|
<h3>Settings</h3>
|
||||||
|
<div class="row">
|
||||||
|
<span>Username</span>
|
||||||
|
<input type="text" id="createGameUsername" value="">
|
||||||
|
</div>
|
||||||
|
<u>Color</u>
|
||||||
|
<div id="createGameSelectColorBar"></div>
|
||||||
|
<u>Mode</u>
|
||||||
|
<div id="createGameSelectModeBar"></div>
|
||||||
|
</div>
|
||||||
|
<span class="centerBar"></span>
|
||||||
|
<div class="right">
|
||||||
|
<h3>Game Settings</h3>
|
||||||
|
<div class="row">
|
||||||
|
<span>Percentage mines</span>
|
||||||
|
<input type="range" min="0" max="1000" value="50" class="slider">
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span>Number of mines</span>
|
||||||
|
<input type="number" id="createGameOptionsMines" value="100">
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span>Minefield Width</span>
|
||||||
|
<input type="number" id="createGameOptionsWidth" value="32">
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<span>Minefield Height</span>
|
||||||
|
<input type="number" id="createGameOptionsHeight" value="32">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<button type="button" id="createRoomButton">Start Game</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
BIN
www/img/city.png
Before Width: | Height: | Size: 296 B |
Before Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 358 B |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
BIN
www/img/modes.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
www/img/rock.png
Before Width: | Height: | Size: 292 B |
BIN
www/img/sea.png
Before Width: | Height: | Size: 285 B |
|
@ -1,53 +1,16 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title></title>
|
<title></title>
|
||||||
<script src="http://localhost:35729/livereload.js" charset="utf-8"></script>
|
<script src="http://localhost:35729/livereload.js" charset="utf-8"></script>
|
||||||
<script type="text/javascript" src="socket.io.min.js"></script>
|
<link rel="stylesheet" href="style.css">
|
||||||
<link rel="stylesheet" href="style.css">
|
</head>
|
||||||
<script src='scripts/script.js' type="module"></script>
|
<body>
|
||||||
</head>
|
<main>
|
||||||
<body>
|
<h1>Multiplayer Minesweeper!</h1>
|
||||||
<!-- Canvas used to generate individual sprites off one sprite atlas -->
|
<h2>Up to 8 Players</h2>
|
||||||
|
<a href="./game.html" class="buttonLink">Play Now!</a>
|
||||||
<canvas class="hidden" id="spriteJank" width=24 height=24></canvas>
|
</main>
|
||||||
<main>
|
</body>
|
||||||
<p id="message"></p>
|
|
||||||
<div id="game" style="display: none;">
|
</html>
|
||||||
<span id="leftBar">
|
|
||||||
<p id="status">Connection Status</p>
|
|
||||||
</span>
|
|
||||||
<span id="rightBar">
|
|
||||||
<div class="canvasContainer">
|
|
||||||
<canvas oncontextmenu="return false;" id="canvas" width=0 height=0></canvas>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="menu" id="menu">
|
|
||||||
<div id="joinType">
|
|
||||||
<h2>Create Room Or Join with code?</h2>
|
|
||||||
<button type="button" id="gotoCreate">create game</button>
|
|
||||||
<button type="button" id="gotoJoin">Join game</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div id="joinGame" style="display: none;">
|
|
||||||
<input type="text" id="joinGameCode" value="">
|
|
||||||
<input type="text" id="joinGameUsername" value="bob">
|
|
||||||
<button type="button" id="joinGameButton">Join</button>
|
|
||||||
</div>
|
|
||||||
<div id="createGame" style="display: none;">
|
|
||||||
<input type="text" id="createGameUsername" value="bob">
|
|
||||||
<button type="button" id="createRoomButton">create Room</button>
|
|
||||||
<div id="createGameOptions">
|
|
||||||
<h3>Options:</h3>
|
|
||||||
<input type="number" id="createGameOptionsMines" value="100">
|
|
||||||
<input type="number" id="createGameOptionsWidth" value="32">
|
|
||||||
<input type="number" id="createGameOptionsHeight" value="32">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import * as main from '../script.js';
|
|
||||||
import {tileArray} from './tileRenderer.js';
|
import {tileArray} from './tileRenderer.js';
|
||||||
import { cursor } from '../interface/game/mouse.js'
|
import { cursor } from '../interface/game/mouse.js'
|
||||||
import { ctx} from './html.js';
|
import { ctx} from './html.js';
|
||||||
|
@ -9,23 +8,22 @@ renderTiles()
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderTiles() { // DRAW THE IMAGE TO THE CANVAS.
|
export function renderTiles() { // DRAW THE IMAGE TO THE CANVAS.
|
||||||
|
const width = game.world.width;
|
||||||
|
const height = game.world.height;
|
||||||
|
canvas.width = game.tileSize*width;
|
||||||
|
canvas.height = game.tileSize*height;
|
||||||
let x, y = 0
|
let x, y = 0
|
||||||
const gridSize = game.gridSize;
|
|
||||||
const tileSize = game.tileSize;
|
const tileSize = game.tileSize;
|
||||||
for(x = 0; x < gridSize[0]; x++){
|
for(x = 0; x < width; x++){
|
||||||
for(y = 0; y < gridSize[1]; y++){
|
for(y = 0; y < height; y++){
|
||||||
const xu = x*tileSize;
|
const xu = x*tileSize;
|
||||||
const yu = y*tileSize;
|
const yu = y*tileSize;
|
||||||
const tempWorld = game.world.data;
|
const tempWorld = game.world.data;
|
||||||
// Draw buildings
|
|
||||||
|
|
||||||
ctx.drawImage(tileArray[tempWorld[x][y].type], xu,yu)
|
ctx.drawImage(tileArray[tempWorld[x][y].type], xu,yu)
|
||||||
|
|
||||||
// Draw Structures
|
|
||||||
const flag = tempWorld[x][y].flag
|
const flag = tempWorld[x][y].flag
|
||||||
// console.log(flag)
|
|
||||||
if (flag !== 0) {
|
if (flag !== 0) {
|
||||||
// console.log("FALAG")
|
|
||||||
ctx.drawImage(tileArray[flag + 7], xu,yu)
|
ctx.drawImage(tileArray[flag + 7], xu,yu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@ import {game} from "../game/game.js"
|
||||||
export var canvas = document.getElementById('canvas');
|
export var canvas = document.getElementById('canvas');
|
||||||
export var ctx = canvas.getContext('2d');
|
export var ctx = canvas.getContext('2d');
|
||||||
export var wrapper = document.getElementById('game');
|
export var wrapper = document.getElementById('game');
|
||||||
canvas.width = game.tileSize*game.gridSize[0];
|
|
||||||
canvas.height = game.tileSize*game.gridSize[1];
|
|
||||||
scaleEverythingGood()
|
scaleEverythingGood()
|
||||||
|
|
||||||
window.addEventListener('resize', scaleEverythingGood);
|
window.addEventListener('resize', scaleEverythingGood);
|
||||||
|
|
|
@ -1,20 +1,26 @@
|
||||||
import {game} from "/scripts/game/game.js"
|
import {game} from "/scripts/game/game.js"
|
||||||
|
|
||||||
export var tileArray = loadSprites();
|
export const tileArray = loadSprites('/img/mine.png', game.tileSize);
|
||||||
export function loadSprites() {
|
var counter = 0;
|
||||||
var tiles = [];
|
|
||||||
var spriteJank = document.getElementById('spriteJank');
|
|
||||||
spriteJank.width = game.tileSize;
|
|
||||||
spriteJank.height = game.tileSize;
|
|
||||||
var ctxj = spriteJank.getContext('2d');
|
|
||||||
var spriteSheet = new Image();
|
|
||||||
|
|
||||||
spriteSheet.src = '/mine.png'
|
export function loadSprites(path, tileSize) {
|
||||||
|
|
||||||
|
let tiles = [];
|
||||||
|
let spriteJank = document.createElement("canvas");
|
||||||
|
spriteJank.id = `spriteJank${counter}`
|
||||||
|
spriteJank.style = "display: none;"
|
||||||
|
spriteJank.width = tileSize;
|
||||||
|
spriteJank.height = tileSize;
|
||||||
|
document.body.appendChild(spriteJank);
|
||||||
|
let ctxj = spriteJank.getContext('2d');
|
||||||
|
let spriteSheet = new Image();
|
||||||
|
|
||||||
|
spriteSheet.src = path
|
||||||
spriteSheet.onload = function() {
|
spriteSheet.onload = function() {
|
||||||
|
|
||||||
const tileSize = game.tileSize;
|
|
||||||
for (let y = 0; y < 8; y++) {
|
for (let y = 0; y < spriteSheet.height/tileSize; y++) {
|
||||||
for (let x = 0; x < 8; x++) {
|
for (let x = 0; x < spriteSheet.width/tileSize; x++) {
|
||||||
ctxj.drawImage(spriteSheet, -x*tileSize,-y*tileSize)
|
ctxj.drawImage(spriteSheet, -x*tileSize,-y*tileSize)
|
||||||
var tmp = new Image();
|
var tmp = new Image();
|
||||||
tmp.src = spriteJank.toDataURL();
|
tmp.src = spriteJank.toDataURL();
|
||||||
|
@ -24,5 +30,7 @@ export function loadSprites() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spriteJank.remove();
|
spriteJank.remove();
|
||||||
|
|
||||||
return tiles;
|
return tiles;
|
||||||
}
|
}
|
||||||
|
export const menuArray = loadSprites('/img/modes.png', 32)
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
class Game {
|
class Game {
|
||||||
constructor(tileSize, gridSize, world, status) {
|
constructor(tileSize, gridSize, world, status) {
|
||||||
this.tileSize = tileSize;
|
this.tileSize = tileSize;
|
||||||
this.gridSize = gridSize;
|
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
reset() {
|
reset() {
|
||||||
game = new Game(16, [16, 16], null, false);
|
game = new Game(16, null, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export var game = new Game(16, [16, 16])
|
export var game = new Game(16, null, false)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {statusElement} from "/scripts/interface/game/html.js"
|
const statusElement = document.getElementById("status")
|
||||||
|
|
||||||
export function updateConnectionStatus(connection) {
|
export function updateConnectionStatus(connection) {
|
||||||
statusElement.textContent = `Server Connection: ${connection}`
|
statusElement.textContent = `Server Connection: ${connection}`
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
export let statusElement = document.getElementById("status")
|
|
||||||
export let buttonBar = document.getElementById("buttonBar")
|
|
|
@ -1,6 +1,5 @@
|
||||||
import {game} from "../../game/game.js";
|
import {game} from "../../game/game.js";
|
||||||
import { clickCanvas } from "/scripts/net/netcode.js";
|
import { clickCanvas } from "/scripts/net/netcode.js";
|
||||||
import { getButton } from "/scripts/interface/game/picker.js";
|
|
||||||
import { canvas } from "../../display/html.js"
|
import { canvas } from "../../display/html.js"
|
||||||
|
|
||||||
class Cursor {
|
class Cursor {
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
import {tileArray} from "/scripts/display/tileRenderer.js"
|
|
||||||
import {buttonBar} from "/scripts/interface/game/html.js"
|
|
||||||
var button = 0;
|
|
||||||
|
|
||||||
function clickSelector(e) {
|
|
||||||
document.querySelectorAll('.button').forEach(item => {
|
|
||||||
item.style ="";
|
|
||||||
})
|
|
||||||
event.target.style = "background: lightslategray;"
|
|
||||||
button = event.target.no
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export function create() {
|
|
||||||
for(let i=0;i < 5;i++) {
|
|
||||||
let span = document.createElement('span')
|
|
||||||
span.className = "button"
|
|
||||||
let n;
|
|
||||||
switch (i) {
|
|
||||||
case (1):
|
|
||||||
n = 1
|
|
||||||
break;
|
|
||||||
case (2):
|
|
||||||
n = 2
|
|
||||||
break;
|
|
||||||
case (3):
|
|
||||||
n = 3
|
|
||||||
break;
|
|
||||||
case (4):
|
|
||||||
n = 4
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
n = 5
|
|
||||||
};
|
|
||||||
span.appendChild(tileArray[n]);
|
|
||||||
buttonBar.appendChild(span);
|
|
||||||
span.no = i;
|
|
||||||
span.addEventListener('click', e => {
|
|
||||||
clickSelector(e);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function getButton() {
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function destroy() {
|
|
||||||
while (buttonBar.lastChild) {
|
|
||||||
buttonBar.removeChild(buttonBar.lastChild)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,10 @@
|
||||||
import * as status from "../../net/status.js"
|
import * as status from "../../net/status.js"
|
||||||
import {joinGame, createGame} from "/scripts/net/netcode.js"
|
import {joinGame, createGame} from "/scripts/net/netcode.js"
|
||||||
import { changeScene } from "/scripts/interface/scene.js"
|
import { changeScene } from "/scripts/interface/scene.js"
|
||||||
|
import * as picker from "./picker.js"
|
||||||
|
import {tileArray, menuArray} from "/scripts/display/tileRenderer.js"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function ID(id) {
|
function ID(id) {
|
||||||
return document.getElementById(id)
|
return document.getElementById(id)
|
||||||
|
@ -13,6 +17,8 @@ const createGameMenu = ID("createGame")
|
||||||
ID("gotoCreate").addEventListener("click", e => {
|
ID("gotoCreate").addEventListener("click", e => {
|
||||||
joinType.style.display = "none"
|
joinType.style.display = "none"
|
||||||
createGameMenu.style.display = ""
|
createGameMenu.style.display = ""
|
||||||
|
picker.create("createGameSelectColorBar", tileArray, [8, 16])
|
||||||
|
picker.create("createGameSelectModeBar", menuArray, [0,4], "wide")
|
||||||
})
|
})
|
||||||
|
|
||||||
ID("gotoJoin").addEventListener("click", e => {
|
ID("gotoJoin").addEventListener("click", e => {
|
||||||
|
@ -29,7 +35,7 @@ ID("joinGameButton").addEventListener("click", e => {
|
||||||
function join(event) {
|
function join(event) {
|
||||||
const roomCode = ID("joinGameCode").value
|
const roomCode = ID("joinGameCode").value
|
||||||
const name = ID("joinGameUsername").value
|
const name = ID("joinGameUsername").value
|
||||||
if (room == '' || name == '' || status.get() == 'disconnected') return
|
if (roomCode == '' || name == '' || status.get() == 'disconnected') return
|
||||||
joinGame({room: roomCode, name: name})
|
joinGame({room: roomCode, name: name})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,6 +43,7 @@ function join(event) {
|
||||||
|
|
||||||
ID("createRoomButton").addEventListener("click", e => {
|
ID("createRoomButton").addEventListener("click", e => {
|
||||||
create(e)
|
create(e)
|
||||||
|
picker.destroy("createGameSelectColorBar")
|
||||||
});
|
});
|
||||||
|
|
||||||
function create(event) {
|
function create(event) {
|
||||||
|
@ -45,14 +52,17 @@ function create(event) {
|
||||||
const width = ID("createGameOptionsWidth").value
|
const width = ID("createGameOptionsWidth").value
|
||||||
const height = ID("createGameOptionsHeight").value
|
const height = ID("createGameOptionsHeight").value
|
||||||
if (name == '' || mines == '' || width == '' || height == '' || status.get() == 'disconnected') return
|
if (name == '' || mines == '' || width == '' || height == '' || status.get() == 'disconnected') return
|
||||||
|
const options = {
|
||||||
const data =
|
|
||||||
{
|
|
||||||
name: name,
|
|
||||||
mines: mines,
|
mines: mines,
|
||||||
width: width,
|
width: width,
|
||||||
height: height
|
height: height
|
||||||
}
|
}
|
||||||
|
const data =
|
||||||
|
{
|
||||||
|
name: name,
|
||||||
|
options: options
|
||||||
|
}
|
||||||
|
console.log(data)
|
||||||
createGame(data)
|
createGame(data)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
40
www/scripts/interface/mainmenu/picker.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
function clickSelector(e, parentID) {
|
||||||
|
document.getElementById(parentID).querySelectorAll('.button').forEach(item => {
|
||||||
|
item.style ="";
|
||||||
|
item.active ="false";
|
||||||
|
})
|
||||||
|
event.target.style = "background: #4CAF50;"
|
||||||
|
event.target.active = "true"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getButton(parentID) {
|
||||||
|
document.getElementById(parentID).querySelectorAll('.button').forEach(item => {
|
||||||
|
if (item.active === "true") {
|
||||||
|
return item.no
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function create(parentID, spriteSheet, ranges, style = "") {
|
||||||
|
const buttonBar = document.getElementById(parentID);
|
||||||
|
|
||||||
|
for(let i=0;i < ranges[1]-ranges[0];i++) {
|
||||||
|
let span = document.createElement('span')
|
||||||
|
span.className = `button ${style}`
|
||||||
|
const n = i + ranges[0]
|
||||||
|
span.appendChild(spriteSheet[n]);
|
||||||
|
buttonBar.appendChild(span);
|
||||||
|
span.no = i;
|
||||||
|
span.addEventListener('click', e => {
|
||||||
|
clickSelector(e, parentID);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function destroy(parentID) {
|
||||||
|
const buttonBar = document.getElementById(parentID);
|
||||||
|
while (buttonBar.lastChild) {
|
||||||
|
buttonBar.removeChild(buttonBar.lastChild)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
import * as picker from "/scripts/interface/game/picker.js"
|
|
||||||
|
|
||||||
export function changeScene(scene) {
|
export function changeScene(scene) {
|
||||||
if (scene == "game") {
|
if (scene == "game") {
|
||||||
|
|
|
@ -32,7 +32,7 @@ socket.on('disconnect', function(data){
|
||||||
|
|
||||||
socket.on('message', function(data) {
|
socket.on('message', function(data) {
|
||||||
const mess = document.getElementById("message")
|
const mess = document.getElementById("message")
|
||||||
mess.textContent = `Server Connection: ${connection}`
|
mess.textContent = `${data}`
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -63,5 +63,6 @@ socket.on('inGame', function(data){
|
||||||
|
|
||||||
socket.on('sync', function (sync){
|
socket.on('sync', function (sync){
|
||||||
game.world = sync.world;
|
game.world = sync.world;
|
||||||
|
console.log(game.world)
|
||||||
render()
|
render()
|
||||||
})
|
})
|
||||||
|
|
165
www/style.css
|
@ -1,16 +1,124 @@
|
||||||
|
* {
|
||||||
|
font-family: pixserif;
|
||||||
|
}
|
||||||
|
|
||||||
/* #mydiv {
|
h1, h2 {
|
||||||
position: absolute;
|
margin: 0px;
|
||||||
cursor: move;
|
}
|
||||||
z-index: 10;
|
|
||||||
background: coral;
|
h1 {
|
||||||
width: 30px;
|
font-size: 3em;
|
||||||
height: 30px;
|
}
|
||||||
border: 1px solid #d3d3d3;
|
|
||||||
} */
|
h2 {
|
||||||
|
font-size: 2.5em;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
p, span, input, button, u {
|
||||||
|
font-size: 1.7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border-color: white;
|
||||||
|
/* height: 3px; */
|
||||||
|
border: none;
|
||||||
|
height: 3px;
|
||||||
|
background: white;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content:space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row > span {
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftRight {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.centerBar {
|
||||||
|
width: 3px;
|
||||||
|
height: inherit;
|
||||||
|
background: white
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
display: inline;
|
||||||
|
margin: 40px;
|
||||||
|
/* background: red; */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
display: inline;
|
||||||
|
margin: 40px;
|
||||||
|
/* background: red; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider {
|
||||||
|
display: inline-block;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
height: 55px;
|
||||||
|
width: 300px;
|
||||||
|
background-color: lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
width: 20px;
|
||||||
|
height: 60px;
|
||||||
|
background: #f1f8t6;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.slider::-moz-range-thumb {
|
||||||
|
width: 20px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 0px;
|
||||||
|
background: #f1f8t6;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=button], button, .buttonLink {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
padding: 14px 20px;
|
||||||
|
margin: 8px 0;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer; }
|
||||||
|
|
||||||
|
input[type=number], input[type=text] {
|
||||||
|
/* width: 100%; */
|
||||||
|
width: 300px;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 12px 20px;
|
||||||
|
margin: 3px 0;
|
||||||
|
border: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: lightgray; }
|
||||||
|
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
/* font-weight: 500; */
|
||||||
|
font-family: "pixserif";
|
||||||
|
src: url('fonts/moderndos.woff2') format('woff2'),
|
||||||
|
url('fonts/moderndos.ttf') format('truetype');
|
||||||
|
}
|
||||||
span.button > img {
|
span.button > img {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
image-rendering: optimizeSpeed; /* STOP SMOOTHING, GIVE ME SPEED */
|
image-rendering: optimizeSpeed; /* STOP SMOOTHING, GIVE ME SPEED */
|
||||||
|
@ -18,22 +126,29 @@ span.button > img {
|
||||||
image-rendering: -o-crisp-edges; /* Opera */
|
image-rendering: -o-crisp-edges; /* Opera */
|
||||||
image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
|
image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
|
||||||
image-rendering: pixelated; /* Chrome */
|
image-rendering: pixelated; /* Chrome */
|
||||||
-ms-interpolation-mode: nearest-neighbor; /* IE8+ */
|
|
||||||
width: 70px;
|
width: 70px;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
transform: translate(0, 8px);
|
transform: translate(0, 10px);
|
||||||
border: 2px solid darkgray;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: lightgray;
|
background: lightgray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.button.wide {
|
||||||
|
width: 128px;
|
||||||
|
height: 128px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.button.wide > img {
|
||||||
|
width: 108px;
|
||||||
|
height: 108px;
|
||||||
|
}
|
||||||
|
|
||||||
span.button {
|
span.button {
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background: tan;
|
background: lightgray;
|
||||||
width:90px;
|
width:90px;
|
||||||
height:90px;
|
height:90px;
|
||||||
margin: 5px 5px 5px 5px;
|
margin: 5px 5px 5px 5px;
|
||||||
|
@ -111,25 +226,5 @@ body {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #2c2f33;
|
background-color: #2c2f33;
|
||||||
color: white;
|
color: white;
|
||||||
font-variant: normal;
|
|
||||||
font-family: verdana;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 25pt;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
h2 {
|
|
||||||
font-size: 20pt;
|
|
||||||
}
|
|
||||||
p{
|
|
||||||
/* font-size: 12pt; */
|
|
||||||
/* text-align: left; */
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: 12pt;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|