Add controls

This commit is contained in:
Alexander Klingenbeck 2023-06-06 08:51:42 +02:00
parent 7036848ce6
commit ded70d470b
6 changed files with 88 additions and 8 deletions

View File

@ -1,2 +1,3 @@
node_modules/
main.js
main.js
editor.js

View File

@ -0,0 +1,58 @@
import { Behaviour, Builder, Entity, HasBoundingBox, HasMouseInteraction, combine, hasDefault, hasDefaultFn, makeEntity, which, withBoundingBox, withComponent, withMouseInteraction } from "./entity"
import { entityAdd, runGame } from "./game"
import { HasText, withText } from "./text"
const withGuiBounds = withComponent<HasBoundingBox>(x => hasDefaultFn(x, 'boundingBox', () => new Rectangle(10,10,100,20)))
type Button = Entity & HasBoundingBox & HasMouseInteraction & HasText
const drawsButton: Behaviour<Button> = {
draw: b => {
b.isClicked = guiButton(b.boundingBox, b.text)
if(b.isClicked && b.onClick) b.onClick()
}
}
const makeButton: Builder<Button> = combine(
makeEntity,
withGuiBounds,
withMouseInteraction,
withComponent<HasText>(x => hasDefault(x, 'text', 'Button')),
which(drawsButton))
interface HasActive {
active: boolean
}
const withActive = withComponent<HasActive>(x => hasDefault(x,'active',false))
interface HasChangedEvent {
onChange?: () => void
}
const withChangedEvent = withComponent<HasChangedEvent>()
type Textbox = Entity & HasBoundingBox & HasText & HasActive & HasChangedEvent
const drawsTextbox: Behaviour<Textbox> = {
draw: t => {
if(guiTextBox(t.boundingBox, t, t.active)){
t.active = !t.active
if(!t.active && t.onChange) t.onChange()
}
}
}
const makeTextbox = combine(makeEntity,
withGuiBounds,
withComponent<HasText>(x => hasDefault(x, 'text', '')),
withActive,
withChangedEvent,
which(drawsTextbox))
runGame({ width: 800, height: 600, title: 'My Editor', flags: FLAG_WINDOW_RESIZABLE }, async (quit) => {
const but = makeButton({
text: 'Click Me!',
onClick: () => but.boundingBox.x += 20
})
const tb = makeTextbox({
text: but.text,
boundingBox: new Rectangle(10, 50, 100, 20),
onChange: () => but.text = tb.text
})
entityAdd(but)
entityAdd(tb)
})

View File

@ -80,7 +80,8 @@ export interface HasMouseInteraction {
hasMouseOver: boolean,
hasMouseEntered: boolean,
hasMouseLeft: boolean
debugClickable: boolean
debugClickable: boolean,
onClick?: () => void
}
export const withMouseInteraction = withComponent<HasMouseInteraction>()
export const checksBoundingBoxClicks: Behaviour<HasMouseInteraction&HasBoundingBox> = {

View File

@ -1,3 +1,5 @@
import { withComponent } from "./entity";
import { hasDefault } from "./entity";
import { Behaviour, Entity, EntityOf } from "./entity";
import { forEachReverse } from "./helpers";
import { resourceUnloadAll } from "./resource";
@ -94,14 +96,29 @@ export const entityRemove = (entity: Entity) => {
}
}
export const runGame = (width: number, height: number, title: string, startupCallback: (quit: () => void) => void | Promise<void>) => {
initWindow(width, height, title)
interface WindowConfig {
width: number,
height: number,
title: string,
flags: number
}
const withConfig = withComponent<WindowConfig>(x => {
hasDefault(x, 'width', 640)
hasDefault(x, 'height', 480)
hasDefault(x, 'title', "Rayjs")
hasDefault(x, 'flags', 0)
})
export const runGame = (options: Partial<WindowConfig>, startupCallback: (quit: () => void) => void | Promise<void>) => {
const config = withConfig(options)
setConfigFlags(config.flags)
initWindow(config.width,config.height,config.title)
setTargetFPS(60)
let quit = false
let exception: any = null
const p = startupCallback(() => quit = true)
if(p) p.catch(e => { exception = e })
while(!windowShouldClose()){
while(!windowShouldClose() && !quit){
dispatchPromises()
if(exception) throw exception
entitiyList.forEach(e => e.behaviours.forEach(b => b.update ? b.update(e) : undefined))

View File

@ -5,7 +5,7 @@ import { entityAdd, entityRemove, runGame } from "./game";
import { ClickableText, makeClickableText, makeParagraph } from "./text";
import { Compiler } from "inkjs";
runGame(800,400, "The Intercept", async (quit) => {
runGame({ width: 800, height: 400, title: "The Intercept" }, async (quit) => {
const source = loadFileText("resources/intercept.ink")
const c = new Compiler(source)
const story = c.Compile()

View File

@ -1,7 +1,10 @@
const path = require('path');
module.exports = {
entry: './src/index.ts',
entry: {
main: './src/index.ts',
editor: './src/editor.ts',
},
devtool: false,
target: "node",
mode: 'production',
@ -18,7 +21,7 @@ module.exports = {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: 'main.js',
filename: '[name].js',
path: path.resolve(__dirname, '.'),
},
};