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