Zarejestruj Zapomniałeś hasła?
Skryptowane Npc
Dodany 4 maja 2009, 14:57 Odsłon 2886
Edytory Ocena
 (8 głosów)
Kategoria Silnik Poziom (Dla średnio-zaawansowanych)
Kilkadziesiat slow wstepu

Ten artykul jak i zasada dzialania silnika oparta jest na kilku grach, co w przeliczeniu na lata wyniesie troche ponad kilka ;p

Niektore elementy zostaly, bo mialem do nich sentyment, a poza kwestia wygladu nie miala ich zmiana zadnego znaczenia. A wiec do rzeczy.

Potrzebne obiekty:
Postac gracza - dowolna, wymagane sa 2 zmienne (przewaznie uzywam A i B)
Npc - dowolny, w moich grach kazda animacja to inny npc. Wymagana 1 zmienna (u mnie A) i jedna flaga (0)
Strzalka - lub inny dowolny obiekt wskazujacy na npc. Wymagane 3 zmienne oraz 1 flaga (A, B, C i 0)
Tlo dialogu - Dowolne, im lepsze tym lepiej.
Ini - Dowolny, dzialajacy rodzaj. (Ew. cos innego, przewaznie uzywam ini)
2 x Named Variable Object - Do przechowywania informacji o npc itp. Mozna uzyc tez czegokolwiek innego co sie nada, np ini (i tak powstal Ivon ze swoim swietnym zapisem~) (Nazwalem je Npc Nvo oraz Nvo)
Advanced Direction Object - Do znajdywania najblizszego npc
Array - Do trzymania listy npc
String - lub cokolwiek innego co wyswietla tekst.
No i oczywiscie String Parser.



Jak mamy juz wszystko w poziomie to zaczynamy!



Tworzenie Npc

Uzywalem 2 metod szukania npc do stworzenia. Fatopodobne oraz Ntfsopodobne.

Jedyna gra Fatopodobna jest Tobira. Folder z npc wyglada mniej-wiecej tak:

Folder Npc napisał(a):


- 1 <- folder poziomu numer 1

- - 1.ini <- npc numer 1

- - 2.ini <- npc numer 2

- - 51.ini

- - 99.ini

- 2 <- folder poziomu numer 2

- - 42.ini

- - 55.ini

- 6

- - 82.ini

Tworzone sa npc z kazdego pliku w folderze.

Ntfsopodobna silnik wczytuje liste npc danego poziomu z pliku lista.ini w folderze z npc'ami a potem tworzy je. Plik listy wyglada tak:

lista.ini napisał(a):
[3]

1=sklep/sprzedawca_broni.ini

2=sklep/sprzedawca_czapek.ini

3=sklep/psorek.ini

4=sklep/sprzedawca_okultysta.ini

5=sklep/sprzedawca_dzemix.ini

7=sklep/sklep_winda_p1.ini

8=sklep/sklep_winda_p2.ini

9=sklep/sklep_winda_p3.ini

14=sklep/sklep_dach.ini

[4]

1=dom/drzwi.ini

2=dom/komputer.ini

3=dom/lozko.ini

4=dom/okno.ini

5=dom/pudlo.ini

26=dom/farba.ini

27=dom/farba_drzwi.ini

[poziom]

numer_npc=sciezka_do_pliku_npc

Wersja Ntfsopodobna jest wygodniejsza, bo wchodzac do folderu da sie domyslic, ktory z nich to jaki poziom oraz jaki plik to ktory npc ;p

Opisze wersje Ntfsopodobna bo ma wiecej zalet niz wad... chyba.

Oto wyglad przykladowego Npc:

npc.ini napisał(a):
[info]

2=1 0 1 1 160 120 0 24

poziom=czy_jest polprzezroczystosc flaga_1 flaga_2 x y animacja kierunek

[dialog]

1=setb 20

wartosc_B=komenda

wartosc_B numer_petli=komenda

1
• Uruchom to zdarzenie 1 raz
Zniszcz wszystkie Npc
2
• Uruchom to zdarzenie 1 raz
Uruchom petle "Npc" 100 razy

Npc na poczatku niszczymy i w osobnym zdarzeniu uruchamiamy petle. Czasami moj mmf2 mial problemy z niszczeniem i uruchamianiem petli jednoczesnie (zostawaly slady po npc).

