Programavimas

Šaškės, kas nors?

Prieš keletą mėnesių manęs paprašė sukurti nedidelę „Java“ biblioteką, prie kurios galėtų prisijungti programa, kad būtų galima pateikti grafinę vartotojo sąsają (GUI) „Checkers“ žaidimui. GUI turi leisti ne tik perduoti šaškių lentą ir šaškes, bet ir tikrintuvą vilkti iš vieno kvadrato į kitą. Be to, tikrintuvas turi būti sutelktas į aikštę ir neturi būti priskirtas kvadratui, kurį užima kitas tikrintuvas. Šiame įraše pristatau savo biblioteką.

Šaškių GUI bibliotekos projektavimas

Kokius visuomenės tipus biblioteka turėtų palaikyti? Šaškėse kiekvienas iš dviejų žaidėjų pakaitomis perkelia vieną savo įprastą (ne karaliaus) šaškę tik į priekį ir galbūt peršoka kito žaidėjo šaškę. Kai tikrintuvas pasiekia kitą pusę, jis paaukštinamas iki karaliaus, kuris taip pat gali judėti atgal. Iš šio aprašymo galime spręsti šiuos tipus:

  • Lenta
  • Tikrintojas
  • „CheckerType“
  • Žaidėjas

A Lenta objektas identifikuoja šaškių lentą. Jis tarnauja kaip konteineris Tikrintojas objektai, užimantys įvairius kvadratus. Jis gali pats išsireikalauti ir paprašyti, kad kiekvienas būtų Tikrintojas objektas pats piešia.

A Tikrintojas objektas identifikuoja tikrintuvą. Jis turi spalvą ir nurodymą, ar tai paprastas, ar karališkas tikrintuvas. Jis gali pats nupiešti savo dydį Lenta, kurio dydžiui įtakos turi Tikrintojas dydžio.

„CheckerType“ yra enumas, kuris identifikuoja tikrintuvo spalvą ir tipą per keturias konstantas: BLACK_KING, BLACK_REGULAR, RED_KINGir RED_REGULAR.

A Žaidėjas objektas yra valdiklis, skirtas judinti šaškę su pasirenkamais šuoliais. Kadangi pasirinkau šį žaidimą įgyvendinti „Swing“, Žaidėjas nėra būtina. Užtat aš pasisukau Lenta į „Swing“ komponentą, kurio konstruktorius registruoja pelės ir pelės judesio klausytojus, kurie tvarko tikrintuvo judėjimą žmogaus grotuvo vardu. Ateityje galėčiau įdiegti kompiuterio grotuvą per kitą giją, sinchronizatorių ir kitą Lenta metodas (pvz., perkelti ()).

Ką veikia viešosios API Lenta ir Tikrintojas prisidėti? Kiek pagalvojęs sugalvojau šią visuomenę Lenta API:

  • Lenta(): Sukonstruoti a Lenta objektas. Konstruktorius atlieka įvairias inicializavimo užduotis, tokias kaip klausytojo registracija.
  • negaliojantis pridėjimas (tikrintuvo tikrintuvas, int eilutė, stulpelis int): Papildyti tikrintojas į Lenta nustatytoje vietoje eilutė ir stulpelį. Eilutė ir stulpelis yra 1 vertės vertės, o ne 0 vertės (žr. 1 pav.). papildyti() metimai java.lang.IllegalArgumentException kai jo eilutės ar stulpelio argumentas yra mažesnis nei 1 arba didesnis nei 8. Be to, jis išmeta nepažymėtą AlreadyOccupiedException kai bandysite pridėti a Tikrintojas į užimtą aikštę.
  • Aspektas getPreferredSize (): Grąžinkite Lenta komponento pageidaujamas dydis išdėstymo tikslais.

1 paveikslas. Lentos viršutinis kairysis kampas yra (1, 1)

Aš taip pat išplėtojau šią visuomenę Tikrintojas API:

  • Tikrintuvas („CheckerType“ tikrintuvo tipas): Sukonstruoti a Tikrintojas nurodyto objekto checkerType (BLACK_KING, BLACK_REGULAR, RED_KINGarba RED_REGULAR).
  • tuščias piešimas (grafika g, int cx, int cy): Pieškite a Tikrintojas naudojant nurodytą grafikos kontekstą g tikrintuvo centre, esančiame (cx, cy). Šis metodas yra skirtas iš Lenta tik.
  • loginės reikšmės yra (int x, int y, int cx, int cy): A statinis paskambinta pagalbininko metodu Lenta kuris nustato, ar pelės koordinatės (x, y) guli tikrintuvo viduje, kurio centro koordinates nurodo (cx, cy) ir kurio matmuo nurodytas kitur Tikrintojas klasė.
  • int getDimension (): A statinis paskambinta pagalbininko metodu Lenta tai nustato šaškės dydį, kad lenta galėtų tinkamai parinkti kvadratus ir bendrą dydį.

