Skip to content

Commit

Permalink
Complete enough for release!
Browse files Browse the repository at this point in the history
  • Loading branch information
eonarheim committed Dec 4, 2023
1 parent d713122 commit 222ef3e
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 24 deletions.
Binary file added res/SpiderSheet.aseprite
Binary file not shown.
Binary file added res/slime.aseprite
Binary file not shown.
Binary file added res/slime.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 13 additions & 3 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as ex from "excalibur";

import { KnightIdle, SpiderIdle } from "./resources";
import { KnightIdle, SlimeIdle, SpiderIdle } from "./resources";
const seed = Date.now();
console.log("Random seed:", seed);
export const RANDOM = new ex.Random(seed);
Expand All @@ -9,7 +9,7 @@ export const SCALE = ex.vec(3, 3);
export const BOARD_OFFSET = ex.vec(32 * 3, 32 * 4);
export const ENEMY_SPEED = 200;

export type UnitType = "Knight" | "Spider";
export type UnitType = "Knight" | "Spider" | "Slime";
export interface UnitConfig {
graphics: {
offset: ex.Vector,
Expand All @@ -27,7 +27,7 @@ export const UNIT_CONFIG: Record<UnitType, UnitConfig> = {
idle: KnightIdle
},
health: 5,
movement: 4,
movement: 3,
attack: 2,
range: 1
},
Expand All @@ -40,6 +40,16 @@ export const UNIT_CONFIG: Record<UnitType, UnitConfig> = {
movement: 3,
attack: 1,
range: 1
},
Slime: {
graphics: {
offset: ex.vec(0, 8 * SCALE.y),
idle: SlimeIdle
},
health: 2,
movement: 1,
attack: 4,
range: 1
}
} as const;

