1. Introducere

Un motor de joc ar fi de puțin folos dacă l-am putea folosi doar pentru a desena ceva pe ecran. Pentru a scrie un joc cu drepturi depline, avem nevoie de el pentru a interacționa cu utilizatorul! Pentru a fi mai precis, programul nostru ar trebui să urmărească acțiunile utilizatorilor și să răspundă la ele.

Pentru a face acest lucru, motorul de joc CodeGym are metode speciale pe care le apelează atunci când utilizatorul face clic pe butoanele mouse-ului sau tastele tastaturii.

Ideea clasei este că scrieți singur aceste metode, iar apoi motorul de joc CodeGym este responsabil pentru apelarea lor. Tot ce aveți nevoie este să declarați aceste metode în codul dvs. Acest lucru este mai ușor de făcut decât pare.


2. Lucrul cu mouse-ul

Motorul de joc are două metode de lucru cu mouse-ul:

void onMouseLeftClick(int x, int y)
void onMouseRightClick(int x, int y)

Pur și simplu declarați aceste metode în propria clasă care moștenește Gameclasa. Și apoi scrieți orice cod doriți în aceste metode. Motorul de joc va apela aceste metode atunci când utilizatorul face clic pe butoanele mouse-ului.

onMouseLeftClick(int x, int y)este apelat de motor când se face clic pe butonul stâng al mouse-ului . Parametrii săi sunt coordonatele celulei terenului de joc în care a avut loc clicul. Coordonatele celulei din stânga sus sunt (0,0). Pentru a utiliza această metodă, trebuie să o înlocuiți, plasând adnotarea @Overrideînaintea numelui metodei.

onMouseRightClick(int x, int y)este apelat când se face clic pe butonul drept al mouse-ului . Funcționează similar cu onMouseLeftClick(int x, int y)metoda.

Exemple de utilizare a acestor metode:

import com.codegym.engine.cell.Color;
import com.codegym.engine.cell.Game;
import com.codegym.engine.cell.Key;

public class MySuperGame extends Game {
   @Override
   public void initialize() {
      // Set the size of the playing field to 3x3
      setScreenSize(3, 3);

      // Paint the playing field white
      for (int x = 0; x < 3; x++) {
         for (int y = 0; y < 3; y++) {
            setCellColor(x, y, Color.WHITE);
         }
      }
   }

   @Override
   public void onMouseLeftClick(int x, int y) {
      // Put a "X" in the cell that was clicked with the left mouse button
      setCellValue(x, y, "X");
   }

   @Override
   public void onMouseRightClick(int x, int y) {
      // Clear the cell that was clicked with the right mouse button
      setCellValue(x, y, "");
   }
}

În exemplul de mai sus, am declarat ambele metode: onMouseLeftClick()și onMouseRightClick(). Prima metodă va fi apelată atunci când utilizatorul face clic pe butonul stâng al mouse-ului pe celulele câmpului de joc. A doua metodă va fi apelată când se face clic pe butonul din dreapta al mouse-ului.

Ca argumente, motorul de joc CodeGym va trece coordonatele (x, y)celulei terenului de joc pe care sa făcut clic cu mouse-ul.



3. Lucrul cu tastatura

Motorul de joc are două metode de lucru cu tastatura:

void onKeyPress(Key key);
void onKeyReleased(Key key);

Dacă doriți să faceți ceva când utilizatorul apasă o tastă, trebuie doar să declarați aceste metode în clasa dvs. care moștenește clasa Game.

Îți scrii codul în aceste metode, iar motorul de joc le va apela atunci când utilizatorul apasă (sau eliberează) o tastă.

onKeyPress(Key key)este apelat atunci când este apăsată orice tastă . Valoarea tastei apăsate (sau ) este transmisă metodei ca parametru. Pentru a utiliza această metodă, trebuie să o înlocuiți, plasând adnotarea înaintea numelui metodei.Key.UNKNOWNkey@Override

onKeyReleased(Key key)este apelat atunci când orice tastă este eliberată . Valoarea tastei corespunzătoare (sau ) este atribuită parametrului . Pentru a utiliza această metodă, trebuie să o înlocuiți, plasând adnotarea înaintea numelui metodei.Key.UNKNOWNkey@Override

Exemple de utilizare a acestor metode:

import com.codegym.engine.cell.Color;
import com.codegym.engine.cell.Game;
import com.codegym.engine.cell.Key;

public class MySuperGame extends Game {
   @Override
   public void initialize() {
      // Set the size of the playing field to 3x3
      setScreenSize(3, 3);

      // Paint the playing field white
      for (int x = 0; x < 3; x++) {
         for (int y = 0; y < 3; y++) {
            setCellColor(x, y, Color.WHITE);
         }
      }
   }

   @Override
   public void onKeyPress(Key key) {
      // When the spacebar is pressed, the center cell turns yellow
      if (key == Key.SPACE) {
         setCellColor(1, 1, Color.YELLOW);
      }
   }