Petla
1
• On Loop Npc
loopindex("Npc")==0
Array->Clear
Npc Nvo->load ini file apppath$+"npc/lista.ini", section str$(frame)
2Zapisywanie do Global string A sciezki do pliku npc
3
• On Loop Npc
Global string A==GetString("Npc Nvo", Str$(LoopIndex("npc")+1))
String parser->string = Global string A
4Sprawdzanie, czy sa juz jakies informacje o tym npc.
5
• On Loop Npc
Len(GetString( "Named variable object", Str$(frame)+"_"+Global String A))<15
Len(Global String A)>=2
Uruchom petle "Npc-wpis" 1 raz
6
• On Loop Npc-wpis
Ini->Set current file to apppath$+"npc/"+Global string A
7Sprawdzanie, czy plik istnieje i czy npc wystepuje w danym poziomie. Jesli tak to przerzuca jego dane do Nvo (ktory trzyma takie oraz inne rzeczy)
8
• On Loop Npc-wpis
Len(GroupItemString$( "Ini", "info", Str$(frame)))>0
Nvo->Set Key Str$(frame)+"_"+Global String A to GroupItemString$( "Ini", "info", Str$(frame))
9
• On Loop Npc
Len(Global String A)>=2
String parser->string = GetString( "Named variable object", Str$(frame)+"_"+Global String A)
10Jesli npc jest i zyje to go tworzymy~!
11
• On Loop Npc
Len(Global String A)>=2
string$( "String Parser" )!=""
listGetAt$( "String Parser", 1)!="0"
Create Npc at -32, -32
Npc->flag 1, 2 on
Npc->A=LoopIndex("npc")+1
Npc->Semi trans=Val(listGetAt$( "String Parser", 2))
Npc->Flag 1*(1-Val(listGetAt$( "String Parser", 3))) to off
Npc->Flag 2*(1-Val(listGetAt$( "String Parser", 3))) to off
Npc->X=Val(listGetAt$( "String Parser", 5))
Npc->Y=Val(listGetAt$( "String Parser", 6))
Npc->Anim=Val(listGetAt$( "String Parser", 7))
Npc->Dir=Val(listGetAt$( "String Parser", 8 ))
Npc->Flag 0 to on
Array item LoopIndex("npc")+1 to Global String A
12
• Uruchom to zdarzenie 1 raz
Global string A="", B=""
Npc Nvo->Clear

I w ten sposob, prawdopodobnie, mamy stworzone npc.



Znajdywanie najblizszego Npc

Jesli wszystko poszlo zgodnie z planem to po poziomie rozstawione sa npc. Graczowi dajemy jakikolwiek ruch, platformowy, 8 kierunkow lub dowolny inny.



1
• Gracz->A==0
Adv Dir Object->Find distance and fixed of Npc
2Jesli najblizszy npc jest rozny od tego, ktorego dane ma strzalka - zapisz jego dane i pokaz strzalke nad nim
3
• Gracz->A==0
• Npc->Fixed==GetFixedObj( "Advanced Direction Object", 0)
GetFixedObj( "Advanced Direction Object", 0)!=Alterable Value A( "Strzalka" )
Strzalka->pos=0,12 od Npc
Strzalka->StrA=StrAtX( "NpcList", Alterable Value A( "Npc" ))
Strzalka->A=Fixed( "Npc" )
4
• Gracz->A==0
• Fixed of Npc==GetFixedObj( "Advanced Direction Object", 0)
Strzalka->pos=0,12 od Npc
5Jesli gracz jest blizej niz 32px od Npc -> pokaz strzalke
6
• Gracz->A==0
• Fixed of Npc==GetFixedObj( "Advanced Direction Object", 0)
GetDistObj( "Advanced Direction Object", 0)<=32
Strzalka->Semi Trans=0
7Jesli gracz wcisnal Enter i jest blizej niz 32px od dowolnego npc -> rozpocznij rozmowe
8
• Wcisnieto enter
• Gracz->A==0
SemiTrans( "Strzalka" )!=128
Strzalka->B,C=0
Strzalka->Flaga 0 on
Gracz->A=2
Gracz->B=1
String=""
Tlo dialogu->Dir=0



Teraz pora na kosmetyke ;p



Kosmetyka
1Jesli gracz nie rozmawia to schowaj tlo dialogowe, jesli rozmawia - pokaz
2
• Gracz->A==0
Tlo dialogu->Semi Trans+=4
String=""
3
• Gracz->A!=0
Tlo dialogu->Semi Trans-=4



A teraz kolej na najciekawsza czesc kursu!