Tai beveik apima visas šaškių GUI bibliotekas, atsižvelgiant į jos tipus ir viešąsias API. Dabar sutelksime dėmesį į tai, kaip aš įgyvendinau šią biblioteką.

Šaškių GUI bibliotekos diegimas

Šaškių GUI biblioteką sudaro keturi viešieji tipai, esantys tame pačiame pavadinime esančiuose šaltinio failuose: AlreadyOccupiedException, Lenta, Tikrintojasir „CheckerType“. Išvardinus 1 dovanas AlreadyOccupiedExceptionšaltinio kodas.

1 sąrašas. AlreadyOccupiedException.java

public class AlreadyOccupiedException pratęsia RuntimeException {public AlreadyOccupiedException (String msg) {super (msg); }}

AlreadyOccupiedException tęsiasi java.lang.RuntimeException, kuris padaro AlreadyOccupiedException nepatikrinta išimtis (jos nereikia gaudyti ar deklaruoti metimai sąlyga). Jei norėčiau pagaminti AlreadyOccupiedException patikrinau, būčiau pratęsęs java.lang. Išimtis. Aš pasirinkau, kad šis tipas būtų netikrinamas, nes jis veikia panašiai kaip ir nepažymėtas Neteisėtas argumentas. Išimtis.

AlreadyOccupiedException pareiškia konstruktorius, kuris pateikia eilutės argumentą, apibūdinantį išimties priežastį. Šis argumentas persiųstas RuntimeException superklasė.

Išvardinus 2 dovanas Lenta.

2 sąrašas. Board.java