   @Override
   public void onKeyReleased(Key key) {
      // When the spacebar is released, the center cell returns to white
      if (key == Key.SPACE) {
         setCellColor(1, 1, Color.WHITE);
      }
   }
}


4. Lista tuturor cheilor acceptate

Când motorul CodeGym apelează metodele onKeyPress()și onKeyReleased(), le transmite informații despre tasta apăsată (eliberată). Pentru a face acest lucru, motorul CodeGym are un tip special numit Key.

În versiunea actuală a motorului, tipul Keyacceptă doar un set limitat de 9 valori:

Valoare Ce a apăsat utilizatorul
Key.ENTER
Utilizatorul a apăsat tasta Enter
Key.ESCAPE
Utilizatorul a apăsat tasta Esc
Key.PAUSE
Utilizatorul a apăsat tasta Pauză
Key.SPACE
Utilizatorul a apăsat tasta Space
Key.LEFT
Utilizatorul a apăsat tasta săgeată stânga
Key.RIGHT
Utilizatorul a apăsat tasta Săgeată dreapta
Key.UP
Utilizatorul a apăsat tasta săgeată sus
Key.DOWN
Utilizatorul a apăsat tasta săgeată în jos
Key.UNKNOWN
Orice cheie în afară de cele enumerate mai sus

Dacă jucătorul apasă pe bara de spațiu, atunci onKeyPress()metoda va fi apelată cu Key.SPACEca parametru. Dacă utilizatorul apasă săgeata stânga, atunci parametrul va fi Key.LEFT. Dacă utilizatorul apasă orice tastă care nu este în lista de mai sus, atunci metoda onKeyPress()va fi apelată cu Key.UNKNOWNca parametru.

Problema aici este că jocurile CodeGym existente au fost concepute pentru a rula pe un telefon. În loc de tastatura standard, avem 8 butoane virtuale:


5. Lucrul cu un cronometru

Multe jocuri au loc în timp real, adică utilizatorul ar putea să nu facă nimic, dar anumite evenimente mai apar în joc. Pentru a vă permite să implementați astfel de jocuri, am adăugat un cronometru motorului de joc.

Iată cum funcționează: porniți cronometrul și setați timpul după care ar trebui să fie declanșat. De exemplu, 500 ms. Apoi, la fiecare jumătate de secundă, motorul de joc CodeGym va apela onTurn()metoda. De un număr infinit de ori - până când temporizatorul este oprit.

Cum folosești un cronometru?

1. Porniți cronometrul

Pentru a porni cronometrul, avem void setTurnTimer(int timeMs)metoda. Metoda ia ca argument durata (în milisecunde sau 1/1000 de secundă) a intervalului dintre apeluri inverse. Trebuie doar să apelați această metodă o dată, iar motorul de joc va începe să apeleze metoda onTurn()la fiecare timeMsmilisecunde.

2. Ignorați onTurn(int)metoda

Pentru a face acest lucru, trebuie să declarați o void onTurn(int step)metodă într-o clasă care moștenește Gameclasa. Motorul de joc va apela această metodă. Cu fiecare apel, motorul trece un număr secvenţial care identifică apelul de metodă ( 1, 2, 3, ...).

3. Opriți cronometrul

Dacă cronometrul nu mai este necesar, de exemplu pentru că utilizatorul a terminat jocul, atunci acesta poate fi dezactivat. Pentru a face acest lucru, apelați pur și simplu stopTurnTimer()metoda.

4 Accelerați/modificați cronometrul

În unele jocuri, frecvența evenimentelor crește în mod regulat, așa că ar fi convenabil să ne putem grăbi cronometrul, adică să reducem timpul dintre apeluri inverse. Și nimic nu ar putea fi mai ușor - doar sunați setTurnTimer(int timeMs)din nou cu noua valoare, iar timpul dintre apeluri către se onTurn()va schimba.

Exemplu:

import com.codegym.engine.cell.Color;
import com.codegym.engine.cell.Game;

public class MySuperGame extends Game {
   ...
   @Override
   public void initialize() {
      // Create a 3x3 playing field
      setScreenSize(3, 3);
      showGrid(false);
      setCellValueEx(1, 1, Color.BLUE, "X", Color.ORANGE, 50);

      setTurnTimer(500); // Turn on the timer. The interval between callbacks is 500ms.
   }

   @Override
   public void onTurn(int step) {
      if (step == 100) {
         stopTurnTimer(); // If this is the 100th callback, then turn off the timer
      }

      if (step % 2 == 1) {
         // If this is an odd calllback, then set the cell background to red
         setCellColor(1, 1, Color.RED);
      } else {
         // If this is an even callback, then set the cell background to blue
         setCellColor(1, 1, Color.BLUE);
      }
   }
   ...
}

În acest exemplu simplu, am creat un câmp care este de 3 celule cu 3 celule. Apoi am pornit un cronometru care va apela onTurn()metoda la fiecare jumătate de secundă.

Aici, culoarea celulei centrale se va schimba la fiecare jumătate de secundă. Textul celulei nu se va schimba. După 50 de secunde (100 de apeluri inverse), culoarea nu se va mai schimba și cronometrul se va opri.