Rozwój
Programowanie SI
- Dokumentacja API
- Wprowadzenie
- plik info.nut
- plik main.nut
- Podstawy
- Poszukiwacz drogi
- Użycie pathfinder`a kolei
- Zapis / Odczyt danych
- Dobrze wiedzieć
-
Squirrel
- Home page
- Typowe błędy
- Listy
- Poradnik na błędy OTTD
- Trams
- Biblioteki SI
- Forum
- Forum FAQ
- Zachowanie SI
- Użycie krótkich nazw
SIy
Wszystko kategorii NoAI
Contents |
require()
Aby dołączyć pliki do main.nut , możesz użyć require() . Ta funkcja działa względnie z bieżącego pliku, więc powinna być łatwa w użyciu. Jest jednak kilka rzeczy, o których należy pamiętać:
- Zawsze zawiera plik w przestrzeni globalnej. To nie jest kod. Tak więc plik musi zawierać pełny kod (rzadko ludzie to zauważą, ale ważne jest, aby wiedzieć) :))
Klasy
Upewnij się, że zainicjowałeś wszystkie swoje niestatystyczne zmienne klas w konstruktorze. Podanie im wartości podczas ich deklarowania nie wystarczy, jeśli utworzysz wiele instancji !! Jeśli nie uda się zainicjować zmiennej w konstruktorze, może to mieć dziwną wartość, na przykład kopiowanie wartości z innej instancji klasy. Poniższe pole pokazuje prawidłowy sposób inicjowania zmiennych. Ważne jest to, że wszystkie zmienne otrzymują wartość w konstruktorze.
class Developer
{
name = null;
age = null;
constructor() {
name = "Unknown Developer";
age = 25;
}
function SetName(name);
// ...
}Deklaracje funkcji
Zauważ też, że deklaracje funkcji w klasie zdarzają się poza ('outside') blokiem należącym do klasy.
class Util{
function Util::GetMsg(){
return "Test";
}
}spowoduje awarię AI podczas ładowania, podczas gdy
class Util{
}
function Util::GetMsg(){
return "Test";
}będzie działać zgodnie z oczekiwaniami.
Squirrel nie ma sposobu na oznaczenie metod jako statycznych lub prywatnych
W innych językach obiektowych możesz ograniczyć sposób wywoływania funkcji podczas ich deklarowania. W wiewiórce jedyną różnicą między funkcją instancji a funkcją statyczną jest sposób ich wywoływania. W innych językach możesz także ustawić metody publiczne lub prywatne. Wszystkie metody wiewiórki są publiczne.
Istnieją dwa sposoby wywoływania funkcji. Możesz zadzwonić do nich z instancji (instance) lub możesz nazwać je statycznie (staticly) . Kiedy wywołujesz funkcję z instancji, albo poprzedzasz połączenie słowem kluczowym this (to), albo wcale go nie poprzedzasz.
Metody AAIFoo.Valuate() zawsze wywołują twoje metody statycznie. Więc każdy niestandardowy rzeczoznawca powinien być niezależny.
instance function MyNewAI::Start()
{
this.MainLoop();
/* MainLoop(); would also work. this. is usually optional. */
/* Note that this sample code won't actually get called, because MainLoop() does not return ;-) */
local otherClass = MyOtherClass();
otherClass.SomeFunction(); // Calls the function with the instance method on another class.
}
function MyNewAI::MainLoop()
{
while(true) { // Loop forever.
this.Sleep(10);
}
}
Gdy wywołujesz metodę z instancji, metoda ma wszystkie zmienne i inne informacje dostępne dla tej instancji klasy. Więc wiersz this.Sleep(10) będzie działał poprawnie, ponieważ AIController ma metodę sleep dla twojej klasy. Pamiętaj, że twoja główna klasa jest rozszerzeniem AIController, a więc ma wszystkie swoje umiejętności, jak również wszelkie inne.
Aby wywołać instancję statyczną, należy poprzedzić metodę nazwą klasy.
static function MyNewAI::Start()
{
MyNewAI.MainLoop();
MyOtherClass.SomeFunction(); // Calls the otherclass function staticly.
}
function MyNewAI::MainLoop()
{
while(true) { // Loop forever.
AIController.Sleep(10); // "this" no longer exists in static context.
}
}
Pamiętaj, że twoje funkcje można wywoływać w dowolny sposób. Od osoby dzwoniącej zależy, jak korzystać z tej funkcji.
Instrukcje przydziału, które zajmują dużo czasu
Załóżmy, że good_pairs jest zmienną składową twojej głównej klasy. Załóżmy, że istnieje metoda FindGoodPairs , która wyszukuje nowe pary i że ta metoda wymaga czasu.
Możesz pomyśleć, że to dobry sposób na aktualizację good_pairs:
this.good_pairs = FindGoodPairs();
Now lets assume FindGoodPairs look some thing like this:
function FindGoodPairs() {
local result = [];
// .. time consuming code that finds good pairs
return result;
}Teraz, jeśli Save() jest wywoływane od momentu wywołania FindGoodPairs(), ale zanim zwróci, good_pairs nie będzie przechowywał starego wyniku poprzedniego wywołania FindGoodPairs, zamiast tego zachowa jakiś częściowy wynik z metody FindGoodPairs.
Nie mogę dokładnie powiedzieć, co się stanie dla różnych sposobów pisania FindGoodPairs, tylko że znalazłem błędy w skryptach związanych z tą rzeczą.
Sposobem na obejście tego jest zmiana kodu, który wywołuje FindGoodPairs w tym celu:
local temp = FindGoodPairs(); this.good_pairs = temp;