importuoti java.awt.Color; importuoti java.awt.Dimension; importuoti java.awt.Grafika; importuoti java.awt.Grafika2D; importuoti java.awt.RenderingHints; importuoti java.awt.event.MouseEvent; importuoti java.awt.event.MouseAdapter; importuoti java.awt.event.MouseMotionAdapter; importuoti java.util.ArrayList; importuoti java.util.List; importuoti javax.swing.JComponent; public class Board praplečia JComponent {// šaškių lentos kvadrato matmenis (25% didesnis nei šaškė) private final static int SQUAREDIM = (int) (Checker.getDimension () * 1,25); // šaškių lentos matmuo (8 kvadratų plotis) privatus finalas int BOARDDIM = 8 * SQUAREDIM; // pageidaujamas plokštės komponento „private Dimension dimPrefSize“ dydis; // vilkimo vėliava - nustatyta kaip „true“, kai vartotojas paspaudžia pelės mygtuką virš tikrintuvo // ir išvaloma į „false“, kai vartotojas atleidžia pelės mygtuko privatų loginį elementą inDrag = false; // poslinkis tarp vilkimo pradžios koordinačių ir tikrintuvo centro koordinačių private int deltax, deltay; // nuoroda į padėtą ​​tikrintuvą vilkimo privataus „PosCheck posCheck“ pradžioje; // centrinė tikrintuvo vieta vilkimo pradžioje private int oldcx, oldcy; // Checker objektų ir jų pradinių pozicijų sąrašas privatus List posChecks; viešoji lenta () {posChecks = new ArrayList (); dimPrefSize = naujas aspektas (BOARDDIM, BOARDDIM); addMouseListener (naujas MouseAdapter () {@Paisyti viešą tuštumą mousePressed (MouseEvent me) {// Paspaudimo metu gaukite pelės koordinates. int x = me.getX (); int y = me.getY (); // Raskite padėtą ​​tikrintuvą pelės paspaudimu. ieškokite (PosCheck posCheck: posChecks) if (Checker.contains (x, y, posCheck.cx, posCheck.cy)) {Board.this.posCheck = posCheck; oldcx = posCheck.cx; oldcy = posCheck.cy ; deltax = x - posCheck.cx; deltay = y - posCheck.cy; inDrag = true; return;}} @Paisyti viešą void mouseReleased („MouseEvent me“) {// Paleidus pelę, išvalykite „inDrag“ (į vykdoma), jei inDrag yra // jau nustatytas. if (inDrag) inDrag = false; dar grįžti; // Pritvirtinkite tikrintuvą prie kvadrato centro. int x = me.getX (); int y = me.getY (); posCheck .cx = (x - deltax) / SQUAREDIM * SQUAREDIM + SQUAREDIM / 2; posCheck.cy = (y - delta) / SQUAREDIM * SQUAREDIM + SQUAREDIM / 2; // Neperkelkite tikrintuvo į užimtą aikštę. ((PosCheck posCheck) : posChecks) if (posCheck! = Board.this.posCheck && posC heck.cx == Board.this.posCheck.cx && posCheck.cy == Board.this.posCheck.cy) {Board.this.posCheck.cx = oldcx; Board.this.posCheck.cy = oldcy; } posCheck = null; perdažyti (); }}); // Prie programėlės pritvirtinkite pelės judesių klausytoją. Tas klausytojas klauso // pelės nuvilkimo įvykių. „addMouseMotionListener“ (naujas „MouseMotionAdapter“) ({@Orride public void mouseDragged (MouseEvent me) {if (inDrag) {// Atnaujinti tikrintuvo centro vietą. posCheck.cx = me.getX () - deltax; posCheck.cy = me.getY ( ) - deltay; perdažyti ();}}}); } public void add (tikrintuvo tikrintuvas, int eilutė, int col) {if (8 eilutė) mesti naują „IllegalArgumentException“ („eilutė už diapazono ribų:“ + eilutė); if (8 skiltis) mesti naują „IllegalArgumentException“ („col out of range:“ + col); PosCheck posCheck = naujas PosCheck (); posCheck.checker = tikrintuvas; posCheck.cx = (col - 1) * SQUAREDIM + SQUAREDIM / 2; posCheck.cy = (1 eilutė) * SQUAREDIM + SQUAREDIM / 2; už (PosCheck _posCheck: posChecks), jei (posCheck.cx == _posCheck.cx && posCheck.cy == _posCheck.cy) mesti naują „AlreadyOccupiedException“ („kvadratas ties (" + eilutė + "," + col + ") užimtas" ); posChecks.add (posCheck); } @Paisyti viešąjį aspektą getPreferredSize () {return dimPrefSize; } @Paisyti apsaugotą tuščią paintComponent (grafika g) {paintCheckerBoard (g); už (PosCheck posCheck: posChecks) if (posCheck! = Board.this.posCheck) posCheck.checker.draw (g, posCheck.cx, posCheck.cy); // Nuvilkite tikrintuvą paskutinį, kad jis pasirodytų virš bet kurio pagrindinio // tikrintuvo. if (posCheck! = null) posCheck.checker.draw (g, posCheck.cx, posCheck.cy); } private void paintCheckerBoard (grafika g) {((Graphics2D) g) .setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Dažų šaškių lenta. už (int eilutė = 0; eilutė <8; eilutė ++) {g.setColor ((((1 eilutė)! = 0)? Spalva. JUODA: Spalva. BALTA); for (int col = 0; col <8; col ++) {g.fillRect (col * SQUAREDIM, eilutė * SQUAREDIM, SQUAREDIM, SQUAREDIM); g.setColor ((g.getColor () == Color.BLACK)? Color.WHITE: Color.BLACK); }}} // padėtas tikrintuvo pagalbininkas klasės privati ​​klasė „PosCheck“ {viešoji tikrintuvo tikrintoja; public int cx; visuomenės int cy; }}

Lenta tęsiasi javax.swing.JKomponentas, kuris padaro Lenta a Sūpynės komponentas. Tokiu būdu galite tiesiogiai pridėti a Lenta komponentą į „Swing“ programos turinio sritį.

Lenta pareiškia SQUAREDIM ir LENTELĖ konstantos, identifikuojančios kvadrato ir langelio taškų matmenis. Inicijuojant SQUAREDIM, Kviečiuosi Checker.getDimension () užuot patekęs į lygiavertę visuomenę Tikrintojas pastovus. Joshua Block atsako, kodėl aš tai darau, 30 punkte (vietoj tarpt konstantos) jo antrojo leidimo, Veiksminga „Java“"Programos, naudojančios tarpt enum raštas yra trapus. Nes tarpt enums yra kompiliavimo laiko konstantos, jos sudaromos klientams, kurie jas naudoja. Jei tarpt susijęs su enum konstanta, jos klientai turi būti sudaryti iš naujo. Jei jų nėra, jie vis tiek bėgs, tačiau jų elgesys bus neapibrėžtas “.

Dėl išsamių komentarų neturiu daug daugiau pasakyti Lenta. Tačiau atkreipkite dėmesį į įdėtą „PosCheck“ klasė, kuri apibūdina padėtą ​​tikrintuvą saugodama a Tikrintojas nuoroda ir jos centro koordinatės, palyginti su viršutiniu kairiuoju Lenta komponentas. Kai pridėsite a Tikrintojas prieštarauti Lenta, jis saugomas naujame „PosCheck“ objektas kartu su tikrintuvo vidurio padėtimi, kuri apskaičiuojama pagal nurodytą eilutę ir stulpelį.

Išvardijamos 3 dovanos Tikrintojas.

$config[zx-auto] not found$config[zx-overlay] not found