最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java實(shí)現(xiàn)2048小游戲(含注釋)

 更新時(shí)間:2021年09月10日 15:37:55   作者:Henrik-Yao  
這篇文章主要為大家介紹了java實(shí)現(xiàn)2048小游戲,含詳細(xì)注釋,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了java實(shí)現(xiàn)2048小游戲的具體代碼,供大家參考,具體內(nèi)容如下

實(shí)現(xiàn)文件

APP.java

import javax.swing.*;

public class APP {
 public static void main(String[] args) {
 new MyFrame();
 }
}

類文件

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

//定義自己的類(主類)去繼承JFrame類并實(shí)現(xiàn)KeyListener接口和ActionListener接口
public class MyFrame extends JFrame implements KeyListener, ActionListener {

 //用于存放游戲各位置上的數(shù)據(jù)
 int[][] data = new int[4][4];

 //用于判斷是否失敗
 int loseFlag = 1;

 //用于累計(jì)分?jǐn)?shù)
 int score = 0;

 //用于切換主題
 String theme = "A";

 //設(shè)置三個(gè)菜單項(xiàng)目
 JMenuItem item1 = new JMenuItem("經(jīng)典");
 JMenuItem item2 = new JMenuItem("霓虹");
 JMenuItem item3 = new JMenuItem("糖果");

 //核心方法
 public MyFrame(){
 //初始化窗口
 initFrame();
 //初始化菜單
 initMenu();
 //初始化數(shù)據(jù)
 initData();
 //繪制界面
 paintView();
 //為窗體提供鍵盤監(jiān)聽(tīng),該類本身就是實(shí)現(xiàn)對(duì)象
 this.addKeyListener(this);
 //設(shè)置窗體可見(jiàn)
 setVisible(true);
 }

 //窗體初始化
 public void initFrame(){
 //設(shè)置尺寸
 setSize(514,538);
 //設(shè)置居中
 setLocationRelativeTo(null);
 //設(shè)置總在最上面
 setAlwaysOnTop(true);
 //設(shè)置關(guān)閉方式
 setDefaultCloseOperation(3);
 //設(shè)置標(biāo)題
 setTitle("2048小游戲");
 //取消默認(rèn)布局
 setLayout(null);
 }

 //初始化菜單
 public void initMenu() {
 //菜單欄目
 JMenuBar menuBar = new JMenuBar();
 JMenu menu1 = new JMenu("換膚");
 JMenu menu2 = new JMenu("關(guān)于我們");

 //添加上menuBar
 menuBar.add(menu1);
 menuBar.add(menu2);

 //添加上menu
 menu1.add(item1);
 menu1.add(item2);
 menu1.add(item3);

 //注冊(cè)監(jiān)聽(tīng)
 item1.addActionListener(this);
 item2.addActionListener(this);
 item3.addActionListener(this);

 //添加進(jìn)窗體
 super.setJMenuBar(menuBar);
 }

 //初始化數(shù)據(jù),在隨機(jī)位置生成兩個(gè)2
 public void initData(){
 generatorNum();
 generatorNum();
 }

 //重新繪制界面的方法
 public void paintView(){
 //調(diào)用父類中的方法清空界面
 getContentPane().removeAll();

 //判斷是否失敗
 if(loseFlag==2){
 //繪制失敗界面
 JLabel loseLable = new JLabel(new ImageIcon("D:\\Download\\BaiDu\\image\\"+theme+"-lose.png"));
 //設(shè)置位置和高寬
 loseLable.setBounds(90,100,334,228);
 //將該元素添加到窗體中
 getContentPane().add(loseLable);
 }

 //根據(jù)現(xiàn)有數(shù)據(jù)繪制界面
 for(int i=0;i<4;i++) {
 //根據(jù)位置循環(huán)繪制
 for (int j = 0; j < 4; j++) {
 JLabel image = new JLabel(new ImageIcon("D:\\Download\\BaiDu\\image\\"+theme+"-"+data[i][j]+".png"));
 //提前計(jì)算好位置
 image.setBounds(50 + 100 * j, 50+100*i, 100, 100);
 //將該元素添加進(jìn)窗體
 getContentPane().add(image);
 }
 }

 //繪制背景圖片
 JLabel background = new JLabel(new ImageIcon("D:\\Download\\BaiDu\\image\\"+theme+"-Background.jpg"));
 //設(shè)置位置和高寬
 background.setBounds(40,40,420,420);
 //將該元素添加進(jìn)窗體
 getContentPane().add(background);

 //得分模板設(shè)置
 JLabel scoreLable = new JLabel("得分:"+score);
 //設(shè)置位置和高寬
 scoreLable.setBounds(50,20,100,20);
 //將該元素添加進(jìn)窗體
 getContentPane().add(scoreLable);

 //重新繪制界面
 getContentPane().repaint();
 }

