2021-05-11 05:37:08 +00:00
|
|
|
import { AnimatableTileFactory } from './animatable_tile_factory.js';
|
|
|
|
|
import { LayeredTileFactory } from './layered_tile_factory.js';
|
|
|
|
|
import { Tile } from './tile.js';
|
|
|
|
|
import { TileFactory } from './tile_factory.js';
|
|
|
|
|
|
2021-05-12 03:54:32 +00:00
|
|
|
function get_distance(x: number, y: number) {
|
|
|
|
|
return Math.sqrt(x ** 2 + y ** 2);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-11 05:37:08 +00:00
|
|
|
export class ProjectileTileFactory extends TileFactory {
|
|
|
|
|
source_tile_factory: AnimatableTileFactory;
|
2021-05-11 06:04:41 +00:00
|
|
|
target_relative_x: number;
|
|
|
|
|
target_relative_y: number;
|
|
|
|
|
spin: number;
|
|
|
|
|
speed: number;
|
2021-05-11 15:55:29 +00:00
|
|
|
loft: number;
|
2021-05-12 05:03:57 +00:00
|
|
|
duration: number;
|
2021-05-11 06:04:41 +00:00
|
|
|
|
2021-05-11 05:37:08 +00:00
|
|
|
tile_factory: TileFactory;
|
|
|
|
|
|
2021-05-11 15:55:29 +00:00
|
|
|
constructor(tile_factory: AnimatableTileFactory, target_relative_x: number, target_relative_y: number, spin: number, speed: number, loft: number) {
|
2021-05-11 05:37:08 +00:00
|
|
|
super(tile_factory.layer_name, tile_factory.width, tile_factory.height);
|
|
|
|
|
|
|
|
|
|
this.source_tile_factory = tile_factory;
|
2021-05-11 06:04:41 +00:00
|
|
|
this.target_relative_x = target_relative_x;
|
|
|
|
|
this.target_relative_y = target_relative_y;
|
|
|
|
|
this.spin = spin;
|
|
|
|
|
this.speed = speed;
|
2021-05-11 15:55:29 +00:00
|
|
|
this.loft = loft;
|
2021-05-11 05:37:08 +00:00
|
|
|
|
|
|
|
|
const copy = tile_factory.copy();
|
2021-05-12 03:54:32 +00:00
|
|
|
|
|
|
|
|
const top = Math.min(0, target_relative_y) - loft;
|
|
|
|
|
let h1_distance = get_distance(target_relative_x / 2, top);
|
|
|
|
|
let h2_distance = get_distance(target_relative_x / 2, target_relative_y - top);
|
|
|
|
|
let total_distance = h1_distance + h2_distance;
|
|
|
|
|
let vertex_offset = h1_distance / total_distance;
|
|
|
|
|
for (let i = 0; i < 5; i++) {
|
|
|
|
|
h1_distance = get_distance(target_relative_x * vertex_offset, top);
|
|
|
|
|
h2_distance = get_distance(target_relative_x * (1 - vertex_offset), target_relative_y - top);
|
|
|
|
|
total_distance = h1_distance + h2_distance;
|
|
|
|
|
vertex_offset = h1_distance / total_distance;
|
|
|
|
|
}
|
2021-05-11 05:37:08 +00:00
|
|
|
|
2021-05-12 05:03:57 +00:00
|
|
|
this.duration = total_distance / speed * 100;
|
|
|
|
|
|
2021-05-11 05:37:08 +00:00
|
|
|
copy.add_animation(
|
|
|
|
|
'launch-x',
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
'offset': 0.0,
|
|
|
|
|
'easing': 'linear',
|
|
|
|
|
'left': '0',
|
|
|
|
|
'transform': 'rotate(0)',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'offset': 1.0,
|
2021-05-11 06:04:41 +00:00
|
|
|
'left': `${target_relative_x / tile_factory.width * 100}%`,
|
2021-05-12 03:54:32 +00:00
|
|
|
'transform': `rotate(${Math.sign(target_relative_x) * total_distance * spin * 10}deg)`,
|
2021-05-11 05:37:08 +00:00
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
{
|
2021-05-12 05:03:57 +00:00
|
|
|
'duration': this.duration,
|
2021-05-11 05:37:08 +00:00
|
|
|
'iterations': 1,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
copy.add_animation(
|
|
|
|
|
'launch-y',
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
'offset': 0.0,
|
|
|
|
|
'easing': 'cubic-bezier(0.33, 0.66, 0.66, 1.00)',
|
|
|
|
|
'top': '0',
|
|
|
|
|
},
|
|
|
|
|
{
|
2021-05-12 03:54:32 +00:00
|
|
|
'offset': vertex_offset,
|
2021-05-11 05:37:08 +00:00
|
|
|
'easing': 'cubic-bezier(0.33, 0.00, 0.66, 0.33)',
|
2021-05-12 03:54:32 +00:00
|
|
|
'top': `${top / tile_factory.height * 100}%`,
|
2021-05-11 05:37:08 +00:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'offset': 1.0,
|
2021-05-11 06:04:41 +00:00
|
|
|
'top': `${target_relative_y / tile_factory.height * 100}%`,
|
2021-05-11 05:37:08 +00:00
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
{
|
2021-05-12 05:03:57 +00:00
|
|
|
'duration': this.duration,
|
2021-05-11 05:37:08 +00:00
|
|
|
'iterations': 1,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
this.tile_factory = new LayeredTileFactory([copy]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
build(tileset: string): Tile {
|
|
|
|
|
const tile = this.tile_factory.build(tileset);
|
|
|
|
|
tile.play('launch-x')!.finished.then(() => tile.remove());
|
|
|
|
|
tile.play('launch-y');
|
|
|
|
|
return tile;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
copy(): ProjectileTileFactory {
|
2021-05-11 06:04:41 +00:00
|
|
|
return new ProjectileTileFactory(
|
|
|
|
|
this.source_tile_factory,
|
|
|
|
|
this.target_relative_x,
|
|
|
|
|
this.target_relative_y,
|
|
|
|
|
this.spin,
|
|
|
|
|
this.speed,
|
2021-05-11 15:55:29 +00:00
|
|
|
this.loft,
|
2021-05-11 06:04:41 +00:00
|
|
|
);
|
2021-05-11 05:37:08 +00:00
|
|
|
}
|
|
|
|
|
}
|