diff --git a/client/src/Bullet.ts b/client/src/Bullet.ts index 470d9eb..6b8c35a 100644 --- a/client/src/Bullet.ts +++ b/client/src/Bullet.ts @@ -30,9 +30,9 @@ export default class Bullet { p5.ellipse(position.x, position.y, 30, 30) } - move() { - this._position.x += this.direction.x - this._position.y += this.direction.y + move(delta: number) { + this._position.x += this.direction.x * delta + this._position.y += this.direction.y * delta this.timeLeftToLive -= Math.abs(this.direction.x) + Math.abs(this.direction.y) } diff --git a/client/src/Cookie.ts b/client/src/Cookie.ts new file mode 100644 index 0000000..73c62be --- /dev/null +++ b/client/src/Cookie.ts @@ -0,0 +1,22 @@ +export function getCookie(cname: string): string { + let name = cname + "=" + let decodedCookie = decodeURIComponent(document.cookie) + let ca = decodedCookie.split(';') + for(let i = 0; i < ca.length; i++) { + let c = ca[i] + while (c.charAt(0) == ' ') { + c = c.substring(1) + } + if (c.indexOf(name) == 0) { + return c.substring(name.length, c.length) + } + } + return ""; +} + +export function setCookie(cname: string, cvalue: string, exdays: number) { + let d = new Date() + d.setTime(d.getTime() + (exdays*24*60*60*1000)) + let expires = "expires=" + d.toUTCString() + document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/" +} \ No newline at end of file diff --git a/client/src/OtherPlayer.ts b/client/src/OtherPlayer.ts index 4e32202..3bb918f 100644 --- a/client/src/OtherPlayer.ts +++ b/client/src/OtherPlayer.ts @@ -4,21 +4,29 @@ import { Position } from "./types" export default class OtherPlayer { + private PLAYER_SPEED = 1 + private KEY_W = 87; + private KEY_A = 65; + private KEY_S = 83; + private KEY_D = 68; + private bullets: Bullet[] = [] private _damage: number + private _defence: number constructor( private _id: string, private _name: string, private _position: Position, private _color: string, + private _keysPressed: Map, private _health: number ) { this._damage = 10 + this._defence = 0 } hit(bullet: Bullet, socket: SocketIOClient.Socket) { - // this.health -= bullet.shooter.damage bullet.timeToLive = -1 socket.emit('hit-player', {player: this.id, damage: bullet.shooter.damage}) } @@ -37,6 +45,18 @@ export default class OtherPlayer { }) } + keyPressed(key: number): boolean { + return this._keysPressed.get(key) || false; + } + + setKeyPressed(key: number, value: boolean) { + this._keysPressed.set(key, value) + } + + clearKeysPressed() { + this._keysPressed.clear() + } + draw(p5: p5, position: Position) { p5.stroke(0, 0, 0) p5.strokeWeight(5) @@ -65,6 +85,18 @@ export default class OtherPlayer { return this._damage } + set damage(dmg: number) { + this._damage = dmg + } + + get defence() { + return this._defence + } + + set defence(def: number) { + this._defence = def + } + get id(): string { return this._id } @@ -97,4 +129,44 @@ export default class OtherPlayer { this._color = color } + move(delta: number) { + let previousPosition = { + x: this.position.x, + y: this.position.y, + } + if (this.keyPressed(this.KEY_A)) { + this.position.x -= this.PLAYER_SPEED * delta; + } + if (this.keyPressed(this.KEY_D)) { + this.position.x += this.PLAYER_SPEED * delta; + } + + if (this.keyPressed(this.KEY_W)) { + this.position.y -= this.PLAYER_SPEED * delta; + } + if (this.keyPressed(this.KEY_S)) { + this.position.y += this.PLAYER_SPEED * delta; + } + + if (this.position.x < -1600) { + this.position.x = -1600 + } + + if (this.position.y < -2000) { + this.position.y = -2000 + } + + if (this.position.x > 1500) { + this.position.x = 1500 + } + + if (this.position.y > 1900) { + this.position.y = 1900 + } + + // if (this.position.x !== previousPosition.x || this.position.y !== previousPosition.y) { + // this.socket.emit('i-moved', {x: this.position.x, y: this.position.y}) + // } + } + } \ No newline at end of file diff --git a/client/src/Player.ts b/client/src/Player.ts new file mode 100644 index 0000000..e69de29 diff --git a/client/src/UserPlayer.ts b/client/src/UserPlayer.ts index 66a8824..2f1ed7d 100644 --- a/client/src/UserPlayer.ts +++ b/client/src/UserPlayer.ts @@ -5,78 +5,28 @@ import { Position } from "./types"; export default class UserPlayer extends OtherPlayer{ - private PLAYER_SPEED = 10 - private KEY_W = 87; - private KEY_A = 65; - private KEY_S = 83; - private KEY_D = 68; - constructor( _id: string, private _socket: SocketIOClient.Socket, _name: string, _position: Position, _color: string, - private _keysPressed: Map, + _keysPressed: Map, _health: number ) { - super(_id, _name, _position, _color, _health) + super(_id, _name, _position, _color, _keysPressed, _health) } get socket(): SocketIOClient.Socket { return this._socket } - keyPressed(key: number): boolean { - return this._keysPressed.get(key) || false; + keyUp(key: number) { + this.socket.emit('key-action', {key: key, isDown: false}) } - setKeyPressed(key: number, value: boolean) { - this._keysPressed.set(key, value) - } - - clearKeysPressed() { - this._keysPressed.clear() - } - - move() { - let previousPosition = { - x: this.position.x, - y: this.position.y, - } - if (this.keyPressed(this.KEY_A)) { - this.position.x -= this.PLAYER_SPEED; - } - if (this.keyPressed(this.KEY_D)) { - this.position.x += this.PLAYER_SPEED; - } - - if (this.keyPressed(this.KEY_W)) { - this.position.y -= this.PLAYER_SPEED; - } - if (this.keyPressed(this.KEY_S)) { - this.position.y += this.PLAYER_SPEED; - } - - if (this.position.x < -1600) { - this.position.x = -1600 - } - - if (this.position.y < -2000) { - this.position.y = -2000 - } - - if (this.position.x > 1500) { - this.position.x = 1500 - } - - if (this.position.y > 1900) { - this.position.y = 1900 - } - - if (this.position.x !== previousPosition.x || this.position.y !== previousPosition.y) { - this.socket.emit('i-moved', {x: this.position.x, y: this.position.y}) - } + keyDown(key: number) { + this.socket.emit('key-action', {key: key, isDown: true}) } } \ No newline at end of file diff --git a/client/src/app.ts b/client/src/app.ts index b6586c9..ec26905 100644 --- a/client/src/app.ts +++ b/client/src/app.ts @@ -27,13 +27,26 @@ const VISIBLE_RANGE_Y = 700 const PLAYER_SIZE = 80 const BULLET_SIZE = 30 +const ITEM_SIZE = 64 const BULLET_SHOOTING_DELAY = 100 +let time = Date.now() + +const getDeltaTime = () => { + let t = Date.now() + let dt = t - time + time = t + return dt +} + + function onKeyDown(e: any) { + game.getPlayer().keyDown(e.keyCode) game.getPlayer().setKeyPressed(e.keyCode, true) } function onKeyUp(e: any) { + game.getPlayer().keyUp(e.keyCode) game.getPlayer().setKeyPressed(e.keyCode, false) } @@ -59,7 +72,7 @@ function onMouseUp(e: MouseEvent) { pos.y -= parseInt(canvas.style.height) / 2 let length = Math.sqrt((pos.x * pos.x) + (pos.y * pos.y)) let scale = 1 / length - scale *= 50 + scale *= 5 pos.x *= scale pos.y *= scale game.getPlayer().addBullet(new Bullet(game.getPlayer(), pos)) @@ -123,6 +136,7 @@ function drawMap(p5: P5) { } } + const sketch = (p5: P5) => { p5.setup = () => { buildMap() @@ -151,6 +165,9 @@ const sketch = (p5: P5) => { } p5.draw = () => { + + let dt = getDeltaTime() + p5.background('#000000') p5.translate(p5.width/2, p5.height/2) @@ -161,9 +178,24 @@ const sketch = (p5: P5) => { // drawing items for (let item of game.getItems()) { - p5.image(item.item.image, item.position.x - game.getPlayer().position.x, item.position.y - game.getPlayer().position.y) - + if (distance(game.getPlayer().position, item.position) < PLAYER_SIZE + ITEM_SIZE) { + switch(item.item.type) { + case "HEAL": + game.getPlayer().health = 100 + socket.emit('item-heal') + break; + case "DAMAGE": + game.getPlayer().damage += 2 + socket.emit('item-damage') + break; + case "DEFENCE": + game.getPlayer().defence += 2 + socket.emit('item-defence') + break; + } + game.removeItem(item) + } } @@ -191,7 +223,7 @@ const sketch = (p5: P5) => { } // move bullet - bullet.move() + bullet.move(dt) // check if bullet colloides with current player if (distance(game.getPlayer().position, bullet.position) < BULLET_SIZE + PLAYER_SIZE) { @@ -229,7 +261,7 @@ const sketch = (p5: P5) => { } // move bullet - bullet.move() + bullet.move(dt) // check if bullet collides with other player for (let otherPlayer of game.getOtherPlayers()) { @@ -250,7 +282,7 @@ const sketch = (p5: P5) => { p5.text(Math.floor(game.getPlayer().position.x) + ':' + Math.floor(game.getPlayer().position.y), -p5.width/2 + 10, -p5.height/2 + 10) // moving player depending on keys pressed - game.getPlayer().move() + game.getPlayer().move(dt) } } diff --git a/client/src/setupSocketEvents.ts b/client/src/setupSocketEvents.ts index 630a787..3f33b73 100644 --- a/client/src/setupSocketEvents.ts +++ b/client/src/setupSocketEvents.ts @@ -1,11 +1,17 @@ import SocketIOClient from 'socket.io-client' import Bullet from './Bullet' +import { getCookie } from './Cookie' import Game from './Game' import OtherPlayer from './OtherPlayer' import { BulletData, PlayerDescription } from './socketDataTypes' import { Position } from './types' export default function setupSocketEvents(socket: SocketIOClient.Socket, game: Game) { + + socket.on('greetings', () => { + socket.emit('greetings', {name: getCookie('player-name')}) + }) + socket.on('your-info', function (playerData: PlayerDescription) { let player = game.getPlayer() player.color = playerData.color @@ -13,25 +19,30 @@ export default function setupSocketEvents(socket: SocketIOClient.Socket, game: G player.name = playerData.name player.position = playerData.position player.health = playerData.health - socket.emit('get-other-players') }) + socket.on('players-info', function (playersData: PlayerDescription[]) { for (let playerData of playersData) { - game.addOtherPlayer(new OtherPlayer(playerData.id, playerData.name, playerData.position, playerData.color, playerData.health)) + game.addOtherPlayer(new OtherPlayer(playerData.id, playerData.name, playerData.position, playerData.color, new Map(), playerData.health)) } }) + socket.on('new-player-joined', function (playerData: PlayerDescription) { if (game.getPlayer().id !== playerData.id) { - game.addOtherPlayer(new OtherPlayer(playerData.id, playerData.name, playerData.position, playerData.color, playerData.health)) + game.addOtherPlayer(new OtherPlayer(playerData.id, playerData.name, playerData.position, playerData.color, new Map(), playerData.health)) } }) + socket.on('player-moved', function (movedPlayerData: {id: string, position: Position}) { for (let playerData of game.getOtherPlayers()) { if (movedPlayerData.id === playerData.id) { playerData.position = movedPlayerData.position; } } + if (game.getPlayer().id === movedPlayerData.id) { + game.getPlayer().position = movedPlayerData.position + } }) socket.on('player-disconnected', function (disconnectedPlayer: string) { game.removeOtherPlayer(disconnectedPlayer) diff --git a/client/static/ded.html b/client/static/ded.html index f4a3771..6a082d2 100644 --- a/client/static/ded.html +++ b/client/static/ded.html @@ -27,7 +27,7 @@
-
U DED...
RESPAWN
+
U DED...
Go back
\ No newline at end of file diff --git a/client/static/game.html b/client/static/game.html new file mode 100644 index 0000000..94539cf --- /dev/null +++ b/client/static/game.html @@ -0,0 +1,14 @@ + + + + + + + Blobby Strike + + + +
+ + + \ No newline at end of file diff --git a/client/static/index.html b/client/static/index.html index 94539cf..5cf6836 100644 --- a/client/static/index.html +++ b/client/static/index.html @@ -1,14 +1,110 @@ - - - - - Blobby Strike - - - -
- - + + + + BlobbyStrike + + + +
+
+

Blobby-Strike

+ +
+
+ + \ No newline at end of file diff --git a/server/src/Player.ts b/server/src/Player.ts index 422bc33..1ab95ff 100644 --- a/server/src/Player.ts +++ b/server/src/Player.ts @@ -1,4 +1,5 @@ import socketIO from 'socket.io' +import { Position } from './types' export default class Player { @@ -6,6 +7,16 @@ export default class Player { private position: {x: number, y: number} private color: string private health: number + private damage: number + private defence: number + private keysPressed: Map + + private KEY_W = 87 + private KEY_A = 65 + private KEY_S = 83 + private KEY_D = 68 + + private MOVEMENT_SPEED = 1 constructor(private _socket: socketIO.Socket) { this.name = 'Player#' + Math.floor(Math.random() * 10000) @@ -15,12 +26,43 @@ export default class Player { } this.color = '#' + (Math.floor(Math.random() * 256)).toString(16) + (Math.floor(Math.random() * 256)).toString(16) + (Math.floor(Math.random() * 256)).toString(16) this.health = Math.floor(Math.random() * 50) + 50 + this.damage = 10 + this.defence = 10 + this.keysPressed = new Map() } get socket() { return this._socket } + setName(name: string) { + this.name = name + } + + getName() { + return this.name + } + + keyAction(key: number, isDown: boolean) { + this.keysPressed.set(key, isDown) + } + + getDamage() { + return this.damage + } + + getDefence() { + return this.defence + } + + setDamage(damage: number) { + this.damage += damage + } + + setDefence(defence: number) { + this.defence += defence + } + getHealth() { return this.health } @@ -48,4 +90,29 @@ export default class Player { this.position.y = y } + getPosition(): Position { + return { + x: this.position.x, + y: this.position.y, + } + } + + move(delta: number) { + if (this.keysPressed.get(this.KEY_A)) { + this.position.x -= this.MOVEMENT_SPEED * delta + } + + if (this.keysPressed.get(this.KEY_D)) { + this.position.x += this.MOVEMENT_SPEED * delta + } + + if (this.keysPressed.get(this.KEY_W)) { + this.position.y -= this.MOVEMENT_SPEED * delta + } + + if (this.keysPressed.get(this.KEY_S)) { + this.position.y += this.MOVEMENT_SPEED * delta + } + } + } \ No newline at end of file diff --git a/server/src/Players.ts b/server/src/Players.ts index fa220b6..d1ce310 100644 --- a/server/src/Players.ts +++ b/server/src/Players.ts @@ -38,6 +38,12 @@ export default class Players { } } + getPlayer(id: string) { + return this.players.find((player) => { + return player.socketID === id + }) + } + getPlayers(): Player[] { let playerList = [] for (let player of this.players) { diff --git a/server/src/app.ts b/server/src/app.ts index 4f35365..196f488 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -1,7 +1,6 @@ import express from 'express' import http from 'http' import socketIO from 'socket.io' -import fs from 'fs' import cors from 'cors' import path from 'path' import Players from './Players' @@ -21,6 +20,11 @@ app.use(express.static(path.join(__dirname, '/../../client/dist'))) app.get('/', function(req, res) { res.sendFile('index.html', { root: __dirname + '/../../client/static/'}); }); + +app.get('/game', function(req, res) { + res.sendFile('game.html', { root: __dirname + '/../../client/static/'}); +}); + app.get('/ded', function(req, res) { res.sendFile('ded.html', { root: __dirname + '/../../client/static/'}); }); @@ -32,9 +36,16 @@ server.listen(8089, function() { io.on('connection', function(socket: socketIO.Socket) { console.log(socket.id, 'connected'); - let player = new Player(socket) - players.addPlayer(socket.id, player) - socket.emit('your-info', player.getPlayerDescription()) + socket.emit('greetings') + + socket.on('greetings', (data: {name: string}) => { + let player = new Player(socket) + player.setName(data.name) + players.addPlayer(socket.id, player) + + socket.emit('your-info', player.getPlayerDescription()) + io.emit('new-player-joined', player.getPlayerDescription()) + }) socket.on('get-other-players', () => { let otherPlayers = [] @@ -46,13 +57,10 @@ io.on('connection', function(socket: socketIO.Socket) { socket.emit('players-info', otherPlayers) }) - io.emit('new-player-joined', player.getPlayerDescription()) - - - socket.on('i-moved', (position: {x: number, y: number}) => { - players.updatePlayerPosition(socket.id, {x: position.x, y: position.y}) - io.emit('player-moved', {id: socket.id, position: position}) - }) + // socket.on('i-moved', (position: {x: number, y: number}) => { + // players.updatePlayerPosition(socket.id, {x: position.x, y: position.y}) + // io.emit('player-moved', {id: socket.id, position: position}) + // }) socket.on('disconnect', () => { console.log(socket.id, 'disconnected') @@ -69,4 +77,78 @@ io.on('connection', function(socket: socketIO.Socket) { io.emit('health-update', {id: data.player, health: hpLeft}) }) + + + + + + + + + + + + + // ITEM ACTIONS // + + socket.on('item-heal', () => { + let p = players.getPlayer(socket.id) + if (p) { + p.player.setHealth(100) + io.emit('health-update', {id: p.player.socket.id, health: p.player.getHealth()}) + } + }) + + socket.on('item-defence', () => { + let p = players.getPlayer(socket.id) + if (p) { + p.player.setDefence(p.player.getDefence() + 5) + } + }) + + socket.on('item-damage', () => { + let p = players.getPlayer(socket.id) + if (p) { + p.player.setDamage(p.player.getDamage() + 5) + } + }) + + socket.on('key-action', (data: {key: number, isDown: boolean}) => { + let p = players.getPlayer(socket.id) + if (p) { + p.player.keyAction(data.key, data.isDown) + } + }) + }); + +let time = Date.now() + +const getDeltaTime = () => { + let t = Date.now() + let dt = t - time + time = t + return dt +} + +setInterval(() => { + // game tick + let delta = getDeltaTime() + + for (let player of players.getPlayers()) { + + if (player.getHealth() <= 0) { + player.socket.disconnect() + } + + // player movement + let previosPosition = player.getPosition() + player.move(delta) + if (previosPosition.x !== player.getPosition().x || previosPosition.y !== player.getPosition().y) { + io.emit('player-moved', {id: player.socket.id, position: player.getPosition()}) + } + // endof: player movement + + } + +}, 1000/60) \ No newline at end of file diff --git a/server/src/types.ts b/server/src/types.ts new file mode 100644 index 0000000..27f190a --- /dev/null +++ b/server/src/types.ts @@ -0,0 +1,4 @@ +export type Position = { + x: number, + y: number, +} \ No newline at end of file