 //用不到的但是必須重寫的方法,無(wú)需關(guān)注
 @Override
 public void keyTyped(KeyEvent e) {}

 //鍵盤被按下所觸發(fā)的方法,在此方法中加入?yún)^(qū)分上下左右的按鍵
 @Override
 public void keyPressed(KeyEvent e) {
 //keyCode接收按鍵信息
 int keyCode = e.getKeyCode();
 //左移動(dòng)
 if(keyCode == 37){
 moveToLeft(1);
 generatorNum();
 }
 //上移動(dòng)
 else if(keyCode==38){
 moveToTop(1);
 generatorNum();
 }
 //右移動(dòng)
 else if(keyCode==39){
 moveToRight(1);
 generatorNum();
 }
 //下移動(dòng)
 else if(keyCode==40){
 moveToBottom(1);
 generatorNum();
 }
 //忽視其他按鍵
 else {
 return;
 }
 //檢查是否能夠繼續(xù)移動(dòng)
 check();
 //重新根據(jù)數(shù)據(jù)繪制界面
 paintView();
 }

 //左移動(dòng)的方法,通過(guò)flag判斷,傳入1是正常移動(dòng),傳入2是測(cè)試移動(dòng)
 public void moveToLeft(int flag) {
 for(int i=0;i<data.length;i++){
 //定義一維數(shù)組接收一行的數(shù)據(jù)
 int[] newArr = new int[4];
 //定義下標(biāo)方便操作
 int index=0;
 for(int x=0;x<data[i].length;x++){
 //將有數(shù)據(jù)的位置前移
 if(data[i][x]!=0){
  newArr[index]=data[i][x];
  index++;
 }
 }
 //賦值到原數(shù)組
 data[i]=newArr;
 //判斷相鄰數(shù)據(jù)是否相鄰,相同則相加,不相同則略過(guò)
 for(int x=0;x<3;x++){
 if(data[i][x]==data[i][x+1]){
  data[i][x]*=2;
  //如果是正常移動(dòng)則加分
  if(flag==1){
  score+=data[i][x];
  }
  //將合并后的數(shù)據(jù)都前移,實(shí)現(xiàn)數(shù)據(jù)覆蓋
  for(int j=x+1;j<3;j++){
  data[i][j]=data[i][j+1];
  }
  //末尾補(bǔ)0
  data[i][3]=0;
 }
 }
 }
 }

 //右移動(dòng)的方法,通過(guò)flag判斷,傳入1是正常移動(dòng),傳入2是測(cè)試移動(dòng)
 public void moveToRight(int flag) {
 //翻轉(zhuǎn)二維數(shù)組
 reverse2Array();
 //對(duì)旋轉(zhuǎn)后的數(shù)據(jù)左移動(dòng)
 moveToLeft(flag);
 //再次翻轉(zhuǎn)
 reverse2Array();
 }

 //上移動(dòng)的方法,通過(guò)flag判斷,傳入1是正常移動(dòng),傳入2是測(cè)試移動(dòng)
 public void moveToTop(int flag) {
 //逆時(shí)針旋轉(zhuǎn)數(shù)據(jù)
 anticlockwise();
 //對(duì)旋轉(zhuǎn)后的數(shù)據(jù)左移動(dòng)
 moveToLeft(flag);
 //順時(shí)針還原數(shù)據(jù)
 clockwise();
 }

 //下移動(dòng)的方法,通過(guò)flag判斷,傳入1是正常移動(dòng),傳入2是測(cè)試移動(dòng)
 public void moveToBottom(int flag) {
 //順時(shí)針旋轉(zhuǎn)數(shù)據(jù)
 clockwise();
 //對(duì)旋轉(zhuǎn)后的數(shù)據(jù)左移動(dòng)
 moveToLeft(flag);
 //逆時(shí)針旋轉(zhuǎn)還原數(shù)據(jù)
 anticlockwise();
 }

 //檢查能否左移動(dòng)
 public boolean checkLeft(){
 //開(kāi)辟新二維數(shù)組用于暫存數(shù)據(jù)和比較數(shù)據(jù)
 int[][] newArr = new int[4][4];
 //復(fù)制數(shù)組
 copyArr(data,newArr);
 //測(cè)試移動(dòng)
 moveToLeft(2);
 boolean flag = false;
 //設(shè)置break跳出的for循環(huán)標(biāo)記
 lo:
 for (int i = 0; i < data.length; i++) {
 for (int j = 0; j < data[i].length; j++) {
 //如果有數(shù)據(jù)不相同,則證明能夠左移動(dòng),則返回true
 if(data[i][j]!=newArr[i][j]){
  flag=true;
  break lo;
 }
 }
 }
 //將原本的數(shù)據(jù)還原
 copyArr(newArr,data);
 return flag;
 }

