Java实现俄罗斯方块小游戏。(附完整源代码)

article/2025/11/2 11:11:20

大家好,我是百思不得小赵。

创作时间:2022 年 5 月 12 日
博客主页: 🔍点此进入博客主页
—— 新时代的农民工 🙊
—— 换一种思维逻辑去看待这个世界 👀
今天是加入CSDN的第1167天。觉得有帮助麻烦👏点赞、🍀评论、❤️收藏


目录

一、游戏背景

二、功能实现

三、效果展示


一、游戏背景

俄罗斯方块是俄罗斯人发明的。这人叫阿列克谢·帕基特诺夫(Алексей Пажитнов 英文:Alexey Pazhitnov)。俄罗斯方块原名是俄语Тетрис(英语是Tetris),这个名字来源于希腊语tetra,意思是“四”,而游戏的作者最喜欢网球(tennis)。于是,他把两个词tetra和tennis合而为一,命名为Tetris,这也就是俄罗斯方块名字的由来。

规则说明:

由小方块组成的不同形状的板块陆续从屏幕上方落下来,玩家通过调整板块的位置和方向,使它们在屏幕底部拼出完整的一条或几条。这些完整的横条会随即消失,给新落下来的板块腾出空间,与此同时,玩家得到分数奖励。没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,玩家便告输,游戏结束。

二、功能实现

开发工具:idea、jdk8

技术汇总:Java基础知识、数组、面向对象、多线程、IO流、Swing。

整体代码分为三个模块:方格模块,七种图形模块,俄罗斯方块主模块。

小方块类:Cell

public class Cell {// 行private int row;// 列private int col;private BufferedImage image;public Cell() {}public Cell(int row, int col, BufferedImage image) {this.row = row;this.col = col;this.image = image;}public int getRow() {return row;}public void setRow(int row) {this.row = row;}public int getCol() {return col;}public void setCol(int col) {this.col = col;}public BufferedImage getImage() {return image;}public void setImage(BufferedImage image) {this.image = image;}@Overridepublic String toString() {return "Cell{" +"row=" + row +", col=" + col +", image=" + image +'}';}@Overridepublic boolean equals(Object o) {if (this == o) {return true;}if (!(o instanceof Cell)) {return false;}Cell cell = (Cell) o;return getRow() == cell.getRow() &&getCol() == cell.getCol() &&Objects.equals(getImage(), cell.getImage());}@Overridepublic int hashCode() {return Objects.hash(getRow(), getCol(), getImage());}//左移动一格public void left(){col--;}//右移动一格public void right(){col++;}//下移动一格public void down(){row++;}
}

 四方格图形的父类:Tetromino

