Wielopoziomowe skille
Aktualny czas: 18-10-17, 05:45 Witaj! Przejdź do zakładki Logowanie lub Rejestracja


Odpowiedz 
[XP] Wielopoziomowe skille
Mateusz SSJ8 Offline
*


Liczba postów: 508
Dołączył: 10-05-13

Pomógł: 40



Post: #1
Wielopoziomowe skille

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".
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".
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.
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:
$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:
$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:
$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"
$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.

Nienawidzony i nienawidzący. Przez nienawiść tego drugiego obaj będą martwi.
(Ten post był ostatnio modyfikowany: 19-09-16 09:10 przez Mateusz SSJ8.)
05-09-16 15:32
Odwiedź stronę użytkownika Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
"Pomógł" przyznał(a):
Helseth Offline
*


Liczba postów: 12
Dołączył: 03-05-13

Pomógł: 0



Post: #2
RE: Wielopoziomowe skille

wrzuć demko ;P
06-09-16 00:29
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
"Pomógł" przyznał(a):
Mateusz SSJ8 Offline
*


Liczba postów: 508
Dołączył: 10-05-13

Pomógł: 40



Post: #3
RE: Wielopoziomowe skille

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.

Nienawidzony i nienawidzący. Przez nienawiść tego drugiego obaj będą martwi.
(Ten post był ostatnio modyfikowany: 16-09-16 08:07 przez Mateusz SSJ8.)
16-09-16 08:06
Odwiedź stronę użytkownika Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
"Pomógł" przyznał(a):
Yoroiookami Offline
*


Liczba postów: 775
Dołączył: 01-05-13

Pomógł: 91



Post: #4
RE: Wielopoziomowe skille

A nie łatwiej po prostu skopiować skilla i trochę go wzmocnić? :ehe:

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:
def self.load_script(filename)
require File.expand_path('./') + '/root/' + filename + '.rb'
end

Więc wrzuciłem po prostu do 'Clear':
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:
Spoiler: (Otwórz)
Co mnie zresztą nie dziwi. Ten tutorial jest chyba dla ludzi, którzy i tak już wiedzą co robią. smiles

[Obrazek: bhixcw.jpg]
[Obrazek: tumblr_static_eyes.gif]
(Ten post był ostatnio modyfikowany: 16-09-16 16:52 przez Yoroiookami.)
16-09-16 16:52
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
"Pomógł" przyznał(a):
Mateusz SSJ8 Offline
*


Liczba postów: 508
Dołączył: 10-05-13

Pomógł: 40



Post: #5
RE: Wielopoziomowe skille

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.

Nienawidzony i nienawidzący. Przez nienawiść tego drugiego obaj będą martwi.
19-09-16 09:09
Odwiedź stronę użytkownika Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
"Pomógł" przyznał(a):
Odpowiedz 


Skocz do:


Użytkownicy przeglądający ten wątek: 1 gości

Kontakt | Ultima Forum | Wróć do góry | Wróć do forów | Wersja bez grafiki | RSS
Powered By MyBB. © 2013 MyBB Group. All Rights Reserved.
Skórka by Ayene.