15 changes: 12 additions & 3 deletions src/levels/level-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ export interface LevelData {
// ]
// }

export const CharToUnit = {
K: 'Knight',
S: 'Spider',
M: 'Slime'
} as const;

export class LevelBase extends ex.Scene {

board!: Board;
Expand Down Expand Up @@ -80,28 +86,31 @@ export class LevelBase extends ex.Scene {
this.camera.pos = this.board.getCenter();
}

private _subscriptions: ex.Subscription[] = [];
override onActivate(): void {
this.resetAndLoad();
this.turnManager.start();
Resources.LevelMusic2.loop = true;
Resources.LevelMusic2.play();

this.engine.input.keyboard.on('press', (evt) => {
this._subscriptions.push(
this.engine.input.keyboard.once('press', (evt) => {
// DELETEME for debugging
if (evt.key === ex.Keys.W) {
(this.players[1] as ComputerPlayer).lose();
}
if (evt.key === ex.Keys.L) {
(this.players[0] as HumanPlayer).lose();
}
});
}));

}

override onDeactivate(): void {
// TODO deactivate event handlers on types that have them!!
Resources.LevelMusic2.instances.forEach(i => i.stop());
Resources.LevelMusic2.stop();
this._subscriptions.forEach(s => s.close());
}

parse(levelData: LevelData): Board {
Expand All @@ -123,7 +132,7 @@ export class LevelBase extends ex.Scene {
const terrain = data.charAt(0) as Terrain;
let unit: Unit | null = null;
if (data.length === 3) {
const unitType: UnitType = data.charAt(1) === 'K' ? 'Knight' : 'Spider';
const unitType: UnitType = CharToUnit[data.charAt(1) as 'K' | 'S' | 'M']
const playerIndex = (+data.charAt(2)) - 1;

unit = new Unit(x, y, unitType, board, this.players[playerIndex]);
Expand Down
15 changes: 10 additions & 5 deletions src/levels/start-screen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,24 @@ export class StartScreen extends ex.Scene {
this.add(this.instructions);
}

_subscriptions: ex.Subscription[] = [];
onActivate(): void {
console.log('activate start screen')
Resources.TitleMusic.loop = true;
Resources.TitleMusic.play();

this.engine.input.pointers.primary.once('down', () => {
this._subscriptions.push(
this.engine.input.pointers.primary.once('down', () => {
this.engine.goToScene('tutorial');
}));
this._subscriptions.push(
this.engine.input.keyboard.once('press', () => {
this.engine.goToScene('tutorial');
});
this.engine.input.keyboard.once('press', () => {
this.engine.goToScene('tutorial');
});
}));

}
onDeactivate(): void {
Resources.TitleMusic.stop();
this._subscriptions.forEach(h => h.close());
}
}
63 changes: 55 additions & 8 deletions src/levels/tutorial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { HumanPlayer } from '../human-player';
export const TutorialData: LevelData = {
name: 'tutorial',
displayName: 'Gentle Plains',
nextLevel: 'level',
nextLevel: 'level1',
width: 6,
height: 3,
maxTurns: 10,
Expand All @@ -21,7 +21,9 @@ export const TutorialData: LevelData = {
}
export class Tutorial extends LevelBase {
focus!: ex.Actor;

tutorialDirections!: ex.Actor;
private bottomScreen = ex.vec(400, 2000);
private centerScreen = ex.vec(400, 700);
constructor() {
super(TutorialData, 'tutorial');
}
Expand All @@ -42,8 +44,44 @@ export class Tutorial extends LevelBase {
this.focus.graphics.opacity = 0;
this.engine.add(this.focus);
}
const screenWidth = engine.screen.resolution.width;
const tutorialDirections = new ex.Text({
text: `S or Tap to Skip!`,
font: new ex.Font({
family: 'notjamslab14',
size: 32 * SCALE.x,
unit: ex.FontUnit.Px,
color: ex.Color.White,
baseAlign: ex.BaseAlign.Top,
quality: 4
}),
});


this.tutorialDirections = new ex.Actor({
name: 'directions',
pos: this.bottomScreen,
coordPlane: ex.CoordPlane.Screen,
color: new ex.Color(50, 240, 50, .4),
width: screenWidth,
height: 100,
z: 10
});
this.tutorialDirections.graphics.opacity = 0;
this.tutorialDirections.graphics.add('text', tutorialDirections);
this.tutorialDirections.graphics.show('text')
engine.add(this.tutorialDirections);
}

async showSkip() {
const transitionTime = 1200;
await this.tutorialDirections.actions.runAction(
new ex.ParallelActions([
new ex.ActionSequence(this.tutorialDirections, ctx =>
ctx.easeTo(this.centerScreen, transitionTime, ex.EasingFunctions.EaseInOutCubic)),
new ex.ActionSequence(this.tutorialDirections, ctx =>
ctx.fade(1, transitionTime))
])
).toPromise();
}

async moveToUnit1() {
Expand Down Expand Up @@ -122,12 +160,20 @@ export class Tutorial extends LevelBase {
await this.focus.actions.fade(0, 200).toPromise();
}

private _subs: ex.Subscription[] = [];
async onActivate() {
this.engine.input.keyboard.once('press', evt => {
if (evt.key === ex.Keys.Esc) {
this.showSkip();
console.log('activate tutorial');
this._subs.push(
this.engine.input.keyboard.on('press', evt => {
if (evt.key === ex.Keys.S) {
this.engine.goToScene('level1');
}
}));
this._subs.push(
this.engine.input.pointers.primary.on('down', evt => {
this.engine.goToScene('level1');
}
})
}));

Resources.LevelMusic2.loop = true;
Resources.LevelMusic2.play();
Expand Down Expand Up @@ -177,7 +223,7 @@ export class Tutorial extends LevelBase {
await this.hideText();

await this.showText(7);
await this.focus.actions.delay(7000);
await this.focus.actions.delay(3000);
await this.hideText();

this.camera.zoomOverTime(1, 1000, ex.EasingFunctions.EaseInOutCubic);
Expand All @@ -187,6 +233,7 @@ export class Tutorial extends LevelBase {

onDeactivate(): void {
Resources.LevelMusic2.stop();
this._subs.forEach(s => s.close());
}

}
4 changes: 2 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ export const Level2Data: LevelData = {
maxTurns: 100,
players: ['human', 'computer'],
data: [
'GK1', 'G', 'GS2', 'G', 'G', 'GS2',
'GK1', 'G', 'GM2', 'G', 'G', 'GS2',
'GK1', 'G', 'G', 'G', 'G', 'GS2',
'GK1', 'G', 'W', 'W', 'G', 'G',
'G', 'G', 'W', 'W', 'G', 'G',
'G', 'G', 'W', 'W', 'G', 'G',
'G', 'GS2', 'W', 'W', 'GS2', 'GS2',
'GM2', 'GM2', 'W', 'W', 'GS2', 'GS2',
]
}

Expand Down
23 changes: 23 additions & 0 deletions src/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as ex from 'excalibur';
import TitleImagePath from '../res/title.png';
import KnightSpriteSheetPath from '../res/KnightSheet.png';
import SpiderSheetPath from '../res/SpiderSheet.png';
import SlimeSheetPath from '../res/slime.png';
import HeartSheetPath from '../res/HeartSheet.png';
import UISheetPath from '../res/UISheet.png';
import TerrainSheetPath from '../res/TerrainSheet.png';
Expand All @@ -26,6 +27,7 @@ export const Resources = {
TitleImage: new ex.ImageSource(TitleImagePath),
KnightSpriteSheet: new ex.ImageSource(KnightSpriteSheetPath),
SpiderSheet: new ex.ImageSource(SpiderSheetPath),
SlimeSheet: new ex.ImageSource(SlimeSheetPath),
HeartSheet: new ex.ImageSource(HeartSheetPath),
UISheet: new ex.ImageSource(UISheetPath),
TerrainSheet: new ex.ImageSource(TerrainSheetPath),
Expand Down Expand Up @@ -142,6 +144,27 @@ export const SpiderIdle = ex.Animation.fromSpriteSheetCoordinates({
]
});

export const SlimeSpriteSheet = ex.SpriteSheet.fromImageSource({
image: Resources.SlimeSheet,
grid: {
rows: 1,
columns: 4,
spriteHeight: 32,
spriteWidth: 32
}
});

export const SlimeIdle = ex.Animation.fromSpriteSheetCoordinates({
spriteSheet: SlimeSpriteSheet,
strategy: ex.AnimationStrategy.Loop,
frameCoordinates: [
{x: 0, y: 0, duration: 200},
{x: 1, y: 0, duration: 200},
{x: 2, y: 0, duration: 200},
{x: 3, y: 0, duration: 200}
]
});

export const KnightSpriteSheet = ex.SpriteSheet.fromImageSource({
image: Resources.KnightSpriteSheet,
grid: {
Expand Down
40 changes: 39 additions & 1 deletion src/turn-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export class TurnManager {
private centerScreen = ex.vec(400, 400);
private bottomScreen = ex.vec(400, 2000);
private victory: ex.Actor;
private victoryDirections: ex.Actor;
private failure: ex.Actor;

constructor(public engine: ex.Engine, public level: LevelBase, public players: Player[], selectionManager: SelectionManager, public maxTurns: number) {
Expand Down Expand Up @@ -84,6 +85,32 @@ export class TurnManager {
this.victory.graphics.show('text')
engine.add(this.victory);

const victoryDirections = new ex.Text({
text: `Click to proceed!`,
font: new ex.Font({
family: 'notjamslab14',
size: 32 * SCALE.x,
unit: ex.FontUnit.Px,
color: ex.Color.White,
baseAlign: ex.BaseAlign.Top,
quality: 4
}),
});

this.victoryDirections = new ex.Actor({
name: 'directions',
pos: this.topScreen,
coordPlane: ex.CoordPlane.Screen,
color: new ex.Color(50, 240, 50, .4),
width: screenWidth,
height: 100,
z: 10
});
this.victoryDirections.graphics.opacity = 0;
this.victoryDirections.graphics.add('text', victoryDirections);
this.victoryDirections.graphics.show('text')
engine.add(this.victoryDirections);

const failureText1 = new ex.Text({
text: `Failure!`,
font: new ex.Font({
Expand Down Expand Up @@ -166,6 +193,15 @@ export class TurnManager {
ctx.fade(1, transitionTime))
])
).toPromise();

await this.victoryDirections.actions.runAction(
new ex.ParallelActions([
new ex.ActionSequence(this.victoryDirections, ctx =>
ctx.easeTo(this.centerScreen.add(ex.vec(0, 150)), transitionTime, ex.EasingFunctions.EaseInOutCubic)),
new ex.ActionSequence(this.victoryDirections, ctx =>
ctx.fade(1, transitionTime))
])
).toPromise();
}

async start() {
Expand All @@ -185,7 +221,9 @@ export class TurnManager {
if (this.currentPlayer instanceof ComputerPlayer) {
await this.showVictory();
this.engine.input.pointers.once('down', () => {
this.engine.goToScene(this.level.levelData.nextLevel);
setTimeout(() => {
this.engine.goToScene(this.level.levelData.nextLevel);
});
});
return;
}
Expand Down
6 changes: 4 additions & 2 deletions todo.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
## Bugs
* [ ] Sometimes the tutorial crashes and there is no way to proceed
* [ ] Re-entering the tutorial is in a weird state

## UI
* [x] Add social card!

## Gameplay
* [x] Start Screen
* [ ] Skip tutorial option
* [ ] Add instructions to the win screen
* [ ] Disable cheats
* [x] Skip tutorial option
* [x] Add instructions to the win screen
* [ ] Add a stats win screen
* [ ] Units kills/units lost
* [ ] Wait for death anim before popping ui?
Expand Down

0 comments on commit 222ef3e

Please sign in to comment.