 //檢查能否右移動(dòng),與checkLeft()方法原理相似
 public boolean checkRight(){
 int[][] newArr = new int[4][4];
 copyArr(data,newArr);
 moveToRight(2);
 boolean flag = false;
 lo:
 for (int i = 0; i < data.length; i++) {
 for (int j = 0; j < data[i].length; j++) {
 if(data[i][j]!=newArr[i][j]){
  flag=true;
  break lo;
 }
 }
 }
 copyArr(newArr,data);
 return flag;
 }

 //檢查能否上移動(dòng),與checkLeft()方法原理相似
 public boolean checkTop(){
 int[][] newArr = new int[4][4];
 copyArr(data,newArr);
 moveToTop(2);
 boolean flag = false;
 lo:
 for (int i = 0; i < data.length; i++) {
 for (int j = 0; j < data[i].length; j++) {
 if(data[i][j]!=newArr[i][j]){
  flag=true;
  break lo;
 }
 }
 }
 copyArr(newArr,data);
 return flag;
 }

 //檢查能否下移動(dòng),與checkLeft()方法原理相似
 public boolean checkBottom(){
 int[][] newArr = new int[4][4];
 copyArr(data,newArr);
 moveToBottom(2);
 boolean flag = false;
 lo:
 for (int i = 0; i < data.length; i++) {
 for (int j = 0; j < data[i].length; j++) {
 if(data[i][j]!=newArr[i][j]){
  flag=true;
  break lo;
 }
 }
 }
 copyArr(newArr,data);
 return flag;
 }

 //檢查是否失敗
 public void check(){
 //上下左右均不能移動(dòng) ,則游戲失敗
 if(checkLeft()==false&&checkRight()==false&&checkTop()==false&&checkBottom()==false){
 loseFlag = 2;
 }
 }

 //復(fù)制二維數(shù)組的方法,傳入原數(shù)組和新數(shù)組
 public void copyArr(int[][] src,int[][] dest){
 for (int i = 0; i < src.length; i++) {
 for (int j = 0; j < src[i].length; j++) {
 //遍歷復(fù)制
 dest[i][j]=src[i][j];
 }
 }
 }

 //鍵盤被松開(kāi)
 @Override
 public void keyReleased(KeyEvent e) {}

 //翻轉(zhuǎn)一維數(shù)組
 public void reverseArray(int[] arr){
 for(int start=0,end=arr.length-1;start<end;start++,end--){
 int temp = arr[start];
 arr[start] = arr[end];
 arr[end] = temp;
 }
 }

 //翻轉(zhuǎn)二維數(shù)組
 public void reverse2Array(){
 for (int i = 0; i < data.length; i++) {
 reverseArray(data[i]);
 }
 }

 //順時(shí)針旋轉(zhuǎn)
 public void clockwise(){
 int[][] newArr = new int[4][4];
 for(int i=0;i<4;i++){
 for(int j=0;j<4;j++){
 //找規(guī)律啦~
 newArr[j][3-i] = data[i][j];
 }
 }
 data = newArr;
 }

 //逆時(shí)針旋轉(zhuǎn)
 public void anticlockwise(){
 int[][] newArr = new int[4][4];
 for(int i=0;i<4;i++){
 for(int j=0;j<4;j++){
 //規(guī)律
 newArr[3-j][i] = data[i][j];
 }
 }
 data = newArr;
 }

 //空位置隨機(jī)生成2
 public void generatorNum(){
 int[] arrarI = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
 int[] arrarJ = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
 int w=0;
 for (int i = 0; i < data.length; i++) {
 for (int j = 0; j < data[i].length; j++) {
 if(data[i][j]==0){
  //找到并存放空位置
  arrarI[w]=i;
  arrarJ[w]=j;
  w++;
 }
 }
 }
 if(w!=0){
 //隨機(jī)數(shù)找到隨機(jī)位置
 Random r= new Random();
 int index = r.nextInt(w);
 int x = arrarI[index];
 int y = arrarJ[index];
 //空位置隨機(jī)生成2
 data[x][y]=2;
 }
 }

