Este artigo descreve o jogo 2048 implementado por Java. Compartilhe -o para sua referência, como segue:
Vamos dar uma olhada no efeito de execução:
O código específico é o seguinte:
pacote awtdemo; importar javax.swing.*; importar java.awt.*; importar java.awt.event.*; importar java.io. Up = 0, para baixo = 1, esquerda = 2, direita = 3; private estático final int wid = 150, sp = 10; @Suppresswarnings ("não utilizado") private int escores = 0; private estático Jlabel Scorelabel; Mudança booleana privada, checkMode = false, gameoverflag = false, succcessflag = false; private int [] etiqueta = {2,4,8,16,32,64,128}; private Color[] clo={ new Color(200,200,200),new Color(228,228,160),new Color(214,163,92),new Color(234,124,72),new Color(240,84,77),new Color(255,68,53),new Color(200,200,64) }; @Suppresswarnings ("RawTypes") mapa privado cmap = new hashmap (); public static retobject [] [] rset = new Rectobject [4] [4]; public retOBject [] [] list = new RectoBject [4] [4]; my2048Panel privado myp; @Suppresswarnings ("RawTypes") Private LinkedList savelist = new LinkedList (); Private Jbutton Gobackbutton; KeyListener KL = new KeyListener () {public void keyPressed (KeyEvent e) {SAVETHESTEP (); gobackbutton.setVisible (true); if (gameoverflag == true) {return; } if (! adirable ()) {gameover (); } int key = e.getKeyCode (); switch (key) {case keyEvent.vk_up: alteração = false; mover -up (true); if (altere == true) {getArAndomRect (); // saveTheStep (); } quebrar; case keyevent.vk_down: alteração = false; mudou -se (verdadeiro); if (altere == true) {getArAndomRect (); // saveTheStep (); } quebrar; case keyevent.vk_left: alteração = false; Moveleft (verdadeiro); if (altere == true) {getArAndomRect (); // saveTheStep (); } quebrar; case keyevent.vk_right: alteração = false; Moveight (verdadeiro); if (altere == true) {getArAndomRect (); // saveTheStep (); } quebrar; } // saveTheStep (); } public void keytyped (keyEvent e) {} public void keyreleased (keyEvent e) {}}; classe RectoBject {private int Value; public RectoBject () {value = 0; } public retOBject (RectoBject obj) {value = obj.value; } public boolean é igual (objeto inobj) {retObject obj = (retObject) inobj; if (obj.value == value) {return true; } retornar false; }} classe Point {int x; int y; public Point (int i, int j) {x = i; y = j; }} classe My2048Panel estende JPanel {private int [] xindex = {sp, 2*sp+wid, 3*sp+2*wid, 4*sp+3*wid}; private int [] yindex = {sp, 2*sp+wid, 3*sp+2*wid, 4*sp+3*wid}; @Suppresswarnings ("deprecação") public void PaintComponent (gráficos g) {// background super.paintComponent (g); for (int i = 0; i <xindex.length; i ++) {for (int j = 0; j <yindex.length; j ++) {g.setColor (color.white); G.DrawRoundRect (xindex [i], yindex [j], wid, wid, wid/5, wid/5); G.SetColor (New Color (197.183.129)); G.FillRoundRect (Xindex [i], Yindex [j], wid, wid, wid/5, wid/5); }} // Retângulo de pintura para (int i = 0; i <4; i ++) {for (int j = 0; j <4; j ++) {if (rset [i] [j]! = null) {g.setColor (color.white); G.DrawRoundRect (Yindex [j], xindex [i], wid, wid, wid/5, wid/5); if (rset [i] [j] .Value <128) {g.setColor ((color) cmap.get (rset [i] [j] .Value)); } else {g.setColor ((color) cmap.get (128)); } g.fillRoundRect (yindex [j], xindex [i], wid, wid, wid/5, wid/5); g.setColor (color.black); Fonte da fonte = nova fonte ("timesroman", font.bold, 50); g.setFont (fonte); FontMetrics fm = Toolkit.getDefaultToolkit (). GetFontMetrics (font); int len = fm.stringwidth (""+rset [i] [j] .Value); int hg = fm.getHeight (); g.DrawString (""+rset [i] [j] .Value, yindex [j]+wid/2-len/2, xindex [i]+wid/2+hg/4); if (rset [i] [j] .Value == 2048 && successflag == false) {succcessflag = true; gameccess (); }}}}}}} classe GameOverPone estende JPanel {public gameOverpane (int w, int h) {setSize (w, h); // SETOPAQUE (FALSE); } @Suppresswarnings ("deprecação") public void PaintComponent (gráfico g) {super.paintcomponent (g); Fonte Fonte = New Font ("Timesroman", Font.Bold, 80); g.setFont (fonte); FontMetrics fm = Toolkit.getDefaultToolkit (). GetFontMetrics (font); int width = fm.stringwidth ("jogo sobre"); int height = fm.getHeight (); g.setColor (nova cor (255,0,0)); G.DrawString ("Game Over!", GetWidth ()/2 largura/2, Gethight ()/2-Hight/2); }} classe SuccessPane estende JPanel {public succcessPane (int w, int h) {setSize (w, h); // SETOPAQUE (FALSE); } public void PaintComponent (Gráfico G) {super.PaintComponent (G); Fonte Fonte = New Font ("Timesroman", Font.Bold, 80); g.setFont (fonte); @Suppresswarnings ("deprecação") fontMetrics fm = toolkit.getDefaultToolkit (). GetFontMetrics (font); int width = fm.stringwidth ("sucesso!"); int height = fm.getHeight (); g.setColor (nova cor (255,0,0)); G.DrawString ("Sucesso!", GetWidth ()/2 largura/2, Gethight ()/2-Hight/2); }} classe logo estende JPanel {public logotipo (int w, int h) {setSize (w, h); } @Suppresswarnings ("não utilizados") public void PaintComponent (gráficos g) {super.paintComponent (g); Fonte Fonte = New Font ("Timesroman", Font.Bold, 60); g.setFont (fonte); @Suppresswarnings ("deprecação") fontMetrics fm = toolkit.getDefaultToolkit (). GetFontMetrics (font); int width = fm.stringwidth ("2048"); int height = fm.getHeight (); g.setColor (nova cor (255,0,0)); G.DrawString ("2048", 20, GetHeight ()/2+20); }} classe pública GobackListener implementa ActionListener {@SuppressWarnings ("RawTypes") public void ActionPerformed (ActionEvent E) {if (savelist.size () == 0) {gobackbutton.setVisible (false); retornar; } ArrayList arr = (ArrayList) savelist.getLast (); scorelabel.settext (""+arr.get (0)); for (int i = 0; i <4; i ++) {for (int j = 0; j <4; j ++) {int num = (int) arr.get (4*i+j+1); if (num! = 0) {rset [i] [j] = new RectoBject (); rset [i] [j] .Value = num; } else {rset [i] [j] = null; }}} savelist.removelt (); repintar (); }} classe pública RESETListener implementa ActionListener {public void ActionPerformed (ActionEvent E) {refreshBest (); for (int i = 0; i <4; i ++) {for (int j = 0; j <4; j ++) {rset [i] [j] = null; }} scorelabel.settext ("0"); repintar (); getArAndomRect (); getArAndomRect (); }} // o applet init public void init () {contêiner cp = getContentPane (); cp.setLayout (nulo); cp.setFocusable (true); cp.addkeylistener (KL); Fonte da fonte = nova fonte ("timesnewman", font.bold, 30); Jlabel sl = new jlabel (); sl.setLayout (New GridLayout (2,1)); Jlabel sllb = new jlabel ("pontuações"); sllb.setFont (fonte); scorelabel = new jlabel ("0"); scorelabel.setFont (Font); sl.add (sllb); sl.add (scorelabel); int melhor = 0; tente {arquivo file = new File ("bestRecord"); if (file.exists ()) {RandomAccessFile f = new RandomAccessFile (arquivo, "rw"); melhor = f.readInT (); F.Close (); }} catch (filenotfoundException e) {melhor = 0; E.PrintStackTrace (); } catch (ioexception e) {melhor = 0; E.PrintStackTrace (); } Jlabel bsl = new jlabel (); bsl.setLayout (New GridLayout (2,1)); Jlabel jl = new jlabel ("melhor"); jl.setFont (fonte); Jlabel jl1 = new jlabel (""+melhor); jl1.setFont (fonte); bsl.add (JL); bsl.add (JL1); myp = novo my2048Panel (); Logotipo = novo logotipo (0,0); gobackbutton = new jbutton ("desfazer"); gobackbutton.setFont (Font); gobackbutton.addactionListener (new gobackListener ()); gobackbutton.addkeyListener (KL); Jbutton jb = new jbutton ("redefinir"); jb.setFont (fonte); jb.addactionListener (new ResetListener ()); jb.addkeylistener (KL); sl.setbounds (500,20,200,80); bsl.setbounds (300,20,200,80); logo.setbounds (0, 0, 600, 100); myp.setbounds (0,90.700.700); gobackbutton.setbounds (700.250.150,60); jb.setbounds (700.450.150,60); cp.add (SL); cp.add (bsl); cp.add (logotipo); cp.add (myp); cp.add (Gobackbutton); cp.add (JB); Arquivo f = novo arquivo ("lastrecord"); if (f.Exists ()) {try {RandomAccessFile arquivo = new RandomAccessFile (f, "rw"); int num = file.readInT (); scorelabel.settext (""+num); for (int i = 0; i <4; i ++) {for (int j = 0; j <4; j ++) {num = file.readInt (); if (num! = 0) {rset [i] [j] = new RectoBject (); rset [i] [j] .Value = num; }}} file.close (); } catch (filenotfoundException e) {e.printStackTrace (); } catch (ioexception e) {e.printStackTrace (); }} else {getarandomRect (); getArAndomRect (); }} @Suppresswarnings ("desmarcado") public Game2048 () {// SaveTheStep (); for (int i = 0; i <7; i ++) {cmap.put (etiqueta [i], clo [i]); }} // moteleft public void moteleft (bandeira booleana) {clearlist (list); for (int i = 0; i <4; i ++) {int k = 0; for (int j = 0; j <4; j ++) {if (rset [i] [j]! }}} para (int i = 0; i <4 && flag; i ++) {for (int j = 0; j <3; j ++) {if (list [i] [j]! = null && list [i] [j+1]! if (checkMode == false) {int sum = integer.parseint (scorelabel.getText ()); soma+= lista [i] [j] .Value; scorelabel.settext (""+soma); } lista [i] [j+1] = null; j ++; }}} if (isChange ()) {if (checkMode == false) {copyset (rset, list); repintar (); moveleleft (falso); } alteração = true; } else {repaint (); }} // Moveright public void Moveright (sinalizador booleano) {clearlist (list); for (int i = 0; i <4; i ++) {int k = 3; for (int j = 3; j> -1; j-) {if (rset [i] [j]! }}} para (int i = 0; i <4 && flag; i ++) {for (int j = 3; j> 0; j-) {if (list [i] [j]! = null && list [i] [j-1]! if (checkMode == false) {int sum = integer.parseint (scorelabel.getText ()); soma+= lista [i] [j] .Value; scorelabel.settext (""+soma); } lista [i] [j-1] = null; J--; }}} if (isChange ()) {if (checkMode == false) {copyset (rset, list); repintar (); MoveirT (falso); } alteração = true; } else {repaint (); }} // moveup public void moveup (sinalizador booleano) {clearlist (list); for (int j = 0; j <4; j ++) {int k = 0; para (int i = 0; i <4; i ++) {if (rset [i] [j]! = null) {list [k ++] [j] = new RectoBject (rset [i] [j]); }}} para (int j = 0; j <4 && flag; j ++) {for (int i = 0; i <3; i ++) {if (list [i] [j]! = null && list [i+1] [j]! if (checkMode == false) {int sum = integer.parseint (scorelabel.getText ()); soma+= lista [i] [j] .Value; scorelabel.settext (""+soma); } lista [i+1] [j] = null; i ++; }}} if (isChange ()) {if (checkMode == false) {copyset (rset, list); repintar (); mover -up (falso); } alteração = true; } else {repaint (); }} // movimentado public void mudou (bandeira booleana) {clearlist (list); for (int j = 0; j <4; j ++) {int k = 3; para (int i = 3; i> -1; i-) {if (rset [i] [j]! = null) {list [k-] [j] = new RectoBject (rset [i] [j]); }}} para (int j = 0; j <4 && flag; j ++) {for (int i = 3; i> 0; i-) {if (list [i] [j]! = null && list [i-1] [j]. if (checkMode == false) {int sum = integer.parseint (scorelabel.getText ()); soma+= lista [i] [j] .Value; scorelabel.settext (""+soma); } lista [i-1] [j] = null; eu--; }}} if (isChange ()) {if (checkMode == false) {copyset (rset, list); repintar (); mudou -se (falso); } alteração = true; } else {repaint (); }} // Outras funções private void copyset (retObject [] [] dst, retObject [] [] src) {for (int i = 0; i <4; i ++) {for (int j = 0; j <4; j ++) {dst [i] [j] = src [i] [j]; }}} // Detecte se o rset é diferente da lista ou não é privada booleana isChange () {for (int i = 0; i <4; i ++) {for (int j = 0; j <4; j ++) {if (rset [i] [j]! verdadeiro; } if (rset [i] [j]! = null && list [i] [j] == null) {return true; } if (rset [i] [j] == null && list [i] [j]! = null) {return true; }} retornar false; } private void clearlist (retObject [] [] s) {for (int i = 0; i <s.length; i ++) {for (int j = 0; j <s [i] .Length; j ++) {s [i] [j] = null; }}} // Obtenha um retângulo aleatório @suppresswarnings ({"desmarcado", "RawTypes"}) public void getArAndomRect () {ArrayList List = new ArrayList (); for (int i = 0; i <4; i ++) {for (int j = 0; j <4; j ++) {if (rset [i] [j] == null) {list.add (new Point (i, j)); }}}} if (list.size () == 0 &&! adirable ()) {gameover (); retornar; } Rand aleatória = novo aleatório (); int index = rand.nextInt (list.size ()); Ponto loc = (ponto) list.get (index); índice = rand.nextint (2); rset [loc.x] [loc.y] = new RectoBject (); if (index == 1) {rset [loc.x] [loc.y] .Value = 4; } else {rset [loc.x] [loc.y] .value = 2; }} // Detecte se existem outras etapas ou não public boolean adirable () {checkMode = true; alteração = false; Moveleft (verdadeiro); Moveight (verdadeiro); mudou -se (verdadeiro); mover -up (true); CheckMode = false; if (altere == true) {return true; } else {return false; }} public void gameover () {gameOverflag = true; Jpanel JL = novo GameOverpane (myp.getwidth (), myp.getHeight ()); jl.setbounds (0, 0, 700, 700); Jbutton jb1 = new jbutton ("novamente"); Fonte da fonte = nova fonte ("timesroman", font.bold, 30); jb1.setOpaque (falso); jb1.setFont (fonte); Jbutton jb2 = new jbutton ("Close"); jb2.SetSize (jb1.getSize ()); JB2.SetOPAQUE (FALSE); jb2.setFont (fonte); jb1.addactionListener (new ActionListener () {public void ActionPerformed (ActionEvent E) {scorelabel.settext ("0"); myp.remove (jl); clearlist (rset); myp.validate (); getArCrect (); getArArDomrect (); }); jb2.addactionListener (new ActionListener () {public void ActionPerformed (ActionEvent E) {refreshBest (); arquivo f = new File ("lastrecord"); if (f.exists ()) {f.Delete ();} System.exit (0);}}); jl.add (JB1); jl.add (JB2); myp.add (jl); jl.validate (); } public void gameccess () {jpanel jl = new succcessPane (myp.getwidth (), myp.getheight ()); JL.SETOPAQUE (FALSO); jl.setbounds (0, 0, 700, 700); Jbutton jb1 = new jbutton ("continuação"); Fonte da fonte = nova fonte ("timesroman", font.bold, 30); jb1.setOpaque (falso); jb1.setFont (fonte); Jbutton jb2 = new jbutton ("Close"); jb2.SetSize (jb1.getSize ()); JB2.SetOPAQUE (FALSE); jb2.setFont (fonte); jb1.addactionListener (new ActionListener () {public void ActionPerformed (ActionEvent e) {myp.remove (jl); myp.validate (); repaint ();}}); jb2.addactionListener (new ActionListener () {public void ActionPerformed (ActionEvent e) {refreshBest (); System.Exit (0);}}); jl.add (JB1); jl.add (JB2); myp.add (jl); jl.validate (); } @Suppresswarnings ("desmarcados") public void SAVETHESTEP () {if (savelist.size () <20) {@suppresswarnings ("RawTypes") ArrayList arr = new ArrayList (); Int Score = Integer.ParseInt (scorelabel.getText ()); Arr.add (pontuação); for (int i = 0; i <4; i ++) {for (int j = 0; j <4; j ++) {if (rset [i] [j]! = null) {arr.add (rset [i] [j] .Value); } else {arr.add (0); }} savelist.addlast (arr); } else {savelist.removefirst (); SAVETHESTEP (); }} public static string title (objeto o) {string t = o.getclass (). tostring (); if (t.indexOf ("classe")! =-1) {t = t.substring (6); } retornar t; } public static void refreshBest () {try {int best = 0; Arquivo f = novo arquivo ("bestRecord"); Arquivo RandomAccessFile; if (f.Exists ()) {file = new RandomAccessFile (f, "rw"); melhor = file.readInT (); file.seek (0); } else {file = new RandomAccessFile (f, "rw"); } //System.out.println("A melhor pontuação é "+melhor); int cur = intege.parseint (scorelabel.getText ()); if (cur> melhor) {file.writeInt (cur); } file.close (); } catch (filenotfoundException e1) {e1.printStackTrace (); } catch (ioexception e2) {e2.printStackTrace (); }} @Suppresswarnings ("Resource") public static void saverecord () {try {RandomAccessFile File = new RandomAccessFile (novo arquivo ("lastrecord"), "rw"); Int Score = Integer.ParseInt (scorelabel.getText ()); file.writeint (pontuação); para (int i = 0; i <4; i ++) {for (int j = 0; j <4; j ++) {if (rset [i] [j]! = null) {file.WriteInt (rset [i] [j] .Value); } else {file.WriteInt (0); }}}}} catch (filenotfoundException e) {e.printStackTrace (); } catch (ioexception e) {e.printStackTrace (); }} public static void run (japplet applet, int width, int alting) {jframe frame = new jframe (title (applet)); frame.addwindowlistener (new windowAdapter () {public void windowclosing (windowEvent e) {refreshBest (); saverecord (); //system.out.println("A pontuação é "+scorelabel.getText ());}}); frame.setDefaultCloseoperation (jframe.exit_on_close); frame.getContentPane (). add (applet); frame.SetSize (largura, altura); applet.init (); applet.start (); frame.setVisible (true); } public static void main (string [] args) {run (novo game2048 (), 900, 800); }}PS: aqui recomendamos dois outros jogos 2048 para sua referência (implementação JS)
Online 2048 jogos:
http://tools.vevb.com/games/game2048
Online 2048 Mini Game Digital Version:
http://tools.vevb.com/games/game2048num
Para obter mais informações sobre os algoritmos Java, os leitores interessados neste site podem visualizar os tópicos: "Estrutura de dados Java e tutorial de algoritmo", "Resumo das dicas de nó da operação Java Dom", "Resumo de dicas de operação de Java e Operação de Java" e "Resumo de Java cache" Tips "TIPS"
Espero que este artigo seja útil para a programação Java de todos.