27
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Misskey Playで使うAiScriptのリファレンス

Last updated at Posted at 2023-02-10

前書き

Misskey Playを作る時の参考にどうぞ。

  • 公式ドキュメント

  • 初めてPlayを作る人はこちらの解説が参考になります

  • 細かい困り事やAiScript全般のことはこちらの記事をどうぞ

  • この記事は以下のソースコードの情報を元に作成しています

実例

おおまかな作り方はPlay作成画面で使える公式プリセットや、他の人が作ったPlayのソースを参考にしてください。

公式プリセット

Omikuji

ユーザーごとに日替わりのおみくじのプリセット

ソースコード
Omikuji
/// @ 0.12.4
// ユーザーごとに日替わりのおみくじのプリセット

// 選択肢
let choices = [
	"ギガ吉"
	"大吉"
	""
	"中吉"
	"小吉"
	"末吉"
	""
	"大凶"
]

// シードが「ユーザーID+今日の日付」である乱数生成器を用意
let random = Math:gen_rng(`{USER_ID}{Date:year()}{Date:month()}{Date:day()}`)

// ランダムに選択肢を選ぶ
let chosen = choices[random(0 (choices.len - 1))]

// 結果のテキスト
let result = `今日のあなたの運勢は **{chosen}** です。`

// UIを表示
Ui:render([
	Ui:C:container({
		align: 'center'
		children: [
			Ui:C:mfm({ text: result })
			Ui:C:postFormButton({
				text: "投稿する"
				rounded: true
				primary: true
				form: {
					text: `{result}{Str:lf}{THIS_URL}`
				}
			})
		]
	})
])

Shuffle

巻き戻し可能な文字シャッフルのプリセット

ソースコード
Shuffle
/// @ 0.12.4
// 巻き戻し可能な文字シャッフルのプリセット

let string = "ペペロンチーノ"
let length = string.len

// 過去の結果を保存しておくやつ
var results = []

// どれだけ巻き戻しているか
var cursor = 0

@do() {
	if (cursor != 0) {
		results = results.slice(0 (cursor + 1))
		cursor = 0
	}

	let chars = []
	for (let i, length) {
		let r = Math:rnd(0 (length - 1))
		chars.push(string.pick(r))
	}
	let result = chars.join("")

	results.push(result)

	// UIを表示
	render(result)
}

@back() {
	cursor = cursor + 1
	let result = results[results.len - (cursor + 1)]
	render(result)
}

@forward() {
	cursor = cursor - 1
	let result = results[results.len - (cursor + 1)]
	render(result)
}

@render(result) {
	Ui:render([
		Ui:C:container({
			align: 'center'
			children: [
				Ui:C:mfm({ text: result })
				Ui:C:buttons({
					buttons: [{
						text: ""
						disabled: !(results.len > 1 && (results.len - cursor) > 1)
						onClick: back
					} {
						text: ""
						disabled: !(results.len > 1 && cursor > 0)
						onClick: forward
					} {
						text: "引き直す"
						onClick: do
					}]
				})
				Ui:C:postFormButton({
					text: "投稿する"
					rounded: true
					primary: true
					form: {
						text: `{result}{Str:lf}{THIS_URL}`
					}
				})
			]
		})
	])
}

do()

Timeline viewer

APIリクエストを行いローカルタイムラインを表示するプリセット

ソースコード
Timeline viewer
/// @ 0.12.4
// APIリクエストを行いローカルタイムラインを表示するプリセット

@fetch() {
	Ui:render([
		Ui:C:container({
			align: 'center'
			children: [
				Ui:C:text({ text: "読み込み中..." })
			]
		})
	])

	// タイムライン取得
	let notes = Mk:api("notes/local-timeline" {})

	// それぞれのノートごとにUI要素作成
	let noteEls = []
	each (let note, notes) {
		let el = Ui:C:container({
			bgColor: "#444"
			fgColor: "#fff"
			padding: 10
			rounded: true
			children: [
				Ui:C:mfm({
					text: note.user.name
					bold: true
				})
				Ui:C:mfm({
					text: note.text
				})
			]
		})
		noteEls.push(el)
	}

	// UIを表示
	Ui:render([
		Ui:C:text({ text: "ローカル タイムライン" })
		Ui:C:button({
			text: "更新"
			onClick: @() {
				fetch()
			}
		})
		Ui:C:container({
			children: noteEls
		})
	])
}

fetch()

応用

地理クイズ (by @syuilo@misskey.io)

2048 (by @madorama_vrc@misskey.io)

パズルゲーム

FlappyUsachan (by @gozaru@misskey.io)

アクション要素のあるゲームも作れる。制作者による解説

サバイバルゲーム (by @mugcAp@misskey.io)

シミュレーション

ガチャシミュレーター (by @salano_ym@misskey.io)

排出対象のデータはPageから取得します。

参考記事

ゲームのイベント予定表 (by @salano_ym@misskey.io)

Pageに保存したデータを取得して表示します。ウィジェット利用向けにコードのアップデートを通知することもできます。(fetch関数参照)

他にも参考になるものがあれば教えてください!

UI操作

Ui:render

Ui:root.update({ children: [...] })の糖衣構文
UIを1から表示するときはこれを使う

UI全体を更新
Ui:render([
  Ui:C:text({text: "A"})
  Ui:C:button({text: "B", onClick: @(){}})
])

Ui:get

コンポーネントをIDで取得。特定のコンポーネントのみ更新するときに使う

