├── 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 |
14 |
17 |
18 |
19 |
20 | -
21 | Up Arrow: move forward
22 |
23 | -
24 | Down Arrow: move back
25 |
26 | -
27 | Left Arrow: turn Left
28 |
29 | -
30 | Right Arrow: turn Right
31 |
32 | -
33 | Spacebar: fire
34 |
35 | -
36 | 1: upgrade range
37 |
38 | -
39 | 2: upgrade ammo
40 |
41 |
42 |
43 |
44 |

45 |
46 |
47 |
Players: 0
48 |
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 |
--------------------------------------------------------------------------------