Mulți dezvoltatori intră în dezvoltarea de software deoarece doresc să construiască jocuri. Nu toată lumea poate fi un dezvoltator profesionist de jocuri, dar toată lumea își poate construi propriile jocuri pentru distracție și poate pentru profit. În această serie de cinci părți, vă voi arăta cum să creați jocuri single-player 2D utilizând Python 3 și cadrul excelent Pygame.
Vom construi o versiune a jocului clasic de breakout. Când totul este spus și terminat, veți avea o înțelegere clară a ceea ce este nevoie pentru a vă crea propriul joc, veți cunoaște capacitățile lui Pygame și veți avea un joc proba.
Iată caracteristicile și capabilitățile pe care le vom implementa:
Ce ești tu? nu ar trebui așteptați este un joc plăcut vizual. Sunt programator și nu artist. Mă îngrijorez mai mult despre estetica codului. Rezultatul designului meu vizual poate fi destul de șocant. În plus, dacă doriți să îmbunătățiți cum arată această versiune de Breakout, aveți tone de spațiu pentru îmbunătățire. Cu acel avertisment rău de la drum, iată o captură de ecran:
Codul sursă complet este disponibil aici.
Jocurile sunt legate de mutarea pixelilor pe ecran și de zgomot. Destul de mult, toate jocurile video / computere au cele mai multe dintre următoarele elemente. Din domeniul de aplicare al acestui articol sunt jocurile client-server și jocurile multi-player, care implică și o mulțime de programe de rețea.
Bucla principală a unui joc rulează și reîmprospătează ecranul la intervale fixe. Aceasta este rata dvs. de cadre, și dictează cât de bine sunt lucrurile netede. În mod obișnuit, jocurile reîmprospătează ecranul de 30-60 de ori pe secundă. Dacă mergeți mai lent, obiectele de pe ecran vor părea ciudate.
În interiorul bucla principală, există trei activități principale: gestionarea evenimentelor, actualizarea stării jocului și desenarea stării actuale a ecranului.
Evenimentele dintr-un joc constau în tot ceea ce se întâmplă în afara controlului codului jocului, dar este relevant pentru funcționarea jocului. De exemplu, dacă în Breakout playerul apasă pe tasta săgeată stânga, jocul trebuie să deplaseze paleta spre stânga. Evenimentele tipice sunt apăsările de presă (și eliberările), mișcarea mouse-ului, clicurile pe butoanele mouse-ului (în special în meniuri) și evenimentele temporizatorului (de exemplu, un efect special expiră după 10 secunde).
Miezul fiecărui joc este starea sa: lucrurile pe care le urmărește și le atrage pe ecran. În Breakout, statul include locația tuturor cărămizilor, poziția și viteza mingii și poziția paletei, precum și viețile și scorul.
Există, de asemenea, statul auxiliar care ajută la gestionarea jocului:
Jocul trebuie să afișeze starea sa pe ecran. Aceasta include desenarea unor forme geometrice, imagini și text.
Cele mai multe jocuri simulează un mediu fizic. În Breakout, mingea bounces off obiecte și are o foarte Sistemul fizic brut al corpului fizic al corpului (dacă îl puteți numi).
Jocurile mai avansate pot avea sisteme fizice mai sofisticate și mai realiste (în special jocuri 3D). Rețineți că unele jocuri, cum ar fi jocurile de cărți, nu au deloc multă fizică, și asta e în regulă.
Există numeroase jocuri în care joci împotriva unui adversar artificial sau a adversarilor sau dacă există dușmani care încearcă să te omoare sau chiar mai rău. Aceste fantezii ale imaginației jocului se comportă adesea într-un mod aparent inteligent în lumea jocului.
De exemplu, dușmanii vă vor urmări și veți fi conștienți de locația dvs. Breakout nu prezintă un AI. Joci împotriva cărămizilor reci și tari. Cu toate acestea, AI în jocuri este adesea foarte simplă și urmează reguli simple (sau complexe) pentru a obține rezultate pseudo-inteligente.
Redarea audio este un alt aspect important al jocurilor. Există în general două tipuri de audio: muzică de fundal și efecte sonore. În Breakout, mă concentrez asupra efectelor sonore care joacă pe scurt când se întâmplă diverse evenimente.
Muzica de fundal este doar muzică care joacă constant în fundal. Unele jocuri nu utilizează muzică de fundal, iar unele comută la fiecare nivel.
Cele mai multe jocuri vă dau o anumită sumă de vieți, iar atunci când vă pierdeți viața, jocul se termină. De asemenea, de multe ori aveți un scor care vă oferă un sentiment de cât de bine faci și o motivație pentru a îmbunătăți data viitoare când joci sau doar să se laude prietenilor tăi despre abilitățile tale Breakout nebun. Multe jocuri au nivele care sunt complet diferite sau cresc nivelul de dificultate.
Înainte de scufundări în și de a începe să pună în aplicare, să învățăm puțin despre Pygame, care va face o mulțime de ridicare grele pentru noi.
Pygame este un cadru Python pentru programarea jocurilor. Acesta este construit pe partea de sus a SDL și are toate lucrurile bune:
usor de invatat
Tip pip instalați pygame
pentru ao instala. Dacă aveți nevoie de altceva, urmați instrucțiunile din secțiunea Noțiuni introductive din Wiki. Dacă rulați MacOS Sierra ca și mine, s-ar putea să aveți probleme. Am reușit să instalez Pygame fără probleme, iar codul părea să funcționeze bine, dar fereastra jocului nu a apărut niciodată.
E un fel de bummer când conduci un joc. În cele din urmă a trebuit să recurg la rularea pe Windows într-un VirtualBox VM. Sperăm că, odată ce ați citit acest articol, problema va fi rezolvată.
Jocurile trebuie să gestioneze o mulțime de informații și să efectueze operații similare pe mai multe obiecte. Breakout este un mini-joc, dar încercarea de a gestiona totul într-un fișier ar fi copleșitoare. În schimb, am optat să creez o structură de fișiere și o arhitectură potrivită pentru jocuri mult mai mari.
├── Pipfile ├── Pipfile.lock ├── README.md ├── ball.py ├── breakout.py ├── brick.py ├── button.py ├── colors.py ├── config PY ├── game.py ├── game_object.py ├── imagini │ └── background.jpg ├── paddle.py ├── sound_effects │ ├── brick_hit.wav │ ├── effect_done.wav │ ├───────────────────────────────────────────────────────────────────────
Pipfile și Pipfile.lock sunt modul modern de gestionare a dependențelor în Python. Directorul de imagini conține imagini utilizate de joc (numai imaginea de fundal din această încarnare), iar directorul sound_effects conține clipuri audio scurte folosite ca efecte sonore (ați ghicit-o).
Fișierele ball.py, paddle.py și brick.py conțin cod specific fiecăruia dintre aceste obiecte Breakout. Le voi acoperi în profunzime mai târziu în serie. Fișierul text_object.py conține cod pentru afișarea textului pe ecran, iar fișierul background.py conține logica jocului specifică Breakout.
Cu toate acestea, există mai multe module care formează un schelet liber, cu scop general. Clasele definite acolo pot fi reutilizate pentru alte jocuri bazate pe Pygame.
GameObject reprezintă un obiect vizual care știe să se facă, să-și mențină limitele și să se deplaseze. Pygame are de fapt o clasă Sprite care are un rol similar, dar în această serie vreau să arăt cum funcționează lucrurile la un nivel scăzut și să nu se bazeze pe prea multă magie preambalată. Aici este clasa GameObject:
de la importul pygame.rect Clasa Rect GameObject: def __init __ (auto, x, y, w, h, viteza = (0,0)): self.bounds = Rect (x, y, @property def left (self): întoarce self.bounds.left @property def right (self): întoarce self.bounds.right @property def top (self): întoarce self.bounds.top @property def bottom (self): reveni self.bounds.bottom lățime @property def (auto): întoarce self.bounds.width înălțimea @property def (auto): întoarcere centru de self.bounds.height @property def (auto): întoarcere self.bounds.center @property def selfx.bounds.center @ proprietatea defineste centrul (self): returneaza self.bounds.centery def draw (auto, suprafata): pass def muta (self, dx, dy): self.bounds = self .desc, dy) actualizare def (auto): dacă self.speed == [0, 0]: return self.move (* self.speed)
GameObject este conceput pentru a servi drept clasă de bază pentru alte obiecte. Expune în mod direct o mulțime de proprietăți ale dreptunghiului propriu, și în proprietățile sale Actualizați()
metoda mută obiectul în funcție de viteza sa actuală. Nu face nimic în ea a desena()
, care ar trebui să fie suprimată de subclasele.
Clasa de joc este nucleul jocului. Rulează bucla principală. Are o mulțime de funcționalități utile. Să o luăm prin metodă.
__ metodei __init ()
metoda inițializează Pygame însuși, sistemul de fonturi și mixerul audio. Motivul pentru care trebuie să efectuați trei apeluri diferite este că nu toate jocurile Pygame utilizează toate componentele, deci controlați ce subsisteme utilizați și inițializați numai acelea cu parametrii lor specifici. Creează imaginea de fundal, suprafața principală (unde este trasată totul) și ceasul de joc cu rata de cadre corectă.
Membrul self.objects va păstra toate obiectele de joc care trebuie redate și actualizate. Diferiții agenți de gestionare gestionează listele funcției de handler care ar trebui să fie apelate atunci când se întâmplă anumite evenimente.
import sys pygame de import din colecțiile de import defaultdict clasa joc: def __ metodei __init (auto, legendă, latime, inaltime, back_image_filename, frame_rate): self.background_image = \ pygame.image.load (back_image_filename) self.frame_rate = frame_rate self.game_over = False self.objects = [] pygame.mixer.pre_init (44100, 16, 2, 4096) pygame.init () pygame.font.init () self.surface = pygame.display.set_mode ((lățime, înălțime)) pygame. display.set_caption (caption) self.clock = pygame.time.Clock () self.keydown_handlers = defaultdict (lista) self.keyup_handlers = defaultdict (lista) self.mouse_handlers = []
Actualizați()
și a desena()
metodele sunt foarte simple. Ei doar iterează peste toate obiectele de joc gestionate și numesc metodele corespunzătoare. Dacă două obiecte de joc se suprapun, ordinea în lista de obiecte determină care obiect va fi redat mai întâi, iar celălalt va acoperi parțial sau complet.
def actual (self): pentru o în self.objects: o.update () def draw (self): pentru o în self.objects: o.draw (self.surface)
handle_events ()
metoda ascultă evenimentele generate de Pygame, cum ar fi evenimentele cheie și mouse-ul. Pentru fiecare eveniment, acesta invocă toate funcțiile de manipulare înregistrate pentru a gestiona acest tip de eveniment.
def handle_events (self): pentru evenimentul din pygame.event.get (): if event.type == pygame.QUIT: pygame.quit () sys.exit () elif event.type == pygame.KEYDOWN: pentru handler in auto.keydown_handlers [event.key]: manipulator (event.key) elif event.type == pygame.KEYUP: pentru handler în self.keydown_handlers [event.key]: handler (event.key) elif event.type în (pygame .MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP, pygame.MOUSEMOTION): pentru handler în self.mouse_handlers: handler (event.type, event.pos)
În cele din urmă, alerga()
metoda rulează bucla principală. Rulează până la joc încheiat
membru devine Adevărat. În fiecare iterație, face redarea imaginii de fundal și invocă ordinea handle_events ()
, Actualizați()
, și a desena()
metode.
Apoi actualizează afișajul, fapt care actualizează afișarea fizică cu tot conținutul redat în timpul acestei iterații. Nu în ultimul rând, ea numește clock.tick ()
metodă pentru a controla când va fi apelată următoarea iterație.
() auto.update () self.draw () pygame.display.update () auto.update () auto.update () auto.surface.blit (auto.background_image, self.clock.tick (self.frame_rate)
În această parte, ați învățat elementele de bază ale programării jocurilor și toate componentele implicate în realizarea jocurilor. Apoi, ne-am uitat la Pygame în sine și cum să-l instaleze. În cele din urmă, am intrat în arhitectura jocului și am examinat structura directorului GameObject
clasă și clasa de joc.
În partea a doua, ne vom uita la TextObject
clasa folosită pentru a face text pe ecran. Vom crea fereastra principală, inclusiv o imagine de fundal, iar apoi vom învăța cum să desenezi obiecte precum mingea și paleta.
În plus, vă rugăm să vedeți ce avem la dispoziție pentru vânzare și pentru a studia în piața Envato și nu ezitați să puneți întrebări și să furnizați feedback-ul dvs. valoros folosind feed-ul de mai jos.