public class Tetromino {public Cell[] cells = new Cell[4];//旋转的状态protected State[] states;//声明旋转次数protected int count = 10000;//左移方法public void moveLeft() {for (Cell cell : cells) {cell.left();}}//右移方法public void moveRight() {for (Cell cell : cells) {cell.right();}}//单元格下落public void moveDrop() {for (Cell cell : cells) {cell.down();}}//编写随机生成四方格public static Tetromino randomOne() {int num = (int) (Math.random() * 7);Tetromino tetromino = null;switch (num) {case 0:tetromino = new I();break;case 1:tetromino = new J();break;case 2:tetromino = new L();break;case 3:tetromino = new O();break;case 4:tetromino = new S();break;case 5:tetromino = new T();break;case 6:tetromino = new Z();break;}return tetromino;}//顺时针旋转的方法public void rotateRight() {if (states.length == 0) {return;}//旋转次数+1count++;State s = states[count % states.length];Cell cell = cells[0];int row = cell.getRow();int col = cell.getCol();cells[1].setRow(row + s.row1);cells[1].setCol(col + s.col1);cells[2].setRow(row + s.row2);cells[2].setCol(col + s.col2);cells[3].setRow(row + s.row3);cells[3].setCol(col + s.col3);}//逆时针旋转的方法public void rotateLeft() {if (states.length == 0) {return;}//旋转次数+1count--;State s = states[count % states.length];Cell cell = cells[0];int row = cell.getRow();int col = cell.getCol();cells[1].setRow(row + s.row1);cells[1].setCol(col + s.col1);cells[2].setRow(row + s.row2);cells[2].setCol(col + s.col2);cells[3].setRow(row + s.row3);cells[3].setCol(col + s.col3);}//四方格旋转状态的内部类protected class State {//存储四方格各元素的位置int row0, col0, row1, col1, row2, col2, row3, col3;public State() {}public State(int row0, int col0, int row1, int col1, int row2, int col2, int row3, int col3) {this.row0 = row0;this.col0 = col0;this.row1 = row1;this.col1 = col1;this.row2 = row2;this.col2 = col2;this.row3 = row3;this.col3 = col3;}public int getRow0() {return row0;}public void setRow0(int row0) {this.row0 = row0;}public int getCol0() {return col0;}public void setCol0(int col0) {this.col0 = col0;}public int getRow1() {return row1;}public void setRow1(int row1) {this.row1 = row1;}public int getCol1() {return col1;}public void setCol1(int col1) {this.col1 = col1;}public int getRow2() {return row2;}public void setRow2(int row2) {this.row2 = row2;}public int getCol2() {return col2;}public void setCol2(int col2) {this.col2 = col2;}public int getRow3() {return row3;}public void setRow3(int row3) {this.row3 = row3;}public int getCol3() {return col3;}public void setCol3(int col3) {this.col3 = col3;}@Overridepublic String toString() {return "State{" +"row0=" + row0 +", col0=" + col0 +", row1=" + row1 +", col1=" + col1 +", row2=" + row2 +", col2=" + col2 +", row3=" + row3 +", col3=" + col3 +'}';}}
}

七种图形类:I、J、L、O、S、T、Z

