Add directional walking unit sprites
This commit is contained in:
@@ -44,10 +44,14 @@ type BattleLayout = {
|
||||
};
|
||||
|
||||
type UnitView = {
|
||||
sprite: Phaser.GameObjects.Image;
|
||||
sprite: Phaser.GameObjects.Sprite;
|
||||
label: Phaser.GameObjects.Text;
|
||||
textureBase: string;
|
||||
direction: UnitDirection;
|
||||
};
|
||||
|
||||
type UnitDirection = 'south' | 'east' | 'north' | 'west';
|
||||
|
||||
type BattlePhase = 'idle' | 'moving' | 'command';
|
||||
type BattleCommand = 'attack' | 'strategy' | 'item' | 'wait';
|
||||
type RosterTab = 'ally' | 'enemy';
|
||||
@@ -245,7 +249,8 @@ export class BattleScene extends Phaser.Scene {
|
||||
private drawUnits() {
|
||||
firstBattleUnits.forEach((unit) => {
|
||||
const sizeRatio = unit.faction === 'ally' ? 1.08 : 1.02;
|
||||
const sprite = this.add.image(this.tileCenterX(unit.x), this.tileCenterY(unit.y), unitTexture[unit.id] ?? 'unit-rebel');
|
||||
const textureBase = unitTexture[unit.id] ?? 'unit-rebel';
|
||||
const sprite = this.add.sprite(this.tileCenterX(unit.x), this.tileCenterY(unit.y), `${textureBase}-south-0`);
|
||||
sprite.setName(`unit-${unit.id}`);
|
||||
sprite.setDisplaySize(this.layout.tileSize * sizeRatio, this.layout.tileSize * sizeRatio);
|
||||
sprite.setDepth(6);
|
||||
@@ -261,7 +266,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
});
|
||||
label.setOrigin(0.5, 0);
|
||||
label.setDepth(7);
|
||||
this.unitViews.set(unit.id, { sprite, label });
|
||||
this.unitViews.set(unit.id, { sprite, label, textureBase, direction: 'south' });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -769,6 +774,8 @@ export class BattleScene extends Phaser.Scene {
|
||||
view.sprite.postFX.clear();
|
||||
view.sprite.clearTint();
|
||||
view.sprite.setAlpha(1);
|
||||
view.sprite.stop();
|
||||
this.setUnitDirectionFrame(view, view.direction);
|
||||
view.label.setAlpha(1);
|
||||
view.label.setColor(unit?.faction === 'ally' ? '#e7edf7' : '#ffebe7');
|
||||
view.label.setBackgroundColor('');
|
||||
@@ -939,29 +946,59 @@ export class BattleScene extends Phaser.Scene {
|
||||
|
||||
const targetX = this.tileCenterX(x);
|
||||
const targetY = this.tileCenterY(y);
|
||||
const direction = this.directionFromDelta(targetX - view.sprite.x, targetY - view.sprite.y);
|
||||
this.tweens.killTweensOf([view.sprite, view.label]);
|
||||
this.playUnitWalk(view, direction);
|
||||
this.tweens.add({
|
||||
targets: view.sprite,
|
||||
x: targetX,
|
||||
y: targetY,
|
||||
duration,
|
||||
ease: 'Sine.easeInOut'
|
||||
ease: 'Sine.easeInOut',
|
||||
onComplete: () => this.stopUnitWalk(view, direction)
|
||||
});
|
||||
this.tweens.add({
|
||||
targets: view.label,
|
||||
x: targetX,
|
||||
y: targetY + this.layout.tileSize * 0.36,
|
||||
y: targetY + this.layout.tileSize * 0.47,
|
||||
duration,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
}
|
||||
|
||||
private directionFromDelta(deltaX: number, deltaY: number): UnitDirection {
|
||||
if (Math.abs(deltaX) > Math.abs(deltaY)) {
|
||||
return deltaX >= 0 ? 'east' : 'west';
|
||||
}
|
||||
return deltaY >= 0 ? 'south' : 'north';
|
||||
}
|
||||
|
||||
private playUnitWalk(view: UnitView, direction: UnitDirection) {
|
||||
view.direction = direction;
|
||||
view.sprite.setFlipX(direction === 'west');
|
||||
view.sprite.play(`${view.textureBase}-walk-${direction}`, true);
|
||||
}
|
||||
|
||||
private stopUnitWalk(view: UnitView, direction: UnitDirection) {
|
||||
view.direction = direction;
|
||||
view.sprite.stop();
|
||||
this.setUnitDirectionFrame(view, direction);
|
||||
}
|
||||
|
||||
private setUnitDirectionFrame(view: UnitView, direction: UnitDirection) {
|
||||
const sourceDirection = direction === 'west' ? 'east' : direction;
|
||||
view.sprite.setTexture(`${view.textureBase}-${sourceDirection}-0`);
|
||||
view.sprite.setFlipX(direction === 'west');
|
||||
}
|
||||
|
||||
private applyActedStyle(unit: UnitData) {
|
||||
const view = this.unitViews.get(unit.id);
|
||||
if (!view) {
|
||||
return;
|
||||
}
|
||||
|
||||
view.sprite.stop();
|
||||
this.setUnitDirectionFrame(view, view.direction);
|
||||
view.sprite.postFX.addColorMatrix().grayscale(1);
|
||||
view.sprite.setAlpha(0.46);
|
||||
view.sprite.setTint(0xb7b7b7);
|
||||
|
||||
@@ -32,6 +32,24 @@ type UnitPixelPalette = {
|
||||
cape?: boolean;
|
||||
};
|
||||
|
||||
type UnitDirection = 'south' | 'east' | 'north' | 'west';
|
||||
type DrawDirection = Exclude<UnitDirection, 'west'>;
|
||||
|
||||
type UnitPixelPose = {
|
||||
direction: DrawDirection;
|
||||
frame: number;
|
||||
bob: number;
|
||||
step: number;
|
||||
arm: number;
|
||||
};
|
||||
|
||||
const unitWalkFrames = [
|
||||
{ bob: 0, step: 0, arm: 0 },
|
||||
{ bob: -1, step: -2, arm: 2 },
|
||||
{ bob: 0, step: 0, arm: 0 },
|
||||
{ bob: -1, step: 2, arm: -2 }
|
||||
];
|
||||
|
||||
export class BootScene extends Phaser.Scene {
|
||||
constructor() {
|
||||
super('BootScene');
|
||||
@@ -194,21 +212,53 @@ export class BootScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
private createPixelUnitTexture(key: string, colors: UnitPixelPalette) {
|
||||
(['south', 'east', 'north'] as DrawDirection[]).forEach((direction) => {
|
||||
unitWalkFrames.forEach((frame, frameIndex) => {
|
||||
this.createPixelUnitFrameTexture(`${key}-${direction}-${frameIndex}`, colors, {
|
||||
direction,
|
||||
frame: frameIndex,
|
||||
...frame
|
||||
});
|
||||
});
|
||||
});
|
||||
this.createPixelUnitAnimations(key);
|
||||
}
|
||||
|
||||
private createPixelUnitAnimations(key: string) {
|
||||
(['south', 'east', 'north', 'west'] as UnitDirection[]).forEach((direction) => {
|
||||
const animationKey = `${key}-walk-${direction}`;
|
||||
if (this.anims.exists(animationKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sourceDirection = direction === 'west' ? 'east' : direction;
|
||||
this.anims.create({
|
||||
key: animationKey,
|
||||
frames: unitWalkFrames.map((_, frameIndex) => ({
|
||||
key: `${key}-${sourceDirection}-${frameIndex}`
|
||||
})),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private createPixelUnitFrameTexture(key: string, colors: UnitPixelPalette, pose: UnitPixelPose) {
|
||||
const graphics = this.make.graphics({ x: 0, y: 0 });
|
||||
this.drawPixelShadow(graphics, colors);
|
||||
this.drawPixelShadow(graphics, colors, pose);
|
||||
|
||||
if (colors.mounted) {
|
||||
this.drawHorse(graphics, colors);
|
||||
this.drawHorse(graphics, colors, pose);
|
||||
}
|
||||
|
||||
if (colors.cape) {
|
||||
this.drawCape(graphics, colors);
|
||||
this.drawCape(graphics, colors, pose);
|
||||
}
|
||||
|
||||
this.drawWeapon(graphics, colors, 'back');
|
||||
this.drawBody(graphics, colors);
|
||||
this.drawHead(graphics, colors);
|
||||
this.drawWeapon(graphics, colors, 'front');
|
||||
this.drawWeapon(graphics, colors, pose, 'back');
|
||||
this.drawBody(graphics, colors, pose);
|
||||
this.drawHead(graphics, colors, pose);
|
||||
this.drawWeapon(graphics, colors, pose, 'front');
|
||||
|
||||
graphics.generateTexture(key, 64, 64);
|
||||
graphics.destroy();
|
||||
@@ -220,25 +270,27 @@ export class BootScene extends Phaser.Scene {
|
||||
graphics.fillRect(x, y, width, height);
|
||||
}
|
||||
|
||||
private drawPixelShadow(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette) {
|
||||
private drawPixelShadow(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette, pose: UnitPixelPose) {
|
||||
const left = colors.mounted ? 7 : 15;
|
||||
const width = colors.mounted ? 48 : 36;
|
||||
this.px(graphics, 0x050609, left, 58, width, 3, 0.5);
|
||||
this.px(graphics, 0x050609, left + 5, 56, width - 10, 2, 0.38);
|
||||
this.px(graphics, 0x050609, left + 12, 54, width - 24, 2, 0.28);
|
||||
const shift = pose.direction === 'east' ? 2 : 0;
|
||||
this.px(graphics, 0x050609, left + shift, 58, width, 3, 0.5);
|
||||
this.px(graphics, 0x050609, left + 5 + shift, 56, width - 10, 2, 0.38);
|
||||
this.px(graphics, 0x050609, left + 12 + shift, 54, width - 24, 2, 0.28);
|
||||
}
|
||||
|
||||
private drawHorse(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette) {
|
||||
private drawHorse(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette, pose: UnitPixelPose) {
|
||||
const outline = colors.outline ?? 0x15100d;
|
||||
this.px(graphics, outline, 9, 38, 40, 13);
|
||||
this.px(graphics, outline, 44, 30, 9, 13);
|
||||
const y = pose.bob;
|
||||
this.px(graphics, outline, 9, 38 + y, 40, 13);
|
||||
this.px(graphics, outline, 44, 30 + y, 9, 13);
|
||||
this.px(graphics, outline, 6, 43, 8, 6);
|
||||
this.px(graphics, 0x5b3824, 11, 39, 36, 10);
|
||||
this.px(graphics, 0x70472c, 13, 37, 25, 4);
|
||||
this.px(graphics, 0x8c5a36, 17, 38, 19, 2);
|
||||
this.px(graphics, 0x3a2418, 13, 49, 6, 9);
|
||||
this.px(graphics, 0x5b3824, 11, 39 + y, 36, 10);
|
||||
this.px(graphics, 0x70472c, 13, 37 + y, 25, 4);
|
||||
this.px(graphics, 0x8c5a36, 17, 38 + y, 19, 2);
|
||||
this.px(graphics, 0x3a2418, 13 + Math.max(0, -pose.step), 49, 6, 9);
|
||||
this.px(graphics, 0x3a2418, 25, 48, 5, 10);
|
||||
this.px(graphics, 0x3a2418, 39, 48, 6, 10);
|
||||
this.px(graphics, 0x3a2418, 39 + Math.max(0, pose.step), 48, 6, 10);
|
||||
this.px(graphics, outline, 12, 57, 8, 2);
|
||||
this.px(graphics, outline, 24, 57, 8, 2);
|
||||
this.px(graphics, outline, 38, 57, 9, 2);
|
||||
@@ -251,110 +303,139 @@ export class BootScene extends Phaser.Scene {
|
||||
this.px(graphics, 0x0b0b0b, 49, 32, 1, 1);
|
||||
}
|
||||
|
||||
private drawCape(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette) {
|
||||
private drawCape(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette, pose: UnitPixelPose) {
|
||||
const outline = colors.outline ?? 0x17100c;
|
||||
this.px(graphics, outline, 16, 20, 22, 24);
|
||||
this.px(graphics, outline, 13, 28, 9, 13);
|
||||
this.px(graphics, 0x6c2722, 17, 21, 20, 21);
|
||||
this.px(graphics, 0x8f392c, 18, 23, 8, 16);
|
||||
this.px(graphics, 0x3f1715, 14, 35, 18, 4);
|
||||
this.px(graphics, 0xc46146, 20, 24, 3, 12);
|
||||
const y = pose.bob;
|
||||
const side = pose.direction === 'east' ? 4 : 0;
|
||||
this.px(graphics, outline, 16 + side, 20 + y, 22, 24);
|
||||
this.px(graphics, outline, 13 + side, 28 + y, 9, 13);
|
||||
this.px(graphics, 0x6c2722, 17 + side, 21 + y, 20, 21);
|
||||
this.px(graphics, 0x8f392c, 18 + side, 23 + y, 8, 16);
|
||||
this.px(graphics, 0x3f1715, 14 + side, 35 + y, 18, 4);
|
||||
this.px(graphics, 0xc46146, 20 + side, 24 + y, 3, 12);
|
||||
}
|
||||
|
||||
private drawWeapon(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette, layer: 'back' | 'front') {
|
||||
private drawWeapon(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette, pose: UnitPixelPose, layer: 'back' | 'front') {
|
||||
const kind = colors.weaponKind ?? 'sword';
|
||||
const metal = colors.metal ?? colors.weapon;
|
||||
const outline = colors.outline ?? 0x101010;
|
||||
const y = pose.bob;
|
||||
|
||||
if (layer === 'back' && kind === 'spear') {
|
||||
this.px(graphics, outline, 50, 8, 4, 47);
|
||||
this.px(graphics, colors.weapon, 51, 10, 2, 44);
|
||||
this.px(graphics, outline, 48, 5, 7, 5);
|
||||
this.px(graphics, metal, 49, 3, 5, 6);
|
||||
this.px(graphics, metal, 46, 9, 10, 2);
|
||||
this.px(graphics, 0xffffff, 50, 4, 2, 3, 0.55);
|
||||
const x = pose.direction === 'east' ? 44 : pose.direction === 'north' ? 13 : 50;
|
||||
this.px(graphics, outline, x, 8 + y, 4, 47);
|
||||
this.px(graphics, colors.weapon, x + 1, 10 + y, 2, 44);
|
||||
this.px(graphics, outline, x - 2, 5 + y, 7, 5);
|
||||
this.px(graphics, metal, x - 1, 3 + y, 5, 6);
|
||||
this.px(graphics, metal, x - 4, 9 + y, 10, 2);
|
||||
this.px(graphics, 0xffffff, x, 4 + y, 2, 3, 0.55);
|
||||
return;
|
||||
}
|
||||
|
||||
if (layer === 'back' && kind === 'glaive') {
|
||||
this.px(graphics, outline, 50, 5, 4, 50);
|
||||
this.px(graphics, colors.weapon, 51, 8, 2, 46);
|
||||
this.px(graphics, outline, 44, 6, 13, 5);
|
||||
this.px(graphics, metal, 45, 5, 10, 5);
|
||||
this.px(graphics, metal, 54, 9, 5, 5);
|
||||
this.px(graphics, metal, 47, 12, 4, 6);
|
||||
this.px(graphics, 0xffffff, 47, 6, 6, 1, 0.48);
|
||||
const x = pose.direction === 'north' ? 12 : 50;
|
||||
this.px(graphics, outline, x, 5 + y, 4, 50);
|
||||
this.px(graphics, colors.weapon, x + 1, 8 + y, 2, 46);
|
||||
this.px(graphics, outline, x - 6, 6 + y, 13, 5);
|
||||
this.px(graphics, metal, x - 5, 5 + y, 10, 5);
|
||||
this.px(graphics, metal, x + 4, 9 + y, 5, 5);
|
||||
this.px(graphics, metal, x - 3, 12 + y, 4, 6);
|
||||
this.px(graphics, 0xffffff, x - 3, 6 + y, 6, 1, 0.48);
|
||||
return;
|
||||
}
|
||||
|
||||
if (layer === 'back' && kind === 'bow') {
|
||||
this.px(graphics, outline, 15, 17, 3, 27);
|
||||
this.px(graphics, outline, 18, 14, 3, 6);
|
||||
this.px(graphics, outline, 18, 41, 3, 6);
|
||||
this.px(graphics, colors.weapon, 17, 18, 2, 25);
|
||||
this.px(graphics, colors.weapon, 19, 15, 2, 5);
|
||||
this.px(graphics, colors.weapon, 19, 41, 2, 5);
|
||||
this.px(graphics, metal, 22, 19, 1, 24, 0.8);
|
||||
this.px(graphics, metal, 11, 32, 12, 1);
|
||||
this.px(graphics, metal, 11, 30, 3, 5);
|
||||
const x = pose.direction === 'east' ? 47 : 15;
|
||||
this.px(graphics, outline, x, 17 + y, 3, 27);
|
||||
this.px(graphics, outline, x + 3, 14 + y, 3, 6);
|
||||
this.px(graphics, outline, x + 3, 41 + y, 3, 6);
|
||||
this.px(graphics, colors.weapon, x + 2, 18 + y, 2, 25);
|
||||
this.px(graphics, colors.weapon, x + 4, 15 + y, 2, 5);
|
||||
this.px(graphics, colors.weapon, x + 4, 41 + y, 2, 5);
|
||||
this.px(graphics, metal, x + 7, 19 + y, 1, 24, 0.8);
|
||||
this.px(graphics, metal, x - 4, 32 + y, 12, 1);
|
||||
this.px(graphics, metal, x - 4, 30 + y, 3, 5);
|
||||
return;
|
||||
}
|
||||
|
||||
if (layer === 'back' && kind === 'axe') {
|
||||
this.px(graphics, outline, 50, 13, 4, 43);
|
||||
this.px(graphics, colors.weapon, 51, 15, 2, 40);
|
||||
this.px(graphics, outline, 43, 11, 16, 9);
|
||||
this.px(graphics, metal, 44, 10, 9, 8);
|
||||
this.px(graphics, metal, 52, 13, 7, 6);
|
||||
this.px(graphics, 0xffffff, 45, 11, 5, 1, 0.5);
|
||||
const x = pose.direction === 'north' ? 12 : 50;
|
||||
this.px(graphics, outline, x, 13 + y, 4, 43);
|
||||
this.px(graphics, colors.weapon, x + 1, 15 + y, 2, 40);
|
||||
this.px(graphics, outline, x - 7, 11 + y, 16, 9);
|
||||
this.px(graphics, metal, x - 6, 10 + y, 9, 8);
|
||||
this.px(graphics, metal, x + 2, 13 + y, 7, 6);
|
||||
this.px(graphics, 0xffffff, x - 5, 11 + y, 5, 1, 0.5);
|
||||
return;
|
||||
}
|
||||
|
||||
if (layer === 'front' && kind === 'dual') {
|
||||
this.px(graphics, outline, 46, 26, 3, 20);
|
||||
this.px(graphics, metal, 47, 22, 2, 20);
|
||||
this.px(graphics, metal, 49, 20, 3, 4);
|
||||
this.px(graphics, colors.accent, 44, 39, 6, 2);
|
||||
this.px(graphics, outline, 17, 31, 3, 17);
|
||||
this.px(graphics, metal, 16, 28, 2, 18);
|
||||
this.px(graphics, metal, 14, 27, 3, 4);
|
||||
this.px(graphics, colors.accent, 16, 42, 6, 2);
|
||||
if (pose.direction === 'north') {
|
||||
this.px(graphics, outline, 18, 30 + y, 3, 15);
|
||||
this.px(graphics, metal, 17, 27 + y, 2, 16);
|
||||
this.px(graphics, outline, 45, 30 + y, 3, 15);
|
||||
this.px(graphics, metal, 46, 27 + y, 2, 16);
|
||||
return;
|
||||
}
|
||||
const side = pose.direction === 'east' ? 3 : 0;
|
||||
this.px(graphics, outline, 46 + side, 26 + y, 3, 20);
|
||||
this.px(graphics, metal, 47 + side, 22 + y, 2, 20);
|
||||
this.px(graphics, metal, 49 + side, 20 + y, 3, 4);
|
||||
this.px(graphics, colors.accent, 44 + side, 39 + y, 6, 2);
|
||||
this.px(graphics, outline, 17 + pose.arm, 31 + y, 3, 17);
|
||||
this.px(graphics, metal, 16 + pose.arm, 28 + y, 2, 18);
|
||||
this.px(graphics, metal, 14 + pose.arm, 27 + y, 3, 4);
|
||||
this.px(graphics, colors.accent, 16 + pose.arm, 42 + y, 6, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (layer === 'front' && kind === 'sword') {
|
||||
this.px(graphics, outline, 48, 22, 4, 28);
|
||||
this.px(graphics, metal, 49, 18, 2, 29);
|
||||
this.px(graphics, metal, 47, 20, 6, 3);
|
||||
this.px(graphics, colors.accent, 46, 42, 7, 2);
|
||||
this.px(graphics, outline, 48, 22 + y, 4, 28);
|
||||
this.px(graphics, metal, 49, 18 + y, 2, 29);
|
||||
this.px(graphics, metal, 47, 20 + y, 6, 3);
|
||||
this.px(graphics, colors.accent, 46, 42 + y, 7, 2);
|
||||
}
|
||||
}
|
||||
|
||||
private drawBody(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette) {
|
||||
private drawBody(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette, pose: UnitPixelPose) {
|
||||
const outline = colors.outline ?? 0x111318;
|
||||
const highlight = colors.highlight ?? colors.robe;
|
||||
const boot = colors.boot ?? 0x16120e;
|
||||
const bodyY = colors.mounted ? 21 : 26;
|
||||
const bodyY = (colors.mounted ? 21 : 26) + pose.bob;
|
||||
const legY = colors.mounted ? 40 : 46;
|
||||
const side = pose.direction === 'east' ? 3 : 0;
|
||||
|
||||
this.px(graphics, outline, 23, legY, 10, 12);
|
||||
this.px(graphics, outline, 35, legY - 2, 10, 14);
|
||||
this.px(graphics, colors.shade, 25, legY, 7, 10);
|
||||
this.px(graphics, colors.robe, 36, legY - 1, 7, 11);
|
||||
this.px(graphics, outline, 23 + side + Math.min(0, pose.step), legY, 10, 12);
|
||||
this.px(graphics, outline, 35 + side + Math.max(0, pose.step), legY - 2, 10, 14);
|
||||
this.px(graphics, colors.shade, 25 + side + Math.min(0, pose.step), legY, 7, 10);
|
||||
this.px(graphics, colors.robe, 36 + side + Math.max(0, pose.step), legY - 1, 7, 11);
|
||||
this.px(graphics, boot, 22, legY + 10, 12, 4);
|
||||
this.px(graphics, boot, 35, legY + 10, 12, 4);
|
||||
this.px(graphics, 0xffffff, 27, legY + 1, 3, 1, 0.3);
|
||||
this.px(graphics, boot, 35 + side, legY + 10, 12, 4);
|
||||
this.px(graphics, 0xffffff, 27 + side, legY + 1, 3, 1, 0.3);
|
||||
|
||||
this.px(graphics, outline, 21, bodyY + 2, 25, 23);
|
||||
this.px(graphics, outline, 18, bodyY + 8, 8, 16);
|
||||
this.px(graphics, outline, 42, bodyY + 6, 8, 16);
|
||||
this.px(graphics, colors.shade, 23, bodyY + 4, 21, 21);
|
||||
this.px(graphics, colors.robe, 24, bodyY + 3, 18, 20);
|
||||
this.px(graphics, highlight, 26, bodyY + 5, 5, 15);
|
||||
this.px(graphics, colors.shade, 37, bodyY + 5, 5, 17);
|
||||
this.px(graphics, colors.robe, 19, bodyY + 9, 7, 13);
|
||||
this.px(graphics, colors.robe, 42, bodyY + 8, 7, 12);
|
||||
this.px(graphics, highlight, 20, bodyY + 10, 3, 9);
|
||||
if (pose.direction === 'east') {
|
||||
this.px(graphics, outline, 25, bodyY + 2, 21, 23);
|
||||
this.px(graphics, outline, 22 + pose.arm, bodyY + 9, 8, 14);
|
||||
this.px(graphics, outline, 42 - pose.arm, bodyY + 8, 8, 14);
|
||||
this.px(graphics, colors.shade, 27, bodyY + 4, 17, 20);
|
||||
this.px(graphics, colors.robe, 28, bodyY + 3, 14, 20);
|
||||
this.px(graphics, highlight, 30, bodyY + 5, 4, 14);
|
||||
this.px(graphics, colors.shade, 39, bodyY + 6, 4, 16);
|
||||
this.px(graphics, colors.robe, 23 + pose.arm, bodyY + 10, 7, 12);
|
||||
this.px(graphics, colors.robe, 42 - pose.arm, bodyY + 9, 7, 11);
|
||||
} else {
|
||||
const backShade = pose.direction === 'north' ? colors.robe : colors.shade;
|
||||
this.px(graphics, outline, 21, bodyY + 2, 25, 23);
|
||||
this.px(graphics, outline, 18, bodyY + 8, 8, 16);
|
||||
this.px(graphics, outline, 42, bodyY + 6, 8, 16);
|
||||
this.px(graphics, backShade, 23, bodyY + 4, 21, 21);
|
||||
this.px(graphics, colors.robe, 24, bodyY + 3, 18, 20);
|
||||
this.px(graphics, highlight, 26, bodyY + 5, 5, 15);
|
||||
this.px(graphics, colors.shade, 37, bodyY + 5, 5, 17);
|
||||
this.px(graphics, colors.robe, 19 + pose.arm, bodyY + 9, 7, 13);
|
||||
this.px(graphics, colors.robe, 42 - pose.arm, bodyY + 8, 7, 12);
|
||||
this.px(graphics, highlight, 20 + pose.arm, bodyY + 10, 3, 9);
|
||||
}
|
||||
|
||||
this.px(graphics, colors.trim, 24, bodyY + 4, 18, 2);
|
||||
this.px(graphics, colors.trim, 25, bodyY + 12, 17, 2);
|
||||
@@ -366,10 +447,12 @@ export class BootScene extends Phaser.Scene {
|
||||
this.px(graphics, 0xf8e6a8, 38, bodyY + 7, 3, 2, 0.78);
|
||||
this.px(graphics, 0xf8e6a8, 27, bodyY + 18, 13, 1, 0.55);
|
||||
|
||||
this.px(graphics, colors.skin, 17, bodyY + 15, 4, 6);
|
||||
this.px(graphics, colors.skin, 48, bodyY + 13, 4, 6);
|
||||
this.px(graphics, colors.skinShade ?? 0x9a6747, 18, bodyY + 20, 3, 2);
|
||||
this.px(graphics, colors.skinShade ?? 0x9a6747, 49, bodyY + 18, 3, 2);
|
||||
if (pose.direction !== 'north') {
|
||||
this.px(graphics, colors.skin, 17 + pose.arm, bodyY + 15, 4, 6);
|
||||
this.px(graphics, colors.skin, 48 - pose.arm, bodyY + 13, 4, 6);
|
||||
this.px(graphics, colors.skinShade ?? 0x9a6747, 18 + pose.arm, bodyY + 20, 3, 2);
|
||||
this.px(graphics, colors.skinShade ?? 0x9a6747, 49 - pose.arm, bodyY + 18, 3, 2);
|
||||
}
|
||||
|
||||
if (colors.weaponKind === 'bow') {
|
||||
this.px(graphics, colors.accent, 39, bodyY + 14, 7, 3);
|
||||
@@ -377,68 +460,79 @@ export class BootScene extends Phaser.Scene {
|
||||
}
|
||||
}
|
||||
|
||||
private drawHead(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette) {
|
||||
private drawHead(graphics: Phaser.GameObjects.Graphics, colors: UnitPixelPalette, pose: UnitPixelPose) {
|
||||
const outline = colors.outline ?? 0x111318;
|
||||
const skinShade = colors.skinShade ?? 0xb17450;
|
||||
const headY = colors.mounted ? 7 : 10;
|
||||
const headY = (colors.mounted ? 7 : 10) + pose.bob;
|
||||
const side = pose.direction === 'east' ? 3 : 0;
|
||||
|
||||
this.px(graphics, outline, 24, headY + 1, 18, 16);
|
||||
this.px(graphics, outline, 21, headY + 6, 5, 7);
|
||||
this.px(graphics, outline, 40, headY + 6, 5, 7);
|
||||
this.px(graphics, colors.skin, 25, headY + 2, 16, 14);
|
||||
this.px(graphics, colors.skin, 22, headY + 7, 4, 5);
|
||||
this.px(graphics, colors.skin, 40, headY + 7, 4, 5);
|
||||
this.px(graphics, skinShade, 34, headY + 9, 5, 5);
|
||||
this.px(graphics, skinShade, 26, headY + 14, 14, 2);
|
||||
|
||||
if (colors.headgear === 'turban') {
|
||||
this.px(graphics, colors.accent, 23, headY - 1, 20, 6);
|
||||
this.px(graphics, colors.trim, 25, headY, 15, 2);
|
||||
this.px(graphics, colors.accent, 31, headY - 4, 8, 4);
|
||||
this.px(graphics, colors.shade, 40, headY + 1, 5, 5);
|
||||
} else if (colors.headgear === 'helmet') {
|
||||
this.px(graphics, outline, 23, headY - 2, 20, 8);
|
||||
this.px(graphics, colors.trim, 25, headY - 3, 16, 6);
|
||||
this.px(graphics, colors.accent, 29, headY - 7, 8, 5);
|
||||
this.px(graphics, colors.metal ?? colors.trim, 26, headY + 3, 15, 2);
|
||||
} else if (colors.headgear === 'cap') {
|
||||
this.px(graphics, colors.hair, 23, headY - 1, 20, 6);
|
||||
this.px(graphics, colors.accent, 25, headY - 2, 15, 3);
|
||||
this.px(graphics, colors.accent, 30, headY - 5, 8, 4);
|
||||
} else {
|
||||
this.px(graphics, colors.hair, 23, headY - 2, 20, 6);
|
||||
this.px(graphics, colors.hair, 22, headY + 2, 6, 9);
|
||||
this.px(graphics, colors.hair, 39, headY + 2, 5, 9);
|
||||
this.px(graphics, colors.accent, 26, headY - 4, 13, 3);
|
||||
this.px(graphics, colors.accent, 29, headY - 7, 8, 4);
|
||||
this.px(graphics, colors.hair, 31, headY - 9, 5, 3);
|
||||
this.px(graphics, outline, 24 + side, headY + 1, pose.direction === 'east' ? 16 : 18, 16);
|
||||
this.px(graphics, outline, 21 + side, headY + 6, 5, 7);
|
||||
this.px(graphics, outline, 40 + side, headY + 6, 5, 7);
|
||||
this.px(graphics, colors.skin, 25 + side, headY + 2, pose.direction === 'east' ? 14 : 16, 14);
|
||||
if (pose.direction !== 'north') {
|
||||
this.px(graphics, colors.skin, 22 + side, headY + 7, 4, 5);
|
||||
this.px(graphics, colors.skin, 40 + side, headY + 7, 4, 5);
|
||||
this.px(graphics, skinShade, 34 + side, headY + 9, 5, 5);
|
||||
this.px(graphics, skinShade, 26 + side, headY + 14, 14, 2);
|
||||
}
|
||||
|
||||
this.px(graphics, 0x050609, 27, headY + 8, 2, 1);
|
||||
this.px(graphics, 0x050609, 36, headY + 8, 2, 1);
|
||||
this.px(graphics, 0x3a1d18, 31, headY + 13, 5, 1);
|
||||
this.px(graphics, 0xffffff, 29, headY + 4, 5, 1, 0.5);
|
||||
this.px(graphics, 0xffffff, 36, headY + 4, 4, 1, 0.42);
|
||||
if (colors.headgear === 'turban') {
|
||||
this.px(graphics, colors.accent, 23 + side, headY - 1, 20, 6);
|
||||
this.px(graphics, colors.trim, 25 + side, headY, 15, 2);
|
||||
this.px(graphics, colors.accent, 31 + side, headY - 4, 8, 4);
|
||||
this.px(graphics, colors.shade, 40 + side, headY + 1, 5, 5);
|
||||
} else if (colors.headgear === 'helmet') {
|
||||
this.px(graphics, outline, 23 + side, headY - 2, 20, 8);
|
||||
this.px(graphics, colors.trim, 25 + side, headY - 3, 16, 6);
|
||||
this.px(graphics, colors.accent, 29 + side, headY - 7, 8, 5);
|
||||
this.px(graphics, colors.metal ?? colors.trim, 26 + side, headY + 3, 15, 2);
|
||||
} else if (colors.headgear === 'cap') {
|
||||
this.px(graphics, colors.hair, 23 + side, headY - 1, 20, 6);
|
||||
this.px(graphics, colors.accent, 25 + side, headY - 2, 15, 3);
|
||||
this.px(graphics, colors.accent, 30 + side, headY - 5, 8, 4);
|
||||
} else {
|
||||
this.px(graphics, colors.hair, 23 + side, headY - 2, 20, 6);
|
||||
this.px(graphics, colors.hair, 22 + side, headY + 2, 6, 9);
|
||||
this.px(graphics, colors.hair, 39 + side, headY + 2, 5, 9);
|
||||
this.px(graphics, colors.accent, 26 + side, headY - 4, 13, 3);
|
||||
this.px(graphics, colors.accent, 29 + side, headY - 7, 8, 4);
|
||||
this.px(graphics, colors.hair, 31 + side, headY - 9, 5, 3);
|
||||
}
|
||||
|
||||
if (colors.beard) {
|
||||
if (pose.direction !== 'north') {
|
||||
this.px(graphics, 0x050609, 27 + side, headY + 8, 2, 1);
|
||||
this.px(graphics, 0x050609, 36 + side, headY + 8, 2, 1);
|
||||
this.px(graphics, 0x3a1d18, 31 + side, headY + 13, 5, 1);
|
||||
this.px(graphics, 0xffffff, 29 + side, headY + 4, 5, 1, 0.5);
|
||||
this.px(graphics, 0xffffff, 36 + side, headY + 4, 4, 1, 0.42);
|
||||
if (pose.direction === 'east') {
|
||||
this.px(graphics, skinShade, 41 + side, headY + 10, 3, 2);
|
||||
}
|
||||
} else {
|
||||
this.px(graphics, colors.shade, 26, headY + 7, 14, 6, 0.55);
|
||||
this.px(graphics, colors.trim, 28, headY + 12, 10, 2, 0.75);
|
||||
}
|
||||
|
||||
if (colors.beard && pose.direction !== 'north') {
|
||||
const beardY = headY + 15;
|
||||
this.px(graphics, outline, 26, beardY - 1, 15, 8);
|
||||
this.px(graphics, colors.hair, 27, beardY, 13, 7);
|
||||
this.px(graphics, 0x4b281d, 28, beardY + 1, 3, 5);
|
||||
this.px(graphics, 0x4b281d, 36, beardY + 1, 2, 5);
|
||||
this.px(graphics, outline, 26 + side, beardY - 1, 15, 8);
|
||||
this.px(graphics, colors.hair, 27 + side, beardY, 13, 7);
|
||||
this.px(graphics, 0x4b281d, 28 + side, beardY + 1, 3, 5);
|
||||
this.px(graphics, 0x4b281d, 36 + side, beardY + 1, 2, 5);
|
||||
|
||||
if (colors.beardStyle === 'long') {
|
||||
this.px(graphics, outline, 28, beardY + 6, 11, 12);
|
||||
this.px(graphics, colors.hair, 29, beardY + 6, 9, 11);
|
||||
this.px(graphics, 0x160d0a, 31, beardY + 14, 5, 5);
|
||||
this.px(graphics, 0x6a3a2a, 31, beardY + 7, 3, 9);
|
||||
this.px(graphics, outline, 28 + side, beardY + 6, 11, 12);
|
||||
this.px(graphics, colors.hair, 29 + side, beardY + 6, 9, 11);
|
||||
this.px(graphics, 0x160d0a, 31 + side, beardY + 14, 5, 5);
|
||||
this.px(graphics, 0x6a3a2a, 31 + side, beardY + 7, 3, 9);
|
||||
} else if (colors.beardStyle === 'wild') {
|
||||
this.px(graphics, outline, 23, beardY + 2, 20, 10);
|
||||
this.px(graphics, colors.hair, 24, beardY + 2, 18, 9);
|
||||
this.px(graphics, outline, 27, beardY + 10, 13, 8);
|
||||
this.px(graphics, colors.hair, 28, beardY + 10, 11, 7);
|
||||
this.px(graphics, 0x4b281d, 26, beardY + 5, 4, 4);
|
||||
this.px(graphics, 0x4b281d, 37, beardY + 5, 4, 4);
|
||||
this.px(graphics, outline, 23 + side, beardY + 2, 20, 10);
|
||||
this.px(graphics, colors.hair, 24 + side, beardY + 2, 18, 9);
|
||||
this.px(graphics, outline, 27 + side, beardY + 10, 13, 8);
|
||||
this.px(graphics, colors.hair, 28 + side, beardY + 10, 11, 7);
|
||||
this.px(graphics, 0x4b281d, 26 + side, beardY + 5, 4, 4);
|
||||
this.px(graphics, 0x4b281d, 37 + side, beardY + 5, 4, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user