Skip to content

Commit

Permalink
[REFACTOR] Add Constants component
Browse files Browse the repository at this point in the history
  • Loading branch information
openhoat committed Oct 21, 2023
1 parent 534fa56 commit cc9124b
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 73 deletions.
35 changes: 5 additions & 30 deletions src/components/alien.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,10 @@ import type { Canvas } from 'terminal-canvas'
import type { Explodable, ShapeConfig, Shooterable } from '../types'
import { center } from '../util/helper'
import { Bullet } from './bullet'
import Constants from './constants'
import { Shape } from './shape'

export class Alien extends Shape implements Shooterable, Explodable {
static readonly colors = {
alien1: '#62DE6D',
alien2: '#42E9F4',
alien3: '#DB55DD',
}
static readonly contents = {
alien1: [
[' {@@} ', ' /""\\ '],
[' {@@} ', ' \\/ '],
],
alien2: [
[' dOOb ', ' ^/\\^ '],
[' dOOb ', ' ~||~ '],
],
alien3: [
[' /MM\\ ', ' |~~| '],
[' /MM\\ ', ' \\~~/ '],
],
exploded: [
[' \\||/ ', ' /||\\ '],
['', ''],
],
}
static readonly height = 2
static readonly width = 6

readonly bullets: Bullet[] = []
readonly score: number

Expand All @@ -42,21 +17,21 @@ export class Alien extends Shape implements Shooterable, Explodable {
) {
super(canvas, {
...config,
height: Alien.height,
width: Alien.width,
height: Constants.alien.height,
width: Constants.alien.width,
})
this.score = score
}

explode(): void {
this.setContents(Alien.contents.exploded)
this.setContents(Constants.alien.contents.exploded)
this.draw({ blink: true })
}

shoot(collisionHandler?: (shape: Shape) => boolean): void {
const bullet = new Bullet(this.canvas, 'down', {
bgColor: this.bgColor,
fgColor: '#FFFFFF',
fgColor: Constants.bullet.color,
x: this.x + center(this.width),
y: this.y + this.height,
})
Expand Down
46 changes: 31 additions & 15 deletions src/components/aliens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,24 @@ import { baseDir } from '../util/base-dir'
import { alea, mapIterate, oneOf, reduceIterate } from '../util/helper'
import { playSound } from '../util/sound-player'
import { Alien } from './alien'
import Constants from './constants'
import { GameEvent } from './game-event'
import { Shape } from './shape'

export class Aliens implements Shapeable, Resetable {
static readonly alienContents = [
Alien.contents.alien1,
Alien.contents.alien2,
Alien.contents.alien2,
Alien.contents.alien3,
Alien.contents.alien3,
Constants.alien.contents.alien1,
Constants.alien.contents.alien2,
Constants.alien.contents.alien2,
Constants.alien.contents.alien3,
Constants.alien.contents.alien3,
]
static readonly aliensColors = [
Alien.colors.alien1,
Alien.colors.alien2,
Alien.colors.alien2,
Alien.colors.alien3,
Alien.colors.alien3,
Constants.alien.colors.alien1,
Constants.alien.colors.alien2,
Constants.alien.colors.alien2,
Constants.alien.colors.alien3,
Constants.alien.colors.alien3,
]
static readonly hMargin = 10
static readonly noItemsPerLine = 11
Expand Down Expand Up @@ -94,9 +95,9 @@ export class Aliens implements Shapeable, Resetable {
bgColor: string | undefined,
): Alien {
const x = Math.round(
hMargin + colIndex * hSpace + hSpace / 2 - Alien.width / 2,
hMargin + colIndex * hSpace + hSpace / 2 - Constants.alien.width / 2,
)
const y = Math.round(3 + rowIndex * (Alien.height + 1))
const y = Math.round(3 + rowIndex * (Constants.alien.height + 1))
const contents =
Aliens.alienContents[rowIndex % Aliens.alienContents.length]!
const fgColor = Aliens.aliensColors[rowIndex % Aliens.aliensColors.length]!
Expand Down Expand Up @@ -188,10 +189,25 @@ export class Aliens implements Shapeable, Resetable {
this.getMinY(),
]
const hasValidPosition =
Shape.checkPosition(this.canvas, minX, minY, Alien.width, Alien.height) &&
Shape.checkPosition(this.canvas, maxX, maxY, Alien.width, Alien.height)
Shape.checkPosition(
this.canvas,
minX,
minY,
Constants.alien.width,
Constants.alien.height,
) &&
Shape.checkPosition(
this.canvas,
maxX,
maxY,
Constants.alien.width,
Constants.alien.height,
)
if (!hasValidPosition) {
if (maxY + Alien.height >= this.canvas.height - Alien.height - 1) {
if (
maxY + Constants.alien.height >=
this.canvas.height - Constants.alien.height - 1
) {
this.events.emit(GameEvent.GameOver)
return
}
Expand Down
56 changes: 56 additions & 0 deletions src/components/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { join } from 'node:path'

import { baseDir } from '../util/base-dir'

const Constants = Object.freeze({
alien: {
colors: {
alien1: '#62DE6D',
alien2: '#42E9F4',
alien3: '#DB55DD',
},
contents: {
alien1: [
[' {@@} ', ' /""\\ '],
[' {@@} ', ' \\/ '],
],
alien2: [
[' dOOb ', ' ^/\\^ '],
[' dOOb ', ' ~||~ '],
],
alien3: [
[' /MM\\ ', ' |~~| '],
[' /MM\\ ', ' \\~~/ '],
],
exploded: [
[' \\||/ ', ' /||\\ '],
['', ''],
],
},
height: 2,
width: 6,
},
bullet: {
color: '#FFFFFF',
},
game: {
backgroundColor: '#000000',
},
gunner: {
contents: {
exploded: [
[" ,' % ", ' ;&+,! '],
[' -,+$! ', ' + ^~ '],
],
normal: [' mAm ', 'MAZAM'],
},
soundFileShoot: join(baseDir, 'sounds', 'shoot.wav'),
},
shelter: {
color: '#F83B3A',
height: 3,
width: 7,
},
})

export default Constants
14 changes: 9 additions & 5 deletions src/components/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import {
} from '../util/key-listener'
import { playSound } from '../util/sound-player'
import { Aliens } from './aliens'
import Constants from './constants'
import { GameEvent } from './game-event'
import { Gunner } from './gunner'
import type { Shape } from './shape'
import { Shelters } from './shelters'

export class Game {
static backgroundColor = '#000000'
static readonly soundFileExplosion = join(baseDir, 'sounds', 'explosion.wav')

readonly aliens: Aliens
Expand All @@ -35,13 +35,15 @@ export class Game {

constructor() {
this.events = new EventEmitter()
const canvas = createCanvas(Game.backgroundColor)
const canvas = createCanvas(Constants.game.backgroundColor)
this.canvas = canvas
this.score = 0
this.gunner = new Gunner(canvas, { bgColor: Game.backgroundColor })
this.gunner = new Gunner(canvas, {
bgColor: Constants.game.backgroundColor,
})
this.aliens = new Aliens(
canvas,
{ bgColor: Game.backgroundColor },
{ bgColor: Constants.game.backgroundColor },
this.events,
)
this.resetShelters()
Expand Down Expand Up @@ -174,6 +176,8 @@ export class Game {
}

resetShelters(): void {
this.shelters = new Shelters(this.canvas, { bgColor: Game.backgroundColor })
this.shelters = new Shelters(this.canvas, {
bgColor: Constants.game.backgroundColor,
})
}
}
19 changes: 4 additions & 15 deletions src/components/gunner.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,24 @@
import { join } from 'node:path'

import type { Canvas } from 'terminal-canvas'

import type { Explodable, Resetable, ShapeConfig, Shooterable } from '../types'
import { baseDir } from '../util/base-dir'
import { center } from '../util/helper'
import { playSound } from '../util/sound-player'
import { Bullet } from './bullet'
import Constants from './constants'
import { Shape } from './shape'

export class Gunner
extends Shape
implements Shooterable, Explodable, Resetable
{
static readonly contents = {
exploded: [
[" ,' % ", ' ;&+,! '],
[' -,+$! ', ' + ^~ '],
],
normal: [' mAm ', 'MAZAM'],
}
static readonly soundFileShoot = join(baseDir, 'sounds', 'shoot.wav')

readonly bullets: Bullet[] = []

firingBullet = false

constructor(canvas: Canvas, config: Pick<ShapeConfig, 'bgColor'>) {
super(canvas, {
...config,
contents: [Gunner.contents.normal],
contents: [Constants.gunner.contents.normal],
fgColor: '#EBDF64',
height: 2,
width: 5,
Expand All @@ -39,7 +28,7 @@ export class Gunner
}

explode(): void {
this.setContents(Gunner.contents.exploded)
this.setContents(Constants.gunner.contents.exploded)
this.draw({ blink: true })
}

Expand All @@ -52,7 +41,7 @@ export class Gunner
if (this.firingBullet) {
return false
}
playSound(Gunner.soundFileShoot)
playSound(Constants.gunner.soundFileShoot)
this.firingBullet = true
const bullet = new Bullet(this.canvas, 'up', {
bgColor: this.bgColor,
Expand Down
11 changes: 4 additions & 7 deletions src/components/shelter.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import type { Canvas } from 'terminal-canvas'

import type { Plan, Shapeable, ShapeConfig } from '../types'
import Constants from './constants'
import { Shape } from './shape'

export class Shelter implements Shapeable {
static color = '#F83B3A'
static readonly height = 3
static readonly width = 7

readonly parts: Map<string, Shape>

constructor(canvas: Canvas, config: Pick<ShapeConfig, 'bgColor' | 'x'>) {
this.parts = new Map<string, Shape>()
const content = ['/MMMMM\\', 'MMMMMMM', 'MMM MMM']
Array.from(Array(Shelter.height)).forEach((_heightItem, dy) => {
Array.from(Array(Constants.shelter.height)).forEach((_heightItem, dy) => {
const partY = Math.round(canvas.height - 10 + dy)
Array.from(Array(Shelter.width)).forEach((_widthItem, dx) => {
Array.from(Array(Constants.shelter.width)).forEach((_widthItem, dx) => {
const partX = Math.round(config.x + dx)
const part = new Shape(canvas, {
bgColor: config.bgColor,
contents: [[Shape.getContentChar(content, dx, dy)]],
fgColor: Shelter.color,
fgColor: Constants.shelter.color,
height: 1,
width: 1,
x: partX,
Expand Down
3 changes: 2 additions & 1 deletion src/components/shelters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Canvas } from 'terminal-canvas'

import type { Plan, Shapeable, ShapeConfig } from '../types'
import { mapIterate } from '../util/helper'
import Constants from './constants'
import { Shelter } from './shelter'

export class Shelters implements Shapeable {
Expand All @@ -13,7 +14,7 @@ export class Shelters implements Shapeable {
const hSpace = Math.round((canvas.width - 2 * hMargin) / noItems)
this.items = mapIterate(noItems, (colIndex) => {
const x = Math.round(
hMargin + colIndex * hSpace + hSpace / 2 - Shelter.width / 2,
hMargin + colIndex * hSpace + hSpace / 2 - Constants.shelter.width / 2,
)
return new Shelter(canvas, {
x,
Expand Down

0 comments on commit cc9124b

Please sign in to comment.