Stonescript おべんきょう 2

> Stone Story RPGの案内へ戻る


↓ 旧ページ
SSR_自分用おべんきょ - Stone Story RPGを機械翻訳 + 備忘録

モンテスちゃんの学び舎その2👶

(:зꇤ )ニ キュ

ふとした時に見るリンク
ja.javascript.info
mozilla.org/ja
docs.python.org/ja
utokyo-ipp.github

敵の名前を完全なユニークとして扱う為に

色々遊んだ後はブログを少し整備して、新しいページを追加(敵図鑑 loc・foeデータ(高難易度のみ))しました。

foe.id, foe.name(en), foe.name(jp), foe.name(tid)

いずれかに統一すると、必ず何かしらユニークとして扱えない敵が発生するという
何を心配せずとも常にユニークとしては扱いたいなら、文字を結合してユニークであろう可能性を上げるか、要所要所で使い分けがね 必要だよね(えぇ…)

そしてお気に入り図鑑

アリくん
アリえんよなぁ…🐜⸒⸒

アリの群れ
アリガトウよなぁ…🐜⸒⸒(可愛い)

カツラ泥棒
…🐍すき

GWは近場で色々お店開拓してました
銀座は半数近くが外国人観光客 みなとみらいは三割前後 ဗီူဗီူ 比率ほんとに変わったね

▲ 上に戻る

内部的な処理の流れが分からない時

とにかくログをとる

var record = []

func write_logs(arr,cont)
  var arr_count = arr.Count()
  ?arr_count = 0
    arr.Add(cont)
  ?arr_count <= screen.h-3 & arr_count > 0
    arr.Insert(0,cont)
  
  /* 記録をし続けたい場合にこれも使う ***********
  ?arr_count > screen.h-3
    arr.RemoveAt(1,cont)
  **********************************************/

// 読み込み順テスト
?a
  write_logs(record,a+time)
  ?b
    write_logs(record,b+time)
?d
  write_logs(record,d+time)

// 読み込み順を表示
?record.Count()
  for i = 0..record.Count()-1
    >`1,@1+i@,[@i@] @record[i]@

▲ 上に戻る

全てのiterableが真、またはiterable が空ならtrue

組み込み関数 — Python 3.12.3 ドキュメント
allちょろ確認(:зꇤ)ニ

var f_state_time
f_state_time = [foe.state,foe.time]

func all(iterable)
    for element : iterable
        ?!element
            return false
    return true

>`1,1,ascii
all       @all(f_state_time)@

foe.state @f_state_time[0]@
foe.time  @f_state_time[1]@
asciiend

▼ iterable のいずれかの要素が真ならTrue
iterable が空なら False

func any(iterable)
    for element : iterable
        ?element
            return true
    return false

▲ 上に戻る

foeの中身を被りなく保存する

スクショ用に(👀 )

var foe_arr
var foes_data = ""
var foe_id_name
foe_arr = string.Split(foe)
foe_id_name = string.Join(" ",foe_arr,0,2)

// 敵の情報を結合して1つの文字列にする
func combine_foes_data()
    var print_w = (screen.w - 3)
    var data_size = string.Size(foe)
    // foeの中身が指定サイズ以下
    ?data_size <= print_w
        foes_data = foes_data + "\n" + foe
    // ※ foeの中身が指定サイズ超過
    ?data_size > print_w
        var foe_arr = string.Break(foe,print_w)
        for i = 0..foe_arr.Count()-1
            foes_data = foes_data + "\n" + foe_arr[i]

// foe_id_nameはユニークに近い文字列にする
// ※ 長い文字列を使わない(結合のループ防止)
?foes_data ! foe_id_name
    combine_foes_data()

// 敵データの表示
?foes_data
    >`1,0,@foes_data@

▲ 上に戻る

再帰処理

4. 関数の再帰呼び出しの動作原理 プログラミング2
Recursive -Slide-

func sum_natural_numbers(n)
    ?n <= 0
        return n
    return n + sum_natural_numbers(n-1)

>`1,6,@sum_natural_numbers(9)@
// 45

Stone Story RPGって以前体験した事あるような独特な世界だな〜と思っていたけど、パタポンだ👶(RATATANっていう精神的続編が出るみたいだね)

