初回プッシュ以外でもプルリクをつくるリンクを表示する
remote: Resolving deltas: 100% (7/7), completed with 7 local objects. remote: remote: Create a pull request for 'baz' on GitHub by visiting: remote: https://github.com/foo/bar/pull/new/baz remote:
このリンク。そのブランチを初めてプッシュしたときしか出してくれず不便なので、ググって.git/hooks/pre-push
に仕込んだ。
#!/bin/sh branch=$(git rev-parse --abbrev-ref HEAD) userRepo=$(git remote -v | grep fetch | awk '{print $2}' | grep "github.com" | cut -d':' -f2) if [ -n "$userRepo" ] then echo "" echo "Create PR at: https://github.com/$userRepo/compare/$branch?expand=1&labels=qux" echo "" fi
よく使うラベルを指定することも可能。
細かくpackage.jsonでmainを指定しておくと便利
読んでなるほどと思ったのでメモ。言われてみれば確かにそう。
components └── Button ├── Button.module.css └── Button.tsx
みたいな構造になっているときにButton.tsxをimportすると
import Button from '~/components/Button/Button'
と書かないといけない。index.tsにする手もあるけど全部index.tsになってしまう。そこで、ここにpackage.jsonを置いて
components └── Button ├── Button.module.css ├── Button.tsx └── package.json
{ main: "Button.tsx" }
とすると
import Button from '~/components/Button'
でimportできる。
Phaser 3でコントローラーを使う
最近遊んでいたのでメモ。
PhaserにはScene Pluginという仕組みがあるようです。そこでthis.game.events.on
でupdate
前にコールバックを仕込めるので、そこでコントローラー入力周りのお世話をしています。
// main.ts import Phaser from 'phaser' import { GamepadPlugin } from './plugins/gamepad' import { GameScene } from './scenes/game' new Phaser.Game({ ... input: { gamepad: true, }, scene: [GameScene], plugins: { scene: [ { key: 'GamepadPlugin', plugin: GamepadPlugin, mapping: 'gamepad', }, ], }, }
// plugins/gamepad.ts type ControllerType = 'NintendoSwitchPro' type Key = 'A' | 'B' | 'X' | 'Y' | 'L1' | 'L2' | 'R1' | 'R2' | 'UP' | 'DOWN' | 'LEFT' | 'RIGHT' | 'START' | 'SELECT' type Button = { pressed: boolean justPressed: boolean } const mappings: Record<ControllerType, Record<Key, number>> = { NintendoSwitchPro: { A: 1, B: 0, X: 3, Y: 2, L1: 4, L2: 6, R1: 5, R2: 7, UP: 12, DOWN: 13, LEFT: 14, RIGHT: 15, START: 9, SELECT: 8, }, } const button: Button = { pressed: false, justPressed: false, } export class GamepadPlugin extends Phaser.Plugins.ScenePlugin { private gamepad?: Phaser.Input.Gamepad.Gamepad private controllerType: ControllerType = 'NintendoSwitchPro' public readonly buttons: Record<Key, Button> = { A: { ...button }, B: { ...button }, X: { ...button }, Y: { ...button }, L1: { ...button }, L2: { ...button }, R1: { ...button }, R2: { ...button }, UP: { ...button }, DOWN: { ...button }, LEFT: { ...button }, RIGHT: { ...button }, START: { ...button }, SELECT: { ...button }, } constructor(scene: Phaser.Scene, pluginManager: Phaser.Plugins.PluginManager) { super(scene, pluginManager, 'GamepadPlugin') } boot() { this.game.events.on(Phaser.Core.Events.PRE_STEP, this.beforeUpdate, this) if (this.scene.input.gamepad.total === 0) { this.scene.input.gamepad.once('connected', (pad: Phaser.Input.Gamepad.Gamepad) => { this.gamepad = pad this.controllerType = this.detectController() }) } else { this.gamepad = this.scene.input.gamepad.pad1 this.controllerType = this.detectController() } } beforeUpdate() { if (this.gamepad) { const mapping = mappings[this.controllerType] Object.entries(mapping).forEach((entry) => { const button = entry[0] as Key const index = entry[1] as number const prevPressed = this.buttons[button].pressed const pressed = this.gamepad?.buttons[index].pressed ?? false this.buttons[button].justPressed = !prevPressed && pressed this.buttons[button].pressed = pressed }) } } private detectController(): ControllerType { if (this.gamepad?.id.match(/Pro Controller/)) { return 'NintendoSwitchPro' } else { return 'NintendoSwitchPro' // fallback } } }
// scenes/game.ts import Phaser from 'phaser' import { GamepadPlugin } from '../plugins/gamepad' export class GameScene extends Phaser.Scene { private gamepad!: GamepadPlugin constructor() { super('GameScene') } preload() {} create() {} update(_time: number, delta: number) { if (this.gamepad.buttons.LEFT.pressed) { // 左 } else if (this.gamepad.buttons.RIGHT.pressed) { // 右 } } }