mirror of
https://github.com/Aviortheking/games.git
synced 2025-04-22 19:02:09 +00:00
feat: Upgraded Engine
Signed-off-by: Avior <f.bouillon@aptatio.com>
This commit is contained in:
parent
bfd4beeaa4
commit
26df50c4a8
5
next-env.d.ts
vendored
5
next-env.d.ts
vendored
@ -1,2 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
|
@ -19,5 +19,5 @@ module.exports = withPlugins([
|
||||
}
|
||||
}]
|
||||
],
|
||||
nextConfig
|
||||
//nextConfig
|
||||
)
|
||||
|
15143
package-lock.json
generated
15143
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
51
package.json
51
package.json
@ -10,32 +10,33 @@
|
||||
"test": "jest --config jext.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dzeio/components": "^0.10.1",
|
||||
"@dzeio/object-util": "^1.2.0",
|
||||
"critters": "^0.0.10",
|
||||
"easy-sitemap": "^1.0.0",
|
||||
"next": "^11.0.0",
|
||||
"next-compose-plugins": "^2.2.0",
|
||||
"next-plausible": "^1.6.1",
|
||||
"next-pre-css": "^1.0.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-feather": "^2.0.9",
|
||||
"stylus": "^0.54.7",
|
||||
"stylus-loader": "^6.0.0",
|
||||
"typescript": "^4.1.3",
|
||||
"webpack": "^5.37.1"
|
||||
"@dzeio/components": "^1.0.0-beta.10",
|
||||
"@dzeio/listener": "^1.0.3",
|
||||
"@dzeio/object-util": "^1",
|
||||
"critters": "^0.0.16",
|
||||
"easy-sitemap": "^1",
|
||||
"lucide-react": "^0.102.0",
|
||||
"next": "^12",
|
||||
"next-compose-plugins": "^2",
|
||||
"next-plausible": "^3",
|
||||
"next-pre-css": "https://github.com/tcgdex/next-pre-css.git",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"stylus": "^0.59.0",
|
||||
"stylus-loader": "^7",
|
||||
"typescript": "^4",
|
||||
"webpack": "^5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.8.7",
|
||||
"@types/favicons": "^6.2.0",
|
||||
"@types/node": "^15.6.0",
|
||||
"@types/react": "^17.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.14.1",
|
||||
"@typescript-eslint/parser": "^4.14.1",
|
||||
"eslint": "^7.1.0",
|
||||
"eslint-config-next": "^10.2.2",
|
||||
"eslint-plugin-react": "^7.18.3",
|
||||
"ts-node": "^9.1.1"
|
||||
"@babel/core": "^7",
|
||||
"@types/favicons": "^6",
|
||||
"@types/node": "^18",
|
||||
"@types/react": "18.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5",
|
||||
"@typescript-eslint/parser": "^5",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "^12",
|
||||
"eslint-plugin-react": "^7",
|
||||
"ts-node": "^10"
|
||||
}
|
||||
}
|
||||
|
42
src/GameEngine/2D/Collider/BoxCollider2D.ts
Normal file
42
src/GameEngine/2D/Collider/BoxCollider2D.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import Collider from '.'
|
||||
import Vector2D from '../Vector2D'
|
||||
|
||||
export default class BoxCollider2D extends Collider<{
|
||||
center?: Vector2D
|
||||
scale?: Vector2D
|
||||
}> {
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns [Vector2D, Vector2D, Vector2D, Vector2D] the four points of the box collider
|
||||
*/
|
||||
public pos(): [Vector2D, Vector2D, Vector2D, Vector2D] {
|
||||
const middle = this.component.getAbsolutePosition(false).sum(this.component.scale.x / 2, this.component.scale.y / 2)
|
||||
const topLeft = this.applyRotation(this.component.getAbsolutePosition(false), middle, this.component.rotation)
|
||||
const topRight = this.applyRotation(topLeft.sum(this.component.scale.x, 0), middle, this.component.rotation)
|
||||
const bottomLeft = this.applyRotation(topLeft.sum(0, this.component.scale.y), middle, this.component.rotation)
|
||||
const bottomRight = this.applyRotation(topLeft.sum(this.component.scale), middle, this.component.rotation)
|
||||
|
||||
return [
|
||||
topLeft,
|
||||
topRight,
|
||||
bottomLeft,
|
||||
bottomRight
|
||||
]
|
||||
}
|
||||
|
||||
private applyRotation(point: Vector2D, middle: Vector2D, rotation: number) {
|
||||
if (rotation === 0) {
|
||||
return point.clone()
|
||||
}
|
||||
|
||||
// FIXME: Fix rotation not returning the correct points for points other than topleft
|
||||
return point.clone()
|
||||
const rot = rotation * (Math.PI / 180)
|
||||
const tmp = point.clone().sum(-middle.x, -middle.y)
|
||||
return new Vector2D(
|
||||
middle.x + (tmp.x * Math.cos(rot) - tmp.y * Math.sin(rot)),
|
||||
middle.y + (tmp.x * Math.sin(rot) + tmp.y * Math.cos(rot))
|
||||
)
|
||||
}
|
||||
}
|
105
src/GameEngine/2D/Collider/Checker.ts
Normal file
105
src/GameEngine/2D/Collider/Checker.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import Collider from '.'
|
||||
import Vector2D from '../Vector2D'
|
||||
import BoxCollider2D from './BoxCollider2D'
|
||||
import Circlecollider2D from './CircleCollider2D'
|
||||
import PointCollider2D from './PointCollider2D'
|
||||
|
||||
export default class Checker {
|
||||
public static boxCircleCollision(box: BoxCollider2D, circle: Circlecollider2D): boolean {
|
||||
// clamp(value, min, max) - limits value to the range min..max
|
||||
|
||||
// Find the closest point to the circle within the rectangle
|
||||
const [topLeft, bottomRight] = box.pos()
|
||||
const center = circle.center()
|
||||
const radius = circle.radius()
|
||||
const closestX = this.clamp(center.x, topLeft.x, bottomRight.x)
|
||||
const closestY = this.clamp(center.y, topLeft.y, bottomRight.y)
|
||||
|
||||
// Calculate the distance between the circle's center and this closest point
|
||||
const distanceX = center.x - closestX
|
||||
const distanceY = center.y - closestY
|
||||
|
||||
// If the distance is less than the circle's radius, an intersection occurs
|
||||
const distanceSquared = distanceX * distanceX + distanceY * distanceY
|
||||
return distanceSquared < radius * radius
|
||||
}
|
||||
|
||||
public static circleCircleCollision(circle1: Circlecollider2D, circle2: Circlecollider2D) {
|
||||
return false
|
||||
}
|
||||
|
||||
public static pointBoxCollision(box1: PointCollider2D, box2: BoxCollider2D) {
|
||||
const [topLeft, , , bottomRight] = box2.pos()
|
||||
return box1.pos().isIn(topLeft, bottomRight)
|
||||
}
|
||||
|
||||
/**
|
||||
* dumb way to check currntly
|
||||
*
|
||||
* TODO: Handle rotation
|
||||
*/
|
||||
public static boxBoxCollision(box1: BoxCollider2D, box2: BoxCollider2D): boolean {
|
||||
|
||||
const selfPos = box1.pos()
|
||||
const otherPos = box2.pos()
|
||||
|
||||
return selfPos[3].x >= otherPos[0].x && // self bottom higher than other top
|
||||
selfPos[0].x <= otherPos[3].x &&
|
||||
selfPos[3].y >= otherPos[0].y &&
|
||||
selfPos[0].y <= otherPos[3].y
|
||||
|
||||
// const b1 = box1.pos()
|
||||
// const b2 = box2.pos()
|
||||
// for (const box1It of b1) {
|
||||
// if (this.pointInRectangle(box1It, b2)) {
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
|
||||
// return false
|
||||
}
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
public static detectCollision(collider1: Collider, collider2: Collider, reverse = false): boolean {
|
||||
if (collider1 instanceof BoxCollider2D && collider2 instanceof Circlecollider2D) {
|
||||
return this.boxCircleCollision(collider1, collider2)
|
||||
} else if (collider1 instanceof Circlecollider2D && collider2 instanceof Circlecollider2D) {
|
||||
return this.circleCircleCollision(collider2, collider1)
|
||||
} else if (collider1 instanceof BoxCollider2D && collider2 instanceof BoxCollider2D) {
|
||||
return this.boxBoxCollision(collider2, collider1)
|
||||
} else if (collider1 instanceof BoxCollider2D && collider2 instanceof PointCollider2D) {
|
||||
return this.pointBoxCollision(collider2, collider1)
|
||||
}
|
||||
|
||||
if (!reverse) {
|
||||
return this.detectCollision(collider2, collider1, true)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private static clamp(value: number, min: number, max: number) {
|
||||
return min > value ? min : max < value ? max : value
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME: does not work perfecly
|
||||
*
|
||||
* @param point the point to check
|
||||
* @param rectangle the rectangle in which to check
|
||||
* @returns if the point is in the defined rectangle or not
|
||||
*/
|
||||
private static pointInRectangle(point: Vector2D, rectangle: [Vector2D, Vector2D, Vector2D, Vector2D]) {
|
||||
const ab = rectangle[1].sum(-rectangle[0].x, -rectangle[0].y)
|
||||
const ad = rectangle[3].sum(-rectangle[0].x, -rectangle[0].y)
|
||||
const am = point.sum(-rectangle[0].x, -rectangle[0].y)
|
||||
|
||||
const abam = ab.x * am.x + ab.y * am.y
|
||||
const abab = ab.x * ab.x + ab.y * ab.y
|
||||
const amad = am.x * ad.x + am.y * ad.y
|
||||
const adad = ad.x * ad.x + ad.y * ad.y
|
||||
|
||||
return 0 <= abam && abam <= abab &&
|
||||
0 <= amad && amad <= adad
|
||||
}
|
||||
}
|
16
src/GameEngine/2D/Collider/CircleCollider2D.ts
Normal file
16
src/GameEngine/2D/Collider/CircleCollider2D.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import Collider from '.'
|
||||
import Vector2D from '../Vector2D'
|
||||
|
||||
export default class Circlecollider2D extends Collider<{
|
||||
radius?: number
|
||||
offset?: Vector2D
|
||||
}> {
|
||||
|
||||
public center(): Vector2D {
|
||||
return new Vector2D(0)
|
||||
}
|
||||
|
||||
public radius(): number {
|
||||
return this.params.radius ?? 0
|
||||
}
|
||||
}
|
16
src/GameEngine/2D/Collider/PointCollider2D.ts
Normal file
16
src/GameEngine/2D/Collider/PointCollider2D.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import Collider from '.'
|
||||
import Vector2D from '../Vector2D'
|
||||
|
||||
export default class PointCollider2D extends Collider<{
|
||||
center?: Vector2D
|
||||
scale?: Vector2D
|
||||
}> {
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns Vector2D the position of the point
|
||||
*/
|
||||
public pos(): Vector2D {
|
||||
return this.component.getAbsolutePosition()
|
||||
}
|
||||
}
|
17
src/GameEngine/2D/Collider/index.ts
Normal file
17
src/GameEngine/2D/Collider/index.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import Component2D from 'GameEngine/Component2D'
|
||||
|
||||
export default abstract class Collider<
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
T extends {} | void = {} | void
|
||||
> {
|
||||
|
||||
public component!: Component2D
|
||||
|
||||
protected params: T = {} as T
|
||||
|
||||
public constructor(it: T | void) {
|
||||
if (it) {
|
||||
this.params = it
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
import GameEngine from 'GameEngine'
|
||||
import Component2D from 'GameEngine/Component2D'
|
||||
import Vector2D from '../Vector2D'
|
||||
|
||||
type BuiltinCollisionTypes = 'click' | 'pointerDown' | 'pointerUp'
|
||||
|
||||
export default class BoxCollider2D {
|
||||
public constructor(
|
||||
private component: Component2D,
|
||||
public type: BuiltinCollisionTypes | string = 'collision',
|
||||
private center = new Vector2D(0, 0),
|
||||
private scale = new Vector2D(1, 1)
|
||||
) {}
|
||||
|
||||
public pointColliding(point: Vector2D, type: BuiltinCollisionTypes | string = 'collision'): boolean {
|
||||
if (this.type !== type) {
|
||||
return false
|
||||
}
|
||||
return point.isIn(
|
||||
...this.pos()
|
||||
)
|
||||
}
|
||||
|
||||
public pos(): [Vector2D, Vector2D] {
|
||||
const scale = this.scale.multiply(this.component.scale)
|
||||
const positionCenter = GameEngine.getGameEngine().currentScene?.position.sum(this.component.origin.sub(
|
||||
new Vector2D(
|
||||
this.component.position.x,
|
||||
this.component.position.y
|
||||
)
|
||||
)) ?? this.component.origin.sub(
|
||||
new Vector2D(
|
||||
this.component.position.x,
|
||||
this.component.position.y
|
||||
)
|
||||
)
|
||||
|
||||
const center = this.center.sum(positionCenter)
|
||||
return [new Vector2D(
|
||||
center.x,
|
||||
center.y
|
||||
),
|
||||
new Vector2D(
|
||||
center.x + scale.x,
|
||||
center.y + scale.y
|
||||
)]
|
||||
}
|
||||
|
||||
public collideWith(collider: BoxCollider2D) {
|
||||
const selfPos = this.pos()
|
||||
const otherPos = collider.pos()
|
||||
|
||||
return selfPos[1].x >= otherPos[0].x && // self bottom higher than other top
|
||||
selfPos[0].x <= otherPos[1].x &&
|
||||
selfPos[1].y >= otherPos[0].y &&
|
||||
selfPos[0].y <= otherPos[1].y
|
||||
}
|
||||
}
|
@ -1,26 +1,29 @@
|
||||
import Component2D, { ComponentState } from 'GameEngine/Component2D'
|
||||
import RectRenderer from 'GameEngine/Renderer/RectRenderer'
|
||||
import BoxCollider2D from '../Collision/BoxCollider2D'
|
||||
import Vector2D from '../Vector2D'
|
||||
|
||||
export default class ColliderDebugger extends Component2D {
|
||||
export default class ColliderDebugger extends Component2D<{collision?: Array<string>}> {
|
||||
|
||||
public readonly name = 'ColliderDebugger'
|
||||
public constructor(component: Component2D, collider: BoxCollider2D) {
|
||||
super()
|
||||
this.collider = collider
|
||||
const [topLeft, bottomRight] = collider.pos()
|
||||
const size = topLeft.sub(bottomRight)
|
||||
this.position = topLeft
|
||||
this.scale = size
|
||||
this.origin = new Vector2D(-(this.scale.x / 2), -(this.scale.y / 2))
|
||||
this.renderer = new RectRenderer(this, {stroke: 'black'})
|
||||
|
||||
public renderer: RectRenderer = new RectRenderer(this, {stroke: 'transparent'})
|
||||
|
||||
public init() {
|
||||
if (!this.parent) {
|
||||
console.error('cant setup, no parent')
|
||||
return
|
||||
}
|
||||
this.collider = this.parent.collider
|
||||
this.position = new Vector2D(0)
|
||||
this.scale = this.parent.scale
|
||||
this.origin = this.parent.origin
|
||||
}
|
||||
|
||||
public update(state: ComponentState) {
|
||||
if (state.isColliding) {
|
||||
(this.renderer as RectRenderer).material = 'rgba(0, 255, 0, .7)'
|
||||
if (state.collideWith?.filter((it) => !this.params.collision ? true : this.params.collision.includes(it.name)).length ?? 0 > 1) {
|
||||
this.renderer.material = 'rgba(0, 255, 0, .7)'
|
||||
} else {
|
||||
(this.renderer as RectRenderer).material = undefined
|
||||
this.renderer.material = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,14 @@ export default class Vector2D {
|
||||
public y: number
|
||||
|
||||
public constructor(
|
||||
x: number,
|
||||
x: number | [number, number],
|
||||
y?: number
|
||||
) {
|
||||
if (typeof x === 'object') {
|
||||
this.x = x[0]
|
||||
this.y = x[1]
|
||||
return
|
||||
}
|
||||
this.x = x
|
||||
if (typeof y === 'number') {
|
||||
this.y = y
|
||||
@ -16,6 +21,11 @@ export default class Vector2D {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return a new vector multiplied with the current one
|
||||
* @param v vector
|
||||
* @returns a new vector
|
||||
*/
|
||||
public multiply(v: Vector2D): Vector2D {
|
||||
return new Vector2D(
|
||||
v.x * this.x,
|
||||
@ -23,6 +33,12 @@ export default class Vector2D {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* return a new vector summed with the current one
|
||||
* @param v vector or x to add
|
||||
* @param y y to add
|
||||
* @returns a new vector
|
||||
*/
|
||||
public sum(v: Vector2D | number, y?: number): Vector2D {
|
||||
if (typeof v === 'number') {
|
||||
return new Vector2D(this.x + v, this.y + (y ?? v))
|
||||
@ -109,4 +125,8 @@ export default class Vector2D {
|
||||
public equal(vector: Vector2D): boolean {
|
||||
return vector.x === this.x && vector.y === this.y
|
||||
}
|
||||
|
||||
public toArray(): [number, number] {
|
||||
return [this.x, this.y]
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ export default class Asset {
|
||||
this.image = new Image()
|
||||
this.image.src = this.path
|
||||
this.image.onload = () => {
|
||||
console.log('resource loaded', this.path, this.image.width, this.image.height)
|
||||
this.isLoaded = true
|
||||
this.status = AssetStatus.LOADED
|
||||
res()
|
||||
|
@ -1,4 +1,4 @@
|
||||
import BoxCollider2D from './2D/Collision/BoxCollider2D'
|
||||
import Collider from './2D/Collider'
|
||||
import Vector2D from './2D/Vector2D'
|
||||
import Renderer from './Renderer'
|
||||
import Scene from './Scene'
|
||||
@ -6,7 +6,7 @@ import Scene from './Scene'
|
||||
export interface ComponentState {
|
||||
mouseHovering?: boolean
|
||||
/**
|
||||
* is it is collinding return the type of collision
|
||||
* is it is colliding return the type of Collider
|
||||
*/
|
||||
isColliding?: string
|
||||
collideWith?: Array<Component2D>
|
||||
@ -16,9 +16,10 @@ export interface ComponentState {
|
||||
|
||||
export type StaticComponent<
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
T extends {} | void = {} | void
|
||||
T extends {} | void = {} | void,
|
||||
C extends Component2D<T> = Component2D<T>
|
||||
> =
|
||||
new (params: T | undefined) => Component2D<T>
|
||||
new (params: T | undefined) => C
|
||||
|
||||
/**
|
||||
* 2D Component
|
||||
@ -71,10 +72,10 @@ T extends {} | void = {} | void
|
||||
/**
|
||||
* Component collider for events
|
||||
*
|
||||
* @type {BoxCollider2D}
|
||||
* @type {Collider}
|
||||
* @memberof Component2D
|
||||
*/
|
||||
public collider?: BoxCollider2D
|
||||
public collider?: Collider
|
||||
|
||||
/**
|
||||
* Parent component of self is any
|
||||
@ -109,6 +110,11 @@ T extends {} | void = {} | void
|
||||
*/
|
||||
public debug?: boolean
|
||||
|
||||
/**
|
||||
* Component rotation in Degrees
|
||||
*/
|
||||
public rotation = 0
|
||||
|
||||
protected params: T = {} as T
|
||||
|
||||
/**
|
||||
@ -117,7 +123,7 @@ T extends {} | void = {} | void
|
||||
*/
|
||||
public abstract readonly name: string
|
||||
|
||||
public constructor(it: T) {
|
||||
public constructor(it: T | void) {
|
||||
if (it) {
|
||||
this.params = it
|
||||
}
|
||||
@ -136,14 +142,33 @@ T extends {} | void = {} | void
|
||||
|
||||
public destroy?(): Promise<void> | void
|
||||
|
||||
public getAbsolutePosition(): Vector2D {
|
||||
const realPosition = this.position.sum(
|
||||
public getAbsolutePosition(calculateRotation = true): Vector2D {
|
||||
let pos = this.position.sum(
|
||||
this.scale.multiply(this.origin)
|
||||
)
|
||||
if (!this.parent) {
|
||||
return realPosition
|
||||
|
||||
if (this.parent) {
|
||||
pos = pos.sum(this.parent.getAbsolutePosition(calculateRotation))
|
||||
}
|
||||
return realPosition.sum(this.parent.getAbsolutePosition())
|
||||
|
||||
if (this.rotation && calculateRotation) {
|
||||
const middle = pos.clone().sum(this.scale.x / 2, this.scale.y / 2)
|
||||
const rot = this.rotation * (Math.PI / 180)
|
||||
const tmp = pos.clone().sum(-middle.x, -middle.y)
|
||||
return pos.set(
|
||||
middle.x + (tmp.x * Math.cos(rot) - tmp.y * Math.sin(rot)),
|
||||
middle.y + (tmp.x * Math.sin(rot) + tmp.y * Math.cos(rot))
|
||||
)
|
||||
}
|
||||
|
||||
return pos
|
||||
}
|
||||
|
||||
public getAbsoluteRotation(): number {
|
||||
if (this.parent) {
|
||||
return this.parent.getAbsoluteRotation() + this.rotation
|
||||
}
|
||||
return this.rotation
|
||||
}
|
||||
|
||||
public setState(key: keyof ComponentState, value: any): void {
|
||||
@ -153,4 +178,8 @@ T extends {} | void = {} | void
|
||||
public updateParam(key: keyof T, value: any): void {
|
||||
this.params[key] = value
|
||||
}
|
||||
|
||||
public getParam(key: keyof T): any {
|
||||
return this.params[key]
|
||||
}
|
||||
}
|
||||
|
@ -6,15 +6,27 @@ import Cursor from './Cursor'
|
||||
/**
|
||||
* Currently not working Camera implementation
|
||||
*/
|
||||
export default class Camera extends Component2D {
|
||||
export default class Camera extends Component2D<{
|
||||
position?: Vector2D
|
||||
zoom?: number
|
||||
}> {
|
||||
public name = 'Camera'
|
||||
public position: Vector2D = new Vector2D(0)
|
||||
|
||||
public zoom = 1
|
||||
|
||||
public init(): void | Promise<void> {
|
||||
if (this.params.position) {
|
||||
this.position = this.params.position
|
||||
}
|
||||
if (this.params.zoom) {
|
||||
this.setZoom(this.params.zoom)
|
||||
}
|
||||
}
|
||||
|
||||
public update() {
|
||||
let needCursorUpdate = false
|
||||
const scene = GameEngine.getGameEngine().currentScene
|
||||
const scene = GameEngine.getGameEngine()?.currentScene
|
||||
if (!scene) {
|
||||
return
|
||||
}
|
||||
@ -42,4 +54,14 @@ export default class Camera extends Component2D {
|
||||
public setZoom(value: number) {
|
||||
this.zoom = value
|
||||
}
|
||||
|
||||
public addToZoom(value: number, min?: number, max?: number) {
|
||||
this.zoom += value
|
||||
if (min && min > this.zoom) {
|
||||
this.zoom = min
|
||||
}
|
||||
if (max && max < this.zoom) {
|
||||
this.zoom = max
|
||||
}
|
||||
}
|
||||
}
|
||||
|
36
src/GameEngine/Components/ComponentRenderer.ts
Normal file
36
src/GameEngine/Components/ComponentRenderer.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import Vector2D from 'GameEngine/2D/Vector2D'
|
||||
import Component2D from 'GameEngine/Component2D'
|
||||
import Renderer from 'GameEngine/Renderer'
|
||||
|
||||
export default class ComponentRenderer extends Component2D<{
|
||||
renderer?: Renderer
|
||||
position?: Vector2D
|
||||
scale?: Vector2D
|
||||
name?: string
|
||||
}> {
|
||||
|
||||
public name = 'ComponentRenderer'
|
||||
|
||||
public update(): void | Promise<void> {
|
||||
if (this.params.renderer) {
|
||||
this.renderer = this.params.renderer
|
||||
}
|
||||
|
||||
if (this.params.name) {
|
||||
this.name = this.params.name
|
||||
}
|
||||
|
||||
if (this.params.position) {
|
||||
this.position = this.params.position
|
||||
}
|
||||
|
||||
if (this.params.scale) {
|
||||
this.scale = this.params.scale
|
||||
}
|
||||
}
|
||||
|
||||
public updateRenderer(key: string, value: any) {
|
||||
(this.renderer as any)[key as any] = value
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
import GameEngine from 'GameEngine'
|
||||
import BoxCollider2D from 'GameEngine/2D/Collision/BoxCollider2D'
|
||||
import PointCollider2D from 'GameEngine/2D/Collider/PointCollider2D'
|
||||
import Vector2D from 'GameEngine/2D/Vector2D'
|
||||
import Component2D from 'GameEngine/Component2D'
|
||||
import RectRenderer from 'GameEngine/Renderer/RectRenderer'
|
||||
import Camera from './Camera'
|
||||
|
||||
export default class Cursor extends Component2D<{
|
||||
debug?: boolean
|
||||
@ -28,7 +29,9 @@ export default class Cursor extends Component2D<{
|
||||
|
||||
public scale: Vector2D = new Vector2D(1)
|
||||
|
||||
public collider: BoxCollider2D = new BoxCollider2D(this)
|
||||
public collider: PointCollider2D = new PointCollider2D()
|
||||
|
||||
private touchZoom = 0
|
||||
|
||||
/**
|
||||
* event handled down event
|
||||
@ -91,14 +94,35 @@ export default class Cursor extends Component2D<{
|
||||
this.onUp(ev)
|
||||
}
|
||||
|
||||
|
||||
private onTouchMove = (ev: TouchEvent) => {
|
||||
// console.log('onTouchMove')
|
||||
this.onMove(ev.touches.item(0) ?? undefined)
|
||||
if (ev.touches.length >= 2) {
|
||||
const cam = GameEngine.getGameEngine().currentScene?.getComponents().find((it) => it.name === 'Camera') as Camera | undefined
|
||||
if (!cam) {
|
||||
return
|
||||
}
|
||||
|
||||
const nv = Math.hypot(
|
||||
ev.touches[0].pageX - ev.touches[1].pageX,
|
||||
ev.touches[0].pageY - ev.touches[1].pageY
|
||||
)
|
||||
|
||||
cam.addToZoom(-((this.touchZoom - nv) / 100), 1)
|
||||
this.touchZoom = nv
|
||||
}
|
||||
}
|
||||
|
||||
private onTouchStart = (ev: TouchEvent) => {
|
||||
// console.log('onTouchStart')
|
||||
this.onDown(ev.touches.item(0) ?? undefined)
|
||||
if (ev.touches.length >= 2) {
|
||||
this.touchZoom = Math.hypot(
|
||||
ev.touches[0].pageX - ev.touches[1].pageX,
|
||||
ev.touches[0].pageY - ev.touches[1].pageY
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private onTouchEnd = (ev: TouchEvent) => {
|
||||
@ -122,7 +146,7 @@ export default class Cursor extends Component2D<{
|
||||
* Catch the onDown events
|
||||
*/
|
||||
private onDown(ev?: MouseEvent | Touch) {
|
||||
console.log('cursor down')
|
||||
// console.log('cursor down')
|
||||
if (ev) {
|
||||
this.updatePosition(
|
||||
ev.clientX ?? 0,
|
||||
@ -136,7 +160,7 @@ export default class Cursor extends Component2D<{
|
||||
* catch the onUp events
|
||||
*/
|
||||
private onUp(ev?: MouseEvent | Touch) {
|
||||
console.log('cursor up')
|
||||
// console.log('cursor up')
|
||||
if (ev) {
|
||||
this.updatePosition(
|
||||
ev.clientX ?? 0,
|
||||
@ -146,8 +170,12 @@ export default class Cursor extends Component2D<{
|
||||
this.eventDown = false
|
||||
}
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
private updatePosition(clientX: number, clientY: number) {
|
||||
const ge = GameEngine.getGameEngine()
|
||||
if (!ge) {
|
||||
return
|
||||
}
|
||||
this.oldPosition = [clientX, clientY]
|
||||
this.position.set(
|
||||
((clientX ?? 0) + window.scrollX - ge.canvas.offsetLeft) /
|
||||
|
@ -7,6 +7,7 @@ import Renderer from '.'
|
||||
interface Params {
|
||||
asset?: Asset
|
||||
stream?: boolean
|
||||
imageRotation?: number
|
||||
debug?: boolean
|
||||
}
|
||||
|
||||
@ -17,13 +18,15 @@ export default class ImageRenderer extends Renderer implements Params {
|
||||
|
||||
public asset?: Asset
|
||||
public stream = true
|
||||
public imageRotation = 0
|
||||
public debug = false
|
||||
|
||||
public constructor(component: Component2D, params?: Params) {
|
||||
super(component)
|
||||
objectLoop(params ?? {}, (value, key) => {this[key as keyof Params] = value})
|
||||
objectLoop(params ?? {}, (value, key) => {this[key as 'stream'] = value as any})
|
||||
}
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
public async render(ge: GameEngine, ctx: CanvasRenderingContext2D) {
|
||||
|
||||
if (!this.asset) {
|
||||
@ -44,15 +47,9 @@ export default class ImageRenderer extends Renderer implements Params {
|
||||
return
|
||||
}
|
||||
|
||||
const globalScale = ge.currentScene?.scale ?? 1
|
||||
const size = this.asset.size()
|
||||
const position = this.getPosition()
|
||||
const final: [number, number, number, number] = [
|
||||
position.x * ge.caseSize.x * globalScale,
|
||||
position.y * ge.caseSize.y * globalScale,
|
||||
(this.component.scale.x ?? ge.caseSize.x) * ge.caseSize.x * globalScale,
|
||||
(this.component.scale.y ?? ge.caseSize.y) * ge.caseSize.y * globalScale
|
||||
]
|
||||
const final = this.preRender(ctx, ge, this.imageRotation)
|
||||
|
||||
if (this.debug || this.component.debug) {
|
||||
ctx.fillStyle = 'red'
|
||||
ctx.fillRect(...final)
|
||||
@ -65,5 +62,7 @@ export default class ImageRenderer extends Renderer implements Params {
|
||||
size.y,
|
||||
...final
|
||||
)
|
||||
|
||||
this.postRender(ctx, ge)
|
||||
}
|
||||
}
|
||||
|
@ -17,22 +17,11 @@ export default class RectRenderer extends Renderer implements Params {
|
||||
|
||||
public constructor(component: Component2D, params?: Params) {
|
||||
super(component)
|
||||
objectLoop(params ?? {}, (value, key) => {this[key as 'material'] = value})
|
||||
objectLoop(params ?? {}, (value, key) => {this[key] = value as any})
|
||||
}
|
||||
|
||||
public async render(ge: GameEngine, ctx: CanvasRenderingContext2D) {
|
||||
const position = this.getPosition()
|
||||
const globalScale = ge.currentScene?.scale ?? 1
|
||||
const item: [number, number, number, number] = [
|
||||
// source x
|
||||
position.x * ge.caseSize.x * globalScale,
|
||||
// source y
|
||||
position.y * ge.caseSize.y * globalScale,
|
||||
// size X
|
||||
this.component.scale.x * ge.caseSize.x * globalScale,
|
||||
// size Y
|
||||
this.component.scale.y * ge.caseSize.y * globalScale
|
||||
]
|
||||
const item = this.preRender(ctx, ge)
|
||||
|
||||
if (this.material) {
|
||||
ctx.fillStyle = this.material
|
||||
@ -57,5 +46,7 @@ export default class RectRenderer extends Renderer implements Params {
|
||||
}
|
||||
ctx.strokeRect(...item)
|
||||
}
|
||||
|
||||
this.postRender(ctx, ge)
|
||||
}
|
||||
}
|
||||
|
@ -23,44 +23,42 @@ export default class TextRenderer extends Renderer implements Params {
|
||||
|
||||
public constructor(component: Component2D, params?: Params) {
|
||||
super(component)
|
||||
objectLoop(params ?? {}, (v, k) => {this[k as 'text'] = v})
|
||||
objectLoop(params ?? {}, (value, key) => {this[key] = value as any})
|
||||
}
|
||||
|
||||
public async render(ge: GameEngine, ctx: CanvasRenderingContext2D) {
|
||||
const position = this.getPosition()
|
||||
const globalScale = ge.currentScene?.scale ?? 1
|
||||
const item: [number, number] = [
|
||||
// source x
|
||||
// 0 - 1.5 - -1.5
|
||||
position.x * ge.caseSize.x * globalScale,
|
||||
// source y
|
||||
position.y * ge.caseSize.y * globalScale
|
||||
]
|
||||
const item = this.preRender(ctx, ge)
|
||||
|
||||
const size = this.component.scale.y * ge.caseSize.y
|
||||
|
||||
// console.log
|
||||
if (this.text) {
|
||||
ctx.textBaseline = 'top'
|
||||
ctx.textAlign = 'left'
|
||||
if (!this.text) {
|
||||
if (this.debug) {
|
||||
console.warn('no text, no display')
|
||||
|
||||
ctx.font = `${this.weight ? `${this.weight} ` : ''}${(this.size ?? size) / 16 * ge.caseSize.x * globalScale * 3}px sans-serif`
|
||||
if (this.color) {
|
||||
ctx.fillStyle = this.color ?? 'black'
|
||||
ctx.fillText(this.text, ...item)
|
||||
}
|
||||
if (this.stroke) {
|
||||
if (typeof this.stroke === 'string') {
|
||||
ctx.strokeStyle = this.stroke
|
||||
ctx.lineWidth = ge.currentScene?.scale ?? 1
|
||||
} else {
|
||||
ctx.strokeStyle = this.stroke.color
|
||||
ctx.lineWidth = this.stroke.width * (ge.currentScene?.scale ?? 1)
|
||||
}
|
||||
ctx.strokeText(this.text, ...item)
|
||||
}
|
||||
} else if (this.debug) {
|
||||
console.warn('no text, no display')
|
||||
return
|
||||
}
|
||||
|
||||
ctx.textBaseline = 'top'
|
||||
ctx.textAlign = 'left'
|
||||
|
||||
ctx.font = `${this.weight ? `${this.weight} ` : ''}${(this.size ?? size) / 16 * ge.caseSize.x * globalScale * 3}px sans-serif`
|
||||
if (this.color) {
|
||||
ctx.fillStyle = this.color ?? 'black'
|
||||
ctx.fillText(this.text, item[0], item[1])
|
||||
}
|
||||
if (this.stroke) {
|
||||
if (typeof this.stroke === 'string') {
|
||||
ctx.strokeStyle = this.stroke
|
||||
ctx.lineWidth = ge.currentScene?.scale ?? 1
|
||||
} else {
|
||||
ctx.strokeStyle = this.stroke.color
|
||||
ctx.lineWidth = this.stroke.width * (ge.currentScene?.scale ?? 1)
|
||||
}
|
||||
ctx.strokeText(this.text, item[0], item[1])
|
||||
}
|
||||
|
||||
this.postRender(ctx, ge)
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ export default class TileRenderer extends Renderer implements Params {
|
||||
|
||||
public constructor(component: Component2D, params?: Params) {
|
||||
super(component)
|
||||
objectLoop(params ?? {}, (value, key) => {this[key as 'id'] = value})
|
||||
objectLoop(params ?? {}, (value, key) => {this[key] = value as any})
|
||||
}
|
||||
|
||||
public async render(ge: GameEngine, ctx: CanvasRenderingContext2D) {
|
||||
|
@ -8,9 +8,10 @@ export default abstract class Renderer {
|
||||
protected component: Component2D
|
||||
) {}
|
||||
|
||||
protected getPosition(): Vector2D {
|
||||
protected getPosition(component?: Component2D): Vector2D {
|
||||
|
||||
const ge = GameEngine.getGameEngine()
|
||||
const realPosition = this.component.getAbsolutePosition().sum(
|
||||
const realPosition = (component ?? this.component).getAbsolutePosition().sum(
|
||||
-(ge.currentScene?.position?.x ?? 0),
|
||||
-(ge.currentScene?.position?.y ?? 0)
|
||||
)
|
||||
@ -18,5 +19,96 @@ export default abstract class Renderer {
|
||||
return realPosition
|
||||
}
|
||||
|
||||
protected realPosition(ge: GameEngine): [number, number, number, number] {
|
||||
const position = this.getPosition()
|
||||
const globalScale = ge.currentScene?.scale ?? 1
|
||||
return [
|
||||
position.x * ge.caseSize.x * globalScale,
|
||||
position.y * ge.caseSize.y * globalScale,
|
||||
this.component.scale.x * ge.caseSize.x * globalScale,
|
||||
this.component.scale.y * ge.caseSize.y * globalScale
|
||||
]
|
||||
}
|
||||
|
||||
protected selfPosition(ge: GameEngine): [number, number, number, number] {
|
||||
const position = this.component.position
|
||||
const globalScale = ge.currentScene?.scale ?? 1
|
||||
return [
|
||||
position.x * ge.caseSize.x * globalScale,
|
||||
position.y * ge.caseSize.y * globalScale,
|
||||
(this.component.scale.x ?? ge.caseSize.x) * ge.caseSize.x * globalScale,
|
||||
(this.component.scale.y ?? ge.caseSize.y) * ge.caseSize.y * globalScale
|
||||
]
|
||||
}
|
||||
|
||||
protected parentRealPosition(ge: GameEngine): [number, number, number, number] {
|
||||
const parent = this.component.parent
|
||||
if (!parent) {
|
||||
return [
|
||||
0,0,0,0
|
||||
]
|
||||
}
|
||||
const position = this.getPosition(parent)
|
||||
const globalScale = ge.currentScene?.scale ?? 1
|
||||
return [
|
||||
position.x * ge.caseSize.x * globalScale,
|
||||
position.y * ge.caseSize.y * globalScale,
|
||||
(parent.scale.x ?? ge.caseSize.x) * ge.caseSize.x * globalScale,
|
||||
(this.component.scale.y ?? ge.caseSize.y) * ge.caseSize.y * globalScale
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the component
|
||||
*
|
||||
* It needs to be closed by rotateFinish
|
||||
* @param ctx the context
|
||||
* @param rotation rotation in degrees
|
||||
*/
|
||||
protected rotateStart(ctx: CanvasRenderingContext2D, sizes: [number, number, number, number], rotation: number) {
|
||||
const radians = rotation * Math.PI / 180
|
||||
ctx.setTransform(
|
||||
1, // Horizontal Scaling
|
||||
0, // Horizontal Skewing
|
||||
0, // Vertical Skewing
|
||||
1, // Vertical Scaling
|
||||
sizes[0], // Horizontal Moving
|
||||
sizes[1] // Vertical Moving
|
||||
)
|
||||
ctx.rotate(radians)
|
||||
}
|
||||
|
||||
protected preRender(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
ge: GameEngine,
|
||||
additionnalRotation = 0
|
||||
): [number, number, number, number] {
|
||||
let position = this.realPosition(ge)
|
||||
|
||||
if (this.component.getAbsoluteRotation() !== 0 || additionnalRotation) {
|
||||
this.rotateStart(
|
||||
ctx,
|
||||
this.component.parent ? this.parentRealPosition(ge) : position,
|
||||
this.component.getAbsoluteRotation() + additionnalRotation
|
||||
)
|
||||
position = this.component.parent ? this.selfPosition(ge) : [0, 0, position[2], position[3]]
|
||||
}
|
||||
|
||||
return position
|
||||
}
|
||||
|
||||
protected postRender(ctx: CanvasRenderingContext2D, ge: GameEngine) {
|
||||
|
||||
// handle rotation reset
|
||||
ctx.resetTransform()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ctx the context
|
||||
*/
|
||||
protected rotateFinish(ctx: CanvasRenderingContext2D) {
|
||||
ctx.resetTransform()
|
||||
}
|
||||
|
||||
public abstract render(ge: GameEngine, ctx: CanvasRenderingContext2D): Promise<void>
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import GameEngine from 'GameEngine'
|
||||
import Component2D, { ComponentState } from './Component2D'
|
||||
import BoxCollider2D from './2D/Collision/BoxCollider2D'
|
||||
import Collider from './2D/Collider'
|
||||
import Checker from './2D/Collider/Checker'
|
||||
import Vector2D from './2D/Vector2D'
|
||||
import { ComponentType } from 'react'
|
||||
import Component2D, { ComponentState } from './Component2D'
|
||||
|
||||
export default class Scene {
|
||||
public static scenes: Record<string, Scene> = {}
|
||||
@ -12,8 +12,8 @@ export default class Scene {
|
||||
|
||||
public position: Vector2D = new Vector2D(0)
|
||||
public scale = 1
|
||||
public components: Array<Component2D> = []
|
||||
|
||||
private components: Array<Component2D> = []
|
||||
private componentsInitialized: Array<boolean> = []
|
||||
private ge!: GameEngine
|
||||
private hasClickedComponent: number | undefined
|
||||
@ -86,34 +86,39 @@ export default class Scene {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
public checkColisions(component: Component2D, exclusion?: Array<Component2D>): Array<Component2D> {
|
||||
const list: Array<Component2D> = []
|
||||
if (component.collider instanceof BoxCollider2D) {
|
||||
const [topLeft, bottomRight] = component.collider.pos()
|
||||
for (const otherComponent of this.components) {
|
||||
if (
|
||||
otherComponent === undefined ||
|
||||
otherComponent.id === component.id ||
|
||||
!(otherComponent.collider instanceof BoxCollider2D)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
if (!component.collider) {
|
||||
return list
|
||||
}
|
||||
for (const otherComponent of this.components) {
|
||||
if (
|
||||
!otherComponent ||
|
||||
otherComponent.id === component.id ||
|
||||
!otherComponent.collider
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Exclude components from being checked
|
||||
if (exclusion?.find((it) => it.id === otherComponent.id)) {
|
||||
continue
|
||||
}
|
||||
// Exclude components from being checked
|
||||
if (exclusion?.find((it) => it.id === otherComponent.id)) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check for collision
|
||||
const otherCollider = otherComponent.collider.pos()
|
||||
if (
|
||||
bottomRight.x > otherCollider[0].x && // self bottom higher than other top
|
||||
topLeft.x < otherCollider[1].x &&
|
||||
bottomRight.y > otherCollider[0].y &&
|
||||
topLeft.y < otherCollider[1].y
|
||||
) {
|
||||
list.push(otherComponent)
|
||||
}
|
||||
if (component.collider) {
|
||||
component.collider.component = component
|
||||
}
|
||||
|
||||
if (otherComponent.collider) {
|
||||
otherComponent.collider.component = otherComponent
|
||||
}
|
||||
|
||||
// Check for collision
|
||||
if (
|
||||
Checker.detectCollision(component.collider, otherComponent.collider)
|
||||
) {
|
||||
list.push(otherComponent)
|
||||
}
|
||||
}
|
||||
return list
|
||||
@ -130,6 +135,7 @@ export default class Scene {
|
||||
|
||||
if (component.childs) {
|
||||
for await (const child of component.childs) {
|
||||
child.parent = component
|
||||
await this.initComponent(child)
|
||||
}
|
||||
}
|
||||
@ -153,7 +159,6 @@ export default class Scene {
|
||||
const toExclude: Array<Component2D> = []
|
||||
if (component.childs && component.childs.length > 0) {
|
||||
for await (const child of component.childs) {
|
||||
child.parent = component
|
||||
toExclude.push(...await this.updateComponent(child))
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ export default class GameEngine {
|
||||
/**
|
||||
* Maximum framerate you want to achieve
|
||||
*
|
||||
* note: -1 mean infinite
|
||||
* note: -1/undefined mean infinite
|
||||
*/
|
||||
goalFramerate?: number
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import Tileset from 'GameEngine/Tileset'
|
||||
|
||||
export class Explosion extends Component2D {
|
||||
|
||||
public name = 'Explosion'
|
||||
public size = {
|
||||
width: .9,
|
||||
height: .9
|
||||
|
@ -1,5 +1,5 @@
|
||||
import GameEngine from 'GameEngine'
|
||||
import BoxCollider2D from 'GameEngine/2D/Collision/BoxCollider2D'
|
||||
import BoxCollider2D from 'GameEngine/2D/Collider/BoxCollider2D'
|
||||
import ColliderDebugger from 'GameEngine/2D/Debug/ColliderDebugger'
|
||||
import PointDebugger from 'GameEngine/2D/Debug/PointDebugger'
|
||||
import Vector2D from 'GameEngine/2D/Vector2D'
|
||||
@ -16,7 +16,9 @@ export default class Item extends Component2D {
|
||||
|
||||
public static explosion = new Explosion()
|
||||
|
||||
public collider: BoxCollider2D = new BoxCollider2D(this, 'click')
|
||||
public name = 'Item'
|
||||
|
||||
public collider: BoxCollider2D = new BoxCollider2D()
|
||||
|
||||
private x: number
|
||||
private y: number
|
||||
@ -43,7 +45,7 @@ export default class Item extends Component2D {
|
||||
// console.log(this.tileset.getSourceData(0), this.tileset.width(0), this.tileset.height(0))
|
||||
// console.log(this.tileset.getSourceData(1))
|
||||
this.childs = [
|
||||
new ColliderDebugger(this, this.collider),
|
||||
new ColliderDebugger(),
|
||||
new PointDebugger(this.collider.pos()[0]),
|
||||
new PointDebugger(this.collider.pos()[1])
|
||||
]
|
||||
|
@ -5,6 +5,7 @@ import RectRenderer from 'GameEngine/Renderer/RectRenderer'
|
||||
export default class Line extends Component2D {
|
||||
|
||||
// public debug = true
|
||||
public name = 'Line'
|
||||
|
||||
public constructor(direction: number, index: number) {
|
||||
super()
|
||||
|
@ -1,5 +1,5 @@
|
||||
import GameEngine from 'GameEngine'
|
||||
import BoxCollider2D from 'GameEngine/2D/Collision/BoxCollider2D'
|
||||
import BoxCollider2D from 'GameEngine/2D/Collider/BoxCollider2D'
|
||||
import ColliderDebugger from 'GameEngine/2D/Debug/ColliderDebugger'
|
||||
import Vector2D from 'GameEngine/2D/Vector2D'
|
||||
import Component2D, { ComponentState } from 'GameEngine/Component2D'
|
||||
@ -7,14 +7,15 @@ import RectRenderer from 'GameEngine/Renderer/RectRenderer'
|
||||
import { globalState } from '..'
|
||||
|
||||
export default class Start extends Component2D {
|
||||
public name = 'Start'
|
||||
public renderer: RectRenderer = new RectRenderer(this, {material: 'yellow'})
|
||||
public position: Vector2D = new Vector2D(1, 1)
|
||||
public scale: Vector2D = new Vector2D(2, 1)
|
||||
public collider: BoxCollider2D = new BoxCollider2D(this, 'click')
|
||||
public childs: Array<Component2D> = [new ColliderDebugger(this, this.collider)]
|
||||
public collider: BoxCollider2D = new BoxCollider2D()
|
||||
public childs: Array<Component2D> = [new ColliderDebugger()]
|
||||
|
||||
public update(state: ComponentState) {
|
||||
if (state.isColliding === 'click') {
|
||||
if (state.collideWith?.find((it) => it.name === 'Cursor')) {
|
||||
console.log('Start Game !')
|
||||
GameEngine.getGameEngine().setScene('TicTacToe')
|
||||
globalState.isPlaying = true
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React from 'react'
|
||||
import App from 'next/app'
|
||||
import React from 'react'
|
||||
|
||||
import PlausibleProvider from 'next-plausible'
|
||||
import '@dzeio/components/style.css'
|
||||
import PlausibleProvider from 'next-plausible'
|
||||
|
||||
export default class CApp extends App {
|
||||
|
||||
@ -10,14 +10,14 @@ export default class CApp extends App {
|
||||
const { Component, pageProps } = this.props
|
||||
|
||||
return (
|
||||
<PlausibleProvider
|
||||
enabled
|
||||
customDomain="https://proxy.dzeio.com"
|
||||
domain="games.avior.me"
|
||||
integrity="sha256-R6vN8jmBq9SIpnfJRnw9eNUfLbC2yO3GPQAKR5ZS7zQ="
|
||||
>
|
||||
<Component {...pageProps} />
|
||||
</PlausibleProvider>
|
||||
// <PlausibleProvider
|
||||
// enabled
|
||||
// customDomain="https://proxy.dzeio.com"
|
||||
// domain="games.avior.me"
|
||||
// integrity="sha256-R6vN8jmBq9SIpnfJRnw9eNUfLbC2yO3GPQAKR5ZS7zQ="
|
||||
// >
|
||||
<Component {...pageProps} />
|
||||
// </PlausibleProvider>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Button, Text, Util, NotificationManager, Col, Row, Input } from '@dzeio/components'
|
||||
import { Button, Col, Input, NotificationManager, Row, Text, Util } from '@dzeio/components'
|
||||
import { GetServerSideProps } from 'next'
|
||||
import React, { MouseEvent as ReactMouseEvent } from 'react'
|
||||
import css from './pokemon-shuffle.module.styl'
|
||||
@ -187,8 +187,9 @@ export default class PokemonShuffle extends React.Component<Props, States> {
|
||||
return NotificationManager.addNotification('Cant move nothing')
|
||||
}
|
||||
document.addEventListener('mousemove', this.mouveMove)
|
||||
this.setState({movingItem: {x,y,cell}})
|
||||
this.state.items[y][x] = undefined
|
||||
const items = this.state.items
|
||||
items[y][x] = undefined
|
||||
this.setState({movingItem: {x,y,cell}, items})
|
||||
this.mouveMove(ev.nativeEvent)
|
||||
return
|
||||
} else {
|
||||
|
@ -6,9 +6,12 @@ import Scene from 'GameEngine/Scene'
|
||||
import Item from 'games/tictactoe/Item'
|
||||
import Line from 'games/tictactoe/Line'
|
||||
import Start from 'games/tictactoe/Menu/Start'
|
||||
import Cursor from 'GameEngine/Components/Cursor'
|
||||
|
||||
export default class Snake extends React.PureComponent {
|
||||
|
||||
private cursor = new Cursor()
|
||||
|
||||
public async componentDidMount() {
|
||||
const ge = new GameEngine('#test', {
|
||||
caseCount: 3,
|
||||
@ -17,19 +20,21 @@ export default class Snake extends React.PureComponent {
|
||||
})
|
||||
const menuScene = new Scene('Menu')
|
||||
menuScene.addComponent(
|
||||
new Start()
|
||||
new Start(),
|
||||
this.cursor
|
||||
)
|
||||
const scene = new Scene('TicTacToe')
|
||||
scene.addComponent(
|
||||
...Array.from(new Array(2)).map((_, index) => new Line(0, index)),
|
||||
...Array.from(new Array(2)).map((_, index) => new Line(1, index)),
|
||||
...Array.from(new Array(9)).map((_, index) => new Item(index)),
|
||||
Item.explosion
|
||||
Item.explosion,
|
||||
this.cursor
|
||||
// new TilingDebugger()
|
||||
)
|
||||
|
||||
ge.start()
|
||||
ge.setScene(menuScene)
|
||||
ge.setScene(menuScene).then(() => ge.start())
|
||||
// ge.start()
|
||||
}
|
||||
|
||||
public render = () => (
|
||||
|
@ -1,38 +1,45 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"baseUrl": "./src",
|
||||
"paths": {
|
||||
"@styl/*": ["client/styl/*"],
|
||||
"@cp/*": ["client/components/*"],
|
||||
"@smd/*": ["client/styl/modules/*"],
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"out",
|
||||
"__tests__"
|
||||
],
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"src/client/styl/stylus.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx"
|
||||
]
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"baseUrl": "./src",
|
||||
"paths": {
|
||||
"@styl/*": [
|
||||
"client/styl/*"
|
||||
],
|
||||
"@cp/*": [
|
||||
"client/components/*"
|
||||
],
|
||||
"@smd/*": [
|
||||
"client/styl/modules/*"
|
||||
]
|
||||
},
|
||||
"incremental": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"out",
|
||||
"__tests__"
|
||||
],
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"src/client/styl/stylus.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx"
|
||||
]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user