おちゃらけた世界のようで敵の苦悩も見えるし、無邪気な残酷さも相まってダークファンタジーとしても楽しめる
ベルセルク好きにも刺さるん

▲ 上に戻る

if文の型や真偽結果を色々表示すると

意外な所でfalseになっていたり

Manual 機械翻訳のコードをブックマークレットで一括取得し、一部コピーしたものをAIでテキスト整形しますた ChatGPT

ChatGPT指示文 配列のカンマ区切り

# 指示 テキスト変換
変換前:
a
b
c
変換後:
a
,b
,c


ChatGPT指示文 配列のコメントアウト連番

# 指示 テキスト変換
変換前:
a
,b
,c
変換後:
a  // 0
,b // 1
,c // 2


Manualページのコードを取得するブックマークレット

javascript:(function()%7Bvar%20newWindow=window.open('about:blank','_blank');newWindow.document.write('%3Chtml%3E%3Chead%3E%3Ctitle%3EExtracted%20Content%3C/title%3E%3C/head%3E%3Cbody%3E%3Cpre%3E');var%20h4IdElements=document.querySelectorAll('h4%5Bid%5D');var%20extractedText='';h4IdElements.forEach(function(element)%7Bvar%20textContent%20=%20element.textContent.trim();%20var%20codeTags%20=%20element.querySelectorAll('code');%20if%20(textContent.toLowerCase()%20!==%20'copy%20code'%20&&%20codeTags.length%20%3E%200)%20%7B%20codeTags.forEach(function(codeTag)%20%7B%20var%20copyButton%20=%20codeTag.querySelector('.copy-button');%20if%20(copyButton)%20%7B%20copyButton.parentNode.removeChild(copyButton);%20%7D%20if%20(!textContent.startsWith('?')%20&&%20!textContent.includes('?%20'))%20%7B%20extractedText%20+=%20codeTag.textContent%20+%20'%5Cn';%20%7D%20else%20%7B%20extractedText%20+=%20codeTag.textContent.replace(/%5E%5C%3F%5Cs*/mg,%20'')%20+%20'%5Cn';%20%7D%20%7D);%20%7D%7D);newWindow.document.write(extractedText);newWindow.document.write('%3C/pre%3E%3C/body%3E%3C/html%3E');%7D)();


なんて楽なんだぁ AI開発ありがたう

▼ 色々型チェック
表示が画面下部に達したら列を変えて表示

var test
test = [
    ((0*0)+"")                // 0
    ,-0                       // 1
    ,math.Pow(0,0)            // 2
    ,test                     // 3
    ,time.msbn                // 4
    ,true                     // 5
    ,fn                       // 6
    ,cnvs                     // 7
    ,summon.GetId()           // 8
    ,loc.stars                // 9
    ,item.left.id             // 10
    ,item.right.id            // 11
    ,item.left.state          // 12
    ,item.left.time           // 13
    ,item.right.state         // 14
    ,item.right.time          // 15
    ,item.potion              // 16
    ,item.CanActivate()       // 17
    ,item.GetCooldown("mask") // 18
    ,item.GetCount("socket sword +21") // 19
    ,item.GetLoadoutL(1)      // 20
    ,item.GetLoadoutR(1)      // 21
    ,foe                      // 22
    ,foe.id                   // 23
    ,foe.name                 // 24
    ,foe.damage               // 25
    ,foe.distance             // 26
    ,foe.count                // 27
    ,foe.GetCount(90)         // 28
    ,foe.hp                   // 29
    ,foe.maxhp                // 30
    ,foe.armor                // 31
    ,foe.maxarmor             // 32
    ,foe.buffs.count          // 33
    ,foe.debuffs.count        // 34
    ,foe.debuffs.string       // 35
    ,foe.state                // 36
    ,foe.time                 // 37
    ,foe.level                // 38
    ,foe.distance             // 39
    ,pickup                   // 40
    ,pickup.distance          // 41
    ,harvest                  // 42
    ,harvest.distance         // 43
    ,armor                    // 44
    ,armor.f                  // 45
    ,maxarmor                 // 46
    ,buffs.count              // 47
    ,buffs.string             // 48
    ,debuffs.count            // 49
    ,debuffs.string           // 50
    ,hp                       // 51
    ,maxhp                    // 52
    ,pos.x                    // 53
    ,pos.y                    // 54
    ,pos.z                    // 55
    ,ai.enabled               // 56
    ,ai.paused                // 57
    ,ai.idle                  // 58
    ,ai.walking               // 59
    ,player.direction         // 60
    ,player.name              // 61
    ,bighead                  // 62
    ,face                     // 63
    ,key                      // 64
    ,player.ShowScaredFace(5) // 65
]

