日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

java實現2048小游戲

瀏覽:23日期:2022-08-17 10:21:41

本文實例為大家分享了java實現2048小游戲的具體代碼,供大家參考,具體內容如下

一、實現效果

java實現2048小游戲

二、實現代碼

Check表示格子,GameView實現游戲視圖界面及功能,是核心。

java實現2048小游戲

Check.java

import java.awt.Color;import java.awt.Font;// 方格類public class Check { public int value; Font font1 = new Font('宋體', Font.BOLD, 46); Font font2 = new Font('宋體', Font.BOLD, 40); Font font3 = new Font('宋體', Font.BOLD, 34); Font font4 = new Font('宋體', Font.BOLD, 28); Font font5 = new Font('宋體', Font.BOLD, 22); public Check() { value = 0; //value為方格中數字 } //字體顏色 public Color getForeground() { switch (value) { case 0: return new Color(0xcdc1b4);//0的顏色與背景色一致,相當于沒有數字 case 2: case 4: return Color.BLACK; default: return Color.WHITE; } } //字體背景顏色,即方格顏色 public Color getBackground() { switch (value) { case 0: return new Color(0xcdc1b4); case 2: return new Color(0xeee4da); case 4: return new Color(0xede0c8); case 8: return new Color(0xf2b179); case 16: return new Color(0xf59563); case 32: return new Color(0xf67c5f); case 64: return new Color(0xf65e3b); case 128: return new Color(0xedcf72); case 256: return new Color(0xedcc61); case 512: return new Color(0xedc850); case 1024: return new Color(0xedc53f); case 2048: return new Color(0xedc22e); case 4096: return new Color(0x65da92); case 8192: return new Color(0x5abc65); case 16384: return new Color(0x248c51); default: return new Color(0x248c51); } } public Font getCheckFont() { if (value < 10) { return font1; } if (value < 100) { return font2; } if (value < 1000) { return font3; } if (value < 10000) { return font4; } return font5; }}

GameView.java

