Commit caa9654c authored by Michele Beccari's avatar Michele Beccari
Browse files
parents 9fe2b348 c8d1f384
Pipeline #6383 skipped with stage
No preview for this file type
......@@ -26,6 +26,9 @@
},
"dependencies": {
"animate.css": "^3.7.0",
"file-loader": "^3.0.1"
"express": "4.15.2",
"file-loader": "^3.0.1",
"socket.io": "^2.2.0",
"socket.io-client": "^2.2.0"
}
}
const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const servers = {}
const players = {}
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
console.log('a user connected');
let server = null
socket.on('connect to server', (msg) => {
console.log(`New server from ${socket} for ${msg}`)
if (servers[msg]) {
servers[msg].push(socket)
} else {
servers[msg] = [socket]
}
server = msg
if (players[msg]) {
players[msg].forEach(a => {
console.log('SENDING ' + JSON.stringify({
myid: a,
x: 597,
y: 2699,
pid: a
}))
socket.emit('data', JSON.stringify({
myid: a,
x: 597,
y: 2699,
pid: a
}))
})
}
});
socket.on('data', msg => {
console.log(`new message ${msg}`)
const parsed = JSON.parse(msg)
if (parsed.id === 'myid') {
if (players[server]) {
players[server].push(parsed.value)
} else {
players[server] = [parsed.value]
}
}
servers[server].forEach(a => {
if (a !== socket) {
console.log('SENDING ' + msg)
a.emit('data', msg)
}
})
})
socket.on('disconnect', (reason) => {
console.log(`${socket} disconnected ${reason}`);
if (servers[server]) {
servers[server] = servers[server].filter(a => a !== socket)
}
});
});
http.listen(3000, () => {
console.log('listening on *:3000');
});
\ No newline at end of file
No preview for this file type
#game-character {
width: 60px;
height: 80px;
.game-character {
width: 180px;
height: 138px;
position: absolute;
z-index: 6000;
}
......
import './Character.css'
import Image from './Character.svg'
import Image2 from './Character2.svg'
import {clamp, fixElement, raycast} from './Utils'
import Image from './assets/SVG/pollo.svg'
import Image2 from './assets/SVG/pollo_cammina.svg'
import Image3 from './assets/SVG/pollo_volo.svg'
import Image4 from './assets/SVG/pollo_bocca_aperta.svg'
import {clamp, fixElement, raycast, base64ToArrayBuffer} from './Utils'
import BezierEasing from 'bezier-easing'
import Projectile from './Projectile'
import VerticalProjectile from './VerticalProjectile'
const JUMP_TICKS = 60
......@@ -57,6 +60,9 @@ class Character {
currentSpeed = 0
verticalSpeed = 0
boccaAperta = 0
boccaAperta2 = 0
isGround() {
let range = Math.abs(this.verticalSpeed)
......@@ -70,13 +76,15 @@ class Character {
return false
}
return result[0]
const real = result[0]
return real
}
constructor(game) {
this.game = game
this.spriteChangeTicks = 30
document.getElementById('game-container').innerHTML += `<div id="game-character"><img alt="game" style="width: 100%; height: 100%;" src="${Image}" /></div>`
this.spriteChangeTicks = 20
document.getElementById('game-container').innerHTML += `<div class="game-character" id="game-character"><img alt="game" style="width: 100%; height: 100%;" src="${Image}" /></div>`
this.shootSFX = document.getElementById('super-sfx-shoot')
this.element = document.getElementById('game-character')
document.onkeydown = (e) => this.onKeyDown(e)
document.onkeyup = (e) => {
......@@ -103,8 +111,16 @@ class Character {
}
addProjectile() {
const projectile = new Projectile(this.x, this.y, 10, this.direction, this.game)
this.playSound(this.shootSFX)
const projectile = new Projectile(this.x + (this.direction === 1 ? this.element.offsetWidth : 0), this.y + 10, 10, this.direction, this.game)
this.game.ticker.add(projectile)
this.boccaAperta = 30
}
addVerticalProjectile() {
const projectile = new VerticalProjectile(this.x + this.element.offsetWidth/2, this.y + this.element.offsetHeight, 10, 1, this.game)
this.game.ticker.add(projectile)
this.boccaAperta2 = 30
}
handleJump() {
......@@ -143,6 +159,7 @@ class Character {
this.game.lose()
}
if (this.direction === Directions.Left) {
this.x -= this.currentSpeed
} else if (this.direction === Directions.Right) {
......@@ -154,16 +171,35 @@ class Character {
this.spriteChangeTicks--
}
const img = this.element.getElementsByTagName('img')[0]
if (this.spriteChangeTicks === 0) {
const img = this.element.getElementsByTagName('img')[0]
img.src = img.src === Image ? Image2 : Image
this.spriteChangeTicks = 30
this.spriteChangeTicks = 20
}
if (this.jumpingTicks !== 0) {
img.src = Image3
}
if (this.boccaAperta !== 0) {
img.src = Image4
this.boccaAperta --
}
if (this.boccaAperta2 !== 0) {
img.src = Image3
this.boccaAperta2 --
}
this.y += this.verticalSpeed
if (this.jumpingTicks !== 0) {
this.handleJump()
if (this.jumpingTicks === 0) {
img.src = Image
}
}
const ground = this.isGround()
......@@ -171,6 +207,9 @@ class Character {
if (this.jumpingTicks <= this.totalJumpTicks / 2) {
this.jumpingTicks = 0;
this.verticalSpeed = 0;
if (this.boccaAperta === 0 && this.boccaAperta2 === 0) {
img.src = Image
}
}
}
......@@ -191,6 +230,8 @@ class Character {
}
this.lastDrawnX = this.x
this.lastDrawnY = this.y
if (this.game.multiplayer)
this.game.multiplayer.emit({id: 'xy', x: this.x, y: this.y})
this.element.style = `top: ${Math.round(this.y)}px; left: ${Math.round(this.x)}px`
fixElement(this.y, this.element.offsetHeight, window.innerHeight / 2, window.innerHeight / 3)
}
......@@ -202,6 +243,10 @@ class Character {
return
}
if (this.game.multiplayer) {
this.game.multiplayer.emit({id: 'key', code: e.keyCode})
}
e.preventDefault();
if ([Keys.ArrowUp, Keys.ArrowDown].includes(e.keyCode)) {
......@@ -223,12 +268,28 @@ class Character {
if (e.keyCode === Keys.D) {
this.addProjectile()
}
if (e.keyCode === Keys.E) {
this.addVerticalProjectile()
}
}
fixPg() {
this.x = clamp(this.x, 0, this.maxWidth)
this.y = clamp(this.y, 0, this.maxHeight)
}
playSound(sound) {
this.game.audioCtx.suspend()
let audioElement = document.createElement('audio')
audioElement.appendChild(sound)
document.getElementById('game-container').appendChild(audioElement)
audioElement.play()
this.game.audioCtx.resume()
}
}
export default Character
\ No newline at end of file
.game-enemy {
background-color: rgba(255, 0, 0, 0.5);
position: absolute;
z-index: 7000;
}
\ No newline at end of file
import './Enemy.css'
import Projectile from './Projectile'
class Enemy {
id = null
x = null
y = null
game = null
element = null
width = null
height = null
constructor(x, y, width, height, game) {
this.x = x
this.y = y
this.game = game
this.width = width
this.height = height
this.id = 'id' + Math.round(Math.random() * 1000)
this.element = document.createElement('div')
this.element.id = this.id
this.element.className = 'game-enemy'
document.getElementById('game-container').appendChild(this.element)
this.draw()
}
tick() {
if (Math.round(Math.random() * 1000) === 4) {
const direction = Math.round(Math.random() * 2) === 0 ? -1 : 1
const projectile = new Projectile(this.x, this.y, 7, direction, this.game)
this.game.ticker.add(projectile)
}
}
draw() {
this.element.style = `top: ${Math.round(this.y)}px; left: ${Math.round(this.x)}px; width: ${this.width}px; height: ${this.height}px`
}
}
export default Enemy
\ No newline at end of file
......@@ -5,19 +5,16 @@ import GameFinishChecker from './GameFinishChecker'
import UIManager from './UIManager.js'
import Usable from './Usable.js'
import bgmusic from './assets/bgmusic.mp3'
import shootSFX from './assets/shootSFX.mp3'
import PageParser from './PageParser'
import Ticker from './Ticker'
<<<<<<< HEAD
import FallManager from './FallManager';
=======
import {base64ToArrayBuffer} from './Utils'
import Multiplayer from './Multiplayer'
>>>>>>> c8d1f38460767211551f6ca83702b42a770ae056
const base64ToArrayBuffer = (base64) => {
let binaryString = window.atob(base64);
let len = binaryString.length;
let bytes = new Uint8Array( len );
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
class Game {
......@@ -30,7 +27,12 @@ class Game {
homeFinder = null
pageParser = null
ticker = null
<<<<<<< HEAD
fallmanager = null;
=======
multiplayer = null
>>>>>>> c8d1f38460767211551f6ca83702b42a770ae056
bgmusic = null
audioCtx = null
source = null
......@@ -43,7 +45,8 @@ class Game {
audioEnabled = true
constructor() {
document.body.innerHTML += '<div id="game-container"><audio><source id="soundtrack-superdubstep" src="' + bgmusic + '" type="audio/mpeg"></audio></div>'
document.body.innerHTML +=`<div id="game-container"><audio><source id="soundtrack-superdubstep" src="`
+ bgmusic + `" type="audio/mpeg"><source id="super-sfx-shoot" src="` + shootSFX + `" type='audio/mpeg'></audio></div>`
this.background = document.getElementById('super-background')
this.bgmusic = document.getElementById('soundtrack-superdubstep').src.replace('data:audio/mpeg;base64,', '')
......@@ -94,6 +97,7 @@ class Game {
setTimeout(() => {
this.pageParser = new PageParser(this)
this.character = new Character(this)
this.multiplayer = new Multiplayer(this)
this.ticker.add(this.character)
this.gameFinishChecker = new GameFinishChecker(this)
this.ticker.add(this.gameFinishChecker)
......
import io from 'socket.io-client';
import MultiplayerCharacter from './MultiplayerCharacter'
class Multiplayer {
game = null
id = null
players = {}
socket = null
constructor(game) {
this.game = game
this.id = Math.floor(Math.random() * 1000)
this.socket = io('http://localhost:3000');
this.socket.emit('connect to server', window.location.href)
this.emit({id: 'myid', value: this.id, x: this.game.character.x, y: this.game.character.y})
this.socket.on('data', (json) => {
const data = JSON.parse(json)
switch (data.id) {
case 'myid':
this.players[data.value] = new MultiplayerCharacter(this.game, data.id, data.x, data.y)
this.game.ticker.add(this.players[data.value])
break
case 'key':
//this.players[data.pid].onKeyDown(data.code)
break
case 'xy':
this.players[data.pid].x = data.x
this.players[data.pid].y = data.y
this.players[data.pid].reDraw()
break
}
})
}
emit(msg) {
msg.pid = this.id
this.socket.emit('data', JSON.stringify(msg))
}
}
export default Multiplayer
\ No newline at end of file
import './Character.css'
import Image from './assets/SVG/pollo.svg'
import Image2 from './assets/SVG/pollo_cammina.svg'
import Image3 from './assets/SVG/pollo_volo.svg'
import Image4 from './assets/SVG/pollo_bocca_aperta.svg'
import {clamp, fixElement, raycast, base64ToArrayBuffer} from './Utils'
import BezierEasing from 'bezier-easing'
import Projectile from './Projectile'
import VerticalProjectile from './VerticalProjectile'
const JUMP_TICKS = 60
const Keys = {
ArrowLeft: 37,
ArrowRight: 39,
ArrowDown: 40,
ArrowUp: 38,
SpaceBar: 32,
D: 68,
E: 69
}
const Directions = {
Left: -1,
Right: 1
}
const keysToDirection = (key) => {
switch( key ){
case Keys.ArrowLeft:
return Directions.Left
case Keys.ArrowRight:
return Directions.Right
default:
return null
}
}
class MultiplayerCharacter {
game = null
element = null
x = 0
y = 0
lastDrawnX = 0
lastDrawnY = 0
movementSpeed = 10
jumpStrength = 10
spriteChangeTicks = 0
direction = Directions.Left
maxHeight = null
maxWidth = null
id = null
jumpingTicks = 0
totalJumpTicks = 0
currentSpeed = 0
verticalSpeed = 0
boccaAperta = 0
boccaAperta2 = 0
isGround() {
let range = Math.abs(this.verticalSpeed)
if (range === 0) range = 5
const result = raycast(this.x + (this.element.offsetWidth/2),
this.y + this.element.offsetHeight - range,
this.y + this.element.offsetHeight + 1 + range)
if (result.length === 0) {
return false
}
const real = result[0]
return real
}
constructor(game, id, x, y) {
this.game = game
this.id = id
this.spriteChangeTicks = 20
document.getElementById('game-container').innerHTML += `<div class="game-character" id="game-character-${this.id}"><img alt="game" style="width: 100%; height: 100%;" src="${Image}" /></div>`
this.source = this.game.audioCtx.createBufferSource()
this.shootSFX = document.getElementById('super-sfx-shoot').src.replace('data:audio/mpeg;base64,', '')
this.element = document.getElementById('game-character-' + this.id)
this.x = x
this.y = y
this.reDraw()
}
startJump() {
this.totalJumpTicks = JUMP_TICKS + 2 * Math.round((Math.random() * 15))
this.jumpingTicks = this.totalJumpTicks
}
addProjectile() {
this.playSound(this.shootSFX)
const projectile = new Projectile(this.x + (this.direction === 1 ? this.element.offsetWidth : 0), this.y + 10, 10, this.direction, this.game)
this.game.ticker.add(projectile)
this.boccaAperta = 30
}
addVerticalProjectile() {
const projectile = new VerticalProjectile(this.x + this.element.offsetWidth/2, this.y + this.element.offsetHeight, 10, 1, this.game)
this.game.ticker.add(projectile)
this.boccaAperta2 = 30
}
handleJump() {
const speed = this.jumpStrength
if (this.jumpingTicks === this.totalJumpTicks) {
this.verticalSpeed = -speed
}
if (this.jumpingTicks === this.totalJumpTicks/2) {
this.verticalSpeed = 0
}
const acceleration = speed/(this.totalJumpTicks/2)
if (this.jumpingTicks <= this.totalJumpTicks/2) { // GIU
this.verticalSpeed += acceleration
} else { // SU
this.verticalSpeed += acceleration
}
this.jumpingTicks--
if (this.jumpingTicks === 0) {
this.verticalSpeed = 0
}
}
tick() {
if (!this.game.started) return
if (this.game.UIManager.timerExpired){
this.game.lose()
}
if (this.direction === Directions.Left) {
this.x -= this.currentSpeed
} else if (this.direction === Directions.Right) {
this.x += this.currentSpeed
}
if (this.currentSpeed !== 0) {
this.spriteChangeTicks--
}
const img = this.element.getElementsByTagName('img')[0]
if (this.spriteChangeTicks === 0) {
img.src = img.src === Image ? Image2 : Image
this.spriteChangeTicks = 20
}
if (this.jumpingTicks !== 0) {
img.src = Image3
}
if (this.boccaAperta !== 0) {
img.src = Image4
this.boccaAperta --
}
if (this.boccaAperta2 !== 0) {
img.src = Image3
this.boccaAperta2 --
}
this.y += this.verticalSpeed
if (this.jumpingTicks !== 0) {
this.handleJump()
if (this.jumpingTicks === 0) {
img.src = Image
}
}
const ground = this.isGround()
if (ground !== false) {
if (this.