見出し画像

【ティラノスクリプト】アイテム取得時の通知のサンプル

アイテム取得時の通知のサンプルです。


【使用素材】

イラスト緑花様の素材を使用させていただきました。

いらすとや様の素材を使用させていただきました。

【toast.js】

// toast_wrapperの作成関数
const createToastWrapperElement = function(settings) {
    const totalHeight = settings.firstToastOffset + 
        (settings.toastHeight + settings.marginBetween) * settings.maxToast - 
        settings.marginBetween + settings.firstToastOffset;

    // toast_wrapperの作成とスタイル適用
    const $toast_wrapper = $('<div id="toast_wrapper"></div>').css({
        width: `${settings.toastWidth}px`,
        height: `${totalHeight}px`,
        position: 'relative'
    });

    // toast_wrapperをDOMに追加
    const target_layer = TYRANO.kag.layer.getLayer(settings.layer, settings.page);
    target_layer.append($toast_wrapper);

    return $toast_wrapper;
};

// トーストを追加する関数
const addToast = function(settings, $toast_wrapper, messages, messageKey) {
    // 各トーストのY座標を計算
    const translateYValues = Array.from({ length: settings.maxToast }, (_, i) =>
        settings.firstToastOffset + (settings.toastHeight + settings.marginBetween) * i
    );

    // 新しいトーストのメッセージとIDを生成
    const existingToastCount = $('.toast_container').length;
    const message = messages[messageKey];
    
    // トーストIDをインクリメント
    TYRANO.kag.stat.f.numOfToast += 1;
    const newToastId = `toast_${TYRANO.kag.stat.f.numOfToast}`;
    
    // 新しいトースト要素を作成
    const $newToast = createToastElement(settings, message, existingToastCount, translateYValues);

    // トーストをDOMに追加し、管理配列に登録
    $toast_wrapper.append($newToast);
    TYRANO.kag.stat.f.toastQueue.push($newToast);

    // トーストの自動削除をセット
    setToastRemovalTimer(settings, $newToast, newToastId, translateYValues);

    // トーストの最大数を超えた場合、古いトーストを削除
    if (TYRANO.kag.stat.f.toastQueue.length > settings.maxToast) {
        removeOldestToast(settings, translateYValues);
    }
};

// トーストの削除タイマーを設定する関数
const setToastRemovalTimer = function(settings, $newToast, newToastId, translateYValues) {
    const timerId = setTimeout(() => {
        // トーストのフェードアウト
        $newToast.find('.toast_inner').addClass('fade-out');
        $newToast.one('animationend', () => {
            // DOMからトーストを削除し、キューとタイマーからも削除
            $newToast.remove();
            TYRANO.kag.stat.f.toastQueue = TYRANO.kag.stat.f.toastQueue.filter(toast => toast.attr('id') !== newToastId);
            delete TYRANO.kag.stat.f.toastTimers[newToastId];

            // トースト位置を更新
            shiftToastPositions(settings, translateYValues);
        });
    }, settings.displayDuration);

    // タイマーIDを保存
    TYRANO.kag.stat.f.toastTimers[newToastId] = timerId;
    $newToast.attr('id', newToastId);
};

// 一番古いトーストを削除する関数
const removeOldestToast = function(settings, translateYValues) {
    const $oldestToast = TYRANO.kag.stat.f.toastQueue.shift(); // 古いトーストをキューから取り出す
    const oldestToastId = $oldestToast.attr('id');

    // 古いトーストのタイマーをクリア
    clearTimeout(TYRANO.kag.stat.f.toastTimers[oldestToastId]);
    delete TYRANO.kag.stat.f.toastTimers[oldestToastId];

    // フェードアウトさせて削除
    $oldestToast.find('.toast_inner').addClass('fade-out');
    $oldestToast.one('animationend', () => {
        $oldestToast.remove();
        shiftToastPositions(settings, translateYValues); // 残りのトーストの位置を調整
    });
};

// トーストの位置をシフトする関数
const shiftToastPositions = function(settings, translateYValues) {
    $('.toast_container').each((index, toast) => {
        $(toast).css('transform', `translateY(${translateYValues[index]}px)`);
    });
};

// 新しいトースト要素を作成する関数
const createToastElement = function(settings, message, index, translateYValues) {
    const translateY = translateYValues[Math.min(index, settings.maxToast - 1)];
    
    // トースト要素を作成して返す
    return $('<div class="toast_container"></div>')
        .append(`<div class="toast_inner">${message}</div>`)
        .css({
            width: `${settings.toastWidth}px`,
            height: `${settings.toastHeight}px`,
            position: 'absolute',
            left: '0px',
            transform: `translateY(${translateY}px)`,
            transition: 'transform 0.3s ease'
        });
};

