├── public ├── index.txt ├── .DS_Store ├── images │ ├── .DS_Store │ └── machine.png ├── bullet.js ├── index.html ├── index.css ├── machine.js └── index.js ├── .DS_Store ├── README.md ├── package.json └── server.js /public/index.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tarantino07/multiplayer-game-with-javascript/HEAD/.DS_Store -------------------------------------------------------------------------------- /public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tarantino07/multiplayer-game-with-javascript/HEAD/public/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # multiplayer-game-with-javascript 2 | 3 | You can play on: https://multiplayer-game-js.herokuapp.com/ 4 | -------------------------------------------------------------------------------- /public/images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tarantino07/multiplayer-game-with-javascript/HEAD/public/images/.DS_Store -------------------------------------------------------------------------------- /public/images/machine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tarantino07/multiplayer-game-with-javascript/HEAD/public/images/machine.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server_trial", 3 | "version": "1.0.0", 4 | "description": "server trial sockt", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js", 9 | "build": "" 10 | }, 11 | "keywords": [ 12 | "socket", 13 | "server" 14 | ], 15 | "author": "Servet Gulnaroglu", 16 | "license": "ISC", 17 | "dependencies": { 18 | "express": "^4.17.1", 19 | "serverless-http": "^2.5.0", 20 | "socket.io": "^2.3.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /public/bullet.js: -------------------------------------------------------------------------------- 1 | class Bullet{ 2 | constructor(x, y, radian, range){ 3 | this.x = x * 1.0; 4 | this.y = y * 1.0; 5 | this.startX = x; 6 | this.startY = y; 7 | this.radian = radian * 1.0; 8 | this.speed = 300 * 1.0/framePerSecond; 9 | this.size = 5; 10 | this.range = range; 11 | } 12 | 13 | move(){ 14 | this.y += Math.sin(this.radian) * this.speed * 1.0; 15 | this.x += Math.cos(this.radian) * this.speed; 16 | } 17 | 18 | draw(){ 19 | canvasContext.fillStyle = 'white'; 20 | canvasContext.fillRect(this.x, this.y, this.size, this.size); 21 | } 22 | 23 | show(){ 24 | this.move(); 25 | this.draw(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | machinewar 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 |
19 | 42 |
43 |
44 | 45 |
46 |
47 |
Players: 0
48 |
49 |
    50 |
    51 |
    52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | //var path = require('path'); 3 | //const serverless = require('serverless-http'); 4 | var app = express(); 5 | const port = process.env.PORT || 3000 6 | var server = app.listen(port); 7 | //var server = app.listen(3000); 8 | app.use(express.static('public'));//folder name = public 9 | var socket = require('socket.io'); 10 | var io = socket(server); 11 | var machines = {}; 12 | var bullets = []; 13 | var playerCount = 0; 14 | var loop; 15 | io.sockets.on('connection', newConnection); 16 | function newConnection(socket){ 17 | playerCount++; 18 | console.log('new connection: ' + socket.id); 19 | io.to(socket.id).emit('getID', socket.id); 20 | io.emit('playerCount', playerCount); 21 | machines[socket.id] = { 22 | machine: { 23 | playerName: 'inLobby', 24 | x: -1200.5, 25 | y: 0.1, 26 | angle: 0, 27 | speed: 4, 28 | size: 32, 29 | radian: 0 * 1.0, 30 | headX: 0.0 * 1.0, 31 | headX: 0.0 * 1.0, 32 | bullets: [], 33 | health: 100 34 | } 35 | }; 36 | 37 | var sendLoop = setInterval(function(){ 38 | var keys = Object.keys(machines); 39 | var playerOrder = []; 40 | for(var i = 0; i < keys.length; i++){ 41 | if(machines[keys[i]].machine.playerName != "inLobby"){ 42 | playerOrder.push({name: machines[keys[i]].machine.playerName, score: machines[keys[i]].machine.score}); 43 | } 44 | } 45 | playerOrder.sort(function(a,b){return b.score - a.score}); 46 | if(playerOrder.length > 5){ 47 | playerOrder.splice(5, playerOrder.length); 48 | } 49 | io.emit('sortedPlayers', playerOrder); 50 | }, 1000); 51 | socket.on('frame', (data) => { 52 | machines[socket.id] = { 53 | machine: data 54 | }; 55 | io.emit('frame', machines); 56 | }); 57 | 58 | socket.on('bullet', (bullet)=>{ 59 | socket.broadcast.emit('bullet', bullet); 60 | }) 61 | socket.on('message', (message) => { 62 | socket.broadcast.emit('message', message); 63 | }) 64 | socket.on('disconnect', (data) => { 65 | console.log('connection lost: ' + socket.id); 66 | console.log('deleted' + machines.id); 67 | playerCount--; 68 | io.emit('playerCount', playerCount); 69 | delete machines[socket.id]; 70 | }) 71 | } 72 | -------------------------------------------------------------------------------- /public/index.css: -------------------------------------------------------------------------------- 1 | @font-face{ 2 | font-family: 'JetBrains Mono'; 3 | src: url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/web/eot/JetBrainsMono-Regular.eot') format('embedded-opentype'), 4 | url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/web/woff2/JetBrainsMono-Regular.woff2') format('woff2'), 5 | url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/web/woff/JetBrainsMono-Regular.woff') format('woff'), 6 | url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/ttf/JetBrainsMono-Regular.ttf') format('truetype'); 7 | font-weight: normal; 8 | font-style: normal; 9 | } 10 | 11 | * { 12 | -webkit-font-feature-settings: "liga" on, "calt" on; 13 | -webkit-font-smoothing: antialiased; 14 | text-rendering: optimizeLegibility; 15 | font-family: 'JetBrains Mono'; 16 | } 17 | 18 | html, body, canvas{ 19 | margin: 0 !important; 20 | padding: 0 !important; 21 | } 22 | 23 | html, body { 24 | width: 100%; 25 | height: 100%; 26 | } 27 | 28 | #imageDiv{ 29 | display:none; 30 | } 31 | 32 | #health{ 33 | background-color:green; 34 | position:absolute; 35 | left: 125px; 36 | top: 400px; 37 | width: 160px; 38 | } 39 | 40 | .enemyHealthBar { 41 | background-color: green; 42 | position: absolute; 43 | width: 30px; 44 | height: 6px; 45 | } 46 | 47 | .chatbox { 48 | position: absolute; 49 | width: 300px; 50 | height: 320px; 51 | background: rgba(255, 255, 255, 0.1); 52 | bottom: 5px; 53 | left: 5px; 54 | border-radius: 5px; 55 | pointer-events: none; 56 | } 57 | 58 | .chatbox .chat-list { 59 | padding: 5px; 60 | margin: 0; 61 | list-style: none; 62 | box-sizing: border-box; 63 | height: 285px; 64 | overflow: hidden; 65 | } 66 | 67 | .chatbox .chat-list li { 68 | padding: 2px; 69 | margin: 3px; 70 | } 71 | 72 | .chatbox .chat-input { 73 | pointer-events: all; 74 | box-sizing: border-box; 75 | width: 100%; 76 | padding: 8px; 77 | background: transparent; 78 | border: none; 79 | border-top: 1px solid #DDD; 80 | outline: none; 81 | color: white; 82 | } 83 | 84 | #keys ul li { 85 | color: white; 86 | } 87 | 88 | #keyButton { 89 | position: absolute; 90 | top: 170px; 91 | left: 10px; 92 | border-radius:3px; 93 | background: white; 94 | border: none; 95 | padding: 15px 32px; 96 | text-align: center; 97 | text-decoration: none; 98 | font-size: 16px; 99 | } 100 | 101 | #keys { 102 | position: absolute; 103 | width: 250px; 104 | visibility: hidden; 105 | left:5px; 106 | top:220px; 107 | } 108 | 109 | /*#chatList, #chatInput{ 110 | font-family: , Charcoal, sans-serif; 111 | }*/ 112 | 113 | #players { 114 | position: absolute; 115 | background: rgba(255, 255, 255, 0.1); 116 | border-top-left-radius: 3px; 117 | border-top-right-radius: 3px; 118 | color: #FFF; 119 | font-size: 18px; 120 | top: 0; 121 | right: 0; 122 | text-align: right; 123 | pointer-events: none; 124 | border-bottom-style: solid; 125 | border-bottom-color: coral; 126 | width: 187px; 127 | 128 | } 129 | 130 | #leaders{ 131 | position:absolute; 132 | width: inherit; 133 | background: rgba(255, 255, 255, 0.1); 134 | color: #FFF; 135 | border-bottom-left-radius: 3px; 136 | border-bottom-right-radius: 3px; 137 | text-align: right; 138 | font-size: 15px; 139 | top: 35px; 140 | right: 0; 141 | pointer-events: none; 142 | border-bottom-style: solid; 143 | border-bottom-color: coral; 144 | width: 187px; 145 | } 146 | 147 | #leaders , #players { 148 | padding:5px; 149 | } 150 | 151 | #playerWrapper li { 152 | white-space: nowrap; 153 | } 154 | 155 | body { 156 | overflow: hidden; 157 | } 158 | 159 | #playersSpan{ 160 | border-bottom-style: solid; 161 | border-bottom-color: coral; 162 | } 163 | -------------------------------------------------------------------------------- /public/machine.js: -------------------------------------------------------------------------------- 1 | class Machine{ 2 | constructor(x, y, angle, health, playerName, bullets){ 3 | this.playerName = playerName; 4 | this.x = x * 1.0; 5 | this.y = y * 1.0; 6 | this.angle = angle; 7 | this.speed = 120.0/framePerSecond; 8 | this.size = 32; 9 | this.radian = this.angle * Math.PI/ 180.0; 10 | this.headX = this.x + this.size / 2 + Math.cos(this.radian) * this.size / 2; 11 | this.headY = this.y + this.size / 2 + Math.sin(this.radian) * this.size / 2; 12 | this.bullets = bullets; 13 | this.health = health; 14 | this.range = 250; 15 | this.maxBulletCount = 8; 16 | this.score = 0; 17 | } 18 | 19 | moveTop(){ 20 | if(this.y + Math.sin(this.radian) * this.speed >= 0 && this.y + Math.sin(this.radian) * this.speed <= maxCanvasHeight- this.size 21 | && this.x + Math.cos(this.radian) * this.speed >= 0 && this.x + Math.cos(this.radian) * this.speed <= maxCanvasWidth - this.size){ 22 | this.y += Math.sin(this.radian) * this.speed; 23 | this.x += Math.cos(this.radian) * this.speed; 24 | } 25 | } 26 | 27 | moveBack(){ 28 | if(this.y - Math.sin(this.radian) * this.speed / 2>= 0 && this.y - Math.sin(this.radian) * this.speed / 2 <= maxCanvasHeight- this.size 29 | && this.x - Math.cos(this.radian) * this.speed / 2>= 0 && this.x - Math.cos(this.radian) * this.speed / 2 <= maxCanvasWidth - this.size){ 30 | this.y -= Math.sin(this.radian) * this.speed / 2; 31 | this.x -= Math.cos(this.radian) * this.speed / 2; 32 | } 33 | } 34 | 35 | update(){ 36 | this.headX = this.x + this.size / 2 + Math.cos(this.radian) * this.size / 2; 37 | this.headY = this.y + this.size / 2 + Math.sin(this.radian) * this.size / 2; 38 | for(var i = 0; i < this.bullets.length; i++){ 39 | var bullet = this.bullets[i]; 40 | if(Math.sqrt(Math.pow(bullet.x - bullet.startX, 2) + Math.pow(bullet.y - bullet.startY, 2)) > this.range - 16 ){ 41 | this.bullets.splice(i,1); 42 | } 43 | } 44 | } 45 | 46 | show(){ 47 | this.drawImage(this.x, this.y, this.size, this.size, this.angle); 48 | this.drawHealthBar(); 49 | this.drawName(); 50 | 51 | } 52 | 53 | drawTail(){ 54 | 55 | } 56 | 57 | showRange(){ 58 | canvasContext.beginPath(); 59 | canvasContext.strokeStyle = 'rgba(255,255,255,0.5)'; 60 | canvasContext.arc(this.x + this.size / 2, this.y + this.size / 2, this.range, 0, 2 * Math.PI); 61 | canvasContext.stroke(); 62 | } 63 | 64 | call(){ 65 | this.update(); 66 | this.show(); 67 | } 68 | 69 | drawImage(x, y, w, h, angle){ 70 | canvasContext.save(); 71 | canvasContext.translate(x + w / 2, y + h / 2); 72 | canvasContext.rotate(- angle * Math.PI / 180.0); 73 | canvasContext.translate(-x - w / 2, -y - h / 2); 74 | canvasContext.drawImage(image, 0, 0, this.size, this.size, x, y, w, h); 75 | canvasContext.restore(); 76 | } 77 | 78 | showBulletCount(){ 79 | 80 | } 81 | 82 | drawHealthBar(){ 83 | if(this.health >= 65) { 84 | canvasContext.fillStyle = '#00c62b'; 85 | canvasContext.fillRect(this.x, this.y + 45, 30 * this.health / 93.75, 6); 86 | } 87 | else if(this.health < 65 && this.health > 30){ 88 | canvasContext.fillStyle = '#dbd000'; 89 | canvasContext.fillRect(this.x, this.y + 45, 30 * this.health / 93.75, 6); 90 | } 91 | else{ 92 | canvasContext.fillStyle = '#d80000'; 93 | canvasContext.fillRect(this.x, this.y + 45, 30 * this.health / 93.75, 6); 94 | } 95 | } 96 | 97 | turnRight(){ 98 | this.angle -= 300/framePerSecond; 99 | this.angle = Math.floor(this.angle); 100 | this.radian = -this.angle * Math.PI/ 180.0; 101 | } 102 | 103 | drawName(){ 104 | canvasContext.fillStyle = 'white'; 105 | canvasContext.font = '15px Arial'; 106 | canvasContext.textAlign = 'center'; 107 | canvasContext.fillText(this.playerName, this.x + 16 , this.y - 15); 108 | } 109 | 110 | turnLeft(){ 111 | this.angle += 300/framePerSecond; 112 | this.angle = Math.floor(this.angle); 113 | this.radian = -this.angle * Math.PI/ 180.0; 114 | } 115 | 116 | fire(){ 117 | this.headX = this.x + this.size / 2 + Math.cos(this.radian) * this.size / 2; 118 | this.headY = this.y + this.size / 2 + Math.sin(this.radian) * this.size / 2; 119 | if(this.bullets.length < this.maxBulletCount){ 120 | this.bullets.push(new Bullet(this.headX, this.headY, this.radian, this.range)); 121 | return true; 122 | } 123 | return false; 124 | } 125 | 126 | getDamage(){ 127 | this.health -= 5; 128 | } 129 | 130 | increaseRange(){ 131 | this.range += 10; 132 | } 133 | 134 | increaseBulletCount(){ 135 | this.maxBulletCount++; 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /public/index.js: -------------------------------------------------------------------------------- 1 | var socket; 2 | var machines = {}; 3 | var framePerSecond = 50; 4 | var gameLoopMS = 20; 5 | socket = io.connect('https://multiplayer-game-js.herokuapp.com/'); 6 | //socket = io.connect('http://localhost:3000/') 7 | var myID; 8 | socket.on('getID', (id)=>{ 9 | myID = id; 10 | }) 11 | var players = document.getElementById('players'); 12 | var maxCanvasWidth = 1920; 13 | var shouldDrawHealthAnimation = false; 14 | var maxCanvasHeight = 1080; 15 | var button; 16 | var healthAnimationX; 17 | var healthAnimationY; 18 | var playerCount; 19 | var increment; 20 | var particleRange = 50; 21 | var particleCount = 4; 22 | var reference = { 23 | x: 0, 24 | y: 0 25 | } 26 | var keyButton = document.getElementById('keyButton'); 27 | var keyCard = document.getElementById('keys'); 28 | keyButton.onclick = function(){ 29 | keyCard.style.visibility = keyCard.style.visibility == 'visible'? 'hidden': 'visible'; 30 | } 31 | var myMoney = 0; 32 | var leaderList = document.getElementById('leaderList') 33 | var canvas = document.getElementById('canvas'); 34 | var cost = 20; 35 | var chatInput = document.getElementById('chatInput'); 36 | var chatList = document.getElementById('chatList'); 37 | canvas.width = window.innerWidth; 38 | canvas.height = window.innerHeight; 39 | window.addEventListener("resize", ()=>{ 40 | if(gameState != gameStates.ENTER_MENU){ 41 | var oldWidth = canvas.width; 42 | var oldHeight = canvas.height; 43 | canvas.width = window.innerWidth; 44 | canvas.height = window.innerHeight; 45 | canvasContext.translate(canvas.width / 2 - myMachine.x, canvas.height / 2 - myMachine.y); 46 | } 47 | }); 48 | var canvasContext = canvas.getContext('2d'); 49 | var allBullets = []; 50 | var myMachine; 51 | var playerName; 52 | var gameStates = { 53 | ENTER_MENU : 0, 54 | GAME : 1, 55 | GAME_OVER_MENU: 2 56 | } 57 | var gameState = gameStates.ENTER_MENU; 58 | var loop; 59 | socket.on('playerCount', (count) => { 60 | players.textContent = 'Players: ' + (count); 61 | }) 62 | socket.on('frame', (data) => { 63 | machines = data; 64 | var keys = Object.keys(data); 65 | }); 66 | 67 | socket.on('bullet', (bullet) =>{ 68 | allBullets.push(new Bullet(bullet.x, bullet.y, bullet.radian, bullet.range)); 69 | }) 70 | 71 | socket.on('message', (message) => { 72 | var el = document.createElement('li'); 73 | el.textContent = message; 74 | el.style.color = 'rgba(255,122,130,1)'; 75 | chatList.appendChild(el); 76 | chatList.scrollTop = chatList.scrollHeight; 77 | }) 78 | 79 | socket.on('sortedPlayers', (sortedPlayers)=>{ 80 | leaderList.innerHTML = ''; 81 | for(var i = 0; i < sortedPlayers.length; i++){ 82 | if(sortedPlayers[i].name != 'inLobby'){ 83 | var li = document.createElement('li'); 84 | li.innerHTML = sortedPlayers[i].name + '
    ' + sortedPlayers[i].score; 85 | leaderList.appendChild(li); 86 | } 87 | } 88 | }) 89 | var machinePng = document.getElementById('image'); 90 | var healthBar = document.getElementById('health'); 91 | var keys = { 92 | w: false, 93 | leftArrow: false, 94 | rigthArrow: false, 95 | downArrow: false, 96 | space: false, 97 | one: false, 98 | two: false, 99 | enter : false 100 | } 101 | 102 | window.onload = ()=>{ 103 | loop = setInterval(show, 1000/framePerSecond); 104 | } 105 | 106 | if(gameState == gameStates.ENTER_MENU){ 107 | canvasContext.fillStyle = 'rgba(0,0,0,0.5)'; 108 | canvasContext.fillRect(canvas.width/4, canvas.height/4, canvas.width/2, canvas.height/2); 109 | canvasContext.fillStyle = 'white'; 110 | canvasContext.font = '20px Arial'; 111 | canvasContext.textAlign = 'center'; 112 | canvasContext.fillText("Enter Name",canvas.width/2, canvas.height/2 - 50); 113 | var input = document.createElement('input'); 114 | input.type = 'text'; 115 | input.id = 'name'; 116 | input.style.position = 'absolute'; 117 | input.style.margin = 'auto'; 118 | input.style.width = '100px'; 119 | input.setAttribute('maxlength', 13); 120 | input.style.top = `${canvas.height / 2}px`; 121 | input.style.left = `${canvas.width / 2 - 50}px`; 122 | input.autofocus = true; 123 | document.body.appendChild(input); 124 | var button = document.createElement('input'); 125 | button.type = 'button'; 126 | button.value = 'START'; 127 | button.id = 'button'; 128 | button.style.position = 'absolute'; 129 | button.style.width = '80px'; 130 | button.style.top = `${canvas.height / 2 + 50}px`; 131 | button.style.left = `${canvas.width / 2 - 40}px`; 132 | button.onclick = () =>{ 133 | playerName = input.value; 134 | myMachine = new Machine( Math.random() * (maxCanvasWidth - 50) , Math.random() * (maxCanvasHeight - 50), 0, 100,playerName ,[]); 135 | gameState = gameStates.GAME; 136 | var el = document.getElementById('name'); 137 | el.parentNode.removeChild(el); 138 | el = document.getElementById('button'); 139 | el.parentNode.removeChild(el); 140 | } 141 | document.body.appendChild(button); 142 | } 143 | 144 | function show(){ 145 | if(gameState == gameStates.GAME || gameState == gameStates.GAME_OVER_MENU) { 146 | update(); 147 | draw(); 148 | } 149 | } 150 | 151 | function update(){ 152 | canvasContext.clearRect(-1000, -1000, maxCanvasWidth + 2000, maxCanvasHeight + 2000); 153 | checkKeys(); 154 | myMachine.x *= 1.0; 155 | myMachine.y *= 1.0; 156 | if(myMachine.health >= 0 ){ 157 | socket.emit('frame', myMachine); 158 | } 159 | canvasContext.translate(-(myMachine.x - canvas.width / 2 + reference.x),-( myMachine.y - canvas.height / 2 + reference.y)); 160 | reference.x += -(myMachine.x - canvas.width / 2 + reference.x); 161 | reference.y += -(myMachine.y - canvas.height / 2 + reference.y); 162 | 163 | } 164 | 165 | function draw(){ 166 | canvasContext.fillStyle = 'black'; 167 | canvasContext.fillRect(-1000, -1000, maxCanvasWidth + 2000, maxCanvasHeight + 2000); 168 | canvasContext.beginPath(); 169 | canvasContext.strokeStyle = 'white'; 170 | canvasContext.rect(0, 0, maxCanvasWidth, maxCanvasHeight); 171 | canvasContext.stroke(); 172 | canvasContext.closePath(); 173 | showMachines(); 174 | canvasContext.textAlign = 'start'; 175 | showScore(); 176 | showLeaderBord(); 177 | showRange(); 178 | showBulletCount(); 179 | showMoney(); 180 | animateMoney(); 181 | if(shouldDrawHealthAnimation) 182 | showHealEffect(increment, healthAnimationX, healthAnimationY); 183 | if(myMachine.health <= 0){ 184 | clearInterval(loop); 185 | gameState = gameStates.GAME_OVER_MENU; 186 | socket.disconnect(); 187 | gameOver(); 188 | } 189 | } 190 | 191 | function showMachines(){ 192 | var keys = Object.keys(machines) 193 | var machine; 194 | 195 | for(var i = 0; i < allBullets.length; i++){ 196 | var is = false; 197 | for(var j = 0; j < myMachine.bullets.length; j++){ 198 | if(allBullets[i].x == myMachine.bullets[j].x && allBullets[i].y == myMachine.bullets[j].y){ 199 | is = true; 200 | } 201 | } 202 | if(is){ 203 | continue; 204 | } 205 | else if(allBullets[i].x > myMachine.x && allBullets[i].x < myMachine.x + myMachine.size && 206 | allBullets[i].y > myMachine.y && allBullets[i].y < myMachine.y + myMachine.size 207 | ){ 208 | myMachine.getDamage(); 209 | showParticles(allBullets[i]); 210 | allBullets.splice(i, 1); 211 | i--; 212 | } 213 | } 214 | for(var i = 0; i < myMachine.bullets.length; i++){ 215 | myMachine.bullets[i].show(); 216 | } 217 | for(var i = 0; i < allBullets.length; i++){ 218 | if(allBullets[i].range - 25 < Math.sqrt(Math.pow(allBullets[i].x - allBullets[i].startX, 2) + Math.pow(allBullets[i].y - allBullets[i].startY, 2))){ 219 | allBullets.splice(i, 1); 220 | i--; 221 | } 222 | } 223 | for(var i = 0; i < keys.length; i++){ 224 | for(var j = 0; j < myMachine.bullets.length; j++){ 225 | if(keys[i] != myID && myMachine.bullets[j].x > machines[keys[i]].machine.x && 226 | myMachine.bullets[j].x < machines[keys[i]].machine.x + myMachine.size && 227 | myMachine.bullets[j].y > machines[keys[i]].machine.y && 228 | myMachine.bullets[j].y < machines[keys[i]].machine.y + myMachine.size 229 | ){ 230 | showParticles(myMachine.bullets[j]); 231 | if(machines[keys[i]].machine.health <= 6){ 232 | shouldDrawHealthAnimation = true; 233 | increment = myMachine.health + 50 > 100 ? 100 - myMachine.health: 50; 234 | myMachine.health += increment; 235 | healthAnimationX = myMachine.x; 236 | healthAnimationY = myMachine.y; 237 | setTimeout(function(){ 238 | shouldDrawHealthAnimation = false; 239 | }, 1400); 240 | } 241 | myMachine.bullets.splice(j, 1); 242 | myMachine.score += 3; 243 | myMoney += 3; 244 | j--; 245 | } 246 | } 247 | } 248 | 249 | for(var i = 0; i < allBullets.length; i++){ 250 | allBullets[i].show(); 251 | } 252 | 253 | myMachine.update(); 254 | myMachine.call(); 255 | for(var i =0; i < myMachine.bullets.length; i++){ 256 | myMachine.bullets[i].draw(); 257 | } 258 | for(var i = 0; i < keys.length; i++){ 259 | if(myID != keys[i] && machines[keys[i]].machine.health > 0){ 260 | machine = new Machine(machines[keys[i]].machine.x, machines[keys[i]].machine.y, machines[keys[i]].machine.angle, machines[keys[i]].machine.health, machines[keys[i]].machine.playerName, Array.isArray(machines[keys[i]].machine.bullets)? machines[keys[i]].machine.bullets : []); 261 | machine.call(); 262 | } 263 | } 264 | myMachine.showRange(); 265 | } 266 | 267 | function gameOver(){ 268 | myMoney = 0; 269 | cost = 20; 270 | var x = reference.x + myMachine.x; 271 | var y = reference.y + myMachine.y; 272 | canvasContext.fillStyle = 'rgba(0,0,0,0.5)'; 273 | canvasContext.fillRect(0, 0, canvas.width, canvas.height); 274 | canvasContext.fillStyle = 'white'; 275 | canvasContext.font = '20px Arial'; 276 | canvasContext.textAlign = 'start'; 277 | canvasContext.fillText("You Lost", x - reference.x, y - reference.y - 50); 278 | canvasContext.fillStyle = 'white'; 279 | canvasContext.fillText('Score: ' + myMachine.score, x - reference.x , y -reference.y - 25); 280 | myMachine.x = -myMachine.range - myMachine.size - 10; 281 | var input = document.getElementById('name') || document.createElement('input'); 282 | input.type = 'text'; 283 | input.id = 'name'; 284 | input.value = playerName; 285 | input.style.position = 'absolute'; 286 | input.style.margin = 'auto'; 287 | input.style.width = '100px'; 288 | input.setAttribute('maxlength', 13); 289 | input.style.top = `${y}px`; 290 | input.style.left = `${x}px`; 291 | document.body.appendChild(input); 292 | button = document.getElementById('button') || document.createElement('input'); 293 | button.type = 'button'; 294 | button.value = 'START'; 295 | button.id = 'button'; 296 | button.style.position = 'absolute'; 297 | button.style.width = '80px'; 298 | button.style.top = `${y + 25}px`; 299 | button.style.left = `${x}px`; 300 | button.autofocus = true; 301 | button.onclick = () =>{ 302 | playerName = input.value; 303 | myMachine = new Machine(Math.random() * (maxCanvasWidth - 50) , Math.random() * (maxCanvasHeight - 50), 0, 100,playerName ,[]); 304 | gameState = gameStates.GAME; 305 | var el = document.getElementById('name'); 306 | el.parentNode.removeChild(el); 307 | el = document.getElementById('button'); 308 | el.parentNode.removeChild(el); 309 | loop = setInterval(show, 1000/framePerSecond); 310 | socket.connect(); 311 | } 312 | document.body.appendChild(button); 313 | } 314 | 315 | function showScore(){ 316 | canvasContext.fillStyle = 'white'; 317 | canvasContext.font = '30px sans-serif'; 318 | canvasContext.fillText('Score: ' + myMachine.score, -reference.x + 10 , - reference.y + 25 ); 319 | } 320 | 321 | function showRange(){ 322 | canvasContext.fillStyle = 'white'; 323 | canvasContext.font = '30px sans-serif'; 324 | canvasContext.fillText('Range: ' + myMachine.range, - reference.x + 10, - reference.y + 60); 325 | } 326 | 327 | function showBulletCount(){ 328 | canvasContext.fillStyle = 'white'; 329 | canvasContext.font = '30px sans-serif'; 330 | canvasContext.fillText('Bullet: ' + ( myMachine.maxBulletCount - myMachine.bullets.length) + ' / ' + myMachine.maxBulletCount, -reference.x + 10,- reference.y + 95); 331 | } 332 | 333 | function showLeaderBord(){ 334 | } 335 | 336 | function showMoney(){ 337 | canvasContext.fillStyle = 'white'; 338 | canvasContext.font = '30px sans-serif'; 339 | canvasContext.fillText('Money: ' + myMoney, -reference.x + 10,- reference.y + 130); 340 | } 341 | 342 | function animateMoney(){ 343 | canvasContext.fillStyle = 'white'; 344 | canvasContext.fillRect(-reference.x + 10, -reference.y + 150, 100, 5) 345 | canvasContext.fillStyle = 'green'; 346 | canvasContext.fillRect(-reference.x + 10, -reference.y + 150, myMoney <= cost? myMoney * cost* (100 / cost)/ cost : 100, 5) 347 | if(myMoney >= cost){ 348 | canvasContext.fillStyle = 'green'; 349 | var xpos = 200; 350 | canvasContext.font = '15px sans-serif'; 351 | canvasContext.fillRect(- reference.x + 10 + xpos, - reference.y + 60 - 20, 170, 20 ); 352 | canvasContext.fillStyle = 'white'; 353 | canvasContext.fillText('to upgrade press 1 (+10)', - reference.x + 10 + xpos + 5, - reference.y + 60 + 5 - 10); 354 | canvasContext.fillStyle = 'green'; 355 | canvasContext.fillRect(- reference.x + 10 + xpos, - reference.y + 95 - 20, 170, 20 ); 356 | canvasContext.fillStyle = 'white'; 357 | canvasContext.fillText('to upgrade press 2 (+1)', - reference.x + 10 + xpos + 5, - reference.y + 95 + 5 - 10); 358 | } 359 | } 360 | 361 | function sendMessage(){ 362 | var input = chatInput.value; 363 | var message = playerName + ': ' + input; 364 | var el = document.createElement('li'); 365 | el.textContent = message; 366 | el.style.color = 'rgba(157,251,255,0.8)'; 367 | chatList.appendChild(el); 368 | chatList.scrollTop = chatList.scrollHeight; 369 | chatInput.value = ''; 370 | socket.emit('message', message); 371 | } 372 | 373 | function showParticles(bullet){ 374 | var particles = []; 375 | var particles2 = []; 376 | for(var i = 0; i < particleCount; i++){ 377 | particles.push(new Bullet(bullet.x, bullet.y, bullet.radian + Math.PI/4 + (Math.PI * i / 2), particleRange)); 378 | } 379 | for(var i = 0; i < particleCount; i++){ 380 | particles2.push(new Bullet(bullet.x, bullet.y, bullet.radian + (Math.PI * i / 2), particleRange / 2)) 381 | } 382 | var particleLoop = setInterval(function(){ 383 | for(var i = 0; i < particles.length; i++){ 384 | particles[i].show(); 385 | } 386 | },1000/framePerSecond); 387 | var particle2Loop = setInterval(function(){ 388 | for( var i = 0; i < particles2.length; i++){ 389 | particles2[i].show(); 390 | } 391 | }, 1000/framePerSecond); 392 | 393 | setTimeout(function(){ 394 | clearInterval(particle2Loop); 395 | particles2 = []; 396 | }, 100); 397 | 398 | setTimeout(function(){ 399 | clearInterval(particleLoop); 400 | particles = []; 401 | },200); 402 | } 403 | 404 | function showHealEffect(increment, x, y){ 405 | canvasContext.fillStyle = 'green'; 406 | canvasContext.font = 'bold 36px Arial'; 407 | canvasContext.fillText( '+' + increment, x, y); 408 | } 409 | 410 | window.addEventListener('keydown', e => { 411 | if(e.keyCode == 38){ 412 | keys['w'] = true; 413 | } else if (e.keyCode == 39){ 414 | keys['rightArrow'] = true; 415 | } else if (e.keyCode == 37){ 416 | keys['leftArrow'] = true; 417 | } else if (e.keyCode == 32){ 418 | keys['space'] = true; 419 | } else if (e.keyCode == 49){ 420 | keys['one'] = true; 421 | } else if (e.keyCode == 50){ 422 | keys['two'] = true; 423 | } else if (e.keyCode == 13){ 424 | keys['enter'] = true; 425 | } else if (e.keyCode == 40){ 426 | keys['downArrow'] = true; 427 | } 428 | }) 429 | 430 | window.addEventListener('scroll', ()=>{ 431 | window.scrollTo(0, 0); 432 | }); 433 | 434 | window.addEventListener('keyup', e => { 435 | /*if(e.keyCode == 38 || e.keyCode == 39 || e.keyCode == 37 || e.keyCode == 32) 436 | // e.preventDefault();*/ 437 | if(e.keyCode == 38){ 438 | keys['w'] = false; 439 | } else if (e.keyCode == 39){ 440 | keys['rightArrow'] = false; 441 | } else if (e.keyCode == 37){ 442 | keys['leftArrow'] = false; 443 | } else if (e.keyCode == 32){ 444 | keys['space'] = false; 445 | } else if (e.keyCode == 49){ 446 | keys['one'] = false; 447 | } else if (e.keyCode == 50){ 448 | keys['two'] = false; 449 | } else if (e.keyCode == 13){ 450 | keys['enter'] = false; 451 | } else if (e.keyCode == 40){ 452 | keys['downArrow'] = false; 453 | } 454 | }) 455 | 456 | window.addEventListener('keydown', e => { 457 | if(e.keyCode == 13 && (gameState == gameStates.ENTER_MENU || gameState == gameStates.GAME_OVER_MENU)) { 458 | button.click(); 459 | } 460 | }) 461 | 462 | 463 | function checkKeys(){ 464 | if(keys.w) 465 | myMachine.moveTop(); 466 | if(keys.rightArrow) 467 | myMachine.turnRight(); 468 | if(keys.leftArrow) 469 | myMachine.turnLeft(); 470 | if(keys.space){ 471 | if(myMachine.fire()){ 472 | socket.emit('bullet', {x: myMachine.headX, y: myMachine.headY, radian: myMachine.radian, range:myMachine.range}); 473 | } 474 | } 475 | if(keys.one && myMoney >= cost){ 476 | keys['one'] = false; 477 | myMachine.increaseRange(); 478 | myMoney -= cost; 479 | cost += 10; 480 | } 481 | if(keys.two && myMoney >= cost){ 482 | keys['two'] = false; 483 | myMachine.increaseBulletCount(); 484 | myMoney -= cost; 485 | cost += 10; 486 | } 487 | if(keys.enter && chatInput.value != ''){ 488 | sendMessage(); 489 | keys['enter'] = false; 490 | } 491 | if(keys.downArrow){ 492 | myMachine.moveBack(); 493 | } 494 | } 495 | 496 | --------------------------------------------------------------------------------