Wielopoziomowe skille - Mateusz SSJ8 - 05-09-16 15:32
Dzisiaj dowiecie się, jak zrobić w grze skille, mające wiele poziomów.Potrzebne nam do tego będą następujące rzeczy:
1. Nadpisana klasa RPG::Actor
2. Nadpisana klasa RPG::Class
3. Nadpisana klasa RPG::Skill
4. Definicja klasy RPG::Feature
5. Definicja klasy RPG::Effect
6. Definicja klasy RPG::Learning
7. Przepisanie wszystkich skryptów w Edytorze na podobieństwo RPG Makera Vx Ace
8. Definicja klasy RPG::Ability
9. Definicja klasy RPG::ItemBase
Po co aż tyle? Przekonacie się. Choć, jak się wkrótce domyślicie, potrzebne może być więcej.
Na początek tworzymy skrypt "Clear" i tam wywołujemy dla modułu "RPG" polecenie usunięcia stałych "Actor", "Class" i "Skill".
Kod:
RPG.send(:remove_const, :Actor) # kasuje oryginalną klasę RPG::Actor
Następnie wchodzimy do modułu DataManager i definiujemy funkcję "load_script" odwołującą się bezpośrednio do pliku "filename".
Kod:
def self.load_script(filename)
require File.expand_path('./') + '/root/' + filename + '.rb'
end
Teraz w głównym folderze naszej gry tworzymy folder "root", aw nim pliki skryptu Ruby o następujących nazwach:
+classes
+actor
+class
+ability
+skill
W pliku "classes" definiujemy na nowo wszystkie klasy modułu RPG, które wykasowaliśmy, plus te, których i tak nie było w naszej grze.
Kod:
class RPG::Actor
attr_reader :id, :features, :user_effects, :target_effects, :levels, :equip_items, :exp_curve, :learnings
attr_accessor :name, :class_id, :description, :nickname, :character_name, :character_hue, :battler_name, :battler_hue, :face_name, :face_hue, :face_index, :exp_for_level
def initialize(id)
@id = id
@name = ''
@class_id = 0
@description = ''
@nickname = ''
@levels = [1, 100]
@exp_curve = [20,0,30,0]
@exp_for_level = nil
@features = []
@user_effects = []
@learnings = []
@target_effects = []
@character_name = ''
@character_hue = 0 # tylko XP
@battler_name = '' #tylko XP
@battler_hue = 0 #tylko XP
@face_name = ''#standardowo tylko VXy
@face_hue = 0 #tylko niestandardowo i XP
@face_index = 0 #standardowo tylko VXy
@equip_items = []
end
end
class RPG::Class
attr_reader :id, :features, :user_effects, :target_effects, :exp_curve, :learnings
attr_accessor :name, :position, :exp_for_level
def initialize(id)
@id = id
@name = ''
@position = 0 #tylko XP
@features = []
@user_effects = []
@target_effects = []
@exp_curve = [0, 0, 0, 0]
@exp_for_level = nil
@learnings = []
end
end
class RPG::ItemBase
attr_reader :id, :user_effects, :target_effects
attr_accessor :name, :icon_name
def initialize(id)
@id = id
init_instances
end
def init_instances
@name = ''
@icon_name = ''
@user_effects = []
@target_effects = []
end
end
class RPG::Ability
attr_reader :features, :costs, :required_levels
attr_accessor :self_learn_levels
def init_instances
super
@features = []
@self_learn_levels = nil
@costs = {}
@required_levels = {}
end
end
class RPG::ActionItem < RPG::ItemBase
attr_reader :available
attr_accessor :animation1_id, :animation2_id, :projectile_id
def init_instances
super
@available = []
@animation1_id = 0
@animation2_id = 0
@projectile_id = 0
end
end
class RPG::Skill < RPG::ActionItem
attr_accessor :target_list, :target_distance, :target_angle, :target_range, :trait, :projectile_id, :req, :hit, :eva, :ptk, :mtk, :str, :int, :rate
def init_instances
super
@target_list = nil
@target_distance = 1
@target_angle = 22.5
@target_range = 0
@trait = false
@req = ''
@projectile_id = 0#tylko, jeśli używasz pocisków
@hit = '100'
@eva = '0'
@ptk = '100'
@mtk = '100'
@str = '0'
@int = '0'
@rate = '(20) / 20'
end
end
class RPG::Feature
attr_reader :condition, :code, :id, :params
def initialize(code, condition, id, *params)
@condition = condition
@code = code
@id = id
@params = params
end
end
class RPG::Effect
attr_reader :key, :code, :id, :params
def initialize(key, code, id, *params)
@key = key
@code = code
@id = id
@params = params
end
end
class RPG::Learning
attr_reader :level, :type, :item_id, :ap, :tech, :req, :learn
def initialize(level, type, item_id, ap, tech, req, learn)
@level = level
@type = type #:ability to umiejętność, :skill to atak
@item_id = item_id
@ap = ap
@tech = tech
@req = req #jeśli ten skrypt nie jest pusty, postęp działa, jeśli ten skrypt zwróci "true"
@learn = learn #jeśli ten skrypt nie jest pusty, zostanie wywołany przy nauce
end
end
Do pliku "actor" wprowadzamy następujący kod:
Kod:
$data_actors = []
size = 1
if size >= 1
id = 1
$data_actors[id] = RPG::Actor.new(id)
$data_actors[id].name = 'Bohater 1'
$data_actors[id].class_id = 1
$data_actors[id].nickname= 'Twardziel'
$data_actors[id].description = 'Jakiś tam tekst'
$data_actors[id].levels[0..1] = [początkowy, końcowy]
$data_actors[id].exp_curve[0..n] = [...] #wprowadź,ile chcesz
$data_actors[id].exp_for_level = wartość #nil oznacza, że będzie z klasy
$data_actors[id].character_name = plik_charsetu
$data_actors[id].character_hue = odcień_charsetu
$data_actors[id].battler_name = plik_grafiki_do_walki
$data_actors[id].battler_hue = odcień_grafiki_do_walki
$data_actors[id].face_name = plik_twarzy
$data_actors[id].face_hue = odcień_twarzy
$data_actors[id].face_index = numer_twarzy
$data_actors[id].features.push(RPG::Feature.new(kod, warunek, id, parametr1, parametr2,...))#dla charakterystyki
$data_actors[id].user_effects.push(RPG::Effect.new(klucz, kod, id, parametr1, parametr2,...))#dla efektu wywołanego na tym bohaterze przez ruch określony kluczem.
$data_actors[id].target_effects.push(RPG::Effect.new(klucz,kod, id, parametr1, parametr2,...))#dla efektu wywołanego na tego, kogo ten bohater potraktował ruchem określonymprzez klucz.
$data_actors[id].learnings.push(RPG::Learning.new(poziom, typ, ID, ap, technika, wymagane, nauka))#dla postępu jednej umiejętności
end
Naszym następnym celem jest plik "class", gdzie wprowadzamy:
Kod:
$data_classes = []
size = 1
if size >= 1
id = 1
$data_classes[id] = RPG::Class.new(id)
$data_classes[id].name = 'Złodziej'
$data_classes[id].position = 1
$data_classes[id].exp_for_level = wartość #nil oznacza, że będzie domyślne
$data_classes[id].features.push(RPG::Feature.new(kod, warunek, id, parametr1, parametr2,...))#jak przy bohaterze
$data_classes[id].user_effects.push(RPG::Effect.new(klucz, kod, id, parametr1, parametr2,...))#jak przy bohaterze
$data_classes[id].target_effects.push(RPG::Effect.new(klucz, kod, id, parametr1, parametr2,...))#jak przy bohaterze
$data_classes[id].learnings.push(RPG::Learning.new(poziom, typ, ID, ap, technika, wymagane, nauka))#dla postępu jednej umiejętności
$data_classes[id].exp_curve[0..n] = [...]#ustaw, ile chcesz
end
Zanim przejdziemy do ostatniej części, krótkie omówienie klasy "RPG::Effect"
Klucz określa, kiedy efekt zostanie wywołany. Wartości są następujące:
+nil - efekt wywołany zostaje zawsze i nie ma znaczenia, gdzie go walniesz.
+symbol "skill" lub "unleash" - dla efektów skilla. Skill nie ma zastosowania przy unleashu i vice versa.
+zbiór pięciu wartości - pierwsza z nich (true/false) określa, czy efekt wywołany jest zawsze (false), czy tylko, kiedy przedmiot został użyty (true). Druga (wzmianka o klasie "RPG::Skill" lub "RPG::Item") określa, czy efekt jest dla skilla, czy dla przedmiotu w plecaku. Trzecia (symbol "id", "kind", lub "type") to sposób weryfikacji, czy ten efekt jest dla tego działania, czy nie. Czwarta jest wartością, którą atak lub przedmiot musi mieć w zmiennej wskazanej przez trzecią wartość. Piąta i ostatnia wartość (tylko "nil" dla przedmiotów, symbole "skill" i "unleash" dla skilli) działają podobnie, jak solo dla efektów skilla.
Funkcję od wyszukiwania efektów wywołanych przez działanie najlepiej napisaćw klasie "Game_Battler" lub "Game_BattlerBase".
W pliku "skill" musimy wprowadzić następujący kod:
Kod:
$data_skills = []
size = 1
if size >= 1
id = 1
$data_skills[id] = RPG::Skill.new(id)
$data_skills[id].name = 'Kamehameha LV'+"#{actor.ability_level(1)}"
$data_skills[id].icon_name = 'fireball'
$data_skills[id].target_list = :enemy
$data_skills[id].target_distance = 10
$data_skills[id].target_angle = 23
$data_skills[id].target_range = 2
$data_skills[id].trait = false
$data_skills[id].req = ''
$data_skills[id].projectile_id = 1
$data_skills[id].animation1_id = 2
$data_skills[id].animation2_id = 7
$data_skills[id].available.push(symbol_ekranu)
$data_skills[id].user_effects.push(RPG::Effect.new(:skill, 101, 1, 0, -50, 0, 0))
$data_skills[id].target_effects.push(RPG::Effect.new(nil, 101, 0, 0, -200, -1, -1))
$data_skills[id].hit = 'a.hit'
$data_skills[id].eva = 'b.eva'
$data_skills[id].ptk = '[0, a.ptk - b.pdf].max * 100 / [1, a.ptk].max'
$data_skills[id].mtk = '[0, a.mtk - b.mdf].max * 100 / [1, a.mtk].max'
$data_skills[id].str = 'a.str'
$data_skills[id].int = 'a.int'
$data_skills[id].rate = '(20) / 20'
end
Ostatnie, co musimy jeszcze zrobić, to zdefiniować jedną albo dwie umiejętności w pliku "ability"
Kod:
$data_abilities = []
size = 1
if size >= 1
id = 1
$data_abilities[id] = RPG::Ability.new(id)
$data_abilities[id].name = 'Skill: Kamehameha'
$data_abilities[id].icon_name = 'fireball'
$data_abilities[id].self_learn_levels = [1, 10]
$data_abilities[id].costs[1] = { :ap => 0, :tech => 500 } #dla poziomu umiejętności
$data_abilities[id].required_levels[1] = 1 #dla jednego poziomu umiejętności
$data_abilities[id].self_learn_levels[1].times { $data_abilities[id].features.push([]) #przed tymi trzema linijkami musisz
$data_abilities[id].user_effects.push([]) #określić poziomy do samodzielnego rozwoju
$data_abilities[id].target_effects.push([]) } #tej umiejętności
$data_abilities[id].features[n].push(RPG::Feature.new(kod, '', 0, id_skilla_kamehameha)) #n oznacza poziom tej umiejętności. Dla nauki skilla
$data_abilities[id].user_effects[n].push(RPG::Effect.new([false, RPG::Skill, :id, 1, :skill], kod, id, p1, p2,...)) #po rozwinięciu tej
$data_abilities[id].target_effects[n].push(RPG::Effect.new([false, RPG::Skill, :id, 1, :skill], kod, id, p1, p2,...)) #umiejętności kod cechy ustal
end
Jeśli nie widziałeś kosztów w "RPG::Skill", to wiedz,że nie bez powodu zostały one stamtąd wywalone. Ich rolę przejęły efekty użytkownika.
I w ten właśnie sposób powinieneś daćradę stworzyć skille.
RE: Wielopoziomowe skille - Helseth - 06-09-16 00:29
wrzuć demko ;P
RE: Wielopoziomowe skille - Mateusz SSJ8 - 16-09-16 08:06
Wątpię, żeby ktoś był aż tak tępy. Przecież nie gmatwam więcej, niż to jest konieczne.
W definicji klasy "RPG::Skill" nie ma "mp_cost", ani "sp_cost", bo od tego są efekty użytkownika (user_effects). Aby odjąć mp lub sp wykonawcy, trzeba właśnie w efektach użytkownika utworzyć obiekt klasy "RPG::Effect" o następujących parametrach:
+klucz - determinujący, przy jakim działaniu efekt zostanie zastosowany.
+kod - ustawiony przez twórcę numer, który oznacza, że efekt bezpośrednio zmienia energię.
+id celu zmiany - standardowo w RPG Makerze XP 0 oznacza HP, a 1 to SP.
+4 parametry - pierwszy określa procent maksymalnego zapasu energii, więc egzekwowane są na nim wartości od -100 do 100. Drugi określa bezwzględną zmianę, więc egzekwowane wartości mogą być dowolne. Trzeci to liczba części siły, o jaką wartość efektu się zmieni (0 to nic, większa leczy, a mniejsza rani). Czwarty i ostatni to liczba części inteligencji, o jaką wartość efektu się zmieni, o działaniach wartości identycznych, jak w przypadku siły. Parametry trzeci i czwarty powinny być ważne tylko, jeśli efekt wywoływany jest na celu.
RE: Wielopoziomowe skille - Yoroiookami - 16-09-16 16:52
A nie łatwiej po prostu skopiować skilla i trochę go wzmocnić? 
Próbowałem zrobić wedle instrukcji, ale natknąłem się na kilka problemów.
Nie wiem co to jest "moduł DataManager", gdzie go znajdę, ani gdzie mam wrzucić to:
Kod:
def self.load_script(filename)
require File.expand_path('./') + '/root/' + filename + '.rb'
end
Więc wrzuciłem po prostu do 'Clear':
Kod:
RPG.send(:remove_const, :Actor) # kasuje oryginalną klasę RPG::Actor
RPG.send(:remove_const, :Class)
RPG.send(:remove_const, :Skill)
RPG.send(:remove_const, :Learning)
def self.load_script(filename)
require File.expand_path('./') + '/root/' + filename + '.rb'
end
Tak czy inaczej starałem się robić według instrukcji, ale wywaliło mi błąd:
Co mnie zresztą nie dziwi. Ten tutorial jest chyba dla ludzi, którzy i tak już wiedzą co robią.
RE: Wielopoziomowe skille - Mateusz SSJ8 - 19-09-16 09:09
Przepraszam, mój błąd. Zamiast "RPG::Learning" w RPG Makerze masz "RPG::Class::Learning".
Kiedy wymieniałem rzeczy potrzebne do zastosowania porady, wspomniałem,że trzeba wszystkie skrypty w Edytorze przepisać na podobieństwo do RPG Makera VX Ace. Jeśli więc nie ma modułu "DataManager", to go mogłeś napisać.
Co do kopiowania skilla, to chciałem całkowicie wyeliminować możliwość opanowania tego samego skilla na wielu różnych poziomach bez użycia typowych zdarzeń. Chyba wiesz, jak one działają. Poza tym uwzględniłem walkę zręcznościową na mapie.
|