【toast.css】

/* toast_wrapperのスタイル */
#toast_wrapper {
    top: 100px;
    overflow: hidden;
}

/* toast_containerのスタイル */
.toast_container {
    position: absolute;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 5px;
    color: #333;
    font-size: 14px;
    transition: transform 0.5s ease-in-out;
}

/* toast_innerのスタイル */
.toast_inner {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-size: 20px;
    background: #0000004d;
    color: white;
    animation: slide-in forwards 1s ease-in-out;
}

/* 退場アニメーションを適用するクラス */
.fade-out {
    animation: fade-out forwards 0.5s ease-in-out;
}

/* 入場アニメーション */
@keyframes slide-in {
    0% {
        transform: translateX(150%); /* 初期位置:画面外右側 */
    }
    100% {
        transform: translateX(0);    /* 最終位置:画面内 */
    }
}

/* 退場アニメーション */
@keyframes fade-out {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}

【scene1.ks】

*start

[loadjs storage="js/toast.js"]
[loadcss file="./data/others/css/toast.css" ]

[cm  ]
[clearfix]
[start_keyconfig]

[bg storage="bg.jpg" time="100"]
[layopt layer="0" visible="true"]

[iscript]

f.settings = {
    layer: 0, // toast_wrapperのレイヤー
    page: 'fore', // toast_wrapperのページ
    toastHeight: 50,              // トーストの縦幅(px)
    toastWidth: 800,              // トーストの横幅(px)
    marginBetween: 10,            // トースト間の余白(px)
    firstToastOffset: 10,         // 最初のトーストのオフセット(px)
    maxToast: 5,               // 最大トースト数(画面内に収まる数)
    displayDuration: 5000         // トーストが表示される時間 (ms)
};

// メッセージの定義
f.messages = {
    item1: "りんご×1",
    item2: "みかん×1",
    item3: "ぶどう×1",
    item4: "バナナ×1",
    item5: "いちご×1",
    item6: "メロン×1",
    item7: "すいか×1",
    item8: "くり×1",
    item9: "さくらんぼ×1",
    item10: "ブルーベリー×1"
};

// トースト管理用の変数
f.numOfToast = 0;              // トーストの番号を管理するカウンタ
f.toastTimers = {};               // トーストごとのタイマーIDを保持するオブジェクト
f.toastQueue = [];                // トーストの管理配列

// toast_wrapperを作成
f.toast_wrapper = createToastWrapperElement(f.settings);  // createToastWrapperElement関数の呼び出し

[endscript]

*button

[button graphic="item1.png" storage="" target="*get" name="item1" x="65" y="160" width="150" height="150" fix="true" exp="f.select = 'item1'" auto_next="false"]
[button graphic="item2.png" storage="" target="*get" name="item2" x="315" y="160" width="150" height="150" fix="true" exp="f.select = 'item2'" auto_next="false"]
[button graphic="item3.png" storage="" target="*get" name="item3" x="565" y="160" width="150" height="150" fix="true" exp="f.select = 'item3'" auto_next="false"]
[button graphic="item4.png" storage="" target="*get" name="item4" x="815" y="160" width="150" height="150" fix="true" exp="f.select = 'item4'" auto_next="false"]
[button graphic="item5.png" storage="" target="*get" name="item5" x="1065" y="160" width="150" height="150" fix="true" exp="f.select = 'item5'" auto_next="false"]
[button graphic="item6.png" storage="" target="*get" name="item6" x="65" y="410" width="150" height="150" fix="true" exp="f.select = 'item6'" auto_next="false"]
[button graphic="item7.png" storage="" target="*get" name="item7" x="315" y="410" width="150" height="150" fix="true" exp="f.select = 'item7'" auto_next="false"]
[button graphic="item8.png" storage="" target="*get" name="item8" x="565" y="410" width="150" height="150" fix="true" exp="f.select = 'item8'" auto_next="false"]
[button graphic="item9.png" storage="" target="*get" name="item9" x="815" y="410" width="150" height="150" fix="true" exp="f.select = 'item9'" auto_next="false"]
[button graphic="item10.png" storage="" target="*get" name="item10" x="1065" y="410" width="150" height="150" fix="true" exp="f.select = 'item10'" auto_next="false"]

[s]

*get

[clearfix name="&f.select"]

[iscript]
addToast(f.settings, f.toast_wrapper, f.messages, f.select);
[endscript]

[return]