import java.awt.*;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.ArrayList;import java.util.List;import java.util.Random;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;public class GameView{ private static final int jframeWidth = 405;//窗口寬高 private static final int jframeHeight = 530; private static int score = 0; Font topicFont = new Font('微軟雅黑', Font.BOLD, 50);//主題字體 Font scoreFont = new Font('微軟雅黑', Font.BOLD, 28);//得分字體 Font explainFont = new Font('宋體', Font.PLAIN,20);//提示字體 private JFrame jframeMain; private JLabel jlblTitle; private JLabel jlblScoreName; private JLabel jlblScore; private JLabel jlblTip; private GameBoard gameBoard; public GameView() { init(); } public void init() { //1、創建窗口 jframeMain = new JFrame('2048小游戲'); jframeMain.setSize(jframeWidth, jframeHeight); jframeMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jframeMain.setLocationRelativeTo(null);//窗口顯示位置居中 jframeMain.setResizable(false); jframeMain.setLayout(null);//設置絕對布局,以便后面可以用setBounds設置位置 jlblTitle = new JLabel('2048', JLabel.CENTER); jlblTitle.setFont(topicFont); jlblTitle.setForeground(Color.BLACK); jlblTitle.setBounds(50, 0, 150, 60); jframeMain.add(jlblTitle); //2、框架窗口搭建好,則需向里面開始添加內容 //設置字體及其顏色、位置 jlblScoreName = new JLabel('得 分', JLabel.CENTER); jlblScoreName.setFont(scoreFont); jlblScoreName.setForeground(Color.WHITE); jlblScoreName.setOpaque(true); jlblScoreName.setBackground(Color.GRAY); jlblScoreName.setBounds(250, 0, 120, 30); jframeMain.add(jlblScoreName); //3、得分區(得分名+分數) jlblScore = new JLabel('0', JLabel.CENTER); jlblScore.setFont(scoreFont); jlblScore.setForeground(Color.WHITE); jlblScore.setOpaque(true); jlblScore.setBackground(Color.GRAY); jlblScore.setBounds(250, 30, 120, 30); jframeMain.add(jlblScore); //4、提示說明區 jlblTip = new JLabel('操作: ↑ ↓ ← →, 按esc鍵重新開始 ', JLabel.CENTER); jlblTip.setFont(explainFont); jlblTip.setForeground(Color.DARK_GRAY); jlblTip.setBounds(0, 60, 400, 40); jframeMain.add(jlblTip); //5、主游戲面板區 gameBoard = new GameBoard(); gameBoard.setBounds(0, 100, 400, 400); gameBoard.setBackground(Color.GRAY); gameBoard.setFocusable(true);//焦點即當前正在操作的組件,也就是移動的數字 gameBoard.setLayout(new FlowLayout()); jframeMain.add(gameBoard); } // 游戲面板 class GameBoard extends JPanel implements KeyListener { private static final int CHECK_GAP = 10;//方格之間的間隙 private static final int CHECK_SIZE = 85;//方格大小 private static final int CHECK_ARC = 20;//方格弧度 private Check[][] checks = new Check[4][4]; private boolean isadd = true; public GameBoard() { initGame(); addKeyListener(this); } private void initGame() { score = 0; for (int indexRow = 0; indexRow < 4; indexRow++) { for (int indexCol = 0; indexCol < 4; indexCol++) { checks[indexRow][indexCol] = new Check(); } } // 最開始時生成兩個數 isadd = true; createCheck(); isadd = true; createCheck(); } @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_ESCAPE: initGame();//重新開始游戲(初始化游戲) break; case KeyEvent.VK_LEFT: moveLeft(); createCheck();//調用一次方法創建一個方格數字 judgeGameOver();//創建后判斷是否GameOver,若所有格子均滿即跳出GameOver break; case KeyEvent.VK_RIGHT: moveRight(); createCheck(); judgeGameOver(); break; case KeyEvent.VK_UP: moveUp(); createCheck(); judgeGameOver(); break; case KeyEvent.VK_DOWN: moveDown(); createCheck(); judgeGameOver(); break; default: break;//按其他鍵沒有反應 } repaint();//刷新,會自動調用paint()方法,重新繪制移動后的圖 } private void createCheck() { List<Check> list = getEmptyChecks(); if (!list.isEmpty() && isadd) { Random random = new Random(); int index = random.nextInt(list.size()); Check check = list.get(index); // 2, 4出現概率3:1 int randomValue = random.nextInt(4); check.value = ( randomValue % 3 == 0 || randomValue % 3 == 1) ? 2 : 4;//只有[0,4)中的2才能生成4 isadd = false; } } // 獲取空白方格 private List<Check> getEmptyChecks() { List<Check> checkList = new ArrayList<>(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (checks[i][j].value == 0) { checkList.add(checks[i][j]); } } } return checkList; } //是否全部格子占滿,全部占滿則GameOver private boolean judgeGameOver() { jlblScore.setText(score + ''); if (!getEmptyChecks().isEmpty()) { return false; } for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { //判斷是否存在可合并的方格 if (checks[i][j].value == checks[i][j + 1].value || checks[i][j].value == checks[i + 1][j].value) { return false; } } } return true; } private void moveLeft() { //找到一個非空格子后checks[i][j].value > 0,可分為三種情況處理 for (int i = 0; i < 4; i++) { for (int j = 1, index = 0; j < 4; j++) { if (checks[i][j].value > 0) { //第一種情況:checks[i][j](非第1列)與checks[i][index]的數相等,則合并乘以2,且得分增加 if (checks[i][j].value == checks[i][index].value) { score += checks[i][index].value *= 2; checks[i][j].value = 0; isadd = true; } else if (checks[i][index].value == 0) { //第二種:若checks[i][index]為空格子,checks[i][j]就直接移到最左邊checks[i][index] checks[i][index].value = checks[i][j].value; checks[i][j].value = 0; isadd = true; } else if (checks[i][++index].value == 0) { //第三種:若checks[i][index]不為空格子,并且數字也不相等,若其旁邊為空格子,則移到其旁邊 checks[i][index].value = checks[i][j].value; checks[i][j].value = 0; isadd = true; } } } } } private void moveRight() { for (int i = 0; i < 4; i++) { for (int j = 2, index = 3; j >= 0; j--) { if (checks[i][j].value > 0) { if (checks[i][j].value == checks[i][index].value) { score += checks[i][index].value *= 2; checks[i][j].value = 0; isadd = true; } else if (checks[i][index].value == 0) { checks[i][index].value = checks[i][j].value; checks[i][j].value = 0; isadd = true; } else if (checks[i][--index].value == 0) { checks[i][index].value = checks[i][j].value; checks[i][j].value = 0; isadd = true; } } } } } private void moveUp() { for (int i = 0; i < 4; i++) { for (int j = 1, index = 0; j < 4; j++) { if (checks[j][i].value > 0) { if (checks[j][i].value == checks[index][i].value) { score += checks[index][i].value *= 2; checks[j][i].value = 0; isadd = true; } else if (checks[index][i].value == 0) { checks[index][i].value = checks[j][i].value; checks[j][i].value = 0; isadd = true; } else if (checks[++index][i].value == 0){ checks[index][i].value = checks[j][i].value; checks[j][i].value = 0; isadd = true; } } } } } private void moveDown() { for (int i = 0; i < 4; i++) { for (int j = 2, index = 3; j >= 0; j--) { if (checks[j][i].value > 0) { if (checks[j][i].value == checks[index][i].value) { score += checks[index][i].value *= 2; checks[j][i].value = 0; isadd = true; } else if (checks[index][i].value == 0) { checks[index][i].value = checks[j][i].value; checks[j][i].value = 0; isadd = true; } else if (checks[--index][i].value == 0) { checks[index][i].value = checks[j][i].value; checks[j][i].value = 0; isadd = true; } } } } } @Override public void paint(Graphics g) { super.paint(g); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { drawCheck(g, i, j); } } // GameOver if (judgeGameOver()) { g.setColor(new Color(64, 64, 64, 100));//RGBA最后一個A可以視為透明度 g.fillRect(0, 0, getWidth(), getHeight());//填充矩形(游戲面板),將暗黑色填充上去 g.setColor(Color.WHITE); g.setFont(topicFont); FontMetrics fms = getFontMetrics(topicFont);//FontMetrics字體測量,該類是Paint的內部類,通過getFontMetrics()方法可獲取字體相關屬性 String value = 'Game Over!'; g.drawString(value, (getWidth()-fms.stringWidth(value)) / 2, getHeight() / 2);//字體居中顯示 } } // 繪制方格 // Graphics2D 類是Graphics 子類,擁有強大的二維圖形處理能力 private void drawCheck(Graphics g, int i, int j) { Graphics2D gg = (Graphics2D) g; //下面兩句是抗鋸齒模式,計算和優化消除文字鋸齒,字體更清晰順滑 gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); gg.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); //獲取方格 Check check = checks[i][j]; //不同數字設置背景色 gg.setColor(check.getBackground()); // 繪制圓角 gg.fillRoundRect(CHECK_GAP + (CHECK_GAP + CHECK_SIZE) * j, CHECK_GAP + (CHECK_GAP + CHECK_SIZE) * i, CHECK_SIZE, CHECK_SIZE, CHECK_ARC, CHECK_ARC); //繪制字體及其顏色 gg.setColor(check.getForeground()); gg.setFont(check.getCheckFont()); // 文字測量,并對文字進行繪制 FontMetrics fms = getFontMetrics(check.getCheckFont()); String value = String.valueOf(check.value); //使用此圖形上下文的當前顏色繪制由指定迭代器給定的文本。 //getAscent()是FontMetrics中的一個方法, //getDescent() 為降部 gg.drawString(value, CHECK_GAP + (CHECK_GAP + CHECK_SIZE) * j + (CHECK_SIZE - fms.stringWidth(value)) / 2, CHECK_GAP + (CHECK_GAP + CHECK_SIZE) * i + (CHECK_SIZE - fms.getAscent() - fms.getDescent()) / 2 + fms.getAscent());//讓數字居中顯示 } @Override public void keyReleased(KeyEvent e) { } @Override public void keyTyped(KeyEvent e) { } } public void showView() { jframeMain.setVisible(true); }}

Main.java

public class Main { public static void main(String[] args) { new GameView().showView(); }}三、重難點講解

3.1 數字移動問題

數字移動是一難點,分三種情況,以moveLeft()為例

(1)按左鍵,若最左邊是相同的,則合并

java實現2048小游戲

(2)若左邊是空格,則直接移動到最左即可

java實現2048小游戲

(3)若最左邊不為空格,且不相等,則看它右邊是否是空格,是則移動到其旁邊

java實現2048小游戲

3.2 繪圖問題—抗鋸齒

java提供的Graphics 2D,它是Graphics 子類

Graphics2D gg = (Graphics2D) g;gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);gg.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_NORMALIZE);

