THRUSTERSSSS! 🔥
This commit is contained in:
parent
b2fb042a90
commit
4ac5752f09
4 changed files with 116 additions and 17 deletions
|
|
@ -1,16 +1,19 @@
|
||||||
import Phaser from 'phaser'
|
import Phaser from 'phaser'
|
||||||
import Bullets from './Bullets'
|
import Bullets from './Bullets'
|
||||||
|
import Thruster from './Thruster'
|
||||||
|
|
||||||
export default class Ship extends Phaser.Physics.Arcade.Sprite {
|
export default class Ship extends Phaser.Physics.Arcade.Sprite {
|
||||||
readonly acceleration = 5
|
readonly acceleration = 5
|
||||||
readonly dragForce = 0.6
|
readonly dragForce = 0.6
|
||||||
|
readonly maxSpeed = 300
|
||||||
|
|
||||||
readonly colliderRadiusRatio = 0.43
|
readonly colliderRadiusRatio = 0.43
|
||||||
readonly wrapMargin = 10
|
readonly wrapMargin = 10
|
||||||
|
|
||||||
readonly fireRate = 5 //shoots/s
|
readonly fireRate = 5 //shoots/s
|
||||||
|
|
||||||
bullets?: Bullets
|
bullets: Bullets
|
||||||
|
thruster: Thruster
|
||||||
|
|
||||||
constructor(scene: Phaser.Scene) {
|
constructor(scene: Phaser.Scene) {
|
||||||
super(
|
super(
|
||||||
|
|
@ -32,6 +35,8 @@ export default class Ship extends Phaser.Physics.Arcade.Sprite {
|
||||||
this.body.setCircle(this.width * this.colliderRadiusRatio)
|
this.body.setCircle(this.width * this.colliderRadiusRatio)
|
||||||
|
|
||||||
this.bullets = new Bullets(scene, this.fireRate)
|
this.bullets = new Bullets(scene, this.fireRate)
|
||||||
|
this.thruster = new Thruster(scene, this)
|
||||||
|
this.setMaxVelocity(this.maxSpeed)
|
||||||
}
|
}
|
||||||
|
|
||||||
preUpdate(time: number, delta: number) {
|
preUpdate(time: number, delta: number) {
|
||||||
|
|
@ -59,5 +64,6 @@ export default class Ship extends Phaser.Physics.Arcade.Sprite {
|
||||||
|
|
||||||
this.body.velocity.add(vec)
|
this.body.velocity.add(vec)
|
||||||
this.scene.physics.world.wrap(this, this.wrapMargin)
|
this.scene.physics.world.wrap(this, this.wrapMargin)
|
||||||
|
this.thruster.update(time, delta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
59
src/classes/Thruster.ts
Normal file
59
src/classes/Thruster.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
import Phaser from 'phaser'
|
||||||
|
import Utils from './Utils'
|
||||||
|
|
||||||
|
export default class Thruster {
|
||||||
|
readonly angleSpan = 40
|
||||||
|
readonly frequency = 100
|
||||||
|
readonly speed = 100
|
||||||
|
readonly framesIndex = 30
|
||||||
|
|
||||||
|
emitter: Phaser.GameObjects.Particles.ParticleEmitter
|
||||||
|
parent: Phaser.Physics.Arcade.Sprite
|
||||||
|
|
||||||
|
constructor(scene: Phaser.Scene, parent: Phaser.Physics.Arcade.Sprite) {
|
||||||
|
this.emitter = scene.add.particles('particles')
|
||||||
|
.createEmitter({
|
||||||
|
frame: [25, 26, 27, 28, 29, 30, 31, 32, 34, 35],
|
||||||
|
speed: this.speed,
|
||||||
|
frequency: this.frequency,
|
||||||
|
scale: { start: 0.2, end: 0 },
|
||||||
|
blendMode: 'ADD',
|
||||||
|
follow: parent
|
||||||
|
})
|
||||||
|
|
||||||
|
this.parent = parent
|
||||||
|
}
|
||||||
|
|
||||||
|
update(time: number, delta: number) {
|
||||||
|
const thrustDirection = Phaser.Math.RadToDeg(
|
||||||
|
this.parent.body.velocity.clone().negate().angle()
|
||||||
|
)
|
||||||
|
|
||||||
|
this.emitter.angle.start = thrustDirection - this.angleSpan / 2
|
||||||
|
this.emitter.angle.end = thrustDirection + this.angleSpan / 2
|
||||||
|
|
||||||
|
const thrustPower = this.getThrustPower()
|
||||||
|
|
||||||
|
this.emitter.setFrequency(thrustPower.frequency)
|
||||||
|
this.emitter.setAlpha(thrustPower.opacity)
|
||||||
|
}
|
||||||
|
|
||||||
|
getThrustPower() {
|
||||||
|
const velocityRange = [0, 320] as const
|
||||||
|
const frequencyRange = [300, 0] as const
|
||||||
|
const opacityRange = [0, 1] as const
|
||||||
|
|
||||||
|
return {
|
||||||
|
frequency: Utils.clampMap(
|
||||||
|
this.parent.body.velocity.length(),
|
||||||
|
...velocityRange,
|
||||||
|
...frequencyRange
|
||||||
|
),
|
||||||
|
opacity: Utils.clampMap(
|
||||||
|
this.parent.body.velocity.length(),
|
||||||
|
...velocityRange,
|
||||||
|
...opacityRange
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/classes/Utils.ts
Normal file
49
src/classes/Utils.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
export default {
|
||||||
|
map(value: number,
|
||||||
|
sourceMin: number,
|
||||||
|
sourceMax: number,
|
||||||
|
targetMin: number,
|
||||||
|
targetMax: number) {
|
||||||
|
|
||||||
|
const sourceRange = sourceMax - sourceMin
|
||||||
|
const targetRange = targetMax - targetMin
|
||||||
|
return (value - sourceMin) / sourceRange * targetRange + targetMin
|
||||||
|
},
|
||||||
|
|
||||||
|
clamp(value: number,
|
||||||
|
min: number,
|
||||||
|
max: number) {
|
||||||
|
let leftLimit = Math.min
|
||||||
|
let rightLimit = Math.max
|
||||||
|
|
||||||
|
if (max < min) {
|
||||||
|
leftLimit = Math.max
|
||||||
|
rightLimit = Math.max
|
||||||
|
}
|
||||||
|
|
||||||
|
return leftLimit(
|
||||||
|
rightLimit(min, value),
|
||||||
|
max)
|
||||||
|
},
|
||||||
|
|
||||||
|
clampMap(value: number,
|
||||||
|
sourceMin: number,
|
||||||
|
sourceMax: number,
|
||||||
|
targetMin: number,
|
||||||
|
targetMax: number) {
|
||||||
|
|
||||||
|
const v = this.map(value,
|
||||||
|
sourceMin,
|
||||||
|
sourceMax,
|
||||||
|
targetMin,
|
||||||
|
targetMax
|
||||||
|
)
|
||||||
|
|
||||||
|
const min = Math.min(targetMin, targetMax)
|
||||||
|
const max = Math.max(targetMin, targetMax)
|
||||||
|
|
||||||
|
return this.clamp(
|
||||||
|
v, min, max
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,21 +19,6 @@ export default class DefaultScene extends Phaser.Scene {
|
||||||
create() {
|
create() {
|
||||||
this.add.image(400, 300, 'sky')
|
this.add.image(400, 300, 'sky')
|
||||||
|
|
||||||
const particles = this.add.particles('particles', 21)
|
|
||||||
|
|
||||||
const emitter = particles.createEmitter({
|
|
||||||
speed: 300,
|
|
||||||
scale: { start: 1, end: 0 },
|
|
||||||
blendMode: 'ADD',
|
|
||||||
})
|
|
||||||
|
|
||||||
const logo = this.physics.add.image(400, 100, 'logo')
|
|
||||||
|
|
||||||
logo.setVelocity(100, 200)
|
|
||||||
logo.setBounce(1, 1)
|
|
||||||
logo.setCollideWorldBounds(true)
|
|
||||||
|
|
||||||
emitter.startFollow(logo)
|
|
||||||
|
|
||||||
this.player = new Ship(this)
|
this.player = new Ship(this)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue