90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
import Crack from "./crack"
|
|
|
|
export default class State {
|
|
readonly canvas: HTMLCanvasElement
|
|
readonly maxCracks: number
|
|
readonly grid: number[][]
|
|
colors: number[]
|
|
seeds: {x: number, y: number}[]
|
|
cracks: Crack[]
|
|
colorIndex: number = 0
|
|
|
|
constructor(colors: number[], maxCracks: number, canvas: HTMLCanvasElement) {
|
|
this.canvas = canvas
|
|
this.maxCracks = maxCracks
|
|
this.grid = []
|
|
this.colors = colors
|
|
this.cracks = []
|
|
this.seeds = []
|
|
|
|
this.init()
|
|
}
|
|
|
|
init(colors?: number[]) {
|
|
if (colors) this.colors = colors
|
|
this.cracks.length = 0
|
|
this.grid.length = 0
|
|
this.seeds.length = 0
|
|
this.colorIndex = 0
|
|
|
|
const height = this.canvas.height
|
|
const width = this.canvas.width
|
|
const context = this.canvas.getContext("2d")
|
|
context.fillStyle = "rgb(255 255 255 / 95%)"
|
|
context.fillRect(0, 0, width, height)
|
|
|
|
for (let x = 0; x < width; x++) {
|
|
this.grid[x] = []
|
|
|
|
for (let y = 0; y < height; y++) {
|
|
this.grid[x][y] = 10001
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < 3; i++) {
|
|
const x = Math.floor(Math.random() * width)
|
|
const y = Math.floor(Math.random() * height)
|
|
const angle = Math.floor(Math.random() * 360)
|
|
this.cracks.push(new Crack(this, x, y, angle))
|
|
this.grid[x][y] = angle
|
|
}
|
|
}
|
|
|
|
addCrack() {
|
|
if (this.cracks.length >= this.maxCracks) return
|
|
|
|
const {x, y, angle} = this.getNewEntry()
|
|
this.cracks.push(new Crack(this, x, y, angle))
|
|
}
|
|
|
|
getNextColor(): number {
|
|
return this.colors[this.colorIndex++ % this.colors.length]
|
|
}
|
|
|
|
isWithinBoundary(x: number, y: number): boolean {
|
|
return x >= 0 && x < this.canvas.width && y >= 0 && y < this.canvas.height
|
|
}
|
|
|
|
getNewEntry(): {x: number, y: number, angle: number} {
|
|
if (!this.seeds.length) {
|
|
const x = Math.floor(Math.random() * this.canvas.width)
|
|
const y = Math.floor(Math.random() * this.canvas.height)
|
|
let angle = this.grid[x][y]
|
|
|
|
if (angle > 10000) {
|
|
angle = Math.floor(Math.random() * 360)
|
|
this.grid[x][y] = angle
|
|
}
|
|
|
|
return {x, y, angle}
|
|
}
|
|
|
|
const randomIndex = Math.floor(Math.random() * this.seeds.length)
|
|
const entry = this.seeds.splice(randomIndex, 1)[0]
|
|
return {
|
|
x: entry.x,
|
|
y: entry.y,
|
|
angle: this.grid[entry.x][entry.y]
|
|
}
|
|
}
|
|
} |