Started city builder like game

Signed-off-by: Avior <github@avior.me>
This commit is contained in:
2022-09-05 00:43:12 +02:00
parent 79b74d16d5
commit 2143f9887e
15 changed files with 296 additions and 21 deletions

View File

@ -5,9 +5,9 @@ import Vector2D from '../Vector2D'
export default class PointDebugger extends Component2D {
public constructor(point: Vector2D, color = 'red') {
super()
this.scale = new Vector2D(.1, .1)
this.scale = new Vector2D(1, 1)
this.position = point
console.log('Debugging point at location', point)
// console.log('Debugging point at location', point)
// this.origin = component.origin
this.renderer = new RectRenderer(this, {material: color})
}

View File

@ -25,10 +25,24 @@ export default class Vector2D {
)
}
public div(v: number): Vector2D {
return new Vector2D(
this.x / v,
this.y / v
)
}
public isIn(topLeft: Vector2D, bottomRight: Vector2D): boolean {
return this.x >= topLeft.x &&
this.y >= topLeft.y &&
this.x <= bottomRight.x &&
this.y <= bottomRight.y
}
public decimalCount(nDecimal: number) {
return new Vector2D(
parseFloat(this.x.toFixed(nDecimal)),
parseFloat(this.y.toFixed(nDecimal))
)
}
}

View File

@ -6,13 +6,13 @@ import Renderer from '.'
interface Params {
material?: string | Asset
stroke?: string
stroke?: string | {color: string, width: number}
}
export default class RectRenderer extends Renderer implements Params {
public material?: string | Asset
public stroke?: string
public stroke?: string | {color: string, width: number}
public constructor(component: Component2D, params?: Params) {
super(component)
@ -45,7 +45,12 @@ export default class RectRenderer extends Renderer implements Params {
ctx.fillRect(...item)
}
if (this.stroke) {
ctx.strokeStyle = this.stroke
if (typeof this.stroke === 'string') {
ctx.strokeStyle = this.stroke
} else {
ctx.strokeStyle = this.stroke.color
ctx.lineWidth = this.stroke.width
}
ctx.strokeRect(...item)
}
}

View File

@ -11,6 +11,8 @@ export default class TextRenderer extends Renderer {
public text?: string
public size?: number
public weight?: 'bold'
public color?: string
public constructor(component: Component2D, params?: Params) {
super(component)
@ -31,10 +33,11 @@ export default class TextRenderer extends Renderer {
// console.log
if (this.text) {
ctx.fillStyle = 'black'
ctx.textBaseline = 'top'
ctx.fillStyle = this.color ?? 'black'
ctx.textBaseline = 'middle'
ctx.textAlign = 'center'
ctx.font = `${size}px sans-serif`
ctx.font = `${this.weight ? `${this.weight} ` : ''}${size + (this.size ?? 0)}px sans-serif`
ctx.fillText(this.text, ...item)
}
}

View File

@ -10,7 +10,11 @@ export default abstract class Renderer {
protected getPosition(): Vector2D {
const ge = GameEngine.getGameEngine()
const realPosition = ge.currentScene!.camera.topLeft.sum(this.component.position)
const realPosition = ge.currentScene?.camera.topLeft.sum(this.component.position)
if (!realPosition) {
console.error('no camera?!?')
return this.component.position
}
return new Vector2D(
realPosition.x - this.component.scale.x / 2 - this.component.origin.x,
realPosition.y - this.component.scale.y / 2 - this.component.origin.y

View File

@ -1,5 +1,4 @@
import GameEngine from 'GameEngine'
import AssetsManager from './Asset'
import Camera from './Components/Camera'
import Component2D, { ComponentState } from './Component2D'
@ -13,6 +12,7 @@ export default class Scene {
private components: Array<Component2D> = []
private ge!: GameEngine
private hasClickedComponent: number | undefined
public constructor(sceneId: string) {
@ -37,8 +37,9 @@ export default class Scene {
}
public async update() {
for (const component of this.components) {
await this.updateComponent(component)
for (let index = 0; index < this.components.length; index++) {
const component = this.components[index];
await this.updateComponent(component, index)
}
}
@ -48,7 +49,7 @@ export default class Scene {
}
}
private async updateComponent(v: Component2D) {
private async updateComponent(v: Component2D, index: number) {
const debug = v.debug
if (debug) {
console.log('Processing Component', v)
@ -56,11 +57,20 @@ export default class Scene {
const state: Partial<ComponentState> = {}
// const width = (v.width() ?? 1) * this.ge.caseSize[0]
// const height = (v.height() ?? 1) * this.ge.caseSize[1]
if (v.collider && v.collider.type === 'click' && this.ge.cursor.isDown && !this.ge.cursor.wasDown) {
if (v.collider && v.collider.type === 'click' && (this.hasClickedComponent === index || !this.hasClickedComponent)) {
if (v.collider.pointColliding(this.ge.cursor.position, 'click')) {
state.isColliding = 'click'
if (this.ge.cursor.isDown && !this.ge.cursor.wasDown) {
state.isColliding = 'click'
this.hasClickedComponent = index
} else if (this.ge.cursor.isDown) {
state.isColliding = 'down'
this.hasClickedComponent = index
}
}
}
if (this.hasClickedComponent === index && !state.isColliding) {
this.hasClickedComponent = undefined
}
// if (v.pos) {
// const ax = v.pos.x * this.ge.caseSize[0]
// const ay = v.pos.y * this.ge.caseSize[1]

View File

@ -93,9 +93,11 @@ export default class GameEngine {
}
})
document.addEventListener('mousedown', () => {
console.log('cursor down')
this.cursor.isDown = true
})
document.addEventListener('mouseup', () => {
console.log('cursor up')
this.cursor.isDown = false
this.cursor.wasDown = false
})