Dialog
1
• Gracz->A==2
• Gracz->B<=0
Gracz->A=0
Gracz->B=0
2
• Wcisnieto enter
• Gracz->A==2
• Gracz->B>0
• Strzalka->Flaga 0 jest off
Gracz->B-=1
Strzalka->Flaga 0 on
String=""
3Wczytaj plik npc do Npc Nvo
4
• Gracz->A==2
• Uruchom raz jesli zapetla sie
Npc Nvo->load ini file apppath$+"npc/"+Alterable String A( "Strzalka" ), section "dialog"
5Jesli Strzalka->B jest mniejsza lub rowna 0 uruchom petle
6
• Gracz->A==2
• Strzalka->B<=0
• Strzalka->Flaga 0 jest on
Global string A=""
Strzalka->B=0
Strzalka->Flaga 0 off
Uruchom petle Npc-komendy 100 razy
7
• Gracz->A==2
• Strzalka->B>0
• Strzalka->Flaga 0 jest on
Strzalka->B-=1



W ten sposob mamy uruchamianie petli komendowej. Odejmowanie od wartosci B strzalki jest przydatne do zrobienia oczekiwania miedzy komendami, np Wyswietl tekst "blah" a po 50 klatkach (~1s) wyswietl tekst " blah".

A teraz co sie dzieje wewnatrz petli...



Wnetrze petli
1Jesli wartosc C strzalki jest wieksza od 0 ustaw index petli na c+1. Wykorzystywane do tego, co opisalem wyzej ;p
2
• On loop Npc-komendy
• Strzalka->C>0
Set loop index Npc-komendy to Alterable Value C( "Strzalka" )+1
Strzalka->C=0
3Wstawianie do string parsera aktualnej komendy.
4
• On loop Npc-komendy
String parser->String = GetString( "Npc nvo", Str$(Alterable Value B( "Gostek" ))+" "+Str$(LoopIndex("npc-komendy")))
5Dla wygody, zerowa petla moze nie wymagac podania 0 w pliku ini (zamiast "1 0=komenda" mozna napisac "1=komenda")
6
• On loop Npc-komendy
loopindex("Npc-komendy")==0
listCount( "String Parser" )==0
String parser->String = GetString( "Npc nvo", Str$(Alterable Value B( "Gostek" )))




Tyle w kwestii prostych spraw. Teraz sprawy banalne, czyli glowna czesc silnika

1
• On loop Npc-komendy
listGetAt$( "String Parser", 1)=="tekst"
String=listGetAt$( "String Parser", 2)

Puf. Teraz npc ze skryptem "1=tekst Blah" teoretycznie spowoduje wyswietlenie tekstu " Blah". Radze zwrocic uwage na spacje na poczatku ;p

Zdarzenie kopiujemy, "tekst" zmieniamy na dowolna inna komende i puf~! Silnik gotowy.



Mozna by jeszcze dodac zmiane animacji tla dialogowego w zaleznosci od flagi 0 strzalki, zeby bylo widac czy mozna juz enterowac~



Teoretycznie ten kurs powinien dzialac. W praktyce go nie testowalem, ale przepisalem wieksza czesc silnika (ktory jak skoncze to dorzuce do kursu). Kiedys zajme sie napisaniem kursu jak zrobic dodatki do silnika, np. Wybor albo inne bajery.

(Przepraszam, jesli jest 'troche' chaotyczne ;p Jesli ktos zauwazy jakies literowki (olac brak ogonkow przy literkach~) to niech da znac ;o)



Przyklad
Ostatnio edytowane 9 sierpnia 2010, 15:33 przez Cremmy
Komentarze
Cremmy @ 6 maja 2009, 19:17
Demo? Tobira, Ivon. Przyklad? Skoro jest zainteresowanie, to wrzuce to, nad czym aktualnie pracuje. Nie wiem, czy bedzie to super dzialalo, bo nie zrobilem w tym zadnej gry, ale to sie pewnie niedlugo zmieni ;p Przyklad
Fadex @ 6 maja 2009, 14:58
Cóż, przejrzałem pobieżnie, powinno działać:P Skrypty fajna rzecz, bardzo ułatwia tworzenie gry. Ba, cała gra może być oparta na skryptach:)
creesee @ 6 maja 2009, 14:48
No, przykład to by się przydał.:(
Bedziu @ 6 maja 2009, 00:10
Przydałoby się DEMO, a nawet skompilowane (zablokowane), aby czasem leniwi twórcy nie szli na łatwiznę i nie kopiowali zdarzeń bezpośrednio z pliku *.mfa
Fanotherpg @ 4 maja 2009, 17:53
Literówki.. hmm całkowity brak zachowania poprawnej ortografii może być literówką:)? A tak to silnik ciekawy z zamysłu pytanie tylko czy działa.
Dodaj komentarz
Kolor:   Rozmiar:

Dodał Cremmy
Profil PW
Twoja ocena
Inne tego autora
b/d
^ Do góry
© 2009 - 2012 Fabryka Gier. Publikowanie materiałów tylko za zgodą autorów.
Realizacja: Maciej Lamberski *-: