累计送礼: 0 个 累计收礼: 1 个 TA的每日心情 开心 2026-7-12 04:10
签到天数: 209 天
连续签到: 2 天
[LV.7]常住居民III
管理员
VIP
7
卡币
25563
OK点
16
推广点
0
同能卷
50
积分 32235
Heya. I was dissapointed with absence of a propper Achievement handler besides Steam API for VX, so I made my own that utilizes local files and
events !
Keeps track of locked and unlocked achievements on title screen via extra window command, an option to reset collection progress as well.
Progress saves between save files, and after a shutdown.
Ruby:
# Achievements Script for RPGMaker VX by @le_kastle (pls credit) module Achievements # Create achievements.txt in Data folder, and achivement images in Graphics/Pictures FILE_PATH = "Data/achievements.txt" ACHIEVEMENTS = { :achievement1 => { :name => "1", :description => "desc1", :achieved => false, :image => "achievement1", :common_event_id => 6 }, :achievement2 => { :name => "2", :description => "desc2", :achieved => false, :image => "achievement2", :common_event_id => 7 }, :achievement3 => { :name => "3", :description => "desc3", :achieved => false, :image => "achievement3", :common_event_id => 8 } } # Common events used for displaying achievement acquirement in game (if you want it) # Loads achievements from a file def self.load_achievements return unless File.exist?(FILE_PATH) File.readlines(FILE_PATH).each do |line| key, value = line.strip.split(" = ") key = key.downcase.to_sym if ACHIEVEMENTS.has_key?(key) ACHIEVEMENTS[key][:achieved] = (value == "true") else puts "Warning: Achievement key '#{key}' not found in ACHIEVEMENTS hash." end end end # Save the achievements to the file def self.save_achievements File.open(FILE_PATH, "w") do |file| ACHIEVEMENTS.each do |key, data| file.puts "#{key} = #{data[:achieved]}" end end end # Unlock an achievement def self.unlock(achievement) return if ACHIEVEMENTS[achievement][:achieved] ACHIEVEMENTS[achievement][:achieved] = true save_achievements end # Check if an achievement is unlocked def self.unlocked?(achievement) ACHIEVEMENTS[achievement][:achieved] end # Reset all achievements def self.reset_achievements ACHIEVEMENTS.each do |key, data| data[:achieved] = false end save_achievements end end # Interpreter integration for unlocking achievements class Game_Interpreter def unlock_achievement(achievement) Achievements.unlock(achievement) end end class Scene_Title < Scene_Base alias achievements_update update unless method_defined?(:achievements_update) def update achievements_update handle_achievements_input if @command_window && @command_window.active end private # Handle Achievements command def command_achievements Sound.play_decision $scene = Scene_Achievements.new end def handle_achievements_input return unless Input.trigger?(Input::C) case @command_window.index when 3 # Achievements command_achievements when 4 # Reset command_reset_achievements end end # Handle Reset Achievements command def command_reset_achievements Sound.play_decision if confirm_reset_achievements Achievements.reset_achievements Sound.play_recovery else Sound.play_buzzer end end # Confirmation to reset def confirm_reset_achievements Graphics.update Input.update # Wait for input for confirmation loop do Graphics.update Input.update if Input.trigger?(Input::C) # Confirm return true elsif Input.trigger?(Input::B) # Cancel with ESC return false end end end end class Scene_Achievements < Scene_Base def start super create_achievement_window end def create_achievement_window @achievement_window = Window_Achievements.new(0, 0, Graphics.width, Graphics.height) end def update super @achievement_window.update if Input.trigger?(Input::B) Sound.play_cancel return_to_title end end # Properly dispose of the window and return to the title def return_to_title @achievement_window.dispose $scene = Scene_Title.new end end # Achievement window class Window_Achievements < Window_Base def initialize(x, y, width, height) super(x, y, width, height) @page = 0 refresh end def refresh self.contents.clear draw_page_indicator achievements = Achievements::ACHIEVEMENTS.to_a[@page * 3, 3] # Adjust number of achievements per page achievements.each_with_index do |(key, data), index| draw_achievement(data, index) end end def draw_page_indicator total_pages = (Achievements::ACHIEVEMENTS.size / 3.0).ceil text = "Page #{@page + 1}/#{total_pages}" self.contents.draw_text(0, self.contents.height - 24, self.contents.width, 24, text, 1) end def draw_achievement(data, index) # Calculate manual position for each achievement entry x = 12 y = index * WLH * 4 # Increase the spacing to reduce overlap # Draw achievement name and description self.contents.font.color = normal_color self.contents.draw_text(x + 110, y, contents.width - 110, WLH, data[:name]) if data[:achieved] self.contents.draw_text(x + 110, y + WLH, contents.width - 110, WLH, data[:description]) end # Draw achievement icon (if available) draw_icon(data[:image], x, y) end def draw_icon(image_name, x, y) bitmap = Cache.picture(image_name) rect = Rect.new(0, 0, 100, 100) self.contents.blt(x, y, bitmap, rect) end def update super if Input.trigger?(Input::RIGHT) next_page elsif Input.trigger?(Input::LEFT) prev_page end end def next_page @page = (@page + 1) % total_pages refresh end def prev_page @page = (@page - 1) % total_pages refresh end def total_pages (Achievements::ACHIEVEMENTS.size / 3.0).ceil # Adjust the page count end end # Load achievements at game start Achievements.load_achievements 复制代码
How to utilize:
1. Put anywhere in your custom scripts area in the editor (Above main)
2. Use this in event tab:
Code:
if Achievements.unlocked?(:achievement1) # Code to execute if the achievement is already unlocked (for example activate switch) else # Unlock if not unlocked already unlock_achievement(:achievement1) end 复制代码
Watch screenshots to see how it works
本贴来自国际rpgmaker官方论坛作者:Kastle处,因国际论坛即将永久关站,为了存档多年珍贵资料,署名转载到本论坛存档,由于官方帖子为英文原帖,需要中文翻译请点击论坛顶部切换语言为中文就可以将帖子翻译成中文浏览,方便大家随时查看,原文地址:
https://forums.rpgmakerweb.com/threads/local-achievements-script-vx-ace.175371/