add visualRadius
This commit is contained in:
+28
-14
@@ -10,18 +10,21 @@ const backgroundColor = new THREE.Color().setHex(0x112233)
|
|||||||
scene.background = backgroundColor
|
scene.background = backgroundColor
|
||||||
renderer.setSize(window.innerWidth, window.innerHeight)
|
renderer.setSize(window.innerWidth, window.innerHeight)
|
||||||
renderer.setAnimationLoop(render)
|
renderer.setAnimationLoop(render)
|
||||||
camera.position.set(5, -12, 10)
|
camera.position.set(5, -12, 20)
|
||||||
camera.rotation.set((60 / 180) * Math.PI, 0, 0)
|
// camera.position.set(5, -12, 10)
|
||||||
|
camera.rotation.set((56 / 180) * Math.PI, 0, 0)
|
||||||
camera.layers.enable(1)
|
camera.layers.enable(1)
|
||||||
camera.layers.enable(2)
|
camera.layers.enable(2)
|
||||||
|
|
||||||
const entityMaterial = new THREE.MeshToonMaterial({ color: 0xffffff })
|
const entityMaterial = new THREE.MeshToonMaterial({ color: 0xffffff })
|
||||||
const projectileMaterial = new THREE.MeshToonMaterial({ color: 0xff00ff })
|
const projectileMaterial = new THREE.MeshToonMaterial({ color: 0xcccccc })
|
||||||
const terrainMaterial = new THREE.MeshToonMaterial({ color: 0xffd700 })
|
const terrainMaterial = new THREE.MeshToonMaterial({ color: 0xffd700 })
|
||||||
|
const opacity = 0.3
|
||||||
const teamMaterials = {
|
const teamMaterials = {
|
||||||
blue: new THREE.MeshToonMaterial({ color: 0x4444ff }),
|
blue: new THREE.MeshToonMaterial({ color: 0x4444ff, transparent: true, opacity }),
|
||||||
neutral: new THREE.MeshToonMaterial({ color: 0x22dd22 }),
|
neutral: new THREE.MeshToonMaterial({ color: 0x22dd22, transparent: true, opacity }),
|
||||||
red: new THREE.MeshToonMaterial({ color: 0xff4444 }),
|
red: new THREE.MeshToonMaterial({ color: 0xff4444, transparent: true, opacity }),
|
||||||
|
projectile: new THREE.MeshToonMaterial({ color: 0xff00ff, transparent: true, opacity }),
|
||||||
}
|
}
|
||||||
|
|
||||||
const minimapCamera = new THREE.OrthographicCamera(-10, 10, 10, -10)
|
const minimapCamera = new THREE.OrthographicCamera(-10, 10, 10, -10)
|
||||||
@@ -41,11 +44,11 @@ const material = new THREE.MeshToonMaterial({ color: 0x115011 })
|
|||||||
const ground = new THREE.Mesh(geometry, material)
|
const ground = new THREE.Mesh(geometry, material)
|
||||||
scene.add(ground)
|
scene.add(ground)
|
||||||
|
|
||||||
const ambientLight = new THREE.AmbientLight(0x404040)
|
const ambientLight = new THREE.AmbientLight(0x404040, 10)
|
||||||
scene.add(ambientLight)
|
scene.add(ambientLight)
|
||||||
|
|
||||||
const directionalLight = new THREE.DirectionalLight(0xffffff, 2.5)
|
const directionalLight = new THREE.DirectionalLight(0xffffff, 2.5)
|
||||||
directionalLight.position.set(-0.3, 0.1, 1)
|
directionalLight.position.set(-0.5, -0.05, 1)
|
||||||
directionalLight.power = 3000
|
directionalLight.power = 3000
|
||||||
scene.add(directionalLight)
|
scene.add(directionalLight)
|
||||||
|
|
||||||
@@ -74,11 +77,12 @@ function followCamera() {
|
|||||||
if (entity == null) { return }
|
if (entity == null) { return }
|
||||||
|
|
||||||
const offsetX = 0
|
const offsetX = 0
|
||||||
const offsetY = -16.5
|
const offsetY = -28
|
||||||
|
|
||||||
const distanceX = Math.abs((entity.position.x + offsetX) - camera.position.x)
|
const distanceX = Math.abs((entity.position.x + offsetX) - camera.position.x)
|
||||||
const distanceY = Math.abs((entity.position.y + offsetY) - camera.position.y)
|
const distanceY = Math.abs((entity.position.y + offsetY) - camera.position.y)
|
||||||
|
|
||||||
|
camera.position.z = 20
|
||||||
if (distanceX > 0.01) {
|
if (distanceX > 0.01) {
|
||||||
if (entity.position.x + offsetX > camera.position.x) {
|
if (entity.position.x + offsetX > camera.position.x) {
|
||||||
camera.position.x += cameraSpeed * distanceX
|
camera.position.x += cameraSpeed * distanceX
|
||||||
@@ -118,7 +122,7 @@ function cameraMovement() {
|
|||||||
else if (keysDown.ArrowDown) { camera.position.y -= cameraSpeed }
|
else if (keysDown.ArrowDown) { camera.position.y -= cameraSpeed }
|
||||||
|
|
||||||
if (keysDown.Space) {
|
if (keysDown.Space) {
|
||||||
camera.position.set(entities['1'].position.x, entities['1'].position.y - 17, 10)
|
camera.position.set(entities[playerId].position.x, entities[playerId].position.y - 28, 20)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +181,7 @@ function connectWebSocket() {
|
|||||||
entity = entities[e.id]
|
entity = entities[e.id]
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
entity = new THREE.Mesh(new THREE.CylinderGeometry(e.radius / 100, e.radius / 100, e.height / 50), entityMaterial)
|
entity = new THREE.Mesh(new THREE.CylinderGeometry(e.visualRadius / 100, e.visualRadius / 100, e.height / 50), entityMaterial)
|
||||||
entity.rotation.x = Math.PI / 2
|
entity.rotation.x = Math.PI / 2
|
||||||
entity.userData.type = 'entity'
|
entity.userData.type = 'entity'
|
||||||
entity.userData.id = e.id
|
entity.userData.id = e.id
|
||||||
@@ -199,8 +203,9 @@ function connectWebSocket() {
|
|||||||
|
|
||||||
const teamMaterial = teamMaterials[e.team]
|
const teamMaterial = teamMaterials[e.team]
|
||||||
const teamMarker = new THREE.Mesh(new THREE.CylinderGeometry((e.radius + 2) / 100, (e.radius + 2) / 100, 1), teamMaterial)
|
const teamMarker = new THREE.Mesh(new THREE.CylinderGeometry((e.radius + 2) / 100, (e.radius + 2) / 100, 1), teamMaterial)
|
||||||
teamMarker.scale.y = e.height / 400
|
const teamMarkerSize = 4000
|
||||||
teamMarker.position.y = (e.height / 800) - (e.height / 100)
|
teamMarker.scale.y = e.height / teamMarkerSize
|
||||||
|
teamMarker.position.y = (e.height / (teamMarkerSize * 2)) - (e.height / 100)
|
||||||
entity.rotation.x = Math.PI / 2
|
entity.rotation.x = Math.PI / 2
|
||||||
entity.add(teamMarker)
|
entity.add(teamMarker)
|
||||||
|
|
||||||
@@ -234,13 +239,22 @@ function connectWebSocket() {
|
|||||||
projectile = projectiles[p.id]
|
projectile = projectiles[p.id]
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
projectile = new THREE.Mesh(new THREE.SphereGeometry(p.radius / 100), projectileMaterial)
|
projectile = new THREE.Mesh(new THREE.SphereGeometry(p.visualRadius / 100), projectileMaterial)
|
||||||
projectile.userData.type = 'projectile'
|
projectile.userData.type = 'projectile'
|
||||||
projectile.userData.id = p.id
|
projectile.userData.id = p.id
|
||||||
projectile.position.set(p.position.x / 100, p.position.y / 100, p.height / 100)
|
projectile.position.set(p.position.x / 100, p.position.y / 100, p.height / 100)
|
||||||
projectile.layers.set(2)
|
projectile.layers.set(2)
|
||||||
scene.add(projectile)
|
scene.add(projectile)
|
||||||
|
|
||||||
|
const teamMaterial = teamMaterials['projectile']
|
||||||
|
const teamMarker = new THREE.Mesh(new THREE.CylinderGeometry((p.radius) / 100, (p.radius) / 100, 1), teamMaterial)
|
||||||
|
const teamMarkerSize = 4000
|
||||||
|
teamMarker.scale.y = p.height / teamMarkerSize
|
||||||
|
teamMarker.position.y = (p.height / (teamMarkerSize * 2)) - (p.height / 100)
|
||||||
|
projectile.rotation.x = Math.PI / 2
|
||||||
|
projectile.layers.set(2)
|
||||||
|
projectile.add(teamMarker)
|
||||||
|
|
||||||
projectiles[p.id] = projectile
|
projectiles[p.id] = projectile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-11
@@ -30,9 +30,10 @@ export default class Ability {
|
|||||||
name: 'Straight Shot',
|
name: 'Straight Shot',
|
||||||
castTime: 0.25,
|
castTime: 0.25,
|
||||||
cooldown: 1,
|
cooldown: 1,
|
||||||
damage: 10,
|
damage: 83,
|
||||||
radius: 60,
|
radius: 60,
|
||||||
range: 1200,
|
range: 1200,
|
||||||
|
visualRadius: 20,
|
||||||
speed: 2000,
|
speed: 2000,
|
||||||
effect: function straightShotEffect(caster, cursor) {
|
effect: function straightShotEffect(caster, cursor) {
|
||||||
const ability = this
|
const ability = this
|
||||||
@@ -47,6 +48,7 @@ export default class Ability {
|
|||||||
position: caster.position.clone(),
|
position: caster.position.clone(),
|
||||||
radius: ability.radius,
|
radius: ability.radius,
|
||||||
speed: ability.speed,
|
speed: ability.speed,
|
||||||
|
visualRadius: ability.visualRadius,
|
||||||
})
|
})
|
||||||
|
|
||||||
projectile.destination = caster.position.clone().add(cursor.clone().sub(caster.position).normalize().multiplyScalar(ability.range + caster.radius))
|
projectile.destination = caster.position.clone().add(cursor.clone().sub(caster.position).normalize().multiplyScalar(ability.range + caster.radius))
|
||||||
@@ -58,13 +60,13 @@ export default class Ability {
|
|||||||
static rangedAttack = new Ability({
|
static rangedAttack = new Ability({
|
||||||
id: 'ranged_attack',
|
id: 'ranged_attack',
|
||||||
name: 'Ranged Attack',
|
name: 'Ranged Attack',
|
||||||
castTime: 0.25,
|
castTime: (1.6 * 0.18839),
|
||||||
cooldown: 1.25,
|
cooldown: 1.6,
|
||||||
damage: 25,
|
damage: 60,
|
||||||
moveCancelable: true,
|
moveCancelable: true,
|
||||||
radius: 5,
|
radius: 5,
|
||||||
range: 500,
|
range: 500,
|
||||||
speed: 600,
|
speed: 2000,
|
||||||
effect: function rangedAttackEffect(caster, cursor) {
|
effect: function rangedAttackEffect(caster, cursor) {
|
||||||
const ability = this
|
const ability = this
|
||||||
const target = caster.closestTargetTo(cursor, ability.range)
|
const target = caster.closestTargetTo(cursor, ability.range)
|
||||||
@@ -110,11 +112,11 @@ export default class Ability {
|
|||||||
static shieldThrow = new Ability({
|
static shieldThrow = new Ability({
|
||||||
id: 'shield_throw',
|
id: 'shield_throw',
|
||||||
name: 'Shield Throw',
|
name: 'Shield Throw',
|
||||||
castTime: 0.15,
|
castTime: 0.25,
|
||||||
cooldown: 5,
|
cooldown: 5,
|
||||||
radius: 20,
|
radius: 110,
|
||||||
range: 1000,
|
range: 1025,
|
||||||
speed: 2000,
|
speed: 2400,
|
||||||
effect: function shieldThrowEffect(caster, cursor) {
|
effect: function shieldThrowEffect(caster, cursor) {
|
||||||
const ability = this
|
const ability = this
|
||||||
const shieldThrowReturn = function shieldThrowReturn(projectile, homingTarget) {
|
const shieldThrowReturn = function shieldThrowReturn(projectile, homingTarget) {
|
||||||
@@ -146,9 +148,9 @@ export default class Ability {
|
|||||||
static blink = new Ability({
|
static blink = new Ability({
|
||||||
id: 'blink',
|
id: 'blink',
|
||||||
name: 'Blink',
|
name: 'Blink',
|
||||||
castTime: 1,
|
castTime: 0.25,
|
||||||
cooldown: 2,
|
cooldown: 2,
|
||||||
range: 400,
|
range: 475,
|
||||||
effect: function blinkEffect(caster, cursor) {
|
effect: function blinkEffect(caster, cursor) {
|
||||||
const ability = this
|
const ability = this
|
||||||
const direction = cursor.clone().sub(caster.position)
|
const direction = cursor.clone().sub(caster.position)
|
||||||
|
|||||||
+6
-1
@@ -13,11 +13,12 @@ export default class Entity {
|
|||||||
health = null
|
health = null
|
||||||
height = 40
|
height = 40
|
||||||
maxHealth = 1
|
maxHealth = 1
|
||||||
memory = {} // TODO: WARNING: currently only used for minions (code smell?)
|
memory = {}
|
||||||
position = null
|
position = null
|
||||||
radius = 0
|
radius = 0
|
||||||
speed = 400
|
speed = 400
|
||||||
team = Team.neutral
|
team = Team.neutral
|
||||||
|
visualRadius = null
|
||||||
|
|
||||||
#attacking = false
|
#attacking = false
|
||||||
#dest = null
|
#dest = null
|
||||||
@@ -39,6 +40,9 @@ export default class Entity {
|
|||||||
if (this.health == null) {
|
if (this.health == null) {
|
||||||
this.health = this.maxHealth
|
this.health = this.maxHealth
|
||||||
}
|
}
|
||||||
|
if (this.visualRadius == null) {
|
||||||
|
this.visualRadius = this.radius
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get destination() { return this.#dest }
|
get destination() { return this.#dest }
|
||||||
@@ -90,6 +94,7 @@ export default class Entity {
|
|||||||
|
|
||||||
castAction(slot, cursor, halt = false) {
|
castAction(slot, cursor, halt = false) {
|
||||||
const ability = this.abilities[slot]
|
const ability = this.abilities[slot]
|
||||||
|
if (ability == null) { return }
|
||||||
|
|
||||||
if (this.casting != null) {
|
if (this.casting != null) {
|
||||||
const abilityBeingCasted = this.casting.ability
|
const abilityBeingCasted = this.casting.ability
|
||||||
|
|||||||
+18
-30
@@ -37,24 +37,29 @@ app.ws('/ws', async (req, res) => {
|
|||||||
console.log(message)
|
console.log(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let delay = 0
|
||||||
|
// if(message.id == '1') {
|
||||||
|
// delay = 45
|
||||||
|
// }
|
||||||
|
|
||||||
if (message.action == 'attack') {
|
if (message.action == 'attack') {
|
||||||
entity.attackAction(new Vector2(message.x, message.y))
|
setTimeout(() => entity.attackAction(new Vector2(message.x, message.y)), delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.action == 'cast') {
|
if (message.action == 'cast') {
|
||||||
entity.castAction(message.slot, new Vector2(message.x, message.y))
|
setTimeout(() => entity.castAction(message.slot, new Vector2(message.x, message.y)), delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.action == 'halt') {
|
if (message.action == 'halt') {
|
||||||
entity.haltAction()
|
setTimeout(() => entity.haltAction(), delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.action == 'stop') {
|
if (message.action == 'stop') {
|
||||||
entity.stopAction()
|
setTimeout(() => entity.stopAction(), delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.action == 'move') {
|
if (message.action == 'move') {
|
||||||
entity.moveAction(new Vector2(message.x, message.y))
|
setTimeout(() => entity.moveAction(new Vector2(message.x, message.y)), delay)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -68,13 +73,13 @@ function laneScenario() {
|
|||||||
game.spawnEntity(player1)
|
game.spawnEntity(player1)
|
||||||
player1.attackAction(new Vector2(500, 150))
|
player1.attackAction(new Vector2(500, 150))
|
||||||
|
|
||||||
// const player2 = new Entity(Template.player({
|
const player2 = new Entity(Template.player({
|
||||||
// id: '2',
|
id: '2',
|
||||||
// spawnPosition: new Vector2(1600, 1800),
|
spawnPosition: new Vector2(1600, 1800),
|
||||||
// team: Team.red,
|
team: Team.red,
|
||||||
// }))
|
}))
|
||||||
// game.spawnEntity(player2)
|
game.spawnEntity(player2)
|
||||||
// player2.attackAction(new Vector2(1600, 1800))
|
player2.attackAction(new Vector2(1600, 1800))
|
||||||
|
|
||||||
const midWallStart = new Vector2(600, 600)
|
const midWallStart = new Vector2(600, 600)
|
||||||
const midWallEnd = new Vector2(1400, 1400)
|
const midWallEnd = new Vector2(1400, 1400)
|
||||||
@@ -116,24 +121,7 @@ function laneScenario() {
|
|||||||
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: redRoute })))
|
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: redRoute })))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// game.logic = gameLogic
|
game.logic = gameLogic
|
||||||
|
|
||||||
// const uBottomPoints = [
|
|
||||||
// midSouthWallPoints.at(0).clone().sub(midWallThickness),
|
|
||||||
// midSouthWallPoints.at(1).clone().sub(midWallThickness),
|
|
||||||
// midNorthWallPoints.at(-2).clone().add(midWallThickness),
|
|
||||||
// midNorthWallPoints.at(-1).clone().add(midWallThickness),
|
|
||||||
// ]
|
|
||||||
// const uBottom = new Terrain(uBottomPoints)
|
|
||||||
// uBottom.id = 'uBottom'
|
|
||||||
// game.addTerrain(uBottom)
|
|
||||||
|
|
||||||
const minion = new Entity({...Template.minion(Team.red, { ranged: true }), logic: null})
|
|
||||||
minion.teleport(new Vector2(850, 250))
|
|
||||||
game.spawnEntity(minion)
|
|
||||||
|
|
||||||
player1.stopAction()
|
|
||||||
player1.castAction(1, new Vector2(850, 250))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
|
|||||||
+7
-1
@@ -6,12 +6,13 @@ export default class Projectile {
|
|||||||
id = crypto.randomUUID()
|
id = crypto.randomUUID()
|
||||||
after = null
|
after = null
|
||||||
height = 50
|
height = 50
|
||||||
memory = {} // TODO: WARNING: currently only used for hit detection (code smell?)
|
memory = {}
|
||||||
onCollide = null
|
onCollide = null
|
||||||
owner = null
|
owner = null
|
||||||
position = new Vector2()
|
position = new Vector2()
|
||||||
radius = 5
|
radius = 5
|
||||||
speed = 1000
|
speed = 1000
|
||||||
|
visualRadius = null
|
||||||
|
|
||||||
#dest = null
|
#dest = null
|
||||||
#homingTarget = null
|
#homingTarget = null
|
||||||
@@ -28,6 +29,9 @@ export default class Projectile {
|
|||||||
|
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
Object.entries(options).forEach(([key, value]) => this[key] = value)
|
Object.entries(options).forEach(([key, value]) => this[key] = value)
|
||||||
|
if (this.visualRadius == null) {
|
||||||
|
this.visualRadius = this.radius
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkCollisions(collider) {
|
checkCollisions(collider) {
|
||||||
@@ -72,6 +76,8 @@ export default class Projectile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#move() {
|
#move() {
|
||||||
|
if (this.destination == null) { return }
|
||||||
|
|
||||||
const speed = (this.speed / (this.game?.tickBudget ?? 1000))
|
const speed = (this.speed / (this.game?.tickBudget ?? 1000))
|
||||||
const prevPos = this.position.clone()
|
const prevPos = this.position.clone()
|
||||||
if (this.position.distanceTo(this.destination) < speed) {
|
if (this.position.distanceTo(this.destination) < speed) {
|
||||||
|
|||||||
+3
-1
@@ -10,9 +10,10 @@ export default class Template {
|
|||||||
logic: this.#minionLogic(options.route),
|
logic: this.#minionLogic(options.route),
|
||||||
maxHealth: options.ranged ? 300 : 450,
|
maxHealth: options.ranged ? 300 : 450,
|
||||||
position: team == Team.blue ? new Vector2(200, 200) : new Vector2(1800, 1800),
|
position: team == Team.blue ? new Vector2(200, 200) : new Vector2(1800, 1800),
|
||||||
radius: options.ranged ? 46 : 48,
|
radius: 48,
|
||||||
speed: 325,
|
speed: 325,
|
||||||
team,
|
team,
|
||||||
|
visualRadius: options.ranged ? 36 : 38,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ export default class Template {
|
|||||||
maxHealth: 600,
|
maxHealth: 600,
|
||||||
spawnPosition: new Vector2(500, 150),
|
spawnPosition: new Vector2(500, 150),
|
||||||
radius: 65,
|
radius: 65,
|
||||||
|
visualRadius: 40,
|
||||||
...overrides,
|
...overrides,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user