public class I extends Tetromino {public I() {cells[0] = new Cell(0,4, Tetris.I);cells[1] = new Cell(0,3, Tetris.I);cells[2] = new Cell(0,5, Tetris.I);cells[3] = new Cell(0,6, Tetris.I);//共有两种旋转状态states =new State[2];//初始化两种状态的相对坐标states[0]=new State(0,0,0,-1,0,1,0,2);states[1]=new State(0,0,-1,0,1,0,2,0);}}
public class J extends Tetromino {public J() {cells[0] = new Cell(0,4, Tetris.J);cells[1] = new Cell(0,3, Tetris.J);cells[2] = new Cell(0,5, Tetris.J);cells[3] = new Cell(1,5, Tetris.J);states=new State[4];states[0]=new State(0,0,0,-1,0,1,1,1);states[1]=new State(0,0,-1,0,1,0,1,-1);states[2]=new State(0,0,0,1,0,-1,-1,-1);states[3]=new State(0,0,1,0,-1,0,-1,1);}
}
public class L extends Tetromino {public L() {cells[0] = new Cell(0,4, Tetris.L);cells[1] = new Cell(0,3, Tetris.L);cells[2] = new Cell(0,5, Tetris.L);cells[3] = new Cell(1,3, Tetris.L);states=new State[4];states[0]=new State(0,0,0,-1,0,1,1,-1);states[1]=new State(0,0,-1,0,1,0,-1,-1);states[2]=new State(0,0,0,1,0,-1,-1,1);states[3]=new State(0,0,1,0,-1,0,1,1);}
}
public class O extends Tetromino {public O() {cells[0] = new Cell(0, 4, Tetris.O);cells[1] = new Cell(0, 5, Tetris.O);cells[2] = new Cell(1, 4, Tetris.O);cells[3] = new Cell(1, 5, Tetris.O);//无旋转状态states = new State[0];}
}
public class S extends Tetromino {public S() {cells[0] = new Cell(0,4, Tetris.S);cells[1] = new Cell(0,5, Tetris.S);cells[2] = new Cell(1,3, Tetris.S);cells[3] = new Cell(1,4, Tetris.S);//共有两种旋转状态states =new State[2];//初始化两种状态的相对坐标states[0]=new State(0,0,0,1,1,-1,1,0);states[1]=new State(0,0,1,0,-1,-1,0,-1);}
}
public class T extends Tetromino {public T() {cells[0] = new Cell(0,4, Tetris.T);cells[1] = new Cell(0,3, Tetris.T);cells[2] = new Cell(0,5, Tetris.T);cells[3] = new Cell(1,4, Tetris.T);states=new State[4];states[0]=new State(0,0,0,-1,0,1,1,0);states[1]=new State(0,0,-1,0,1,0,0,-1);states[2]=new State(0,0,0,1,0,-1,-1,0);states[3]=new State(0,0,1,0,-1,0,0,1);}
}
public class Z extends Tetromino {public Z() {cells[0] = new Cell(1,4, Tetris.Z);cells[1] = new Cell(0,3, Tetris.Z);cells[2] = new Cell(0,4, Tetris.Z);cells[3] = new Cell(1,5, Tetris.Z);//共有两种旋转状态states =new State[2];//初始化两种状态的相对坐标states[0]=new State(0,0,-1,-1,-1,0,0,1);states[1]=new State(0,0,-1,1,0,1,1,0);}
}

俄罗斯方块游戏主类:Tetris

public class Tetris extends JPanel {//正在下落的方块private Tetromino currentOne = Tetromino.randomOne();//将要下落的方块private Tetromino nextOne = Tetromino.randomOne();//游戏主区域private Cell[][] wall = new Cell[18][9];//声明单元格的值private static final int CELL_SIZE = 48;//游戏分数池int[] scores_pool = {0, 1, 2, 5, 10};//当前游戏的分数private int totalScore = 0;//当前消除的行数private int totalLine = 0;//游戏三种状态 游戏中、暂停、结束public static final int PLING = 0;public static final int STOP = 1;public static final int OVER = 2;//当前游戏状态值private int game_state;//显示游戏状态String[] show_state = {"P[pause]", "C[continue]", "S[replay]"};//载入方块图片public static BufferedImage I;public static BufferedImage J;public static BufferedImage L;public static BufferedImage O;public static BufferedImage S;public static BufferedImage T;public static BufferedImage Z;public static BufferedImage background;static {try {I = ImageIO.read(new File("images/I.png"));J = ImageIO.read(new File("images/J.png"));L = ImageIO.read(new File("images/L.png"));O = ImageIO.read(new File("images/O.png"));S = ImageIO.read(new File("images/S.png"));T = ImageIO.read(new File("images/T.png"));Z = ImageIO.read(new File("images/Z.png"));background = ImageIO.read(new File("images/background.png"));} catch (IOException e) {e.printStackTrace();}}@Overridepublic void paint(Graphics g) {g.drawImage(background, 0, 0, null);//平移坐标轴g.translate(22, 15);//绘制游戏主区域paintWall(g);//绘制正在下落的四方格paintCurrentOne(g);//绘制下一个将要下落的四方格paintNextOne(g);//绘制游戏得分paintSource(g);//绘制当前游戏状态paintState(g);}public void start() {game_state = PLING;KeyListener l = new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {int code = e.getKeyCode();switch (code) {case KeyEvent.VK_DOWN:sortDropActive();break;case KeyEvent.VK_LEFT:moveleftActive();break;case KeyEvent.VK_RIGHT:moveRightActive();break;case KeyEvent.VK_UP:rotateRightActive();break;case KeyEvent.VK_SPACE:hadnDropActive();break;case KeyEvent.VK_P://判断当前游戏状态if (game_state == PLING) {game_state = STOP;}break;case KeyEvent.VK_C:if (game_state == STOP) {game_state = PLING;}break;case KeyEvent.VK_S://重新开始game_state = PLING;wall = new Cell[18][9];currentOne = Tetromino.randomOne();nextOne = Tetromino.randomOne();totalScore = 0;totalLine = 0;break;}}};//将窗口设置为焦点this.addKeyListener(l);this.requestFocus();while (true) {if (game_state == PLING) {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}if (camDrop()) {currentOne.moveDrop();} else {landToWall();destroyLine();if (isGameOver()) {game_state = OVER;} else {//游戏没有结束currentOne = nextOne;nextOne = Tetromino.randomOne();}}}repaint();}}//创建顺时针旋转public void rotateRightActive() {currentOne.rotateRight();if (outOFBounds() || coincide()) {currentOne.rotateLeft();}}//瞬间下落public void hadnDropActive() {while (true) {//判断能否下落if (camDrop()) {currentOne.moveDrop();} else {break;}}//嵌入到墙中landToWall();destroyLine();if (isGameOver()) {game_state = OVER;} else {//游戏没有结束currentOne = nextOne;nextOne = Tetromino.randomOne();}}//按键一次,下落一格public void sortDropActive() {if (camDrop()) {//当前四方格下落一格currentOne.moveDrop();} else {landToWall();destroyLine();if (isGameOver()) {game_state = OVER;} else {//游戏没有结束currentOne = nextOne;nextOne = Tetromino.randomOne();}}}//单元格嵌入墙中private void landToWall() {Cell[] cells = currentOne.cells;for (Cell cell : cells) {int row = cell.getRow();int col = cell.getCol();wall[row][col] = cell;}}//判断四方格能否下落public boolean camDrop() {Cell[] cells = currentOne.cells;for (Cell cell : cells) {int row = cell.getRow();int col = cell.getCol();//判断是否到达底部if (row == wall.length - 1) {return false;} else if (wall[row + 1][col] != null) {return false;}}return true;}//消除行public void destroyLine() {int line = 0;Cell[] cells = currentOne.cells;for (Cell cell : cells) {int row = cell.getRow();if (isFullLine(row)) {line++;for (int i = row; i > 0; i--) {System.arraycopy(wall[i - 1], 0, wall[i], 0, wall[0].length);}wall[0] = new Cell[9];}}//分数池获取分数,累加到总分totalScore += scores_pool[line];//总行数totalLine += line;}//判断当前行是否已经满了public boolean isFullLine(int row) {Cell[] cells = wall[row];for (Cell cell : cells) {if (cell == null) {return false;}}return true;}//判断游戏是否结束public boolean isGameOver() {Cell[] cells = nextOne.cells;for (Cell cell : cells) {int row = cell.getRow();int col = cell.getCol();if (wall[row][col] != null) {return true;}}return false;}private void paintState(Graphics g) {if (game_state == PLING) {g.drawString(show_state[PLING], 500, 660);} else if (game_state == STOP) {g.drawString(show_state[STOP], 500, 660);} else {g.drawString(show_state[OVER], 500, 660);g.setColor(Color.RED);g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 60));g.drawString("GAME OVER!", 30, 400);}}private void paintSource(Graphics g) {g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 30));g.drawString("分数: " + totalScore, 500, 250);g.drawString("行数: " + totalLine, 500, 430);}private void paintNextOne(Graphics g) {Cell[] cells = nextOne.cells;for (Cell cell : cells) {int x = cell.getCol() * CELL_SIZE + 370;int y = cell.getRow() * CELL_SIZE + 25;g.drawImage(cell.getImage(), x, y, null);}}private void paintCurrentOne(Graphics g) {Cell[] cells = currentOne.cells;for (Cell cell : cells) {int x = cell.getCol() * CELL_SIZE;int y = cell.getRow() * CELL_SIZE;g.drawImage(cell.getImage(), x, y, null);}}private void paintWall(Graphics g) {for (int i = 0; i < wall.length; i++) {for (int j = 0; j < wall[i].length; j++) {int x = j * CELL_SIZE;int y = i * CELL_SIZE;Cell cell = wall[i][j];//判断是否有小方块if (cell == null) {g.drawRect(x, y, CELL_SIZE, CELL_SIZE);} else {g.drawImage(cell.getImage(), x, y, null);}}}}//判断是否出界public boolean outOFBounds() {Cell[] cells = currentOne.cells;for (Cell cell : cells) {int col = cell.getCol();int row = cell.getRow();if (row < 0 || row > wall.length - 1 || col < 0 || col > wall[0].length-1) {return true;}}return false;}//按键一次,左移一次public void moveleftActive() {currentOne.moveLeft();//判断是否越界或重合if (outOFBounds() || coincide()) {currentOne.moveRight();}}//按键一次,右移一次public void moveRightActive() {currentOne.moveRight();//判断是否越界或重合if (outOFBounds() || coincide()) {currentOne.moveLeft();}}//判断是否重合public boolean coincide() {Cell[] cells = currentOne.cells;for (Cell cell : cells) {int row = cell.getRow();int col = cell.getCol();if (wall[row][col] != null) {return true;}}return false;}public static void main(String[] args) {JFrame jFrame = new JFrame("俄罗斯方块");//创建游戏界面Tetris panel = new Tetris();jFrame.add(panel);//设置可见jFrame.setVisible(true);//设置窗口大小jFrame.setSize(810, 940);//设置剧中jFrame.setLocationRelativeTo(null);//设置窗口关闭时停止jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//游戏主要开始逻辑panel.start();}
}

三、效果展示

游戏开始,方快下落,右边区域展示即将下落的方块图、分数、消除的行数以及游戏切换的状态。

按下空格键,方块瞬间下落, 按下P键游戏暂停,消除一行分数为1(此处由分数池进行控制)

