zoukankan      html  css  js  c++  java
  • java课程设计-赛博朋克2048小游戏

    Cyberpunk2048

    团队情况

    成员 任务分配 -
    刘炜 代码整合,框架整理,游戏玩法登陆系统等关键代码编写,项目打包 组长
    林毅 背景音乐背景图片插入,基础和主界面GUI 组员
    童浚 tile类编写,方格类绘制,计时器代码 组员

    参考项目

    https://www.cnblogs.com/my-program-life/p/10987657.html Java 实现2048游戏之详细教程
    https://blog.csdn.net/hunt_er/article/details/84320980?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control java程序添加背景音乐

    gitee地址

    https://gitee.com/mikehro/cyberpunk2048

    前期调查

    网页版2048https://www.2048.org/

    (利用方向键控制方格移动方向,相同数字合并)

    功能框架图

    面向对象设计

    包-类图

    UML

    项目运行截图

    1.开始界面

    新加入了背景图片

    2.登陆界面

    3.开始游戏

    4.游戏中

    5.游戏失败

    项目关键代码

    1.游戏窗口(GUI)和游戏开始界面绘制

      public void paintComponent(Graphics gg) {//绘制方格初始化(优先级高)
        super.paintComponent(gg);
        Graphics2D g = (Graphics2D) gg;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,//设置绘制参数,消除文字锯齿,消除画图锯齿
            RenderingHints.VALUE_ANTIALIAS_ON);
        drawGrid(g);//画出方格
      }
      void drawGrid(Graphics2D g) {//绘制方格所在区域
        g.setColor(gridColor);//提取颜色
        g.fillRoundRect(200, 100, 499, 499, 15, 15);//填充背景,即绘制圆角矩形块
        if (gamestate == State.running) {//如果游戏状态运行中,即“running”
          for (int r = 0; r < side; r++) {
            for (int c = 0; c < side; c++) {
              if (tiles[r][c] == null) {
                g.setColor(emptyColor);//空区域颜色
                g.fillRoundRect(215 + c * 121, 115 + r * 121, 106, 106, 7, 7);//绘制空区域
              } else {
                drawTile(g, r, c);//绘制方格数字块
              }
            }
          }
        } else {
        
          g.setColor(startColor);
          g.fillRoundRect(215, 115, 469, 469, 7, 7);
          g.setColor(gridColor);
          g.setFont(new Font("SansSerif", Font.BOLD, 128));//设置字体
          g.drawString("2048", 310, 270);//游戏标题
          g.setFont(new Font("SansSerif", Font.BOLD, 20));
          g.drawString("赛博朋克    ", 330, 170);
          g.drawString("网络1914 刘炜 林毅 童浚   ", 330, 300);
          g.setFont(new Font("SansSerif", Font.BOLD, 50));
          if (gamestate == State.won) {//如果游戏状态为“won”
            g.drawString("你成功了!", 390, 350);
          } else if (gamestate == State.over)//如果游戏状态为“Over”
            g.drawString("Game Over", 300, 350);
          g.setColor(gridColor);
          g.setFont(new Font("SansSerif", Font.BOLD, 20));
          g.drawString("       点击开始新游戏", 330, 470);
          g.drawString("(使用方向键来移动全部方块)", 310, 530);
          if (gamestate == State.change) {
        	  g.setColor(startColor);
              g.fillRoundRect(215, 115, 469, 469, 7, 7);
        	  g.setColor(gridColor);
              g.setFont(new Font("SansSerif", Font.BOLD, 50));//设置字体
              
              g.drawString("1->简单难度", 310, 300);
              g.drawString("2->普通难度", 310, 350);
              g.drawString("3->困难难度", 310, 400);
              g.drawString("4->赛博难度", 310, 450);
              
              addKeyListener(new KeyAdapter() {//监听键盘
          	      
          	      public void keyPressed(KeyEvent e) {//若键盘点击......
          	        switch (e.getKeyCode()) {//数字键选择
          	          case KeyEvent.VK_1:
          	            target=256;
          	            break;
          	          case KeyEvent.VK_2:
          	        	target=512;
          	            break;
          	          case KeyEvent.VK_3:
          	        	target=1024;
          	            break;
          	          case KeyEvent.VK_4:
            	        	target=2048;
            	            break;
          	        }
          	       
          	        repaint();
          	      }
          	    });
          }
         
        }
      }
    
      public static void main(String[] args) {//Main方法
    	  
        SwingUtilities.invokeLater(() -> {//设置GUI
          JFrame f = new JFrame();
          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//可关闭窗口
          f.setTitle("赛博朋克2048");//窗口标题
          f.setResizable(true);//面板可调节
          f.add(new Game2048(), BorderLayout.CENTER);//游戏置入窗口
          new Play0("Highway Superstar - Easy Ride.mp3").start();//播放背景音乐
          f.pack();
          f.setLocationRelativeTo(null);
          f.setVisible(true);//可见
        });
      }
    }            
    

    2.方块移动,合并

     private boolean move(int countDownFrom, int yIncr, int xIncr) {//方向键方格移动
        boolean moved = false;//未完成移动
        for (int i = 0; i < side * side; i++) {//遍历区域内所有方格
          int j = Math.abs(countDownFrom - i);
          int r = j / side;//计算方格坐标
          int c = j % side;
          if (tiles[r][c] == null)//若方格为空
            continue;
          int nextR = r + yIncr;//移动后坐标
          int nextC = c + xIncr;
          while (nextR >= 0 && nextR < side && nextC >= 0 && nextC < side) {//不超出区域
            Tile next = tiles[nextR][nextC];
            Tile curr = tiles[r][c];
            if (next == null) {//若下一方格为空
              if (checkingAvailableMoves)
                return true;//可移动
              tiles[nextR][nextC] = curr;//交换
              tiles[r][c] = null;//原方块置0
              r = nextR;
              c = nextC;
              nextR += yIncr;
              nextC += xIncr;
              moved = true;//成功移动
            } else if (next.canMergeWith(curr)) {//下一不为空,考虑合并
              if (checkingAvailableMoves)
                return true;
              int value = next.mergeWith(curr);
              if (value > highest)
                highest = value;//合并诞生新最高分
              score += value;//总得分计算
              tiles[r][c] = null;
              moved = true;//成功合并
              break;
            } else//不可移动
              break;
          }
        }
        if (moved) {//判断移动后得分状态执行下一步
          if (highest < target) {//若小于得分目标
            clearMerged();
            addRandomTile();//添加随机方格块
            if (!movesAvailable()) {//无法再移动
              gamestate = State.over;//游戏状态变为“Over”
            }
          } else if (highest == target)//最高分与目标分相同
            gamestate = State.won;//游戏状态变为“Won”
        }
        return moved;
      }
    
      //方向键移动
      boolean moveUp() {//上移
        return move(0, -1, 0);
      }
      boolean moveDown() {//下移
        return move(side * side - 1, 1, 0);
      }
      boolean moveLeft() {//左移
        return move(0, 0, -1);
      }
      boolean moveRight() {//右移
        return move(side * side - 1, 0, 1);
      }
      void clearMerged() {//清除面板
        for (Tile[] row : tiles)//foreach循环遍历所有方格获取坐标
          for (Tile tile : row)//根据坐标遍历所有方格
            if (tile != null)//若方块为空
              tile.setMerged(false);//设置false
      }
      boolean movesAvailable() {//方格移动状态
        checkingAvailableMoves = true;//可移动
        boolean hasMoves = moveUp() || moveDown() || moveLeft() || moveRight();
        checkingAvailableMoves = false;//不可移动
        return hasMoves;
      }
    
    

    3.方块类

    import java.awt.*;
    import java.awt.event.*;
    import java.util.Random;
    import javax.swing.*;
    
    public class Tile {//方格数字块类
      private boolean merged;//合并与否
      private int value;//方格数字
      Tile(int val) {//构造方法
        value = val;
      }
      int getValue() {
        return value;
      }
      void setMerged(boolean m) {
        merged = m;
      }
      boolean canMergeWith(Tile other) {//判断两个方格是否可合并
        return !merged && other != null && !other.merged && value == other.getValue();
      }
      int mergeWith(Tile other) {//合并方法
        if (canMergeWith(other)) {
          value *= 2;//数值翻倍
          merged = true;//合并成功
          return value;//返回数值
        }
        return -1;
      }
    }
    

    代码静态扫描

    项目总结(不足与展望)

    1.由于疫情在家和个人能力问题,整个项目最终的完成度并不高,附件功能如难度选择,用户登陆,分数排名都没实装。
    2.UI界面不过完善也不够美观,GUI相关功能还需要学习和完善。
    3.背景音乐仅仅只是插入,没有提供静音等修改选项。
    4.受限于2048游戏框架,玩法单一枯燥。希望之后能够有时间改进和增添关卡。
    5.登陆界面目前只是空壳,因为数据库这一块实在没弄懂......

  • 相关阅读:
    《Ubuntu标准教程》学习总结
    Ubuntu下安装VirtualBox并为其添加USB支持
    Eclipse下配置TinyOS开发环境
    Ubuntu下的网络服务
    Ubuntu12.04添加环境变量
    Ubuntu12.04下搭建Java环境
    poj 1066 线段相交
    poj 2653 (线段相交判断)
    poj 2398 (叉积+二分)
    hdu 4883 思维题
  • 原文地址:https://www.cnblogs.com/MIKEHRO/p/14336294.html
Copyright © 2011-2022 走看看