// 画面表示 型/真偽の色分け
func show_types(arr)
    // 型判定の比較に使用するキーワード
    var search_types = [
        "string"    // 0
        ,"int"      // 1
        ,"float"    // 2
        ,"array"    // 3
        ,"bignumber"// 4
        ,"bool"     // 5
        ,"function" // 6
        ,"object"   // 7
        ,"null"     // 8
    ]
    // 型別の文字色
    var type_colors = [
        "#E5384D"  // 0
        ,"#38A8E5" // 1
        ,"#37E5D3" // 2
        ,"#F4BB54" // 3
        ,"#E55F36" // 4
        ,"#36E56B" // 5
        ,"#C454F4" // 6
        ,"#DDDDDD" // 7
        ,"#808080" // 8
    ]
    
    ?arr.Count()
        // _x x座標
        // _y y座標
        // _w ブロック幅
        var type_x  = 1
        var index_x = 11
        var bool_x  = 15
        var _y = 0
        var block_w = 25
        for i = 0..arr.Count()-1
            // 調整 xy座標
            ?_y = screen.h - 3
                type_x  += block_w
                index_x += block_w
                bool_x  += block_w
                _y = 0
            _y++
            // 表示 true/false判定
            ?arr[i]
                >`@index_x@,@_y@,#green,[@i@]
                >`@bool_x@,@_y@,#green,@arr[i]@
            ?!arr[i]
                >`@index_x@,@_y@,#red,[@i@]
                >`@bool_x@,@_y@,#red,@arr[i]@
            for j = 0..search_types.Count()-1
                // 表示 型判定
                ?Type(arr[i]) = search_types[j]
                    >`@type_x@,@_y@
                    ^,@type_colors[j]@,█@search_types[j]@
                    break

// component/functionの表示確認用に用意
?loc.begin
    var cnvs = ui.AddCanvas()
var fn = func()
    return

// 実行 型判定
show_types(test)

型/真偽判定の関数だけ

// 画面表示 型/真偽の色分け
func show_types(arr)
    // 型判定の比較に使用するキーワード
    var search_types = [
        "string"    // 0
        ,"int"      // 1
        ,"float"    // 2
        ,"array"    // 3
        ,"bignumber"// 4
        ,"bool"     // 5
        ,"function" // 6
        ,"object"   // 7
        ,"null"     // 8
    ]
    // 型別の文字色
    var type_colors = [
        "#E5384D"  // 0
        ,"#38A8E5" // 1
        ,"#37E5D3" // 2
        ,"#F4BB54" // 3
        ,"#E55F36" // 4
        ,"#36E56B" // 5
        ,"#C454F4" // 6
        ,"#DDDDDD" // 7
        ,"#808080" // 8
    ]
    
    ?arr.Count()
        // _x x座標
        // _y y座標
        // _w ブロック幅
        var type_x  = 1
        var index_x = 11
        var bool_x  = 15
        var _y = 0
        var block_w = 25
        for i = 0..arr.Count()-1
            // 調整 xy座標
            ?_y = screen.h - 3
                type_x  += block_w
                index_x += block_w
                bool_x  += block_w
                _y = 0
            _y++
            // 表示 true/false判定
            ?arr[i]
                >`@index_x@,@_y@,#green,[@i@]
                >`@bool_x@,@_y@,#green,@arr[i]@
            ?!arr[i]
                >`@index_x@,@_y@,#red,[@i@]
                >`@bool_x@,@_y@,#red,@arr[i]@
            for j = 0..search_types.Count()-1
                // 表示 型判定
                ?Type(arr[i]) = search_types[j]
                    >`@type_x@,@_y@
                    ^,@type_colors[j]@,█@search_types[j]@
                    break

PCのコーディングソフト使えばテキストの列で整形とかも楽にできるのかな?
テキスト整形といえば…というわけではないですが、今はKNIMEでExcelのデータ操作を簡単に出来ちゃうみたいだね👶
ノード操作って楽だからいいよねい