上面這兩個語句實現的功能是消除文字鋸齒,字體更清晰順滑,可以看下圖沒有setRenderingHint和有setRenderingHint的區別

java實現2048小游戲

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品麻豆久久| 亚洲91精品| 蜜桃视频第一区免费观看| 久久国产直播| 欧美亚洲激情| 少妇精品导航| 欧美日韩国产高清| 亚洲男女自偷自拍| 亚洲精品大全| 日本中文字幕一区二区视频| 综合激情在线| 青青伊人久久| 久久免费视频66| www在线观看黄色| 国产盗摄——sm在线视频| 精品三级久久| 欧美精品黄色| 中文一区一区三区免费在线观 | 久久精品国产网站| 日本久久精品| 欧美精品一区二区三区精品| 国产一区丝袜| 亚洲天堂成人| 亚洲三级国产| 毛片不卡一区二区| 成人一区而且| 亚洲欧美高清| 国产日韩欧美一区| 成人片免费看| 91精品国产福利在线观看麻豆| 国产精品普通话对白| 日韩中文字幕无砖| 久久精品国产99国产| 久久国产日韩| 日欧美一区二区| 国产一区二区三区黄网站| 日韩国产综合| 亚洲欧美日韩一区在线观看| 中文无码日韩欧| 麻豆91精品视频| 久久精品官网| 综合亚洲自拍| 97精品国产福利一区二区三区| 欧美二区视频| 欧美日韩在线精品一区二区三区激情综合 | 欧美一区自拍| 亚洲涩涩在线| 亚洲免费观看高清完整版在线观| 国产精品一区三区在线观看| 亚洲播播91| 日韩1区2区日韩1区2区| 日韩欧美国产精品综合嫩v| 性色av一区二区怡红| 国产精品v日韩精品v欧美精品网站| 久久久国产亚洲精品| 亚州av日韩av| 日韩三级精品| 九九精品调教| 18国产精品| 亚洲高清成人| 国产精品久久亚洲不卡| 黄页网站一区| a国产在线视频| 男女男精品网站| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 欧美日韩免费观看一区=区三区| 日韩欧美2区| 高清av一区| 丝袜美腿高跟呻吟高潮一区| 精品久久福利| 日韩av一区二区在线影视| 久久精品国产68国产精品亚洲| 国产精品一级| 一区二区三区四区精品视频| 久久久久久黄| 九九久久国产| 欧美日韩亚洲三区| 石原莉奈在线亚洲二区| 久久精品影视| 高清一区二区三区| 国产精品久久| 日韩精品国产精品| 亚洲韩日在线| 欧美日韩国产观看视频| 国产精成人品2018| 中文字幕一区二区三区在线视频| 日韩精品水蜜桃| 成人台湾亚洲精品一区二区| 97精品资源在线观看| 美女网站久久| 国产高清久久| 99久久久久| 蜜臀久久精品| 色一区二区三区四区| 欧美激情一区| 国产伦乱精品| 日韩av一级片| 一区二区亚洲视频| 香蕉成人久久| 久久先锋影音| 国产一区成人| 首页亚洲欧美制服丝腿| 欧美午夜不卡影院在线观看完整版免费| 日本不卡免费高清视频在线| 精品无人区麻豆乱码久久久 | 成人在线丰满少妇av| 精品久久国产一区| 久久不见久久见免费视频7| 欧美日一区二区在线观看| 日韩黄色免费网站| 亚洲综合激情在线| 蜜臀av性久久久久蜜臀aⅴ四虎| 亚洲一级二级| 欧美1区2区3区| 婷婷中文字幕一区| 九一精品国产| 午夜欧美精品| 免费一级片91| 亚洲精品国产精品粉嫩| 亚洲日本国产| 日韩国产在线一| 97成人在线| 国产精品丝袜在线播放| 国产精品成人一区二区网站软件| 国产精品一区二区av交换 | 四虎8848精品成人免费网站| 丰满少妇一区| 伊人久久av| 欧美中文字幕一区二区| 1024精品久久久久久久久| 欧美精品一二| 亚洲永久精品唐人导航网址| 日韩不卡手机在线v区| 国产探花一区二区| 日韩福利在线观看| 国产精品va| 日韩国产一区二区| 亚洲欧洲一区| 婷婷亚洲精品| 国产精品香蕉| 精品国产免费人成网站| 国产一在线精品一区在线观看| 黄色日韩精品| 亚洲日本欧美| 国产精品久久久久77777丨| 福利一区二区三区视频在线观看| 高清一区二区三区av| 天堂资源在线亚洲| 免费精品视频最新在线| 青青在线精品| 国产精品久久久久久久久妇女| 激情综合自拍| 91大神在线观看线路一区| 精品国产乱码久久久| 肉色欧美久久久久久久免费看| 午夜在线视频一区二区区别| 欧美精品中文字幕亚洲专区| 色一区二区三区| 亚洲欧美视频| 美女国产一区二区三区| 欧洲激情综合| 欧美欧美黄在线二区| 久久男人天堂| 在线精品一区二区| 国产成人调教视频在线观看| 欧美特黄一区| 牛牛精品成人免费视频| 性欧美xxxx免费岛国不卡电影| 日韩中文字幕| 国产传媒在线| 日韩精品一区二区三区中文在线 | 精品一区视频| 亚洲特级毛片| 国产探花一区二区| 久久男女视频| 日韩不卡免费视频| 国产精品久久久久蜜臀| 视频一区二区中文字幕| 免费视频一区二区三区在线观看 | 国产va在线视频| 综合激情视频| 亚洲69av| 丝袜av一区| 国产亚洲人成a在线v网站| 日韩毛片视频| 欧美日一区二区在线观看| 欧美成人高清| 美日韩一区二区三区| 欧美在线网站| 国产福利一区二区精品秒拍| 国产精品普通话对白| 国产成人免费| 日欧美一区二区| 蜜臀久久99精品久久一区二区| 国产精品密蕾丝视频下载| 久久一二三区| 欧美黄色网页| 国产精品久久久久久av公交车 | 成人亚洲一区二区| 日韩精品视频网站|