Compare commits
3 Commits
2934363bed
...
0c4c6fe58c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c4c6fe58c | ||
|
|
815a589b23 | ||
|
|
711c0e25ac |
|
|
@ -52,7 +52,10 @@ https://wakamaifondue.com/
|
||||||
|
|
||||||
## Pluto Goals: Phase 2
|
## Pluto Goals: Phase 2
|
||||||
|
|
||||||
- [ ] pico8-style games
|
|
||||||
- [ ] public tunnel for your NOSE webapps
|
- [ ] public tunnel for your NOSE webapps
|
||||||
- [ ] self updating
|
- [ ] public tunnel lives through reboots
|
||||||
|
- [ ] self updating NOSE server
|
||||||
- [ ] `pub/` static hosting in webapps
|
- [ ] `pub/` static hosting in webapps
|
||||||
|
- [ ] game/bin/www cartridges
|
||||||
|
- [ ] upload files to projects
|
||||||
|
- [ ] pico8-style games
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,7 @@ export function update(_delta: number, input: InputState) {
|
||||||
paused = !paused
|
paused = !paused
|
||||||
if (paused) return
|
if (paused) return
|
||||||
|
|
||||||
if (input.justPressed.has(" ")) {
|
if (input.justPressed.has(" ") || input.justPressed.has("z")) {
|
||||||
rotateShape()
|
rotateShape()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ export async function handleGameStart(msg: Message) {
|
||||||
canvas = createCanvas()
|
canvas = createCanvas()
|
||||||
canvas.focus()
|
canvas.focus()
|
||||||
setStatus(msgId, "ok")
|
setStatus(msgId, "ok")
|
||||||
canvas.addEventListener("keydown", handleKeydown)
|
window.addEventListener("keydown", handleKeydown)
|
||||||
canvas.addEventListener("keyup", handleKeyup)
|
window.addEventListener("keyup", handleKeyup)
|
||||||
window.addEventListener("resize", resizeCanvas)
|
window.addEventListener("resize", resizeCanvas)
|
||||||
resizeCanvas()
|
resizeCanvas()
|
||||||
gameLoop(new GameContext(canvas.getContext("2d")!), game)
|
gameLoop(new GameContext(canvas.getContext("2d")!), game)
|
||||||
|
|
@ -137,6 +137,10 @@ function gameLoop(ctx: GameContext, game: Game) {
|
||||||
function endGame() {
|
function endGame() {
|
||||||
running = false
|
running = false
|
||||||
|
|
||||||
|
window.removeEventListener("keydown", handleKeydown)
|
||||||
|
window.removeEventListener("keyup", handleKeyup)
|
||||||
|
window.removeEventListener("resize", resizeCanvas)
|
||||||
|
|
||||||
if (oldMode === "tall") browserCommands.mode?.()
|
if (oldMode === "tall") browserCommands.mode?.()
|
||||||
|
|
||||||
canvas.classList.remove("active")
|
canvas.classList.remove("active")
|
||||||
|
|
|
||||||
64
app/src/js/gamepad.ts
Normal file
64
app/src/js/gamepad.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
////
|
||||||
|
// Support for gamepads.
|
||||||
|
// Maps incoming gamepad button presses to keyboard buttons.
|
||||||
|
//
|
||||||
|
|
||||||
|
const BUTTONS = [
|
||||||
|
"A", "B", "X", "Y",
|
||||||
|
"LB", "RB", "LT", "RT",
|
||||||
|
"Select", "Start",
|
||||||
|
"LStick", "RStick",
|
||||||
|
"DPad Up", "DPad Down", "DPad Left", "DPad Right"
|
||||||
|
]
|
||||||
|
|
||||||
|
const BUTTONS_TO_KEYS: Record<number, string> = {
|
||||||
|
0: "z", // A → Z
|
||||||
|
1: "x", // B → X
|
||||||
|
2: "c", // X → C
|
||||||
|
3: "v", // Y → V
|
||||||
|
12: "ArrowUp",
|
||||||
|
13: "ArrowDown",
|
||||||
|
14: "ArrowLeft",
|
||||||
|
15: "ArrowRight",
|
||||||
|
9: "Enter", // Start
|
||||||
|
8: "Escape" // Select
|
||||||
|
}
|
||||||
|
|
||||||
|
const activePads = new Set<number>()
|
||||||
|
const prevState: Record<number, boolean[]> = {}
|
||||||
|
|
||||||
|
export function initGamepad() {
|
||||||
|
window.addEventListener("gamepadconnected", e => {
|
||||||
|
console.log("Gamepad connected:", e.gamepad)
|
||||||
|
activePads.add(e.gamepad.index)
|
||||||
|
requestAnimationFrame(handleGamepad)
|
||||||
|
})
|
||||||
|
|
||||||
|
window.addEventListener("gamepaddisconnected", e => {
|
||||||
|
console.log("Gamepad disconnected:", e.gamepad)
|
||||||
|
activePads.delete(e.gamepad.index)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleGamepad() {
|
||||||
|
const pads = navigator.getGamepads()
|
||||||
|
for (const gp of pads) {
|
||||||
|
if (!gp) continue
|
||||||
|
if (!prevState[gp.index]) prevState[gp.index] = gp.buttons.map(() => false)
|
||||||
|
|
||||||
|
gp.buttons.forEach((btn, i) => {
|
||||||
|
const was = prevState[gp.index]![i]
|
||||||
|
const is = btn.pressed
|
||||||
|
if (was !== is) {
|
||||||
|
const key = BUTTONS_TO_KEYS[i]
|
||||||
|
if (key) {
|
||||||
|
const type = is ? "keydown" : "keyup"
|
||||||
|
window.dispatchEvent(new KeyboardEvent(type, { code: key, key }))
|
||||||
|
}
|
||||||
|
prevState[gp.index]![i] = is
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(handleGamepad)
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ import { initCompletion } from "./completion.js"
|
||||||
import { initCursor } from "./cursor.js"
|
import { initCursor } from "./cursor.js"
|
||||||
import { initEditor } from "./editor.js"
|
import { initEditor } from "./editor.js"
|
||||||
import { initFocus } from "./focus.js"
|
import { initFocus } from "./focus.js"
|
||||||
|
import { initGamepad } from "./gamepad.js"
|
||||||
import { initHistory } from "./history.js"
|
import { initHistory } from "./history.js"
|
||||||
import { initHyperlink } from "./hyperlink.js"
|
import { initHyperlink } from "./hyperlink.js"
|
||||||
import { initInput } from "./input.js"
|
import { initInput } from "./input.js"
|
||||||
|
|
@ -13,6 +14,7 @@ initCompletion()
|
||||||
initCursor()
|
initCursor()
|
||||||
initFocus()
|
initFocus()
|
||||||
initEditor()
|
initEditor()
|
||||||
|
initGamepad()
|
||||||
initHistory()
|
initHistory()
|
||||||
initHyperlink()
|
initHyperlink()
|
||||||
initInput()
|
initInput()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user