add skillshots
This commit is contained in:
+84
-9
@@ -13,6 +13,7 @@ camera.rotation.set((60 / 180) * Math.PI, 0, 0)
|
||||
camera.layers.enable(1)
|
||||
|
||||
const entityMaterial = new THREE.MeshToonMaterial({ color: 0xffffff })
|
||||
const projectileMaterial = new THREE.MeshToonMaterial({ color: 0xff00ff })
|
||||
const terrainMaterial = new THREE.MeshToonMaterial({ color: 0xffd700 })
|
||||
|
||||
const minimapCamera = new THREE.OrthographicCamera(-10, 10, 10, -10)
|
||||
@@ -23,6 +24,7 @@ minimapRenderer.setAnimationLoop(minimapRender)
|
||||
minimapCamera.position.set(10, 10, 10)
|
||||
|
||||
const entities = {}
|
||||
const projectiles = {}
|
||||
const positionTweens = {}
|
||||
const terrains = {}
|
||||
|
||||
@@ -44,12 +46,13 @@ global.renderer = renderer
|
||||
global.camera = camera
|
||||
global.scene = scene
|
||||
|
||||
const tweenDuration = 60
|
||||
const tweenDuration = 33
|
||||
const keysDown = {}
|
||||
const mouse = {}
|
||||
|
||||
function render() {
|
||||
cameraMovement()
|
||||
Object.values(positionTweens).forEach((tween) => tween.update())
|
||||
Object.values(positionTweens).forEach((tween) => tween.update()) // TODO: clean up tweens
|
||||
renderer.render(scene, camera)
|
||||
}
|
||||
|
||||
@@ -111,6 +114,20 @@ function cameraMovement() {
|
||||
}
|
||||
}
|
||||
|
||||
function raycastToGround() {
|
||||
const canvas = renderer.domElement
|
||||
raycaster.setFromCamera(new THREE.Vector2((mouse.x / canvas.clientWidth) * 2 - 1, (mouse.y / canvas.clientHeight) * -2 + 1), camera)
|
||||
const intersect = raycaster.intersectObject(ground).at(0)?.point
|
||||
if (intersect != null) {
|
||||
return {
|
||||
x: Math.round(intersect.x * 100),
|
||||
y: Math.round(intersect.y * 100),
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
var websocket = null
|
||||
global.websocket = null
|
||||
var timerId = null
|
||||
@@ -152,6 +169,7 @@ function connectWebSocket() {
|
||||
entity.rotation.x = Math.PI / 2
|
||||
entity.userData.type = 'entity'
|
||||
entity.userData.id = e.id
|
||||
entity.position.set(e.position.x / 100, e.position.y / 100, e.radius / 100)
|
||||
scene.add(entity)
|
||||
|
||||
const hpMargin = 0.4
|
||||
@@ -179,6 +197,38 @@ function connectWebSocket() {
|
||||
hp.position.x = -(1 - percentageHp) / 2
|
||||
}
|
||||
|
||||
for (const p of Object.values(projectiles)) {
|
||||
p.userData.flaggedForRemoval = true
|
||||
}
|
||||
|
||||
for (const p of state.projectiles ?? []) {
|
||||
let projectile
|
||||
if (p.id in projectiles) {
|
||||
projectile = projectiles[p.id]
|
||||
}
|
||||
else {
|
||||
projectile = new THREE.Mesh(new THREE.SphereGeometry(p.radius / 100), projectileMaterial)
|
||||
projectile.userData.type = 'projectile'
|
||||
projectile.userData.id = p.id
|
||||
projectile.position.set(p.position.x / 100, p.position.y / 100, p.visualHeight / 100)
|
||||
scene.add(projectile)
|
||||
|
||||
projectiles[p.id] = projectile
|
||||
}
|
||||
|
||||
projectile.userData.flaggedForRemoval = false
|
||||
// projectile.position.set(p.position.x / 100, p.position.y / 100, p.visualHeight / 100)
|
||||
positionTweens[projectile.id] = new Tween(projectile.position).to({ x: p.position.x / 100, y: p.position.y / 100, z: p.visualHeight / 100 }, tweenDuration).start()
|
||||
}
|
||||
|
||||
for (const p of Object.values(projectiles)) {
|
||||
if (p.userData.flaggedForRemoval) {
|
||||
scene.remove(p)
|
||||
delete projectiles[p.userData.id]
|
||||
delete positionTweens[p.userData.id]
|
||||
}
|
||||
}
|
||||
|
||||
for (const t of state.terrains ?? []) {
|
||||
let terrain
|
||||
if (t.id in terrains) {
|
||||
@@ -216,22 +266,43 @@ window.addEventListener('load', () => {
|
||||
canvas.classList.add('canvas')
|
||||
|
||||
canvas.addEventListener('mousedown', (event) => {
|
||||
raycaster.setFromCamera(new THREE.Vector2((event.clientX / canvas.clientWidth) * 2 - 1, (event.clientY / canvas.clientHeight) * -2 + 1), camera)
|
||||
const intersect = raycaster.intersectObject(ground).at(0)?.point
|
||||
const intersect = raycastToGround()
|
||||
if (intersect != null) {
|
||||
const { x, y } = intersect
|
||||
if (event.button == 0) {
|
||||
const x = Math.round(intersect.x * 100)
|
||||
const y = Math.round(intersect.y * 100)
|
||||
websocket.send(JSON.stringify({ action: 'teleport', id: playerId, x, y }))
|
||||
websocket.send(JSON.stringify({ action: 'cast', slot: 0, id: playerId, x, y }))
|
||||
}
|
||||
|
||||
if (event.button == 2) {
|
||||
const x = Math.round(intersect.x * 100)
|
||||
const y = Math.round(intersect.y * 100)
|
||||
websocket.send(JSON.stringify({ action: 'move', id: playerId, x, y }))
|
||||
}
|
||||
}
|
||||
})
|
||||
window.addEventListener('keydown', (event) => {
|
||||
const intersect = raycastToGround()
|
||||
if (intersect != null) {
|
||||
const { x, y } = intersect
|
||||
if (event.code == 'KeyQ') {
|
||||
websocket.send(JSON.stringify({ action: 'cast', slot: 1, id: playerId, x, y }))
|
||||
}
|
||||
if (event.code == 'KeyW') {
|
||||
websocket.send(JSON.stringify({ action: 'cast', slot: 2, id: playerId, x, y }))
|
||||
}
|
||||
if (event.code == 'KeyE') {
|
||||
websocket.send(JSON.stringify({ action: 'cast', slot: 3, id: playerId, x, y }))
|
||||
}
|
||||
if (event.code == 'KeyR') {
|
||||
websocket.send(JSON.stringify({ action: 'cast', slot: 4, id: playerId, x, y }))
|
||||
}
|
||||
|
||||
if (event.code == 'KeyD') {
|
||||
websocket.send(JSON.stringify({ action: 'teleport', id: playerId, x, y }))
|
||||
}
|
||||
if (event.code == 'KeyF') {
|
||||
websocket.send(JSON.stringify({ action: 'teleport', id: playerId, x, y }))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
document.addEventListener('wheel', (event) => {
|
||||
if (event.deltaY < 0) {
|
||||
@@ -264,6 +335,10 @@ window.addEventListener('load', () => {
|
||||
cameraLocked = !cameraLocked
|
||||
}
|
||||
})
|
||||
window.addEventListener('mousemove', (event) => {
|
||||
mouse.x = event.clientX
|
||||
mouse.y = event.clientY
|
||||
})
|
||||
|
||||
document.body.appendChild(canvas)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user