▲ 上に戻る

セクション区切り string.Format

microsoft C#
+値, -値, 0で書式指定文字列の変化する
セミコロン(;)で区切ったセクションは最大3つまで

セクション1つ 書式指定文字列は全ての値に適用
セクション2つ 最初のセクションが正の値とゼロに適用
2 番目のセクションが負の値に適用
セクション3つ 最初のセクションが正の値
2 番目のセクションが負の値
3 番目のセクションがゼロに適用

…(ぇぇゃん👶)

▼ セクション3つ その1

>`1,1,@string.Format("{0:正;負;ゼロ}", 10)@
>`1,2,@string.Format("{0:正;負;ゼロ}", -10)@
>`1,3,@string.Format("{0:正;負;ゼロ}", 0)@
// 正
// 負
// ゼロ

▼ セクション3つ その2

>`1,1,@string.Format("{0:+#;-#;0}", 10)@
>`1,2,@string.Format("{0:+#;-#;0}", -10)@
>`1,3,@string.Format("{0:+#;-#;0}", 0)@
// "+10"
// "-10"
// "0"

▲ 上に戻る

if文の&をマスターしよう

比較は両辺の型に注意が必要だけど、&で繋いだものはそれぞれtrueであればOK✍️👶たまに意味不になる

例1:

var int_ = 1
var str_ = "あ"
var null_
// var null_ = nullのようなもの

?int_ & str_ & null_ = null
^& 今半のすき焼きを食べたい
    >true
    // true

▼ 処理のイメージ

?int_ & str_ & null_ = null
^& 今半のすき焼きを食べたい
↓
?true & true & true
^& true
↓
true

例2:

var int_ = 1
var str_ = ""
var null_

?int_ & str_ & null_ = null
    >true
    // 表示なし

▼ 処理のイメージ

?int_ & str_ & null_ = null
↓
?true & false & true
↓
false
↓
1つでもfalseの場合false

ifで比較を使用せず、単体使用でfalseになるもの
false, null, 0, 0.0, ""

if文の判定結果を可視化してみよう

▲ 上に戻る

if文に使うものを型判別して処理の理解を深める

if文の判定結果を可視化してみよう
👆🏻true,false判定したものを型判別してみる
型判別の色がキツかったから画像は色変した👶

var arr_ = [
    1       // 0
    , 0     // 1
    , -1    // 2
    , 1.0   // 3
    , 0.1   // 4
    , 0.0   // 5
    , -0.1  // 6
    , -1.0  // 7
    , "0"   // 8
    , a     // 9
    , "あ"  // 10
    , " "   // 11
    , " "  // 12
    , ""    // 13
    , True  // 14
    , true  // 15
    , False // 16
    , false // 17
    , null  // 18
    , NaN   // 19
    , []    // 20
    , [a][0] // 21
    , item.left // 22
    , totaltime     // 23
    , totaltime = 0 // 24
    , foe           // 25
    , foe.distance <= 16 & foe = "Ice" // 26
]

for i = 0..arr_.Count()-1
    ?Type(arr_[i]) = string
        >`1,@i@,#dd0000,[@i@] @Type(arr_[i])@
    ?Type(arr_[i]) = int
        >`1,@i@,#0000dd,[@i@] @Type(arr_[i])@
    ?Type(arr_[i]) = float
        >`1,@i@,#00dddd,[@i@] @Type(arr_[i])@
    ?Type(arr_[i]) = bool
        >`1,@i@,#dd00dd,[@i@] @Type(arr_[i])@
    ?Type(arr_[i]) = array
        >`1,@i@,#dddd00,[@i@] @Type(arr_[i])@
    // ※ Typeの戻り値はstring型なので
    // 両辺の型を合わせて比較する
    ?Type(arr_[i]) = "null"
        >`1,@i@,#999999,[@i@] @Type(arr_[i])@

※ こんなイメージ👀
?Type(null) = "null"

?"null" = "null"

true

?Type(null) = null

?"null" = null

false

=,<=など比較を使う場合は両辺の型を意識する✍️(˘ω˘ )
string,int,floatくらいしか意識してなかったけど
同じ文字に見えても型に相違があれば期待した結果にならないし ifを扱いきるって結構難しいですね
そして未だに扱いきれない

▲ 上に戻る

if文の判定結果を可視化してみよう

>@foe.distance <= 16 & foe = " Poison "@
// 条件を満たす場合"True"
// 満たさない場合  "False"

↑ これでもいいですが、他にも色々見てみまっしゅ

if文に入れたものはTrue, Falseの2択で評価されるという事もはじめの頃は分からず、苦戦した思い出があります

test()

func test()
    var text = [
        1       // 0
        , 0     // 1 False
        , -1    // 2
        , 1.0   // 3
        , 0.1   // 4
        , 0.0   // 5 False
        , -0.1  // 6
        , -1.0  // 7
        , "0"   // 8
        , a     // 9
        , "あ"  // 10
        , " "   // 11
        , " "  // 12
        , ""    // 13 False
        , True  // 14
        , true  // 15
        , False // 16
        , false // 17 False
        , null  // 18 False
        , NaN   // 19
        , []    // 20
        , [a][0] // 21
        , item.left // 22 両手武器含め
                    // 左手に持ち物がなければFalse
        , totaltime     // 23 totaltime = 0でFalse
        , totaltime = 0 // 24 totaltime = 0は常にFalse
        , foe           // 25 敵情報が無ければFalse
        , foe.distance <= 16 & foe = "Ice" // 26
        // それぞれ条件式を満たさなければFalse
    ]
    for i = 0..text.Count()-1
        ?text[i]
            >`1,@1+i@,#green,True  [@i@] @text[i]@
        ?!text[i]
            >`1,@1+i@,#red,False [@i@] @text[i]@

まとめてみよう
ざっくり言うと特定の文字を除き、文字が存在する場合にTrueって事だねい
頭文字大文字のFalseがTrue判定になるのは予想外

判定 if文
True 英字 ※1
日本語 ※1
他言語 ※1
文字化け
記号 ※2
True
true
False
0(0.0など0のみの数)以外の数字
文字列の"0"
半角スペース
全角スペース
False
false
0
0.0 ※3
null
"" ※1のようなもの…ではなかった
エラー
用途が定められた記号を文頭に配置(一部除外)。文末も注意

※1 非初期化の変数として使用した文字列は値が代入される迄null相当(というかnull)になるので、nullの期間はif文で使うとFalseとして処理される
※2 用途が定められた記号は一部を除きエラー
※3 小数点以下に0以外があればTrue

▲ 上に戻る

ステージの敵名一覧を取得

discord: p3lb0x
string.Format便利だなぁ(👀 )

var foesAdded = ""

// 新しいfoe.idであればfoesAddedに追加
?foe & (foesAdded ! foe.id)
    foesAdded = string.Format(
    ^"{0}\n{1}",foesAdded,foe.id)

?foesAdded
    >`1,5,@foesAdded@
    // 敵名
    // 敵名
    // 敵名etc...

▲ 上に戻る

自動で属性選択

1番上がいいかな…?👶

手堅く完全一致検索

// 連結情報(immune_to_属性)を拾わない
var f_arr
f_arr = s_split(foe)
var s_equals = string.Equals

var auto_attr = ""
?s_equals(f_arr,"Perfected")
    auto_attr = ""
:?s_equals(f_arr,"Poison")
    auto_attr = "Ice"
:?s_equals(f_arr,"Vigor")
    auto_attr = "Poison"
:?s_equals(f_arr,"AEther")
    auto_attr = "Vigor"
:?s_equals(f_arr,"Fire")
    auto_attr = "AEther"
:?s_equals(f_arr,"Ice")
    auto_attr = "Fire"

>`1,6,auto_attr = @auto_attr@

半角スペース込みで小文字/大文字を区別

// 連結情報(immune_to_属性)を拾わない
// ある程度柔軟な検索が可能
// 注意点: foe情報の行頭か行末に非連結の属性情報が配置されると機能しない(たぶん)
var f_arr
f_arr = s_split(foe)
var auto_attr = ""

// ?foe = " Perfected "でも🙆‍♀️
?foe = " Poison Vigor AEther Fire Ice "
    auto_attr = ""
:?foe = " Poison "
    auto_attr = "Ice"
:?foe = " Vigor "
    auto_attr = "Poison"
:?foe = " AEther "
    auto_attr = "Vigor"
:?foe = " Fire "
    auto_attr = "AEther"
:?foe = " Ice "
    auto_attr = "Fire"

>`1,6,auto_attr = @auto_attr@

データを元に完全一致検索

// 連結情報(immune_to_属性)を拾わない
var f_arr
f_arr = string.Split(foe)

var auto_attr
auto_attr = get_player_attr()

func get_player_attr()
    var attr_list = [
        ["Perfected",""]
        ,["Poison","Ice"]
        ,["Vigor","Poison"]
        ,["AEther","Vigor"]
        ,["Fire","AEther"]
        ,["Ice","Fire"]
    ]
    var result = ""
    for i = 0..attr_list.Count()-1
        for j = 0..f_arr.Count()-1
            ?string.Equals(f_arr[j],attr_list[i][0])
                result = attr_list[i][1]
                return result
    return result

>`1,6,auto_attr = @auto_attr@

▲ 上に戻る

string.Formatの書式指定子を色々お試し

久々に見ませう
microsoft 書式指定子

▼ 標準書式指定子

var s_format = string.Format
var test = [
    "{0:G4}"  // General
    , "{0:N}" // Number
    , "{0:F}" // Fixed-point
    , "{0:E}" // Exponential(scientific)
    , "{0:P}" // Percent
    , "{0:D}" // Decimal
    , "{0:X}" // Hexadecimal
    , "{0:x}" // Hexadecimal
    , "{0:C}" // Currency
]

for i = 0..test.Count()-1
    >`1,@1+i@,@s_format(test[i], 123456789)@
    // 1.235E+08
    // 123,456,789.00
    // 123456789.00
    // 1234568E+008
    // 12,345,678,900.00%
    // 123456789
    // 75BCD15
    // 75bcd15
    // ¥123,456,789

追加チラリ sejuku.net

▼ 0埋め

>`1,1,@string.Format("{0:00000}",10)@
// 00010

>1,2,@string.Format("{0:D5}",10)@
// 00010

▼ 小数点以下の桁数を指定

>@string.Format("{0:#},{0:#.##}",math.pi)@
// 3,3.14

▼ 3桁区切り

>@string.Format("{0:#,0}",123456789)@
// 123,456,789

▼ 複数の文字列を連結

>@string.Format("{0} Story {1}","Stone","RPG")@
// Stone Story RPG

▲ 上に戻る

右揃えの九九表を作ってみよう

そろそろイベンツやりますかぁ👶
x3だと詰まって見えるからx4にちた

// 2文字を上限に右寄せ
var alignR_s2 = "{0,2}"

// 九九表
for x = 1..9
  for y = 1..9
    >`@x*4@,@y@,@string.Format(alignR_s2,x*y)@

いや…こっちでいっか!

// 九九表
for x = 1..9
  for y = 1..9
    >`@x*4@,@y@,@string.Format("{0,2}",x*y)@

▲ 上に戻る

アプリ再起動まで消した関数定義を使える

アプリ再起動までエラーを吐かず、働き続ける関数

▼ まずは定義名を一致させて使う

func test(a, b)
    return a + b

>`1,6,@test(1, 2)@
// 3

▼ アプリを再起動せず、定義を消す
もしくは定義名をデタラメにする

>`1,6,@test(1, 2)@
// 3

アプリを再起動してようやくエラー
変数も似たような件が起きてた気がする
そっちはまた別問題な気もするけど エラーにはならなかったから

今回はキャッシュというやつ?
重い関数を1回読み込んだら2回目以降は軽い表示になった事あるし
コンボちゃんが貼ってたfillなんかがそうだなぁ Discord

// Fills the screen with UI panels
var y = -1
func AddRow()
  y++
  for x = 0..screen.w-1
    var p = ui.AddPanel()
    p.style = 8
    p.x = x
    p.y = y
    p.w = 1
    p.h = 1
    p.dock = top_left
    p.color = #808080
?y < screen.h
  AddRow()
  AddRow()

▲ 上に戻る

bladeでより多くの敵を巻き込むscreen.iを取得

ダッシュ判定の距離以下で敵の最大数が更新された場合、screen.i保存

追記: foe.GetCountは多分1ベースでpos.xは0ベースなので5行目のrelative_2scrn_w = screen.w - scrn_posx末尾に + 1を足しておいた

var scrn_posx
var relative_2scrn_w
var f_count_2scrn
scrn_posx = screen.FromWorldX(pos.x)
relative_2scrn_w = screen.w - scrn_posx + 1
f_count_2scrn = foe.GetCount(relative_2scrn_w)

// screen.Next()使用
?scrn_posx > -1
    screen.Next()

// f_count_storeはscrn_i_store格納の判定に使用
var f_count_store = 0
var scrn_i_store = 0

?foe.distance <= 16
^& f_count_store <= f_count_2scrn
    f_count_store = f_count_2scrn
    scrn_i_store = screen.i

// 二画面分の最大敵数となるscreen.iを確認
>`1,6,ascii
scrn_i_store    @scrn_i_store@
f_count_store   @f_count_store@

relative_2scrn_w @relative_2scrn_w@
f_count_2scrn    @f_count_2scrn@

screen.i  @screen.i@
screen.w  @screen.w@
scrn_posx @scrn_posx@
asciiend

各ステージを数回まわして保存された値

ステージ 難易度 screen.i
scrn_i_store
二画面分の敵数
f_count_store
枯木の渓谷 ☆14 1 23
恐怖の洞窟 ☆15 4 20
キノコの森 ☆15 3 34
呪われた会館 ☆15 4 44
地獄の鉱山 ☆15 3 37
氷の尾根 ☆15 2 35
神殿 ☆15 12 41

画像のa - bの理由はマイナス値をマイナスするとプラスになるから…👶

// 例
var a = 10
var b = -5
var c = 0

?time <= 30
    c = a + b
:
    c = a - b

>@c@
// time30以下で5
// time30超で15

manualのstorage使って色々やってみたいけど、弄った事を忘れて(?!)色々ポイポイしちゃいそう
そんなもんで、弄りづらいっぴ
storage.Set(string, value)いつか使ってみたいね

▲ 上に戻る

エーテルのお守り

新しいお守りが追加されたね👶

ID
武器 aether_talisman
召喚 voidweaver
デバフ unstable

IDはmanualのクールダウン IDリストとスクリプトで確認出来るのだ
公式manual(英語)Cooldown IDで検索して1ヒットに絞りまする

▼ ID確認

// 召喚
?item.GetCooldown("aether_talisman") <= 0
^& item.CanActivate()
^& summon.count = 0
^| item.right = "aether_talisman"
^& item.right.state = 2
  equipR aether_talisman
  activate R

?summon.GetId() ! null
  >`0,1,召喚: @summon.GetId()@
  //    召喚: voidweaver

?foe
  >f0,0,デバフ: @foe.debuffs.string@
  //    デバフ: unstable

▼ voidweaverの能力発動例

?item.GetCooldown("voidweaver") <= 0
^& item.CanActivate()
^& summon.GetId() = "voidweaver"
^& foe.count > 18
  activate voidweaver

▼ cinderwispの能力発動例

?item.GetCooldown("cinderwisp") <= 0
^& item.CanActivate()
^& summon.GetId() = "cinderwisp"
^& summon.GetVar("ignition") = 10
  activate cinderwisp

▲ 上に戻る

指定size分、行(列)移動したら次の行(列)へ

var size = 10

>`@time % size@,@time / size@,#ffaa00,█
>`@time / size@,@time % size@,#ff00aa,█

フラッとBARへ入店
メニューにシガーがあるじゃあ〜りませんか
シガーといえばTar
折角だから頼むよね

ゲホゴホッこれは高尚な嗜み いい体験になりました
一度吸ってみたかったんだ
▲ 上に戻る

draw_circle

👶
https://retu27.com/enun_xyjiku.html

var m_floor = math.Floor
var tt
tt = totaltime

func draw_circle(x,y,dia,speed)
  var p_x = m_floor(math.Cos(tt/speed)*dia)
  var p_y = m_floor(math.Sin(tt/speed)*(dia/2))-1
  >`@x+p_x+dia@,@y+p_y+(dia/2)+1@,#ff0088,█

// draw_circle(x,y,dia,speed)
draw_circle(0,0,screen.h,15.0)
draw_circle(0,0,screen.w/2,20.0)
draw_circle(0,0,10,30.0)

▲ 上に戻る