设为首页收藏本站同能贴吧 切换语言 繁体中文
开启辅助访问 切换到窄版
扫描二维码关注官方公众号
返回列表
+ 发新帖
查看: 113|回复: 0

[转载发布] Costume Selector

[复制链接]
累计送礼:
0 个
累计收礼:
1 个
  • TA的每日心情
    开心
    2026-7-12 04:10
  • 签到天数: 209 天

    连续签到: 2 天

    [LV.7]常住居民III

    9071

    主题

    864

    回帖

    6万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    7
    卡币
    58883
    OK点
    16
    推广点
    0
    同能卷
    50
    积分
    68848

    灌水之王

    发表于 2026-8-3 13:06:40 | 显示全部楼层 |阅读模式
    This is a script that I wrote and allows to set up sprites in 96x128 sheets as costumes for the Player to pick from and use.
    I wrote it to suit my personal needs when playing RPG Maker VX Ace games, but I figured it'd be cool to share it with all of you.
    You're all constantly sharing cool scripts for free and stuff so I might as well put my grain of sand.

    Key Points

    To open the selector you can use
    1. SceneManager.call(Scene_SpriteSelector)
    复制代码
    .


    The magic happens in the "@sprite_data" array
    Which uses the following parameters:
    -The filename of a 96x128 sprite sheet containing your sprite's walking frames
    -A switch Id to toggle when you pick a sprite to use
    -A text string meant to describe each sprite
    -A switch Id that defines whether the sprite is unlocked and ready to use or not.
    -An item Id through which you can unlock specific sprites by having a specific item in the inventory.
    Setting the 2nd, 4th or 5th parameters (parameters 1, 3 and 4 in the code) to "-1" disables them.

    The script is somewhat messy because I wrote it for personal usage.
    Consider this something that you can plop into a project and will work as intended at best, and a script to use as a base to work with at worst.

    By default, the selector is designed for games that use a base screen resolution of 640x480 pixels
    But this can be easily adjusted with the variables that I laid at the top. Reducing the padding between or the amount of sprites per row and column should make it easy for this script to work in other screen resolutions besides the intended 640x480 for example.
    Probably.

    The script has a small safety measure of sorts
    If you input an invalid or nonexistent filename the script will show "a code-based placeholder sprite" kinda thing, a black square with a question mark.
    I should expand that and make it detect sprite sheets that don't adjust to the 96x128px criteria, buuut I'm kinda lazy and I personally don't need to do that so.

    The script uses a
    1. SPRITE_ID_VARIABLE
    复制代码
    to track the Id of the current sprite in use

    By default,
    1. SPRITE_ID_VARIABLE
    复制代码
    is set to 6.
    As a result, if you added 50 sprites to pick from and selected the 44th, the value of the Variable 6 would be set to 44.

    Pics and Vids



    Code

                    Ruby:       
    1. #############################################################################################################
    2. #                                                                                                           #
    3. # Terms of Use:                                                                                             #
    4. #                                                                                                           #
    5. # - This script can be used in commercial and non-commercial projects.                                      #
    6. #                                                                                                           #
    7. # - This script can be edited and used as a base to work with.                                              #
    8. #                                                                                                           #
    9. # - Redistribution is allowed but the link to this script's thread in RPG Maker Forums has to be included.  #
    10. #   https://forums.rpgmakerweb.com/index.php?threads/costume-selector.176487                                #
    11. #                                                                                                           #
    12. # - If you use this script in a publicly published project                                                  #
    13. #   regardless of whether it's commercial or not,                                                           #
    14. #   credits to me (Nanjo from the RPG Maker Forums) are mandatory.                                          #
    15. #                                                                                                           #
    16. #############################################################################################################
    17. class Scene_SpriteSelector < Scene_MenuBase
    18.   FRAME_WIDTH = 32
    19.   FRAME_HEIGHT = 32
    20.   ARROW_OFFSET_Y = -24
    21.   SPRITE_OFFSET_Y = 16
    22.   VERTICAL_SPACING = 16
    23.   HORIZONTAL_SPACING = 18
    24.   TOP_PADDING = 40
    25.   SPRITES_PER_ROW = 11
    26.   SPRITES_PER_COLUMN = 6
    27.   SPRITES_PER_PAGE = SPRITES_PER_ROW * SPRITES_PER_COLUMN
    28.   SPRITE_ID_VARIABLE = 6
    29.   ACTOR_ID = 1
    30.   def start
    31.     super
    32.     @current_page = 0
    33.     @current_index = 0
    34.     create_background_window
    35.     create_sprites
    36.     create_arrow
    37.     create_message_window
    38.     update_arrow
    39.   end
    40.   def create_background_window
    41.     @background_window = Window_Base.new(0, 0, Graphics.width, Graphics.height - 72)
    42.     @background_window.opacity = 128
    43.   end
    44.   def create_sprites
    45.     dispose_sprites
    46.     @sprites = []
    47.     @unlocked_sprites = []
    48.     @sprite_data = [
    49.       ["Actor1", -1, "Actor 1 sprite", -1, -1],
    50.       ["Actor2", -1, "Actor 2 sprite", -1, -1],
    51.       ["Actor3", -1, "Actor 3 sprite", -1, -1],
    52.       ["Actor4", -1, "Actor 4 sprite", -1, -1],
    53.       ["Insane1", -1, "Unlocks when Life Up is in inventory", -1, 9],
    54.       ["Insane2", -1, "Unlocks when Switch 1 is ON", 1, -1],
    55.       ["Monster1", -1, "Unlocks when Life Up is in inventory and Switch 2 is ON", 2, 9],
    56.       ["Monster2", 2, "Sets Switch 2 to ON", -1, -1],
    57.     ]
    58.     @viewport = Viewport.new(0, 0, Graphics.width, Graphics.height - 72)
    59.     @viewport.z = 100
    60.     first_row_y = TOP_PADDING
    61.     page_data = @sprite_data[@current_page * SPRITES_PER_PAGE, SPRITES_PER_PAGE] || []
    62.     page_data.each_with_index do |data, index|
    63.       sprite = Sprite.new(@viewport)
    64.       character_name = data[0]
    65.       next if character_name.nil?
    66.       sprite.opacity = ($game_switches[data[3]] || data[3] == -1) && ($game_party.has_item?($data_items[data[4]]) || data[4] == -1) ? 255 : 100
    67.       @unlocked_sprites.push(sprite.opacity == 255)
    68.       begin
    69.         sprite.bitmap = Cache.character(character_name)
    70.       rescue StandardError
    71.         sprite.bitmap = Bitmap.new(FRAME_WIDTH, FRAME_HEIGHT)
    72.         sprite.bitmap.fill_rect(0, 0, FRAME_WIDTH, FRAME_HEIGHT, Color.new(0, 0, 0))
    73.         draw_small_question_mark(sprite.bitmap)
    74.       end
    75.       sprite.src_rect.set(0, 0, FRAME_WIDTH, FRAME_HEIGHT)
    76.       row = index / SPRITES_PER_ROW
    77.       col = index % SPRITES_PER_ROW
    78.       sprite.x = 50 + col * (FRAME_WIDTH + HORIZONTAL_SPACING)
    79.       sprite.y = first_row_y + row * (FRAME_HEIGHT + SPRITE_OFFSET_Y + VERTICAL_SPACING)
    80.       @sprites.push(sprite)
    81.     end
    82.   end
    83.   def draw_small_question_mark(bitmap)
    84.     font = Font.new(24)
    85.     bitmap.font = font
    86.     question_text = "?"
    87.     text_width = bitmap.text_size(question_text).width
    88.     text_height = bitmap.text_size(question_text).height
    89.     x = (FRAME_WIDTH - text_width) / 2
    90.     y = (FRAME_HEIGHT - text_height) / 2
    91.     bitmap.draw_text(x, y, text_width, text_height, question_text, 1)
    92.   end
    93.   def create_message_window
    94.     @message_window = Window_Base.new(0, Graphics.height - 72, Graphics.width, 72)
    95.     @message_window.contents = Bitmap.new(@message_window.width - 32, @message_window.height - 32)
    96.     update_message
    97.   end
    98.   def update_message
    99.     @message_window.contents.clear
    100.     if @sprite_data[@current_index]
    101.       text = @sprite_data[@current_index][2]
    102.       @message_window.draw_text(0, 0, @message_window.contents.width, 48, text, 1)
    103.     end
    104.   end
    105.   def create_arrow
    106.     @arrow_sprite = Sprite.new(@viewport)
    107.     @arrow_sprite.bitmap = Bitmap.new(32, 16)
    108.     @arrow_sprite.bitmap.clear
    109.     16.times do |y|
    110.       x_start = y
    111.       x_end = 31 - y
    112.       @arrow_sprite.bitmap.fill_rect(x_start, y, x_end - x_start + 1, 1, Color.new(255, 0, 0))
    113.     end
    114.     @arrow_sprite.ox = 16
    115.     @arrow_sprite.oy = 0
    116.   end
    117.   def update_arrow
    118.     return if @sprites.empty? || @sprites[@current_index].nil?
    119.     sprite = @sprites[@current_index]
    120.     @arrow_sprite.x = sprite.x + FRAME_WIDTH / 2
    121.     @arrow_sprite.y = sprite.y + ARROW_OFFSET_Y
    122.   end
    123.   def handle_input
    124.     if Input.repeat?(:RIGHT)
    125.       if @current_index < SPRITES_PER_PAGE - 1 && @current_page * SPRITES_PER_PAGE + @current_index < @sprite_data.size - 1
    126.         @current_index += 1
    127.       elsif (@current_page + 1) * SPRITES_PER_PAGE < @sprite_data.size
    128.         @current_page += 1
    129.         @current_index = 0
    130.       end
    131.       create_sprites
    132.       update_arrow
    133.       update_message
    134.     elsif Input.repeat?(:LEFT)
    135.       if @current_index > 0
    136.         @current_index -= 1
    137.       elsif @current_page > 0
    138.         @current_page -= 1
    139.         @current_index = SPRITES_PER_PAGE - 1
    140.       end
    141.       create_sprites
    142.       update_arrow
    143.       update_message
    144.     elsif Input.repeat?(:DOWN)
    145.       if @current_index + SPRITES_PER_ROW < SPRITES_PER_PAGE && @current_page * SPRITES_PER_PAGE + @current_index + SPRITES_PER_ROW < @sprite_data.size
    146.         @current_index += SPRITES_PER_ROW
    147.       elsif (@current_page + 1) * SPRITES_PER_PAGE < @sprite_data.size
    148.         @current_page += 1
    149.         @current_index += SPRITES_PER_ROW - SPRITES_PER_PAGE
    150.       end
    151.       create_sprites
    152.       update_arrow
    153.       update_message
    154.     elsif Input.repeat?(:UP)
    155.       if @current_index - SPRITES_PER_ROW >= 0
    156.         @current_index -= SPRITES_PER_ROW
    157.       elsif @current_page > 0
    158.         @current_page -= 1
    159.         @current_index -= SPRITES_PER_ROW - SPRITES_PER_PAGE
    160.       end
    161.       create_sprites
    162.       update_arrow
    163.       update_message
    164.     elsif Input.trigger?(:C)
    165.       selected_index = @current_page * SPRITES_PER_PAGE + @current_index
    166.       if @unlocked_sprites[@current_index]
    167.         sprite_name = @sprite_data[selected_index][0]
    168.         begin
    169.           Cache.character(sprite_name)
    170.         rescue StandardError
    171.           Sound.play_buzzer
    172.           return
    173.         end
    174.         $game_player.set_graphic(sprite_name, 0)
    175.         $game_variables[SPRITE_ID_VARIABLE] = selected_index if SPRITE_ID_VARIABLE != -1
    176.         $game_switches[@sprite_data[selected_index][1]] = true if @sprite_data[selected_index][1] != -1
    177.         Sound.play_ok
    178.         SceneManager.return
    179.       else
    180.         Sound.play_buzzer
    181.       end
    182.     elsif Input.trigger?(:B)
    183.       SceneManager.return
    184.     end
    185.   end
    186.   def update
    187.     super
    188.     handle_input
    189.   end
    190.   def dispose_sprites
    191.     @sprites.each(&:dispose) if @sprites
    192.     @sprites = []
    193.   end
    194. end
    复制代码


    Special thanks to Anonymous for helping me fix a problem with the cursor when switching between sprite pages that was driving me crazy!

    Well, that's all from me!

    Take care
    !​




    本贴来自国际rpgmaker官方论坛作者:Nanjo处,因国际论坛即将永久关站,为了存档多年珍贵资料,署名转载到本论坛存档,由于官方帖子为英文原帖,需要中文翻译请点击论坛顶部切换语言为中文就可以将帖子翻译成中文浏览,方便大家随时查看,原文地址:https://forums.rpgmakerweb.com/threads/costume-selector.176487/

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    天天去同能,天天有童年!
    回复 送礼论坛版权

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    高级模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    简体中文
    繁體中文
    English(英语)
    日本語(日语)
    Deutsch(德语)
    Русский язык(俄语)
    بالعربية(阿拉伯语)
    Türkçe(土耳其语)
    Português(葡萄牙语)
    ภาษาไทย(泰国语)
    한어(朝鲜语/韩语)
    Français(法语)
    关闭

    幸运抽奖

    社区每日抽奖来袭,快来试试你是欧皇还是非酋~

    立即查看

    聊天机器人
    Loading...

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2026-8-17 06:15 , Processed in 0.145418 second(s), 55 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表