Working Multiplayer system
This commit is contained in:
parent
962a376115
commit
ef376178df
BIN
Assets/Sheet.xcf
BIN
Assets/Sheet.xcf
Binary file not shown.
42
TODO.md
Normal file
42
TODO.md
Normal file
|
@ -0,0 +1,42 @@
|
|||
# Project To Do list
|
||||
|
||||
## Short Term
|
||||
- [] Kill socket when browser closes/inactive.
|
||||
- [] Make client get textures from single sprite sheet
|
||||
|
||||
## Mid Term
|
||||
- [] Implement Rooms with different games on server
|
||||
- [] Add room selection menu on client
|
||||
- [] Implement Players
|
||||
- [] Player Names
|
||||
- [] Player Colors
|
||||
- [] Prevent Duplicate player info
|
||||
## Long Term
|
||||
- [] Power and money system for players
|
||||
- [] Add land ownership
|
||||
- [] Land Claiming
|
||||
- [] Difficulty to claim hills and seas
|
||||
- [] Create bouy flag sprite
|
||||
- [] Make differentiation between land owned by different players
|
||||
- [] System to have animated widgets overtop of the canvas.
|
||||
- [] Explosion
|
||||
- [] Selection cursor
|
||||
- [] Color for different land status (claimed/open/unclaimable)
|
||||
- [] Create spites for classes of buildings for economy.
|
||||
- [x] Factory
|
||||
- [x] Farmland/town
|
||||
- [] Fishing area
|
||||
- [] Building selection menu
|
||||
## Longer Term
|
||||
|
||||
- [] Add tests to ensure features act as they should
|
||||
- [] Handle player death/leaving
|
||||
- [] Dead player's resources go to killer with some tax.
|
||||
- [] Leaving player's resources go to player
|
||||
## Finishing Touches
|
||||
- [] Sounds
|
||||
- [] Graphics Redo
|
||||
- [] Fancy webpage decorations
|
||||
|
||||
## Maybe
|
||||
- [] Chat
|
134
index.js
134
index.js
|
@ -1,9 +1,61 @@
|
|||
var noise = require('noisejs');
|
||||
var express = require('express');
|
||||
|
||||
var express = require('express');
|
||||
const worldgen = require("./worldgen.js")
|
||||
const util = require("./util.js")
|
||||
const gridSize = [18, 18];
|
||||
const perlinScale = 3;
|
||||
var world = generateWorld();
|
||||
|
||||
class Player {
|
||||
constructor(id, color) {
|
||||
this.id = id;
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
class Game {
|
||||
constructor() {
|
||||
this.players = [];
|
||||
this.world = worldgen.generateWorld(gridSize, perlinScale);
|
||||
}
|
||||
|
||||
addPlayer(id) {
|
||||
var color
|
||||
switch(util.randomNumber(1,4)) {
|
||||
case 1:
|
||||
color = "red";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
color = "aquamarine";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
color = "green";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
color = "yellow";
|
||||
break;
|
||||
}
|
||||
const player = new Player(id, color);
|
||||
this.players.push(player);
|
||||
}
|
||||
|
||||
removePlayer(id) {
|
||||
this.players = this.players.filter(obj => obj.id != id);
|
||||
console.log("removed player - " + id)
|
||||
}
|
||||
|
||||
getPlayerByID(id) {
|
||||
console.log(this.players)
|
||||
console.log(id)
|
||||
const player = this.players.filter(obj => obj.id == id)[0]
|
||||
return player
|
||||
}
|
||||
|
||||
}
|
||||
var game = new Game();
|
||||
|
||||
|
||||
var app = express() //Static resources server
|
||||
app.use(express.static(__dirname + '/www/'));var server = app.listen(8082, function () {
|
||||
|
@ -14,66 +66,36 @@ app.use(express.static(__dirname + '/www/'));var server = app.listen(8082, funct
|
|||
var io = require('socket.io')(server);/* Connection events */
|
||||
io.on('connection', function(client) {
|
||||
console.log('User connected');
|
||||
client.on('joinGame', function(tank){
|
||||
console.log(client.id + ' joined the game');
|
||||
|
||||
// client.emit('addTank', { id: tank.id, type: tank.type, isLocal: true, x: initX, y: initY, hp: TANK_INIT_HP });
|
||||
// client.broadcast.emit('addTank', { id: tank.id, type: tank.type, isLocal: false, x: initX, y: initY, hp: TANK_INIT_HP} );
|
||||
// game.addTank({ id: tank.id, type: tank.type, hp: TANK_INIT_HP});
|
||||
client.emit('gameVars', {gridSize: gridSize, world: world})
|
||||
client.on('disconnect', function(){
|
||||
console.log(client.id + ' disconnected.')
|
||||
game.removePlayer(client.id)
|
||||
client.broadcast.emit('playerList', game.players)
|
||||
})
|
||||
|
||||
client.on('joinGame', function(tank){
|
||||
game.addPlayer(client.id);
|
||||
console.log(client.id + ' joined the game');
|
||||
client.emit('gameVars', {gridSize: gridSize, world: game.world})
|
||||
client.broadcast.emit('playerList', game.players)
|
||||
client.emit('playerList', game.players)
|
||||
})
|
||||
client.on('leaveGame', function(tank){
|
||||
console.log(client.id + ' disconnected.')
|
||||
game.removePlayer(client.id)
|
||||
client.broadcast.emit('playerList', game.players)
|
||||
})
|
||||
|
||||
client.on('clickCanvas', function(data){
|
||||
const xu = data.tilePosition[0]
|
||||
const yu = data.tilePosition[1]
|
||||
world[xu][yu].structure = data.structure
|
||||
client.broadcast.emit('sync',{world: world})
|
||||
client.emit('sync',{world: world})
|
||||
game.world[xu][yu].structure = data.structure
|
||||
game.world[xu][yu].owner = game.getPlayerByID(client.id).color;
|
||||
// console.log(world[xu][yu].owner = game.getPlayerbyID(client.id))
|
||||
|
||||
client.broadcast.emit('sync',{world: game.world})
|
||||
client.emit('sync',{world: game.world})
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
function randomNumber(min, max) {
|
||||
return Math.floor(Math.random() * (max - min) + min);
|
||||
}
|
||||
|
||||
function generateWorld(){
|
||||
let x, y = 0
|
||||
|
||||
let tempWorld = Array.from(Array(gridSize[0]), () => new Array(gridSize[1]));
|
||||
for (x = 0; x < gridSize[0]; x++){
|
||||
for (y = 0; y < gridSize[1]; y++){
|
||||
tempWorld[x][y] = {type: 0, structure: 0}
|
||||
}
|
||||
}
|
||||
|
||||
noise.seed(Math.random())
|
||||
for(x = 0; x < gridSize[0]; x++){
|
||||
for(y = 0; y < gridSize[1]; y++){
|
||||
|
||||
var value = (noise.perlin2(x/perlinScale, y/perlinScale))*10;
|
||||
if (value >= -3) {
|
||||
tempWorld[x][y].type = 0
|
||||
} else if (value < -3) {
|
||||
tempWorld[x][y].type = 1
|
||||
}
|
||||
if (value > 1.4) {
|
||||
tempWorld[x][y].type = 2
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
for (i = 0; i < gridSize[0]*gridSize[1]/15; i){
|
||||
x = randomNumber(0,gridSize[0]);
|
||||
y = randomNumber(0,gridSize[1]);
|
||||
if (tempWorld[x][y].type != 1) {
|
||||
i++;
|
||||
tempWorld[x][y].structure = 1
|
||||
}
|
||||
}
|
||||
return tempWorld;
|
||||
}
|
||||
|
|
5
util.js
Normal file
5
util.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
function randomNumber(min, max) {
|
||||
return Math.floor(Math.random() * (max - min) + min);
|
||||
}
|
||||
|
||||
module.exports = {randomNumber}
|
40
worldgen.js
Normal file
40
worldgen.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
var noise = require('noisejs');
|
||||
const util = require("./util.js")
|
||||
|
||||
function generateWorld(gridSize, perlinScale){
|
||||
let x, y = 0
|
||||
|
||||
let tempWorld = Array.from(Array(gridSize[0]), () => new Array(gridSize[1]));
|
||||
for (x = 0; x < gridSize[0]; x++){
|
||||
for (y = 0; y < gridSize[1]; y++){
|
||||
tempWorld[x][y] = {type: 0, structure: 0, owner: null}
|
||||
}
|
||||
}
|
||||
|
||||
noise.seed(Math.random())
|
||||
for(x = 0; x < gridSize[0]; x++){
|
||||
for(y = 0; y < gridSize[1]; y++){
|
||||
|
||||
var value = (noise.perlin2(x/perlinScale, y/perlinScale))*10;
|
||||
if (value >= -3) {
|
||||
tempWorld[x][y].type = 0
|
||||
} else if (value < -3) {
|
||||
tempWorld[x][y].type = 1
|
||||
}
|
||||
if (value > 1.4) {
|
||||
tempWorld[x][y].type = 2
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
for (i = 0; i < gridSize[0]*gridSize[1]/15; i){
|
||||
x = util.randomNumber(0,gridSize[0]);
|
||||
y = util.randomNumber(0,gridSize[1]);
|
||||
if (tempWorld[x][y].type != 1) {
|
||||
i++;
|
||||
tempWorld[x][y].structure = 1
|
||||
}
|
||||
}
|
||||
return tempWorld;
|
||||
}
|
||||
module.exports = { generateWorld };
|
|
@ -9,15 +9,21 @@
|
|||
<body>
|
||||
<h1>Uber Secret Project</h1>
|
||||
<div class="container">
|
||||
<canvas class="" id="spritejank" width=24 height=24></canvas>
|
||||
<div class="wrapper">
|
||||
<canvas id="canvas" width=0 height=0></canvas>
|
||||
<div class="canvasStack">
|
||||
<canvas class="canvas1" id="canvas" width=0 height=0></canvas>
|
||||
<canvas class="canvas2" id="hud" width="0" height="0"></canvas>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<p>Info</p><br>
|
||||
<p id="cash">$0</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src='script.js'></script>
|
||||
</html>
|
||||
|
|
|
@ -4,24 +4,35 @@ var gridSize;
|
|||
var cash = 99;
|
||||
var world
|
||||
var canvas = document.getElementById('canvas');
|
||||
var hud = document.getElementById('hud');
|
||||
var ctx = canvas.getContext('2d');
|
||||
var hctx = hud.getContext('2d');
|
||||
var socket = io.connect('http://127.0.0.1:8082/');
|
||||
function joinGame(tankName, tankType, socket){
|
||||
if(tankName != ''){
|
||||
socket.emit('joinGame', {name: tankName, type: tankType});
|
||||
function joinGame(socket){
|
||||
socket.emit('joinGame', {});
|
||||
}
|
||||
function leaveGame(socket){
|
||||
socket.emit('leaveGame', {});
|
||||
}
|
||||
joinGame("aaa", "blue", socket);
|
||||
|
||||
joinGame(socket);
|
||||
|
||||
window.onbeforeunload = function(){
|
||||
socket.disconnect();
|
||||
world = []
|
||||
}
|
||||
|
||||
socket.on('gameVars', function(tank){
|
||||
gridSize = tank.gridSize;
|
||||
world = tank.world;
|
||||
console.log(gridSize, world)
|
||||
console.log(tank)
|
||||
|
||||
fill_canvas()
|
||||
});
|
||||
|
||||
socket.on('playerList', function(data){
|
||||
console.log(data)
|
||||
});
|
||||
|
||||
socket.on('sync', function (sync){
|
||||
world = sync.world;
|
||||
render()
|
||||
|
@ -49,13 +60,14 @@ window.onload = function () {
|
|||
function fill_canvas() {
|
||||
// CREATE CANVAS CONTEXT.
|
||||
|
||||
canvas.addEventListener("mousedown", function(e)
|
||||
hud.addEventListener("mousedown", function(e)
|
||||
{
|
||||
getMousePosition(canvas, e);
|
||||
});
|
||||
canvas.width = tileSize*gridSize[0];
|
||||
canvas.height = tileSize*gridSize[1];
|
||||
|
||||
hud.width = canvas.width
|
||||
hud.height = canvas.height
|
||||
|
||||
|
||||
render()
|
||||
|
@ -74,20 +86,41 @@ function render() { // DRAW THE IMAGE TO THE CANVAS.
|
|||
for(y = 0; y < gridSize[1]; y++){
|
||||
const xu = x*tileSize;
|
||||
const yu = y*tileSize;
|
||||
if (world[x][y].type == 0) {
|
||||
|
||||
// Draw buildings
|
||||
switch (world[x][y].type) {
|
||||
case (0):
|
||||
ctx.drawImage(tiles[0], xu,yu)
|
||||
} else if (world[x][y].type == 1) {
|
||||
break;
|
||||
case (1):
|
||||
ctx.drawImage(tiles[2], xu,yu)
|
||||
}
|
||||
if (world[x][y].type == 2) {
|
||||
break;
|
||||
case (2):
|
||||
ctx.drawImage(tiles[1], xu,yu)
|
||||
break;
|
||||
}
|
||||
if (world[x][y].structure == 1) {
|
||||
|
||||
// Draw Structures
|
||||
switch (world[x][y].structure) {
|
||||
case (1):
|
||||
ctx.drawImage(tiles[3], xu,yu)
|
||||
}
|
||||
if (world[x][y].structure == 2) {
|
||||
break;
|
||||
|
||||
case (2):
|
||||
ctx.drawImage(tiles[4], xu,yu)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Draw Property overlays
|
||||
if (world[x][y].owner != null){
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = world[x][y].owner;
|
||||
|
||||
ctx.rect(xu, yu, tileSize, tileSize)
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.fill()
|
||||
ctx.globalAlpha = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -109,7 +142,7 @@ function getMousePosition(canvas, event) {
|
|||
|
||||
|
||||
console.log("Click!")
|
||||
|
||||
console.log(xu,yu)
|
||||
socket.emit('clickCanvas', {tilePosition: [xu,yu], structure: 2});
|
||||
// if (tile.type != 1 && tile.structure != 1 && cash > 10) {
|
||||
// tile.structure = 2
|
||||
|
|
BIN
www/sheet.png
Normal file
BIN
www/sheet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.2 KiB |
|
@ -5,18 +5,30 @@ canvas {
|
|||
image-rendering: crisp-edges;
|
||||
border: solid white;
|
||||
border-radius: 6px;
|
||||
background-color: #ccc;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
/* display: inline-block; */
|
||||
/* margin: auto; */
|
||||
}
|
||||
|
||||
.right {
|
||||
background: red;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
width: 60px;
|
||||
.canvas1{
|
||||
z-index: 0;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.canvas2 {
|
||||
z-index: 1;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
|
||||
.canvasStack {
|
||||
position: fixed;
|
||||
top: 150px;
|
||||
|
||||
}
|
||||
|
||||
body {
|
||||
text-align: center;
|
||||
background-color: #2c2f33;
|
||||
|
@ -25,13 +37,12 @@ font-variant: normal;
|
|||
font-family: verdana;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
/* .wrapper {
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
margin: auto;
|
||||
background-color: #ff00ff;
|
||||
}
|
||||
} */
|
||||
.container{
|
||||
margin: 0px;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue