Help us understand the problem. What is going on with this article?

【TIC-80】2.25方向境界タイルの自動生成とremapでの表示

More than 1 year has passed since last update.

境界線にどうしてここまでこだわるのか‥‥。
空の境界線上のNEW HORIZON...

自分の最初の記事よりはだいぶ汎用的なものになった...はず(?)

境界線タイル設定.gif

こんな感じでスプライトエディタでタイルを作って‥
(FC仮面ライダー倶楽部のつるてかレンガリスペクト)

境界マップ.gif

マップエディタでペタペタとならべて

境界コード.gif

初期化時にでも今回作成の関数を呼んで、remap用関数にセットして、map命令にこの関数を指定して実行すると。

境界実行.gif

じゃん!
同じタイルはつながって、それ以外の間には境界線が引かれます。
(境界付きのタイルが並べられます)
後ろにエラーが見えている? HAHAHA

境界タイル生成とremap用関数を返す、両方を行う関数は以下のような仕様です。

bordertilef(fidx,nums,leftup,bcolor,bwidth,tilesync)

  • fidx : 生成対象の開始タイル番号
  • nums : タイル個数(開始タイルから右にこの個数分処理)
  • leftup : 左上を考慮するか否か(true or false)
  • bcolor : 境界線の色番号
  • bwidth : 境界線の幅(ドット)
  • tilesync : 境界タイルを tic ファイル(ゲームのROMに当たる)に反映するか否か

別タイル.gif

このような単色タイルをセットして、初期化部分とメインループ部分を以下のようにすると

testinit.lua
testinit=function()
    rm=bordertilef(16,16,true,7,2)
    rmflag=true
end

testinit()

function TIC()
    map(0,17,30,17,0,0,-1,1,rmflag and rm)
    if btnp(0,1,30) then rmflag = not rmflag end
end

kirikae.gif

このように境界の幅や色を変えたり、左上の考慮を有効にすると角が欠けるのを防ぐことができます。
mget(x,y)で取得できるワールドマップのタイル番号はそのままなので、remapをセットするかしないかで境界の有無の切り替えが可能です。

全リストは以下の通りです。

bordertile.lua
PTN={
    {true,false,true,false},
    {true,true,false,false},
    {true,true,true,false},
    {true,false,false,false}
}

-- common function from TIC-80 wiki
function sset(x,y,c)
    local addr=0x4000+(x//8+y//8*16)*32
    poke4(addr*2+x%8+y%8*8,c)end
function sget(x,y)
    local addr=0x4000+(x//8+y//8*16)*32
    return peek4(addr*2+x%8+y%8*8)end

-- my function
function bordertilef(fidx,nums,leftup,bcolor,bwidth,tilesync)
    local id,n,pn=fidx or 0,nums or 16,leftup and 4 or 3
    local bc,bw,bg=bcolor or 0,bwidth or 1,bgidx or 0
    for i=id,id+n-1 do
        local sx,sy=i%16*8,i//16*8
        local org={}
        for j=0,63 do
            org[j]=sget(sx+j%8,sy+j//8) end
        for nn=1,pn do
            for yy=0,7 do
                for xx=0,7 do
                    local isb=PTN[nn][(xx<bw and 0 or 1)+(yy<bw and 0 or 2)+1]
                    sset(sx+xx,nn*8+sy+yy,isb and bc or org[xx+yy*8])end end end end
    if tilesync then sync(1,0,true) end
    return function(tile,x,y)
        local dLeft=(tile==mget((x-1)%240,y%136))and 0 or 1
        local dUp=(tile==mget(x%240,(y-1)%136))and 0 or 2
        local dLU=(dLeft==0 and dUp==0 and leftup and tile~=mget((x-1)%240,(y-1)%136))and 4 or 0
        return tile+(dLeft+dUp+dLU)*16 end end

testinit=function()
    rm=bordertilef(16,16,true,7,2)
    rmflag=true
end

testinit()

function TIC()
    map(0,17,30,17,0,0,-1,1,rmflag and rm)
    if btnp(0,1,30) then rmflag=not rmflag end
end

う、う~ん... 微妙に分かりづらいなあ。1週間後はともかく1ヶ月後の自分がきちんと理解できるか自信がないので今のウチにどんな考えで組んだのかメモっておきたいけど‥‥
後で追記か別途続きを書くとします。(書きます、多分)

uokagi
プログラムは極稀に(数年に一度)スクリプト系を触る程度です。今はAviUtlやTIC-80のためにLuaを触っています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした