01
z 05
Wprowadzenie do samouczków dotyczących programowania gier
Jest to pierwsza z kilku samouczków do programowania gier w C dla kompletnych początkujących. Zamiast koncentrować się na nauczaniu języka C, a następnie pokazywać przykładowe programy, których uczą języka C, udostępniając Ci kompletne programy (np. Gry) w języku C
Prostota
Pierwszą grą z tej serii jest konsola (tj. Gra tekstowa o nazwie Star Empires). Star Empires to prosta gra, w której musisz przejąć wszystkie 10 systemów w Galaktyce, jednocześnie powstrzymując przeciwnika AI.
Zaczynasz posiadać System 0, podczas gdy twój wróg ma własny System 9. Pozostałe osiem systemów (1-8) zaczyna neutralnych. Wszystkie systemy zaczynają się w kwadracie 5 parsek x 5 parsek, więc żaden system nie dzieli więcej niż 6 parsek. Dwa najdalsze punkty to (0,0) i (4,4). Według twierdzenia Pitagorasa najdalszą odległość od dowolnych dwóch systemów stanowi pierwiastek kwadratowy ((4)2 + (4)2), który jest pierwiastkiem kwadratowym z 32, który wynosi około 5,657.
Uwaga: nie jest to wersja ostateczna i zostanie zmieniona. Ostatnia zmiana: 21 sierpnia 2011 r.
Turn Based & Real-Time
Gra opiera się na turach i w każdej turze wydajesz rozkazy przeniesienia dowolnej liczby flot z dowolnego posiadanego systemu do dowolnego innego systemu. Jeśli posiadasz więcej niż jeden system, możesz zlecić flotom przejście ze wszystkich systemów do systemu docelowego. Odbywa się to proporcjonalnie w zaokrągleniu w górę, więc jeśli posiadasz trzy systemy (1,2,3) z obecnymi 20, 10 i 5 flotami i zamówisz 10 Flot, aby przejść do systemu 4, a następnie 6 przejdzie z systemu 1, 3 z systemu 2 i 1 z systemu 3. Każda flota porusza się o 1 sek. Na turę.
Każda tura trwa 5 sekund, ale możesz zmienić prędkość, aby ją przyspieszyć lub spowolnić, zmieniając 5 w tym wierszu kodu na 3 lub 7 lub cokolwiek innego. Poszukaj tego wiersza kodu:
onesec = clock () + (5 * CLOCKS_PER_SEC);
Samouczek programowania C.
Ta gra została zaprogramowana i zakłada, że nie znasz żadnego programowania w C. W miarę postępów przedstawię funkcje programowania w tym i kolejnych dwóch lub trzech samouczkach. Najpierw potrzebujesz kompilatora dla systemu Windows. Oto dwa bezpłatne:
- Próbować CC386
- Lub Visual C ++ 2010 Express
Artykuł CC386 przeprowadzi Cię przez proces tworzenia projektu. Jeśli zainstalujesz ten kompilator, wszystko, co musisz zrobić, to załadować program Hello World zgodnie z opisem, skopiować i wkleić kod źródłowy na przykładzie, zapisać go, a następnie nacisnąć F7, aby go skompilować i uruchomić. Podobnie artykuł w Visual C ++ 2010 tworzy program hello world. Zastąp go i naciśnij F7, aby zbudować Star Empires., F5, aby go uruchomić.
Na następnej stronie - Sprawienie, by Star Empires działało
02
z 05
Spraw, by Star Empires działało
Spraw, by Star Empires działało
Musimy przechowywać informacje o flotach i systemach w grze. Flota to jeden lub więcej statków z rozkazem przejścia z jednego systemu do drugiego. Układ gwiezdny to kilka planet, ale w tej grze jest bardziej abstrakcyjnym bytem. W przypadku floty musimy przechowywać następujące informacje.
- System pochodzenia (1-10).
- System docelowy (1-10)
- Ile statków (1-Many)
- Zmienia się na przyjazd
- Czyja to flota? 0 = gracz, 9 = wróg
Użyjemy struktury w C do przechowywania tego:
struct flota {
int fromsystem;
int tosystem;
int zmienia;
int flotyzować;
int właściciel;
};
Struktur to zbiór danych, w tym przypadku 5 liczb, którymi manipulujemy jako jeden. Każdy numer ma nazwę, np. Fromsystem, tosystem. Te nazwy są nazwami zmiennymi w C i mogą zawierać podkreślenia takie jak to, ale nie spacje. W C liczby są albo liczbami całkowitymi; liczby całkowite, takie jak 2 lub 7, nazywane są liczbami całkowitymi, lub liczby z częściami dziesiętnymi, takimi jak 2,5 lub 7.3333, i nazywane są liczbami zmiennoprzecinkowymi. W całym Star Empires używamy pływaków tylko raz. W kawałku kodu obliczającym odległość między dwoma miejscami. Każda inna liczba jest liczbą całkowitą.
Flota to nazwa struktury danych zawierającej pięć zmiennych wewnętrznych. To dotyczy jednej floty. Nie wiemy, ile flot będziemy musieli pomieścić, więc przydzielimy obfite miejsce na 100 za pomocą tablicy. Pomyśl o strukturze jak o stole obiadowym z miejscem dla pięciu osób (ints). Tablica jest jak długi rząd stołów obiadowych. 100 stolików oznacza, że może pomieścić 100 x 5 osób.
Gdybyśmy faktycznie serwowali te 100 stołów obiadowych, musielibyśmy wiedzieć, który stół był który, i robimy to przez numerację. W C zawsze numerujemy elementy tablic zaczynające się od 0. Pierwszy stół obiadowy (flota) ma numer 0, następny to 1, a ostatni 99. Zawsze pamiętam, jak wiele stołów obiadowych jest od samego początku? Pierwszy jest na początku, więc jest równy 0.
W ten sposób deklarujemy floty (tj. Nasze stoły obiadowe).
struktury flotowe [100];
Przeczytaj to od lewej do prawej. Flota strukturalna odnosi się do naszej struktury na jedną flotę. Nazwa floty to nazwa, którą nadajemy wszystkim flotom, a [100] mówi nam, że w zmiennej floty jest 100 x struct flota. Każda int zajmuje 4 miejsca w pamięci (zwane bajtami), więc jedna flota zajmuje 20 bajtów, a 100 flot to 2000 bajtów. Zawsze dobrze jest wiedzieć, ile pamięci potrzebuje nasz program do przechowywania danych.
We flocie strukturalnej każda liczba całkowita zawiera liczbę całkowitą. Liczba ta jest przechowywana w 4 bajtach, a jej zakres wynosi od -2 147 483 647 do 2 147 483 648. Przez większość czasu będziemy używać mniejszych wartości. Istnieje dziesięć systemów, więc zarówno system, jak i tosystem będą miały wartości od 0 do 9.
Na następnej stronie: Systemy i liczby losowe
03
z 05
Informacje o systemach i liczbach losowych
Każdy z neutralnych systemów (1-8) zaczyna się od 15 statków (numer, który wybrałem z powietrza!) Na początek, a pozostałe dwa (twój: system 0 i twój komputerowy przeciwnik w systemie 9) mają po 50 statków każdy. W każdej turze liczba statków w systemie jest zwiększana o 10% w zaokrągleniu w dół. Więc po jednej turze, jeśli ich nie poruszysz, twoje 50 stanie się 55, a każdy z neutralnych systemów będzie miał 16 (15 + 1,5 zaokrąglone w dół). Pamiętaj, że liczba flot przenoszących się do innego systemu nie rośnie.
Zwiększanie liczby statków w ten sposób może wydawać się trochę dziwne, ale zrobiłem to, aby gra się rozwijała. Zamiast zaśmiecać ten samouczek zbyt dużą ilością decyzji projektowych, napisałem osobny artykuł o decyzjach projektowych Star Empires.
Wdrażanie systemów
Na początku musimy wygenerować wszystkie systemy i umieścić je na mapie, z maksymalnie jednym systemem każda lokalizacja, ponieważ na naszej siatce 5 x 5 znajduje się 25 lokalizacji, będziemy mieli dziesięć systemów i 15 pustych lokalizacje. Generujemy je za pomocą funkcji GenMapSystems (), którą przejrzymy na następnej stronie.
System jest przechowywany w strukturze z następującymi 4 polami, które są wszystkie int.
system strukturalny {
int x, y;
int numfleets;
int właściciel;
};
Galaktyka (wszystkie 10 systemów) jest przechowywana w innym układzie, podobnie jak w przypadku flot, z wyjątkiem tego, że mamy 10 systemów.
galaktyka systemu strukturalnego [10];
Losowe liczby
Wszystkie gry wymagają liczb losowych. C ma wbudowaną funkcję rand (), która zwraca losową liczbę całkowitą. Możemy wymusić to w zakresie, przekazując maksymalną liczbę i używając operatora%. (Moduł). To jest jak arytmetyka zegara, tyle że zamiast 12 lub 24 podajemy liczbę int o nazwie max.
/ * zwraca liczbę między 1 a maksimum * /
int Losowo (int max) {
return (rand ()% max) +1;
}
To jest przykład funkcji, która jest fragmentem kodu owiniętym wewnątrz kontenera. Pierwszy wiersz, który zaczyna się / * i kończy * /, jest komentarzem. Mówi, co robi kod, ale jest ignorowany przez kompilator, który odczytuje instrukcje C i konwertuje je na instrukcje, które komputer rozumie i potrafi wykonać bardzo szybko.
- Zastanawiasz się, co to jest kompilator? Czytać Co to jest kompilator? (Artykuł)
Funkcja jest jak funkcja matematyczna, taka jak Sin (x). Ta funkcja składa się z trzech części:
int Losowo (int max)
Int mówi, jaki typ liczby zwraca (zwykle int lub liczba zmiennoprzecinkowa). Random to nazwa funkcji i (int max) mówi, że podajemy liczbę int. Możemy użyć tego w następujący sposób:
int kości;
kości = Losowe (6); / * zwraca losową liczbę od 1 do 6 * /
Linia:
return (rand ()% max) +1;
Na następnej stronie: Generowanie losowej mapy startowej
04
z 05
Generowanie losowej mapy startowej
Poniższy kod generuje mapę początkową. To pokazano powyżej.
void GenMapSystems () {
int i, x, y;
for (x = 0; x for (y = 0; y layout [x] [y] = '';
}
InitSystem (0,0,0,50,0,0);
InitSystem (9,4,4,50,1);
/ * Znajdź puste miejsce na pozostałe 8 systemów * /
dla (i = 1; robię {
x = Losowo (5) -1;
y = Losowo (5) -1;
}
while (layout [x] [y]! = '');
InitSystem (i, x, y, 15, -1);
}
}
Generowanie systemów polega na dodaniu systemów gracza i przeciwników (na 0,0) i (4,4), a następnie losowym dodaniu 8 systemów w pozostałych 23 pustych miejscach.
Kod wykorzystuje trzy zmienne int zdefiniowane przez linię
int i, x, y;
Zmienna to lokalizacja w pamięci, która zawiera wartość całkowitą. Zmienne xiy utrzymują współrzędne układów i będą zawierać wartość z zakresu 0-4. Zmienna i służy do zliczania w pętlach.
Aby umieścić 8 losowych systemów w siatce 5x5, musimy wiedzieć, czy dana lokalizacja ma już system i zapobiec umieszczeniu innego systemu w tej samej lokalizacji. W tym celu używamy prostej dwuwymiarowej tablicy znaków. Typ char jest innym typem zmiennej w C i zawiera pojedynczy znak, taki jak „B” lub „x”.
Podkład na typy danych w C
Podstawowym typem zmiennych w C są int (liczby całkowite jak 46), char (pojedynczy znak jak „A”) i float (do przechowywania liczb z liczbą zmiennoprzecinkową jak 3,567). Tablice [] służą do przechowywania list tego samego elementu. Więc char [5] [5] definiuje listę list; dwuwymiarowy zestaw znaków. Pomyśl o tym jak o 25 kawałkach Scrabble ułożonych w siatkę 5 x 5.
Teraz We Loop!
Każdy znak jest początkowo ustawiany na spację w podwójnej pętli, używając dwóch do instrukcji. Instrukcja for składa się z trzech części. Inicjalizacja, część porównawcza i część zmian.
for (x = 0; x for (y = 0; y layout [x] [y] = '';
}
- x = 0; To jest część inicjalizacji.
- x
- x ++. To jest część zmiany. Dodaje 1 do x.
Więc (dla (x = 0; x
Wewnątrz pętli for (x jest pętlą for y, która robi to samo dla y. Ta pętla y ma miejsce dla każdej wartości X. Gdy X wynosi 0, Y zapętla się od 0 do 4, gdy X wynosi 1, Y zapętla się i tak dalej. Oznacza to, że każda z 25 lokalizacji w tablicy układu jest inicjowana w spację.
Po pętli for wywoływana jest funkcja InitSystem z pięcioma parametrami int. Przed wywołaniem należy zdefiniować funkcję, inaczej kompilator nie będzie wiedział, ile parametrów powinien mieć. InitSystem ma te pięć parametrów.
Na następnej stronie: Generowanie losowej mapy początkowej trwa ...
05
z 05
Generowanie losowej mapy początkowej jest kontynuowane
Są to parametry InitSystem.
- systemindex - wartość od 0 do 9.
- xiy - współrzędne układu (0-4).
- numships - ile statków jest w tym systemie.
- właściciel. Kto jest właścicielem systemu. 0 oznacza gracza, 9 oznacza wroga.
Zatem linia InitSystem (0,0,0,50,0) inicjuje system 0 w lokalizacjach x = -0, y = 0 z 50 statkami do właściciela 0.
C ma trzy typy pętli, podczas gdy pętle, dla pętli i pętli do i używamy dla i robimy w funkcji GenMapSystems. Tutaj musimy umieścić pozostałe 8 systemów gdzieś w galaktyce.
dla (i = 1; robię {
x = Losowo (5) -1;
y = Losowo (5) -1;
}
while (layout [x] [y]! = '');
InitSystem (i, x, y, 15,0);
}
W tym kodzie są dwie zagnieżdżone pętle. Pętla zewnętrzna jest instrukcją for, która zlicza zmienną i od wartości początkowej 1 do wartości końcowej 8. Użyjemy i, aby odnieść się do systemu. Pamiętaj, że zainicjowaliśmy już system 0 i 9, więc teraz inicjujemy systemy 1-8.
Wszystko od do {do chwili (układ [x] [y] to druga pętla). Jego składnia to do {coś} while (warunek jest spełniony); Przypisujemy więc losowe wartości xiy, każda wartość z zakresu 0-4. Losowa (5) zwraca wartość z zakresu od 1 do 5, odejmując 1, otrzymujemy zakres 0-4.
Nie chcemy umieszczać dwóch układów na tych samych współrzędnych, więc ta pętla szuka losowej lokalizacji, w której jest miejsce. Jeśli jest tam system, układ [x] [y] nie będzie spacją. Kiedy wywołujemy InitSystem, umieszcza tam inną wartość. BTW! = Oznacza nie równy, a == oznacza równy.
Kiedy kod osiągnie po chwili system InitSystem (układ [x] [y]! = ''), Xiy zdecydowanie odnoszą się do miejsca w układzie, które ma w nim miejsce. Możemy więc wywołać InitSystem, a następnie przejść do pętli for, aby znaleźć losową lokalizację dla następnego systemu, dopóki wszystkie 8 systemów nie zostaną umieszczone.
Pierwsze połączenie z InitSystem ustawia system 0 w lokalizacji 0,0 (lewy górny róg siatki) z 50 flotami i wygrałem przeze mnie. Drugie połączenie inicjuje system 9 w lokalizacji 4,4 (prawy dolny róg) z 50 flotami i jest własnością gracza 1. Przyjrzymy się bliżej temu, co faktycznie robi InitSystem w następnym samouczku.
#definiować
Te linie deklarują wartości dosłowne. Zwyczajowo umieszcza się je dużymi literami. Wszędzie, gdzie kompilator widzi MAXFLEETS, używa wartości 100. Zmień je tutaj, a dotyczy to wszystkich:
- # zdefiniować SZEROKOŚĆ 80
- # zdefiniować WYSOKOŚĆ 50
- # zdefiniować MAXLEN 4
- # zdefiniować MAXFLEETS 100
- # zdefiniować MAXSYSTEMS 10
- # zdefiniować FIGHTMARKER 999
Wniosek
W tym samouczku Omówiliśmy zmienne oraz użycie int, char i struct do grupowania ich oraz tablicy do tworzenia listy. Następnie proste zapętlenie za pomocą for i do. Jeśli zbadasz kod źródłowy, te same struktury będą widoczne za każdym razem.
- dla (i = 0; i
- dla (i = 0; i
Samouczek Spójrz na aspekty C wspomniane w tym samouczku.