Dont even remember what was done :D
This commit is contained in:
41
client/src/Bullet.ts
Normal file
41
client/src/Bullet.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import p5 from "p5";
|
||||
import OtherPlayer from "./OtherPlayer";
|
||||
import { Position } from "./types";
|
||||
|
||||
export default class Bullet {
|
||||
|
||||
private timeLeftToLive = 2000;
|
||||
|
||||
private _position: Position
|
||||
|
||||
constructor(
|
||||
private _shooter: OtherPlayer,
|
||||
private direction: Position,
|
||||
) {
|
||||
this._position = {..._shooter.position}
|
||||
}
|
||||
|
||||
get position() {
|
||||
return this._position
|
||||
}
|
||||
|
||||
get shooter() {
|
||||
return this._shooter
|
||||
}
|
||||
|
||||
move() {
|
||||
this._position.x += this.direction.x
|
||||
this._position.y += this.direction.y
|
||||
|
||||
this.timeLeftToLive -= Math.abs(this.direction.x) + Math.abs(this.direction.y)
|
||||
}
|
||||
|
||||
get timeToLive() {
|
||||
return this.timeLeftToLive
|
||||
}
|
||||
|
||||
set timeToLive(time: number) {
|
||||
this.timeLeftToLive = time
|
||||
}
|
||||
|
||||
}
|
||||
78
client/src/Game.ts
Normal file
78
client/src/Game.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { Socket } from "socket.io-client";
|
||||
import Bullet from "./Bullet";
|
||||
import OtherPlayer from "./OtherPlayer";
|
||||
import UserPlayer from "./UserPlayer";
|
||||
import { PlayerDescription } from "./socketDataTypes";
|
||||
import Pickable from "./Pickable";
|
||||
|
||||
export default class Game {
|
||||
|
||||
private player: UserPlayer
|
||||
private otherPlayers: OtherPlayer[] = []
|
||||
private bullets: Bullet[] = []
|
||||
private items: Pickable[] = []
|
||||
|
||||
constructor(_socket: SocketIOClient.Socket) {
|
||||
this.player = new UserPlayer(_socket.id, _socket, '', {x:0, y:0}, 'white', new Map<number, boolean>(), 100)
|
||||
}
|
||||
|
||||
addItem(item: Pickable) {
|
||||
this.items.push(item)
|
||||
}
|
||||
|
||||
getItems() {
|
||||
return this.items
|
||||
}
|
||||
|
||||
removeItem(pickable: Pickable) {
|
||||
this.items = this.items.filter((item) => {
|
||||
return item !== pickable
|
||||
})
|
||||
}
|
||||
|
||||
getPlayer(): UserPlayer {
|
||||
return this.player
|
||||
}
|
||||
|
||||
setPlayer(description: PlayerDescription) {
|
||||
this.player.id = description.id
|
||||
this.player.name = description.name
|
||||
this.player.position = description.position
|
||||
this.player.color = description.color
|
||||
}
|
||||
|
||||
addOtherPlayer(player: OtherPlayer) {
|
||||
if (player.id === this.player.id) return
|
||||
let oPlayer = this.otherPlayers.find((otherPlayer) => {
|
||||
return player.id === otherPlayer.id
|
||||
})
|
||||
if (oPlayer) {
|
||||
oPlayer.color = player.color
|
||||
oPlayer.id = player.id
|
||||
oPlayer.name = player.name
|
||||
oPlayer.position = player.position
|
||||
} else {
|
||||
this.otherPlayers.push(player)
|
||||
}
|
||||
}
|
||||
|
||||
removeOtherPlayer(id: string) {
|
||||
this.otherPlayers = this.otherPlayers.filter((player) => {
|
||||
return player.id !== id
|
||||
})
|
||||
}
|
||||
|
||||
getOtherPlayers() {
|
||||
return this.otherPlayers
|
||||
}
|
||||
|
||||
getOtherPlayer(id: string) {
|
||||
for (let player of this.otherPlayers) {
|
||||
if (player.id === id) {
|
||||
return player
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
20
client/src/Item.ts
Normal file
20
client/src/Item.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import p5 from "p5";
|
||||
|
||||
export default class Item {
|
||||
|
||||
constructor(
|
||||
private _image: p5.Image,
|
||||
private _type: "HEAL" | "DAMAGE" | "DEFENCE"
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
get image() {
|
||||
return this._image
|
||||
}
|
||||
|
||||
get type() {
|
||||
return this._type
|
||||
}
|
||||
|
||||
}
|
||||
18
client/src/MapTile.ts
Normal file
18
client/src/MapTile.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import p5 from "p5";
|
||||
import { Position } from "./types";
|
||||
|
||||
export default class MapTile {
|
||||
|
||||
constructor(private _image: p5.Image, private _position: Position) {
|
||||
|
||||
}
|
||||
|
||||
get image() {
|
||||
return this._image
|
||||
}
|
||||
|
||||
get position() {
|
||||
return this._position
|
||||
}
|
||||
|
||||
}
|
||||
101
client/src/OtherPlayer.ts
Normal file
101
client/src/OtherPlayer.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import p5 from "p5"
|
||||
import Bullet from "./Bullet"
|
||||
import { Position } from "./types"
|
||||
|
||||
export default class OtherPlayer {
|
||||
|
||||
private bullets: Bullet[] = []
|
||||
private _damage: number
|
||||
|
||||
constructor(
|
||||
private _id: string,
|
||||
private _name: string,
|
||||
private _position: Position,
|
||||
private _color: string,
|
||||
private _health: number
|
||||
) {
|
||||
this._health = 100
|
||||
this._damage = 10
|
||||
}
|
||||
|
||||
hit(bullet: Bullet, socket: SocketIOClient.Socket) {
|
||||
this.health -= bullet.shooter.damage
|
||||
bullet.timeToLive = -1
|
||||
socket.emit('health-update', {player: this.id, health: this.health})
|
||||
}
|
||||
|
||||
addBullet(bullet: Bullet) {
|
||||
this.bullets.push(bullet)
|
||||
}
|
||||
|
||||
getBullets() {
|
||||
return this.bullets
|
||||
}
|
||||
|
||||
removeExpiredBullets() {
|
||||
this.bullets = this.bullets.filter((bullet) => {
|
||||
return bullet.timeToLive > 0
|
||||
})
|
||||
}
|
||||
|
||||
draw(p5: p5, position: Position) {
|
||||
p5.stroke(0, 0, 0)
|
||||
p5.strokeWeight(5)
|
||||
p5.fill(this.color)
|
||||
p5.ellipse(position.x, position.y, 80, 80)
|
||||
p5.textSize(32)
|
||||
p5.fill(255, 255, 255)
|
||||
p5.textAlign(p5.CENTER, p5.CENTER)
|
||||
p5.text(this.name, position.x - 300, position.y - 150, 600, 50)
|
||||
p5.noStroke()
|
||||
p5.fill('#850000')
|
||||
p5.rect(position.x - 50, position.y - 90, 100, 5)
|
||||
p5.fill('#008500')
|
||||
p5.rect(position.x - 50, position.y - 90, this.health, 5)
|
||||
}
|
||||
|
||||
get health() {
|
||||
return this._health
|
||||
}
|
||||
|
||||
set health(hp: number) {
|
||||
this._health = hp
|
||||
}
|
||||
|
||||
get damage() {
|
||||
return this._damage
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
return this._id
|
||||
}
|
||||
|
||||
set id(id: string) {
|
||||
this._id = id
|
||||
}
|
||||
|
||||
get position(): Position {
|
||||
return this._position
|
||||
}
|
||||
|
||||
set position(position: Position) {
|
||||
this._position = position
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
return this._name
|
||||
}
|
||||
|
||||
set name(name: string) {
|
||||
this._name = name
|
||||
}
|
||||
|
||||
get color(): string {
|
||||
return this._color
|
||||
}
|
||||
|
||||
set color(color: string) {
|
||||
this._color = color
|
||||
}
|
||||
|
||||
}
|
||||
22
client/src/Pickable.ts
Normal file
22
client/src/Pickable.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import Item from "./Item";
|
||||
import { Position } from "./types";
|
||||
|
||||
export default class Pickable {
|
||||
|
||||
constructor(
|
||||
private _position: Position,
|
||||
private _item: Item,
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
get position() {
|
||||
return this._position
|
||||
}
|
||||
|
||||
get item() {
|
||||
return this._item
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
82
client/src/UserPlayer.ts
Normal file
82
client/src/UserPlayer.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import SocketIOClient from "socket.io-client";
|
||||
import Bullet from "./Bullet";
|
||||
import OtherPlayer from "./OtherPlayer";
|
||||
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<number, boolean>,
|
||||
_health: number
|
||||
) {
|
||||
super(_id, _name, _position, _color, _health)
|
||||
}
|
||||
|
||||
get socket(): SocketIOClient.Socket {
|
||||
return this._socket
|
||||
}
|
||||
|
||||
keyPressed(key: number): boolean {
|
||||
return this._keysPressed.get(key) || 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})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,112 +1,137 @@
|
||||
import P5 from 'p5'
|
||||
import io from 'socket.io-client'
|
||||
import Game from './Game'
|
||||
import MapTile from './MapTile'
|
||||
import OtherPlayer from './OtherPlayer'
|
||||
import prealoadResources from './preloadResources'
|
||||
import setupSocketEvents from './setupSocketEvents'
|
||||
import Bullet from './Bullet'
|
||||
import { Position } from './types'
|
||||
import Pickable from './Pickable'
|
||||
import Item from './Item'
|
||||
|
||||
const socket = io("https://blobbystrike.ioi.lt", {secure: true});
|
||||
const socket = io("https://blobbystrike.ioi.lt", {secure: true})
|
||||
const game = new Game(socket)
|
||||
|
||||
let canvas: HTMLCanvasElement;
|
||||
let images: Map<string, P5.Image>
|
||||
let fonts: Map<string, P5.Font>
|
||||
|
||||
var tileTypes, mapTiles: any = [];
|
||||
let canvas: HTMLCanvasElement
|
||||
var tileTypes, mapTiles: MapTile[] = []
|
||||
|
||||
const PLAYER_SPEED = 10;
|
||||
let shootingDelay = Date.now()
|
||||
|
||||
let Player = {
|
||||
id: '',
|
||||
name: '',
|
||||
position: {x:0, y:0},
|
||||
color: '#' + (Math.floor(Math.random() * 256)).toString(16) + (Math.floor(Math.random() * 256)).toString(16) + (Math.floor(Math.random() * 256)).toString(16),
|
||||
keysPressed: [false],
|
||||
}
|
||||
const VISIBLE_RANGE = 2000
|
||||
const VISIBLE_RANGE_X = 1200
|
||||
const VISIBLE_RANGE_Y = 700
|
||||
|
||||
var OtherPlayers: any = []
|
||||
const PLAYER_SIZE = 80
|
||||
const BULLET_SIZE = 30
|
||||
|
||||
var KEY_W = 87;
|
||||
var KEY_A = 65;
|
||||
var KEY_S = 83;
|
||||
var KEY_D = 68;
|
||||
|
||||
let grassImage: P5.Image;
|
||||
const BULLET_SHOOTING_DELAY = 100
|
||||
|
||||
function onKeyDown(e: any) {
|
||||
Player.keysPressed[e.keyCode] = true;
|
||||
game.getPlayer().setKeyPressed(e.keyCode, true)
|
||||
}
|
||||
function onKeyUp(e: any) {
|
||||
Player.keysPressed[e.keyCode] = false;
|
||||
game.getPlayer().setKeyPressed(e.keyCode, false)
|
||||
}
|
||||
|
||||
function onContextMenu() {
|
||||
Player.keysPressed = [];
|
||||
game.getPlayer().clearKeysPressed()
|
||||
}
|
||||
|
||||
function getCursorPosition(canvas: HTMLCanvasElement, event: MouseEvent) {
|
||||
const rect = canvas.getBoundingClientRect()
|
||||
const x = event.clientX - rect.left
|
||||
const y = event.clientY - rect.top
|
||||
return {
|
||||
x: x,
|
||||
y: y,
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseUp(e: MouseEvent) {
|
||||
if (shootingDelay > Date.now()) return
|
||||
shootingDelay = Date.now() + BULLET_SHOOTING_DELAY
|
||||
let pos = getCursorPosition(canvas, e)
|
||||
pos.x -= parseInt(canvas.style.width) / 2
|
||||
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
|
||||
pos.x *= scale
|
||||
pos.y *= scale
|
||||
game.getPlayer().addBullet(new Bullet(game.getPlayer(), pos))
|
||||
socket.emit('shoot', {position: game.getPlayer().position, direction: pos})
|
||||
}
|
||||
|
||||
function onCanvasResize() {
|
||||
var w = window.innerWidth;
|
||||
var h = window.innerHeight;
|
||||
var w = window.innerWidth
|
||||
var h = window.innerHeight
|
||||
|
||||
var scale = 16/9;
|
||||
var windowScale = w/h;
|
||||
var windowScale = w/h
|
||||
|
||||
if (scale > windowScale) {
|
||||
// higher
|
||||
canvas.style.width = w + 'px';
|
||||
canvas.style.height = (w/16*9) + 'px';
|
||||
canvas.style.width = w + 'px'
|
||||
canvas.style.height = (w/16*9) + 'px'
|
||||
} else {
|
||||
// wider
|
||||
canvas.style.width = (h/9*16) + 'px';
|
||||
canvas.style.height = h + 'px';
|
||||
canvas.style.width = (h/9*16) + 'px'
|
||||
canvas.style.height = h + 'px'
|
||||
}
|
||||
}
|
||||
|
||||
function drawPlayer(p5: P5, player: any, x: any, y: any) {
|
||||
function drawPlayer(p5: P5, player: OtherPlayer, x: any, y: any) {
|
||||
p5.stroke(0, 0, 0)
|
||||
p5.strokeWeight(5)
|
||||
// translate(-width/2, -height/2)
|
||||
p5.fill(player.color)
|
||||
p5.ellipse(x, y, 80, 80);
|
||||
p5.textSize(32);
|
||||
p5.fill(255, 255, 255);
|
||||
p5.textAlign(p5.CENTER, p5.CENTER);
|
||||
p5.text(player.name, x - 300,y - 100, 600, 50);
|
||||
p5.ellipse(x, y, 80, 80)
|
||||
p5.textSize(32)
|
||||
p5.fill(255, 255, 255)
|
||||
p5.textAlign(p5.CENTER, p5.CENTER)
|
||||
p5.text(player.name, x - 300,y - 150, 600, 50)
|
||||
p5.noStroke()
|
||||
p5.fill('#850000')
|
||||
p5.rect(x - 50, y - 90, 100, 5)
|
||||
p5.fill('#008500')
|
||||
p5.rect(x - 50, y - 90, player.health, 5)
|
||||
}
|
||||
|
||||
function relativePosition(pos1: any, pos2: any) {
|
||||
return {
|
||||
x: pos2.x - pos1.x,
|
||||
y: pos2.y - pos1.y,
|
||||
}
|
||||
function drawBullet(p5: P5, color: string, x: any, y: any) {
|
||||
p5.stroke(0, 0, 0)
|
||||
p5.strokeWeight(3)
|
||||
p5.fill(color)
|
||||
p5.ellipse(x, y, 30, 30)
|
||||
}
|
||||
|
||||
function buildMap() {
|
||||
tileTypes = {
|
||||
grass: {
|
||||
image: grassImage
|
||||
image: images.get('grass')
|
||||
}
|
||||
}
|
||||
|
||||
for (let x = 0; x < 10; x++) {
|
||||
mapTiles[x] = []
|
||||
for (let y = 0; y < 6; y++) {
|
||||
mapTiles[x][y] = {
|
||||
tile: tileTypes.grass.image,
|
||||
x: x * 380,
|
||||
y: y * 380,
|
||||
}
|
||||
for (let x = -20; x < 20; x++) {
|
||||
for (let y = -20; y < 20; y++) {
|
||||
mapTiles.push(
|
||||
new MapTile(
|
||||
images.get('grass')!,
|
||||
{
|
||||
x: x * (images.get('grass')?.width || 256),
|
||||
y: y * (images.get('grass')?.height || 256)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
console.log(mapTiles)
|
||||
}
|
||||
|
||||
function isVisible(middlePoint: any, visibleAreaSize: any, position: any, size: any) {
|
||||
if (
|
||||
position.x - size.width > middlePoint.x - visibleAreaSize.width/2 &&
|
||||
position.x + size.width < middlePoint.x + visibleAreaSize.width/2 &&
|
||||
position.y - size.height > middlePoint.y - visibleAreaSize.height/2 &&
|
||||
position.y + size.height < middlePoint.y + visibleAreaSize.height/2
|
||||
) {
|
||||
// console.log('visible')
|
||||
return true;
|
||||
}
|
||||
// console.log('not visible')
|
||||
return false;
|
||||
function isVisible(p1: Position, p2: Position) {
|
||||
return Math.abs(p1.x - p2.x) < VISIBLE_RANGE_X && Math.abs(p1.y - p2.y) < VISIBLE_RANGE_Y
|
||||
}
|
||||
|
||||
function distance(p1: any, p2: any) {
|
||||
@@ -114,103 +139,134 @@ function distance(p1: any, p2: any) {
|
||||
}
|
||||
|
||||
function drawMap(p5: P5) {
|
||||
|
||||
for (let xTiles of mapTiles) {
|
||||
for (let yTile of xTiles) {
|
||||
if (distance(Player.position, {x: yTile.x, y: yTile.y}) < 2000) {
|
||||
p5.image(yTile.tile, yTile.x + p5.width/2, yTile.y + p5.height/2)
|
||||
}
|
||||
for (let tile of mapTiles) {
|
||||
if (isVisible(game.getPlayer().position, tile.position)) {
|
||||
p5.image(tile.image, tile.position.x - game.getPlayer().position.x - tile.image.width/2, tile.position.y - game.getPlayer().position.y - tile.image.height/2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
socket.on('your-info', function (playerData: any) {
|
||||
Player.name = playerData.name;
|
||||
Player.position = playerData.position;
|
||||
Player.color = playerData.color;
|
||||
Player.id = playerData.id;
|
||||
})
|
||||
socket.on('players-info', function (playersData: any) {
|
||||
for (let playerData of playersData) {
|
||||
if (Player.id !== playerData.id) {
|
||||
OtherPlayers.push({
|
||||
name: playerData.name,
|
||||
position: playerData.position,
|
||||
color: playerData.color,
|
||||
id: playerData.id,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
socket.on('new-player-joined', function (playerData: any) {
|
||||
if (Player.id !== playerData.id) {
|
||||
OtherPlayers.push({
|
||||
name: playerData.name,
|
||||
position: playerData.position,
|
||||
color: playerData.color,
|
||||
id: playerData.id,
|
||||
})
|
||||
}
|
||||
})
|
||||
socket.on('player-moved', function (movedPlayerData: any) {
|
||||
for (let playerData of OtherPlayers) {
|
||||
if (Player.id !== movedPlayerData.id && movedPlayerData.id === playerData.id) {
|
||||
playerData.position = movedPlayerData.position;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const sketch = (p5: P5) => {
|
||||
|
||||
p5.setup = () => {
|
||||
buildMap()
|
||||
p5.createCanvas(1920, 1080);
|
||||
p5.createCanvas(1920, 1080, p5.WEBGL);
|
||||
canvas = document.querySelector('canvas')!
|
||||
onCanvasResize()
|
||||
window.addEventListener('resize', onCanvasResize)
|
||||
document.addEventListener('keydown', onKeyDown)
|
||||
document.addEventListener('keyup', onKeyUp)
|
||||
document.addEventListener("contextmenu", onContextMenu);
|
||||
document.addEventListener("contextmenu", onContextMenu)
|
||||
canvas.addEventListener("mousedown", onMouseUp)
|
||||
p5.textFont(fonts.get('Ubuntu')!)
|
||||
|
||||
game.addItem(new Pickable({x: 150, y: 150}, new Item(images.get('healthPack')!, "HEAL")))
|
||||
game.addItem(new Pickable({x: 150, y: 100}, new Item(images.get('powerUp')!, "DAMAGE")))
|
||||
game.addItem(new Pickable({x: 150, y: 100}, new Item(images.get('shield')!, "DEFENCE")))
|
||||
}
|
||||
|
||||
p5.preload = () => {
|
||||
grassImage = p5.loadImage('grass.png');
|
||||
let resources = prealoadResources(p5)
|
||||
|
||||
images = resources.images
|
||||
fonts = resources.fonts
|
||||
|
||||
setupSocketEvents(socket, game)
|
||||
}
|
||||
|
||||
p5.draw = () => {
|
||||
p5.translate(-Player.position.x, Player.position.y)
|
||||
p5.background('#000000')
|
||||
// p5.translate(p5.width/2, p5.height/2)
|
||||
|
||||
|
||||
// drawing map background
|
||||
drawMap(p5)
|
||||
|
||||
for (let otherPlayer of OtherPlayers) {
|
||||
drawPlayer(p5, otherPlayer, otherPlayer.position.x + p5.width/2, -otherPlayer.position.y + p5.height/2)
|
||||
|
||||
|
||||
// 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)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
p5.translate(Player.position.x, -Player.position.y)
|
||||
drawPlayer(p5, Player, p5.width/2, p5.height/2)
|
||||
p5.text(Math.floor(Player.position.x) + ':' + Math.floor(Player.position.y), p5.width/2, 50)
|
||||
for (let otherPlayer of game.getOtherPlayers()) {
|
||||
// going through other player list
|
||||
|
||||
// draw player if in range
|
||||
if (isVisible(game.getPlayer().position, otherPlayer.position)) {
|
||||
otherPlayer.draw(p5, {
|
||||
x: otherPlayer.position.x - game.getPlayer().position.x,
|
||||
y: otherPlayer.position.y - game.getPlayer().position.y
|
||||
})
|
||||
}
|
||||
|
||||
// going through bullets of that player
|
||||
for (let bullet of otherPlayer.getBullets()) {
|
||||
|
||||
// draw bullet if in range
|
||||
if (isVisible(game.getPlayer().position, bullet.position)) {
|
||||
drawBullet(p5, bullet.shooter.color, bullet.position.x - game.getPlayer().position.x, bullet.position.y - game.getPlayer().position.y)
|
||||
}
|
||||
|
||||
// move bullet
|
||||
bullet.move()
|
||||
|
||||
// check if bullet colloides with current player
|
||||
if (distance(game.getPlayer().position, bullet.position) < BULLET_SIZE + PLAYER_SIZE) {
|
||||
bullet.timeToLive = -1
|
||||
}
|
||||
|
||||
// check if bullet collides with other player
|
||||
for (let otherPlayerCheck of game.getOtherPlayers()) {
|
||||
if (distance(otherPlayerCheck.position, bullet.position) < BULLET_SIZE + PLAYER_SIZE) {
|
||||
// check if player bullet collides with is not the player who shot the bullet
|
||||
if (otherPlayerCheck.id !== bullet.shooter.id) {
|
||||
bullet.timeToLive = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// removig bullets that has traveled far enough
|
||||
otherPlayer.removeExpiredBullets()
|
||||
}
|
||||
|
||||
let previousPosition = {
|
||||
x: Player.position.x,
|
||||
y: Player.position.y,
|
||||
}
|
||||
if (Player.keysPressed[KEY_A]) {
|
||||
Player.position.x -= PLAYER_SPEED;
|
||||
}
|
||||
if (Player.keysPressed[KEY_D]) {
|
||||
Player.position.x += PLAYER_SPEED;
|
||||
}
|
||||
|
||||
if (Player.keysPressed[KEY_W]) {
|
||||
Player.position.y += PLAYER_SPEED;
|
||||
}
|
||||
if (Player.keysPressed[KEY_S]) {
|
||||
Player.position.y -= PLAYER_SPEED;
|
||||
}
|
||||
if (Player.position.x !== previousPosition.x || Player.position.y !== previousPosition.y) {
|
||||
socket.emit('i-moved', {x: Player.position.x, y: Player.position.y})
|
||||
// drawing current player
|
||||
game.getPlayer().draw(p5, {x: 0, y: 0})
|
||||
|
||||
|
||||
// going through current player bullets
|
||||
for (let bullet of game.getPlayer().getBullets()) {
|
||||
// drawing bullet if in range
|
||||
if (isVisible(game.getPlayer().position, bullet.position)) {
|
||||
drawBullet(p5, bullet.shooter.color, bullet.position.x - game.getPlayer().position.x, bullet.position.y - game.getPlayer().position.y)
|
||||
}
|
||||
|
||||
// move bullet
|
||||
bullet.move()
|
||||
|
||||
// check if bullet collides with other player
|
||||
for (let otherPlayer of game.getOtherPlayers()) {
|
||||
if (distance(otherPlayer.position, bullet.position) < BULLET_SIZE + PLAYER_SIZE) {
|
||||
// register hit to other player
|
||||
otherPlayer.hit(bullet, game.getPlayer().socket)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// removig bullets that has traveled far enough
|
||||
game.getPlayer().removeExpiredBullets()
|
||||
|
||||
// drawing coordinates of the current player
|
||||
p5.fill('#ffffff')
|
||||
p5.stroke('#000000')
|
||||
p5.textAlign(p5.LEFT, p5.TOP)
|
||||
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()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
22
client/src/preloadResources.ts
Normal file
22
client/src/preloadResources.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import P5 from 'p5'
|
||||
|
||||
export default function prealoadResources(p5: P5): {
|
||||
images: Map<string, P5.Image>,
|
||||
fonts: Map<string, P5.Font>
|
||||
} {
|
||||
|
||||
let images = new Map<string, P5.Image>()
|
||||
let fonts = new Map<string, P5.Font>()
|
||||
|
||||
images.set('grass', p5.loadImage('images/grass.png'))
|
||||
images.set('powerUp', p5.loadImage('images/PowerUp.png'))
|
||||
images.set('shield', p5.loadImage('images/Shield.png'))
|
||||
images.set('healthPack', p5.loadImage('images/HealthPack.png'))
|
||||
|
||||
fonts.set('Ubuntu', p5.loadFont('fonts/Ubuntu/Ubuntu-Regular.ttf'))
|
||||
|
||||
return {
|
||||
images,
|
||||
fonts
|
||||
};
|
||||
}
|
||||
59
client/src/setupSocketEvents.ts
Normal file
59
client/src/setupSocketEvents.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import SocketIOClient from 'socket.io-client'
|
||||
import Bullet from './Bullet'
|
||||
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('your-info', function (playerData: PlayerDescription) {
|
||||
let player = game.getPlayer()
|
||||
player.color = playerData.color
|
||||
player.id = playerData.id
|
||||
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))
|
||||
}
|
||||
})
|
||||
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))
|
||||
}
|
||||
})
|
||||
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;
|
||||
}
|
||||
}
|
||||
})
|
||||
socket.on('player-disconnected', function (disconnectedPlayer: string) {
|
||||
game.removeOtherPlayer(disconnectedPlayer)
|
||||
})
|
||||
|
||||
socket.on('shoot', (data: BulletData) => {
|
||||
let otherPlayer = game.getOtherPlayer(data.id)
|
||||
if (otherPlayer) {
|
||||
otherPlayer.addBullet(new Bullet(otherPlayer, data.direction))
|
||||
}
|
||||
})
|
||||
|
||||
socket.on('health-update', (data: {id: string, health: number}) => {
|
||||
let otherPlayer = game.getOtherPlayer(data.id)
|
||||
if (otherPlayer) {
|
||||
otherPlayer.health = data.health
|
||||
}
|
||||
if (game.getPlayer().socket.id === data.id) {
|
||||
game.getPlayer().health = data.health
|
||||
if (data.health <= 0) {
|
||||
window.location.href = '/ded';
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
18
client/src/socketDataTypes.ts
Normal file
18
client/src/socketDataTypes.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Position } from "./types"
|
||||
|
||||
export type PlayerDescription = {
|
||||
name: string,
|
||||
color: string,
|
||||
position: {
|
||||
x: number,
|
||||
y: number,
|
||||
},
|
||||
id: string,
|
||||
health: number,
|
||||
}
|
||||
|
||||
export type BulletData = {
|
||||
id: string,
|
||||
position: Position,
|
||||
direction: Position
|
||||
}
|
||||
4
client/src/types.ts
Normal file
4
client/src/types.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export type Position = {
|
||||
x: number,
|
||||
y: number,
|
||||
}
|
||||
Reference in New Issue
Block a user