 //換膚操作
 @Override
 public void actionPerformed(ActionEvent e) {
 //接收動(dòng)作監(jiān)聽(tīng),
 if(e.getSource()==item1){
 theme = "A";
 }else if(e.getSource()==item2){
 theme = "B";
 }else if(e.getSource()==item3){
 theme = "C";
 }
 //換膚后重新繪制
 paintView();
 }
}


 //測(cè)試失敗效果的數(shù)據(jù)
 /*int[][] data = {
 {2,4,8,4},
 {16,32,64,8},
 {128,2,256,2},
 {512,8,1024,2048}
 };*/

運(yùn)行效果

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 淺談java是如何做資源回收補(bǔ)救的

    淺談java是如何做資源回收補(bǔ)救的

    這篇文章主要介紹了淺談java是如何做資源回收補(bǔ)救的,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • SpringBatch從入門到精通之StepScope作用域和用法詳解

    SpringBatch從入門到精通之StepScope作用域和用法詳解

    這篇文章主要介紹了SpringBatch從入門到精通之StepScope作用域和用法詳解,主要包括IOC容器中幾種bean的作用范圍以及可能遇到的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • SpringMVC框架post提交數(shù)據(jù)庫(kù)出現(xiàn)亂碼解決方案

    SpringMVC框架post提交數(shù)據(jù)庫(kù)出現(xiàn)亂碼解決方案

    這篇文章主要介紹了SpringMVC框架post提交數(shù)據(jù)庫(kù)出現(xiàn)亂碼解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java實(shí)現(xiàn)花卉管理系統(tǒng)

    Java實(shí)現(xiàn)花卉管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)花卉管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Spring Security SecurityContextHolder組件示例說(shuō)明

    Spring Security SecurityContextHolder組件示例說(shuō)明

    SpringSecurity的SecurityContextHolder組件是存儲(chǔ)當(dāng)前安全上下文的地方,包括認(rèn)證用戶信息,它支持全局訪問(wèn)、線程局部存儲(chǔ)和上下文傳播,是SpringSecurity認(rèn)證和授權(quán)的核心,文章通過(guò)示例展示了如何訪問(wèn)已認(rèn)證用戶的詳細(xì)信息、手動(dòng)設(shè)置認(rèn)證信息以及使用認(rèn)證信息保護(hù)方法
    2024-11-11
  • Java字符串相關(guān)類使用方法詳解

    Java字符串相關(guān)類使用方法詳解

    String、StringBuilder、StringBuffer還傻傻分不清,下面這篇文章主要給大家介紹了關(guān)于Java字符串相關(guān)類使用的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • java中static關(guān)鍵字用法詳解

    java中static關(guān)鍵字用法詳解

    這篇文章主要為大家詳細(xì)介紹了java中static關(guān)鍵字的用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • SpringBoot?集成短信和郵件的配置示例詳解

    SpringBoot?集成短信和郵件的配置示例詳解

    這篇文章主要介紹了SpringBoot?集成短信和郵件的相關(guān)知識(shí),項(xiàng)目中使用lombok插件和swagger依賴,無(wú)相關(guān)依賴的請(qǐng)自行修改,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • java開(kāi)發(fā)web前端cookie session及token會(huì)話機(jī)制詳解

    java開(kāi)發(fā)web前端cookie session及token會(huì)話機(jī)制詳解

    如果把人體比作一個(gè)web系統(tǒng)的話,cookie、session和token就好像人體的經(jīng)絡(luò)和血管一樣,而web系統(tǒng)中的數(shù)據(jù),就好像人體的血液一樣。血液依靠著血管在人體內(nèi)流動(dòng),就如數(shù)據(jù)根據(jù)cookie和session機(jī)制在web系統(tǒng)中流動(dòng)一樣
    2021-10-10
  • SpringBoot配置mybatis駝峰命名規(guī)則自動(dòng)轉(zhuǎn)換的實(shí)現(xiàn)

    SpringBoot配置mybatis駝峰命名規(guī)則自動(dòng)轉(zhuǎn)換的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot配置mybatis駝峰命名規(guī)則自動(dòng)轉(zhuǎn)換的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09

最新評(píng)論

新密市| 泸定县| 偏关县| 宜川县| 伊宁市| 和田县| 河东区| 颍上县| 昌图县| 江安县| 宝丰县| 邯郸县| 洛南县| 杭锦旗| 鄂托克前旗| 彭阳县| 天镇县| 鹿泉市| 始兴县| 崇文区| 贵州省| 白沙| 商丘市| 万宁市| 高雄市| 库尔勒市| 通河县| 临西县| 双城市| 洛南县| 内黄县| 灵宝市| 民丰县| 句容市| 楚雄市| 磴口县| 雷波县| 黑河市| 安宁市| 怀安县| 民县|