text1の内容を更新
Ui:C:text({text: "A"}, "text1")
Ui:get("text1").update({text: "B"})

Ui:root

UIのルート。あまり使わないかも

Ui:root.update({
  children: [ // 中身のコンポーネントの配列
    Ui:C:text({text: "A"})
  ]
})

Ui:patch

未実装っぽい

UIコンポーネント

  • コンポーネント定義の各要素は省略可能
  • component.idでコンポーネントのIDを取得
  • component.update({...})でコンポーネントを更新

UIデモ

表示系

Ui:C:text

MFMではない通常のテキスト。

Ui:C:text({
  text: "内容" // 表示するテキスト
  size: 1 // 文字サイズ
  bold: false // ボールド
  color: '#000' // 色
  font: 'monospace' // フォント serif,sans-serif,monospace
})

Ui:C:mfm

MFMテキスト。

Ui:C:mfm({
  text: "内容" // 表示するテキスト
  size: 1 // 文字サイズ
  bold: false // ボールド
  color: '#000' // 色
  font: 'monospace' // フォント serif,sans-serif,monospace
  onClickEv: @(id) {
    <: `{id} clicked` // $[clickable.ev=SOMEID TEXT]
  }
})

入力系

Ui:C:button

ボタン。

var counter = 0

Ui:C:button({
  text: "ボタン" // 表示するテキスト
  onClick: @(){ counter += 1 } // 押したときのイベント
  primary: false // 色を付けて強調
  rounded: false // 角を丸く
  disabled: false // 無効化
})

Ui:C:buttons

横並びの複数のボタン。

Ui:C:buttons({
  buttons: [ // ボタン定義の配列 Ui:C:buttonと同じ
    {text: "a", onClick: @(){...}}
    {text: "b", onClick: @(){...}}
  ]
})

Ui:C:switch

ON/OFFのスイッチ

var func1_enabled = false

Ui:C:switch({
  onChange: @(enabled) { // 変更された時のイベント
    func1_enabled = enabled
  }
  default: false // デフォルト
  label: "ラベル"
  caption: "キャプション"
})

Ui:C:textarea

複数行のテキスト入力。

var the_text = ""

Ui:C:textarea({
  onInput: @(text){ the_text = text } // 入力された時のイベント
  default: "デフォルト"
  label: "ラベル"
  caption: "キャプション"
})

Ui:C:textInput

1行のテキスト入力。

var the_text = ""

Ui:C:textInput({
  onInput: @(text){ the_text = text } // 入力された時のイベント
  default: "デフォルト"
  label: "ラベル"
  caption: "キャプション"
})

Ui:C:numberInput

数値入力。

var the_number = 0

Ui:C:numberInput({
  onInput: @(number){ the_number = number } // 入力された時のイベント
  default: 0 // デフォルト
  label: "ラベル"
  caption: "キャプション"
})

Ui:C:select

複数の選択肢から1つ選ぶ。

var the_value = ""

Ui:C:select({
  items: [ // 選択肢の配列
    {text: "A", value: "v1"}
    {text: "B", value: "v2"}
  ]
  onChange: @(value){ the_value = value } // 変更された時のイベント
  default: "v1" // デフォルト
  label: "ラベル"
  caption: "キャプション"
})

コンテナ系

Ui:C:container

幅寄せしたり色を付けたりする

Ui:C:container({
  children: [Ui:C:text({text: "A"})] // 中身のコンポーネントの配列
  align: 'center' // 幅寄せ left,center,right
  bgColor: '#000' // 背景色
  fgColor: '#00f' // 文字色
  font: 'serif' // フォント serif,sans-serif,monospace
  borderWidth: 1 // 枠幅
  borderColor: '#f00' // 枠の色
  padding: 1
  rounded: false // 角を丸く
  hidden: false // 隠す
})

Ui:C:folder

折りたためるフォルダ

Ui:C:folder({
  children: [Ui:C:text({text: "A"})] // 中身のコンポーネントの配列
  title: "タイトル"
  opened: true // 開いているか
})

ノート投稿

Ui:C:postForm

Misskeyの投稿フォーム。(Misskey2023.9.0から)

Ui:C:postForm({
  form: {text: "投稿内容"} // 投稿フォームのデフォルト文字列
})

Ui:C:postFormButton

Misskeyの投稿フォームをポップアップ表示するボタン。

Ui:C:postFormButton({
  text: "投稿!" // 表示するテキスト
  primary: true // 色を付けて強調
  rounded: true // 角を丸く
  form: {text: "投稿内容"} // 投稿フォームのデフォルト文字列
})

ダイアログ

Mk:dialog

第3引数はinfo,success,warning,error,questionが指定可能。省略するとinfo

Mk:dialog("エラー!", "エラーが発生しました", "info")

Mk:confirm

ユーザーがOKを押すとtrueキャンセルを押すとfalseが返る。

let ok = Mk:confirm("確認", "実行しますか?", "info")

readline

Misskey上では文字列入力のダイアログが表示される。

let name = readline('名前を入力してください')

セーブ・ロード

ローカルに保存される。

Mk:save

cookie_countに9999を保存
Mk:save("cookie_count", 9999)

Mk:load

cookie_countの値を取得
let cookie_count = Mk:load("cookie_count")

Misskey API

Mk:api

Mk:api(ENDPOINT, PARAMETER, TOKEN)
APIドキュメント

ローカルTLを取得
Mk:api("notes/local-timeline", {})
27
19
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?