 按下C键游戏继续。

 按下S键,游戏重新开始。

 方块占满,游戏结束,此时可以按下S键重新开始游戏。

本次游戏中所使用的素材文件以及所有的源代码文件都已经同步到Github,小伙伴们点击下方链接直接获取。

Github链接地址:点击获取完整源代码,下载到本地即可运行https://github.com/xiaoZ-zhao/Tetris

Gitee地址:Tetris: 【开箱即用】使用Java实现俄罗斯方块,开发工具idea - Gitee.comhttps://gitee.com/xiaoZcode/Tetris/tree/master


http://chatgpt.dhexx.cn/article/q6qQ4oro.shtml

相关文章

Java实现俄罗斯方块游戏(简单版)

游戏页面效果如下&#xff1a; 俄罗斯方块游戏本身的逻辑&#xff1a; 俄罗斯方块游戏的逻辑是比较简单的。它就类似于堆砌房子一样&#xff0c;各种各样的方地形状是不同的。但是&#xff0c;俄罗斯方块游戏的界面被等均的分为若干行和若干列&#xff0c;因此方块的本质就是占…

vs2019功能介绍_MFC界面库BCGControlBar v30.0新功能详解:支持VS 2019

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v30.0正式发布&#xff01;新版本添加了对Visual Studio 2019的支持等。接下来几篇文章将对这个版本的新功能一一进行介绍&#xff0c;让您对BCG这个控件有一个全新的认…

MFC界面库BCGControlBar v32.0 - 网格、报表控件升级

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v32.0正式发布&#xff01;新版本支持Windows 11、增强功能区简化模式、改进控件外观等&#xff0c;以及其他新功能和改进。需要最新版的可以点击这里【BCG下载】 BCGC…

MFC扩展库BCGControlBar :网格和报告控件

BCGControlBar ("Business Components Gallery ControlBar")是MFC扩展库&#xff0c;使您可以创建具有完全自定义选项&#xff08;功能区、可自定义工具栏、菜单等&#xff09;以及一组专业设计的丰富Microsoft Office和Microsoft Visual Studio的应用程序 GUI控件&a…

MFC界面库之BCGControlers使用

觉得默认的MFC实在是太丑了,想要用一下扩展的界面库.网上查了些资料.不过在这里我还是小结一下使用的过程吧! 1.当然是安装文件了,在上一步不用多勾选,直接按照默认的就可以了...但是要注意一定要以管理员身份运行BCGCBProBuildWizard.exe否则没有办法通过...... 2.配置lib文件…

MFC界面控件BCGControlBar v33.3 - 编辑控件功能升级

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版和BCGSuite for MFC v33.3已正式发布了&#xff0c;该版本包含了增强的Ribbon自定义、新的…

MFC界面美化

排列整齐 基于MFC编写GUI代码时&#xff0c;界面美化最基本的部分就是排列整齐&#xff0c;如果是用Visual Studio 2015 IDE 开发&#xff0c;那就十分方便了&#xff0c;在快捷功能框即有相关按钮&#xff0c;这和Qt的控件调整有些类似&#xff0c;可以有效减少我们在布局上耗…

MFC界面库BCGControlBar v30.0新功能详解:支持VS 2019

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v30.0正式发布&#xff01;新版本添加了对Visual Studio 2019的支持等。接下来几篇文章将对这个版本的新功能一一进行介绍&#xff0c;让您对BCG这个控件有一个全新的认…

VS2017 MFC使用Skin++界面库实例(最简单的方法为自己的MFC程序换肤)

MFC的界面太丑了&#xff0c;又不想学界面设计&#xff0c;找了好多资源&#xff0c;要么各种各样的错误对于我这样的小白来说很难解决&#xff0c;要么就是使用起来太复杂&#xff0c;暂时也没有太多时间去研究&#xff0c;后来终于找到了VS2017也能用&#xff0c;简单方便的S…

MFC界面库BCGControlBar v33.0 - 全新升级Ribbon Bar、工具栏等

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v33.0正式发布&#xff01;此版本包括对每个显示器 DPI 感知的支持、改进的信息框和桌面警报控件、主题编辑框气球工具提示和其他新功能和改进。需要最新版的可以点击这…

MFC界面库BCGControlBar的介绍

英文原文&#xff1a; http://www.bcgsoft.com/bcgcontrolbarpro.htm BCGControlBar是MFC的一个扩展库其英文全称是"Business Components Gallery ControlBar"&#xff0c;它允许你去创建像完全自定义的像Microsoft Office 2000/XP/2003/2007/2010/2013 and Visua…

MFC界面库BCGControlBar v32.2 - Ribbon Bar功能增强

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v32.2正式发布&#xff01;新版本改进的功能区和框架标题命令搜索、带有可选复选框的网格日期选择器、带有标签的功能区滑块等&#xff0c;需要最新版的可以点击这里【B…

MFC界面库BCGControlBar v32.0 - 支持Windows 11

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v32.0正式发布&#xff01;新版本支持Windows 11、增强功能区简化模式、改进控件外观等&#xff0c;以及其他新功能和改进。需要最新版的可以点击这里【BCG下载】 BCGC…

MFC界面库BCGControlBar v33.0 - Docking Pane、仪表盘组件升级

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v33.0正式发布&#xff01;此版本包括对每个显示器 DPI 感知的支持、改进的信息框和桌面警报控件、主题编辑框气球工具提示和其他新功能和改进。需要最新版的可以点击这…

MFC界面库BCGControlBar v33.2 - Calendar、Planner控件升级

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC 和BCGSuite for MFC v…

MFC界面库BCGControlBar Pro for MFC v33.1 - 更适配Windows 11

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC v33.1全新发布&#xff01;BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间…

MFC界面库BCGControlBar v32.1 - 支持Visual Studio 2022

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v32.1正式发布&#xff01;新版本包含对Visual Studio 2022的支持、改进Windows 11中的框架和弹出窗口外观、网格文本溢出等。需要最新版的可以点击这里【BCG下载】 BC…

MFC界面库BCGControlBar v32.1 - 可视化管理器和主题升级

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v32.1正式发布&#xff01;新版本包含对Visual Studio 2022的支持、改进Windows 11中的框架和弹出窗口外观、网格文本溢出等。 BCGControlBar Pro for MFC v32.1正式版…

MFC界面库总结

好东西&#xff0c;果断收藏 刚开始用C做界面的时候&#xff0c;根本不知道怎么用简陋的MFC控件做出比较美观的界面&#xff0c;后来就开始逐渐接触到BCG Xtreme ToolkitPro v15.0.1&#xff0c;Skin,等界面库&#xff0c;以及一些网友自己写的界面库&#xff0c;开始对于C软件…

MFC界面库

刚开始用C做界面的时候&#xff0c;根本不知道怎么用简陋的MFC控件做出比较美观的界面&#xff0c;后来就开始逐渐接触到BCG Xtreme ToolkitPro v15.0.1&#xff0c;Skin,等界面库&#xff0c;以及一些网友自己写的界面库&#xff0c;开始对于C软件界面美化有了一点点的心得。…