前言

俄罗斯方块是一款风靡全球,从一开始到现在都一直经久不衰的电脑、手机、掌上游戏机产品,是一款游戏规则简单,但又不缺乏乐趣的简单经典小游戏,上手容易,适用范围广泛,人所共知。俄罗斯方块游戏简单的基本规则是有小方块组成的7种不同的规则图形陆续从屏幕上落下,玩家操作移动使其下落拼出一条完整的横条,随即会消失,玩家得分,游戏等级提高,当没有被消除的图形堆积到屏幕顶端时,游戏结束。

俄罗斯方块游戏最初是由俄罗斯人阿列克谢·帕基特诺夫在1984年开发的休闲小游戏,曾几何时它创造了无可匹敌的商业价值,影响了一代休闲小游戏的开发与产业链。随着信息时代科技时代的不断发展和变化,计算机已经普及到每一个人的生活中,在繁忙的工作生活中,这一类休闲小游戏给人们带来了些许的放松。

《俄罗斯方块升级版》游戏用java语言实现,采用了swing技术进行了界面化处理,设计思路用了面向对象思想。

主要需求

整个游戏系统会随机产生7种由四个小方块组成的不同形状的方块,经过旋转后得到28种状态,如果增加游戏难度,会增加六种不同形状的方块形状,同样经过旋转后增加24种状态。方块按一定的速度自由下落,玩家通过键盘上的上下左右按键控制方块的左右移动和旋转,将方块落下后放在合适的位置。当方块落下后,如果方块落下后有一整行被方块填满,那么该一整行消去。当一行被消去时,玩家得分增加10分,当得分达到100分后,玩家等级增加一级,速度加快一级,难度加大。如果当方块落下后整个游戏画布界面被占满,则方块不再下落,游戏宣告失败。游戏具体的功能需求有如下几个:

  • 游戏界面需求:游戏的良好的界面会让玩家眼前一亮,更加能充分的感受到游戏带来的娱乐性,放松性。本游戏的默认背景色是深绿色,游戏主界面画面自定义为自己的所喜欢的图片,并可以更改,主界面方块默认用橘黄色,预显方块颜色默认为淡紫色。背景色、前景色对比鲜明,以达到让玩家眼前一亮的感觉,并能在游戏达到高等级状态,方块下落速度渐高的情况下使玩家能够清楚的分辨出下落方块的形状,增加游戏的刺激性。
  • 游戏形状需求:用数组作为存储方块52种状态的数据结构,即初级等级长条形、Z字形、反Z形、田字形、7字形、反7形、T字型一共7种形状的向4个方向的旋转变形,和中级等级的三种方块12种不同的状态,高级等级的三种方块12种不同的状态。各个方块可以实现按逆时针的旋转方式旋转,并且方块能否旋转需要用条件加以判断,如果旋转后可能发生越界,则不能旋转,需要调整位置来保证他可以旋转。

主要设计

以下该游戏中类的设计:
MyFrame类:继承自JFrame类,作为游戏的主类,负责对游戏的主体全局进行控制,连接与指挥各个类的枢纽。
PreView类:继承自JPanel类,作为操作面板类,负责安放主游戏窗口,积分板,级别控制按钮等窗口用以控制游戏进程。
GameCanvas类:继承自JPanel类,ChangeBlockColor线程类动态改变画布类的方格颜色,画布类通过检查方格颜色来体现ChangeBlockColor方块的移动情况与消去状况。
Box类:方格类,组成方块的基本元素,主要表达方式为颜色。
Block类:作为操控方块的类,控制方块的移动,下落以及变形。

  • 游戏主界面显示模块:
    游戏主界面采用Swing组件开发,并且向其注册监听器,以实现各种控制功能,综合游戏窗体的设计,其上至少需要注册三个监听器,分别是动作监听器(ActionListener)、键盘监听器(KeyListener)、选项监听器(ItemListener)。
    根据初步设计,可以确定客户端上所要用到的Swing组件对象有JFrame对象、JPanel对象,JLabel对象、JButton对象、JMenuBar对象、JMenu对象、JMenuItem对象、JTextField对象、JTextArea对象、JDialog对象等,至少十个Swing组件对象。

  • 背景画布模块设计:该游戏的主背景画布是一个20行、12列的二维数组,方块显示是由相应颜色变化来标识,主窗体用颜色填充后可形成呈现出来背景样式和方块。本游戏用继承自JPanel的GameCanvas类控制背景画布的显示,用rows代表画布的行数,cols代表画布的列数,行数和列数决定着画布拥有方格的数目。

  • 预览方块模块设计:方块和数据信息是游戏中最基本的功能模块。Box这个类方格类,是组成块的基本元素,用自己的颜色来表示块的外观 ,MyTask继承TimerTask类用来定时下落,用计数方式来实现速度的改变,MyListener类继承KeyAdapter类用来实现按键监听,控制方块的上下左右。定义一个4x4方阵,共16个小格。用“0”和“1”来表示每个方格是绘制新颜色还是保留底色。

  • 方块移动、旋转模块设计:方块的翻转与移动比较容易实现,方块移动只需要改变方块的横坐标或纵坐标,然后重新绘制方块即可。方块翻转也只需要改变背景数组的值,重新绘制方
    即可。
    本游戏方块下落时,进行动态绘制,实现Cloneable接口, 以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。方块的操作类BlockOperation继承Thread类,重写run()方法,以实现方块的动态正确下落。当然,在线程中要判定方块是处于moving状态还是pausing状态

功能截图

游戏开始主界面:

游戏菜单:

设计方块颜色:

代码实现

MyFrame


public class MyFrame extends JFrame{JPanel jp_pan=new JPanel();JPanel jp_pre=new JPanel();JPanel jp_ctrl=new JPanel();JPanel jp_scor=new JPanel();Zidingyi zi;JRadioButtonMenuItem jr1=new JRadioButtonMenuItem("初级",true);JRadioButtonMenuItem jr2=new JRadioButtonMenuItem("中级");JRadioButtonMenuItem jr3=new JRadioButtonMenuItem("高级");JLabel jt9=new JLabel("得分:0" );static JLabel jt10=new JLabel("等级:1" );JMenu m1=new JMenu("游戏");JMenu m2=new JMenu("帮助");JCheckBox jc1;JSlider jsl;
//  Dialog dia;//创建对话框static ImageIcon  background = new ImageIcon(Constant.backGround1);// 把背景图片加到labelstatic JLabel label = new JLabel(background);
//  Dialog dia=new Dialog(this, "自定义", false);int scor=0;//初始化分数为0static int rank=0;//初始化等级为0int highC=0;boolean upspeed=false;boolean isTime=true;boolean runstop;static boolean isRank=false;static boolean changeBack=false;public static boolean playing=false;static boolean isMusic=true;static boolean high=false;PreView pv=new PreView();JMenuItem ji1=new JMenuItem("开局");GameCanvas gc=new GameCanvas(20, 12);//画出20行12列private Block block=new Block();//当前块private int newspeed=1000;//默认当前等级为1MusicPlayer mp=new MusicPlayer();Timer time=new Timer();MyTask mytask;int temp=1;
//  游戏主构造函数public MyFrame(String str){super(str);this.setSize(450, 570);Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();//获取屏幕尺寸setLocation((scrSize.width - getSize().width) / 2,(scrSize.height - getSize().height) / 2);//设置屏幕居中this.setLayout(null);//label的大小为jframe的大小label.setBounds(0, 0, this.getWidth(), this.getHeight());//把label加到jframe的最底层,比jframe上的那个panel还下面this.getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));//label比jframe上的那个panel还下面,那需要把那个panel设为透明的,不然就盖住背景了JPanel imagePanel = (JPanel) this.getContentPane();imagePanel.setOpaque(false);addMenu();//游戏开始按钮ji1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stub// 如果游戏已经开始,再按一次即显示游戏结束if (playing == true) {ji1.setText("开局");if(isMusic==true){mp.playStart();}gc.setGameOver(true);gc.repaint();MyFrame.rank=11-Constant.step;MyFrame.jt10.setText("等级:"+MyFrame.rank);runstop=true;block.isAlive=false;block=new Block();mytask.cancel();playing = false;} else {reset();if(isMusic==true){mp.playStart();}MyFrame.rank=11-Constant.step;MyFrame.jt10.setText("等级:"+MyFrame.rank);ji1.setText("结束游戏");playing = true;mytask=new MyTask();time.schedule(mytask, 0, 100);//100毫秒执行一次Thread thread = new Thread(new play());// 调用开始游戏的方法thread.start();}};});this.add(gc);//添加游戏画布addRight();//添加右边this.setFocusable(true);//设置可获得焦点this.requestFocus();//设置焦点this.addKeyListener(new MyListener());this.setVisible(true);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}
public static void setBackGround(){label.setIcon(background);
}/*** 定时下落,用计数方式来实现速度的改变* */private class MyTask extends TimerTask {@Overridepublic void run() {temp++;if (temp % Constant.step == 0) {block.newL = block.x;block.newH = block.y + 1;
//              block.yy();if (block.pausing == true)return;if (high == true) {block.earse();highC++;if (highC == 4) {gc.addRow();highC = 0;}}if (block.isMoveAble(block.newH, block.newL)) {block.earse();block.y++;block.display();gc.repaint();} else {block.isAlive = false;gc.repaint();// cancel();} // 取消定时器任务temp = 1;}}}private class play implements Runnable {public void run() {/*          if(killThread==true)return;*/int col = (int) (Math.random() * (gc.getCols() - 3));//随即位置生成列int style = Constant.STYLES[(int) (Math.random() * Block.get_addl())][(int) (Math.random() * 4)];while (playing) {if (block != null) {//判断当前方块是否死亡if (block.isAlive) {try {Thread.currentThread().sleep(100);} catch (InterruptedException ie) {ie.printStackTrace();}continue;}}isFullLine();
//              if(upspeed)//判断是否加速,是的话则进行调用
//              upLevel();if(isGameOver()){if(isMusic==true){mp.playGameOver();}gc.setGameOver(true);gc.repaint();ji1.setText("开局");mytask.cancel();playing=false;return;}block = new Block(style, -1, col, gc);block.jixu();//防止在暂停时候重新开始游戏,暂停字还不消失gc.repaint();// 将创建出来的方块显示出来block.isAlive = true;col = (int) (Math.random() * (gc.getCols() - 3));//随即位置生成列style = Constant.STYLES[(int) (Math.random() * Block.get_addl())][(int) (Math.random() * 4)];pv.setStyle(style);}}/*** 增加速度*/private void upLevel() {if(Constant.step-1<1){return;}Constant.step=Constant.step-1;    //速度增加一级rank++;                   jt10.setText("等级:"+rank);upspeed=false;//将标志位至为false     }/*** 判断是否满行,满行则调用消行方法。*/private void isFullLine() {// TODO Auto-generated method stubfor (int i = 0; i < 20; i++) {int row = 0;boolean flag = true;for (int j = 0; j < 12; j++) {if (!gc.getBox(i, j).isColorBox()) {flag = false;break;}}if (flag == true) {row = i;gc.delete(row);//删除行if(isMusic==true){mp.playEraseSound();}addScor();//增加分数if(scor%10==0)//设置为10分增加一个等级upspeed=true;//将速度增加标志位至为trueif(upspeed==true)upLevel();}}}/*** 得分的计算方法*/private void addScor() {scor=scor+10;jt9.setText("得分:"+scor);}}/*** 判断最顶层是否有被占用,游戏是否结束*/private boolean isGameOver() {for (int i = 0; i < 12; i++) {Box box = gc.getBox(0, i);if (box.isColorBox())return true;}return false;}private void reset() {scor=0;rank=0;jt10.setText("等级:"+rank);jt9.setText("得分:"+scor);upspeed=false;playing=true;runstop=false;
//      block.pausing=false;
//      isTime=true;
//      block=new Block();
//      block.isAlive=false;gc.setGameOver(false);gc.repaint();gc.reset();}
/*  private class MenuKeyListener extends KeyAdapter{public void keyPressed(KeyEvent e) {int i = e.getKeyCode();switch (i) {case KeyEvent.VK_C:System.out.println("111");;break;case KeyEvent.VK_DOWN:block.moveDown();break;case KeyEvent.VK_LEFT:block.moveLeft();break;}}}*//*** *按键监听,上下左右。*/private class MyListener extends KeyAdapter{@Overridepublic void keyPressed(KeyEvent e) {// TODO Auto-generated method stubint i = e.getKeyCode();switch (i) {case KeyEvent.VK_UP:block.moveUp();break;case KeyEvent.VK_DOWN:block.moveDown();break;case KeyEvent.VK_LEFT:block.moveLeft();break;case KeyEvent.VK_RIGHT:block.moveRight();break;case KeyEvent.VK_SPACE:block.quickDown();break;case KeyEvent.VK_P:block.pause();break;case KeyEvent.VK_C:block.jixu();break;}}}/*** 菜单添加方法*/private void addMenu() {// TODO Auto-generated method stubJMenuBar jb1=new JMenuBar();
//      m1.addKeyListener(new MenuKeyListener());//监听Dialog对话框,如果有等级改变则改变选择m1.addChangeListener(new ChangeListener() {@Overridepublic void stateChanged(ChangeEvent e) {// TODO Auto-generated method stubint i=Block.get_addl();if(i==7)jr1.setSelected(true);else if(i==10)jr2.setSelected(true);elsejr3.setSelected(true);}});//        JMenuItem ji1=new JMenuItem("开局(O)");jr1.addActionListener(new MenuActionListener());jr2.addActionListener(new MenuActionListener());jr3.addActionListener(new MenuActionListener());ButtonGroup bg=new ButtonGroup();bg.add(jr1);bg.add(jr2);bg.add(jr3);JMenuItem ji2=new JMenuItem("自定义");ji2.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent arg0) {// TODO Auto-generated method stubzi=new Zidingyi(MyFrame.this,"自定义",false,block,gc);zi.setVisible(true);if(playing==true)block.pause();}});JMenuItem ji3=new JMenuItem("退出");ji3.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent arg0) {// TODO Auto-generated method stubSystem.exit(1);//退出程序}});JMenuItem ji4=new JMenuItem("关于");ji4.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubJDialog dl=new Version(MyFrame.this,"版本信息",false);}});//调用颜色对话框设置方块颜色JMenuItem ji_color=new JMenuItem("方块颜色");ji_color.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubColor newFrontColor = JColorChooser.showDialog(MyFrame.this,"设置方块颜色",gc.getBlockColor());if (newFrontColor != null)gc.setBlockColor(newFrontColor);}});MyFrame.this.setJMenuBar(jb1);jb1.add(m1);jb1.add(m2);m1.add(ji1);m1.add(jr1);m1.add(jr2);m1.add(jr3);m1.add(ji2);m1.add(ji_color);m1.add(ji3);m2.add(ji4);   }/*** 右界面的添加*/private void addRight() {// TODO Auto-generated method stub
//      JTextField jt1=new JTextField("下一块");JLabel jt1=new JLabel("下一块");jt1.setFont(new Font("华文行楷", Font.BOLD, 18));jt1.setOpaque(false);
//      jt1.setEditable(false);jp_pre.setLayout(null);jt1.setBounds(5, 0, 80, 20);jp_pre.add(jt1);pv.setBounds(10, 20, 102, 102);jp_pre.add(pv);//添加预览窗口jp_pre.setBounds(308, 5, 120, 125);//设置坐标jp_pre.setOpaque(false);//设置背景为透明MyFrame.this.add(jp_pre);
//      JTextField jt2=new JTextField("功能键盘" );JLabel jt2=new JLabel("功能键盘");jt2.setFont(new Font("华文行楷", Font.BOLD, 23));
//      jt2.setEditable(false);jt2.setOpaque(false);
//      JTextField jt3=new JTextField("快速向下:↓" );JLabel jt3=new JLabel("快速向下:↓");jt3.setFont(new Font("华文行楷", Font.BOLD, 15));
//      jt3.setEditable(false);jt3.setOpaque(false);
//      JTextField jt4=new JTextField("旋转:↑" );JLabel jt4=new JLabel("旋转:↑");jt4.setFont(new Font("华文行楷", Font.BOLD, 15));
//      jt4.setEditable(false);jt4.setOpaque(false);
//      JTextField jt5=new JTextField("向左:←" );JLabel jt5=new JLabel("向左:←");jt5.setFont(new Font("华文行楷", Font.BOLD, 15));
//      jt5.setEditable(false);jt5.setOpaque(false);
//      JTextField jt6=new JTextField("向右:→" );JLabel jt6=new JLabel("向右:→");jt6.setFont(new Font("华文行楷", Font.BOLD, 15));
//      jt6.setEditable(false);jt6.setOpaque(false);JLabel jt11=new JLabel("一键下落:空格");jt11.setFont(new Font("华文行楷", Font.BOLD, 15));
//      jt6.setEditable(false);jt6.setOpaque(false);
//      JTextField jt7=new JTextField("暂停:P" );JLabel jt7=new JLabel("暂停:P");jt7.setFont(new Font("华文行楷", Font.BOLD, 15));
//      jt7.setEditable(false);jt7.setOpaque(false);
//      JTextField jt8=new JTextField("继续:C" );JLabel jt8=new JLabel("继续:C");jt8.setFont(new Font("华文行楷", Font.BOLD, 15));
//      jt8.setEditable(false);jt8.setOpaque(false);jp_ctrl.setLayout(new GridLayout(8, 1, 0, 0));
//      jp_ctrl.setBorder(BorderFactory.createBevelBorder(EtchedBorder.LOWERED));jp_ctrl.add(jt2);jp_ctrl.add(jt3);jp_ctrl.add(jt4);jp_ctrl.add(jt5);jp_ctrl.add(jt6);jp_ctrl.add(jt11);jp_ctrl.add(jt7);jp_ctrl.add(jt8);jp_ctrl.setOpaque(false);jp_ctrl.setBounds(310, 145, 120, 200);MyFrame.this.add(jp_ctrl);
//      jt9.setEditable(false);jt9.setOpaque(false);jt9.setForeground(Color.BLACK);
//      jt10.setEditable(false);jt10.setOpaque(false);jt10.setForeground(Color.BLACK);jp_scor.setLayout(new GridLayout(2, 1, 0, 20));jp_scor.add(jt9);jt9.setFont(new Font("华文行楷", Font.BOLD, 26));jt10.setFont(new Font("华文行楷", Font.BOLD, 26));jp_scor.add(jt10);jt9.setBackground(Color.LIGHT_GRAY);jt10.setBackground(Color.LIGHT_GRAY);jp_scor.setOpaque(false);jp_scor.setBounds(320, 360, 100, 140);MyFrame.this.add(jp_scor);}/*** 菜单等级的监听**/private class MenuActionListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {//获取JMenuItem对象JMenuItem j=((JMenuItem)e.getSource());if(j==jr1){//              newLevel=Constant.LEVEL_1;Block.set_addl(7);}if(j==jr2){Block.set_addl(10);}if(j==jr3){//              high=true;Block.set_addl(13);}}}public static void main(String[] args) {new MyFrame("俄罗斯方块");}}

GameCanvas

public class GameCanvas extends JPanel {private Color backColor = Color.GRAY, frontColor = Color.orange;private int rows, cols, score = 0, scoreForLevelUpdate = 0;private Box[][] boxes;private int boxWidth=25, boxHeight=25;private boolean gameOver=false;public boolean pau=false;/*** 画布类的构造函数* @param rows int, 画布的行数* @param cols int, 画布的列数* 行数和列数决定着画布拥有方格的数目*/public GameCanvas(int rows, int cols) {this.rows = rows;this.cols = cols;this.setOpaque(false);boxes = new Box[rows][cols];for (int i = 0; i < boxes.length; i++) {for (int j = 0; j < boxes[i].length; j++) {boxes[i][j] = new Box(false);}}setBounds(0, 0, 300, 500);//设置相对位置坐标setBorder(new EtchedBorder(EtchedBorder.RAISED, Color.white, new Color(148, 145, 140)));}/*** 画布类的构造函数* @param rows 与public GameCanvas(int rows, int cols)同* @param cols 与public GameCanvas(int rows, int cols)同* @param backColor Color, 背景色* @param frontColor Color, 前景色*/public GameCanvas(int rows, int cols,Color backColor, Color frontColor) {this(rows, cols);this.backColor = backColor;this.frontColor = frontColor;}/*** 设置游戏背景色彩* @param backColor Color, 背景色彩*/public void setBackgroundColor(Color backColor) {this.backColor = backColor;}/*** 取得游戏背景色彩* @return Color, 背景色彩*/public Color getBackgroundColor() {return backColor;}/*** 设置游戏方块色彩* @param frontColor Color, 方块色彩*/public void setBlockColor(Color frontColor) {this.frontColor = frontColor;}/*** 取得游戏方块色彩* @return Color, 方块色彩*/public Color getBlockColor() {return frontColor;}/*** 取得画布中方格的行数* @return int, 方格的行数*/public int getRows() {return rows;}/*** 取得画布中方格的列数* @return int, 方格的列数*/public int getCols() {return cols;}/*** 取得游戏成绩* @return int, 分数*/public int getScore() {return score;}/*** 取得自上一次升级后的积分* @return int, 上一次升级后的积分*/public int getScoreForLevelUpdate() {return scoreForLevelUpdate;}/*** 得到某一行某一列的方格引用。* @param row int, 要引用的方格所在的行* @param col int, 要引用的方格所在的列* @return ErsBox, 在row行col列的方格的引用*/public Box getBox(int row, int col) {if (row < 0 || row > boxes.length - 1|| col < 0 || col > boxes[0].length - 1)return null;return boxes[row][col];}/*** 消行*/public void delete(int row) {//创建新Box存储新状态,不能直接赋值,赋值只是指向同一个对象for (int i = row; i > 0; i--) {for (int j = 0; j < 12; j++)boxes[i][j] = new Box(boxes[i - 1][j].isColorBox());}repaint();}/*** 自动上涨*/public void addRow() {for (int i = 0; i <19 ; i++) {for (int j = 0; j < 12; j++) {boxes[i][j] = new Box(boxes[i + 1][j].isColorBox());}}for (int i = 0; i < 12; i++) {int a = (int) (Math.random() * 2);if (a == 1)boxes[19][i] = new Box(true);elseboxes[19][i] = new Box(false);}repaint();}/*** 画组件。* @param g 图形设备环境*/public void paint(Graphics g) {super.paint(g);if (gameOver) {paintGame(g);g.setColor(Color.RED);g.setFont(new Font("黑体", Font.BOLD, 80));// g.drawString("GAME\nOVER",10, 220);g.drawString("GAME", 50, 220);g.drawString("OVER", 50, 310);} else if(pau==true){paintGame(g);g.setColor(Color.BLUE);g.setFont(new Font("华文行楷", Font.BOLD, 40));// g.drawString("GAME\nOVER",10, 220);g.drawString("暂停", 100, 200);g.drawString("按C继续!", 60, 310);}elsepaintGame(g);}public void paintGame(Graphics g) {g.setColor(Color.BLUE);g.draw3DRect(0, 0, 298, 498, true);g.setColor(frontColor);
//      int a;
//      int key=0x8000;
//      int y1=0;for (int i = 0; i < boxes.length; i++) {for (int j = 0; j < boxes[i].length; j++) {if (boxes[i][j].isColorBox() == true) {g.setColor(frontColor);// 获取方格颜色g.fill3DRect(j * boxWidth, i * boxHeight, boxWidth,boxHeight, true);// j,i是相反过来的}}}}}/*** 设置游戏结束*/public boolean setGameOver(boolean go){gameOver=go;return gameOver;}/*** 重置画布*/public void reset() {for (int i = 0; i < boxes.length; i++) {for (int j = 0; j < boxes[i].length; j++)boxes[i][j].setColor(false);}repaint();}}

总结

通过此次的《俄罗斯方块升级版》游戏实现,让我对swing的相关知识有了进一步的了解,对java这门语言也有了比以前更深刻的认识。

java的一些基本语法,比如数据类型、运算符、程序流程控制和数组等,理解更加透彻。java最核心的核心就是面向对象思想,对于这一个概念,终于悟到了一些。

源码获取

源码下载地址:传送门------->

可关注博主后,私聊博主免费获取
需要技术指导,写项目程序,等更多服务请联系博主

今天是持续写作的第 31 / 100 天。
可以关注我,点赞我、评论我、收藏我啦。

猿创征文|JAVA 实现《俄罗斯方块升级版》游戏相关推荐

  1. 猿创征文 | Java知识【Java基础语法】

    目录 1,注释 1.1:使用的技巧 1.2:注意点 2,关键字 2.1:概念 2.2:第一个关键字class 3,字面量 4,变量 4.1:什么是变量? 4.2:变量的定义格式 4.2.1:格式详解 ...

  2. 猿创征文 | Java知识【Java运算符】

    目录 1,运算符和表达式 运算符: 表达式: 2,算术运算符 练习:数值拆分 3,隐式转换 概念: 简单记忆: 两种提升规则: 取值范围从小到大的关系: 5,强制转换 概念: 书写格式: 6,字符串的 ...

  3. 猿创征文|【C++游戏引擎Easy2D】我拿吃零食的时间,学会了在C++上添加可点击按钮

  4. 猿创征文|【C++游戏引擎Easy2D】炫酷动画来这学,位移动画构造函数让节点执行动画

  5. 猿创征文 | Java知识【顺序结构判断语句】

     目录 第一章:流程控制语句 1.1:流程控制语句分类 1.2:顺序结构 第二章:判断语句:if语句 2.1:if语句格式1 2.2:if语句格式2 2.3:if语句格式3 第一章:流程控制语句 1. ...

  6. 猿创征文|收到谷歌开发者大会正式邀请(Java学生的自学之路)

    文章目录 一.前言 二.收到谷歌邮件 三.感想 四.学习之路 1. 坚持看网课并整理笔记 2.勤加练习 3.坚持总结 4.刷题技巧 5.心态调整 五.结语 一.前言 上一次通过了CSDN内部筛选后,在 ...

  7. 猿创征文|《Java》关键字大全-小结

    目录 关键字 一.Java中的关键字有: 二.访问控制 1.public 2.protected: 3.private: 三.类.方法.变量.修饰符 1.abstract: 2.class: 3.ex ...

  8. 猿创征文|当我在追光 我与光同航--我与Java的技术成长之路

    文章目录 前言 材料转码 初识JAVA 大学建议 1. 参加比赛 2. 坚持创作 3.养成看书的习惯 Java路线 1. java基础 2. 数据库 3. javaWeb 4. 框架 前言 今天借着官 ...

  9. 猿创征文|我的前端学习之旅【来自一名大四老学长的真情流露】

    猿创征文 | 我的前端学习之旅 自我介绍 我浑噩的大一大二(是不是另一个你) 我的大三生活 大三上(学习过程.学习方法.推荐网站) 大三下(技术提升.荣誉证书.推荐比赛) 我与 CSDN 的机缘(从小 ...

  10. 猿创征文 | DevOps运维的10个日常使用工具分享

    猿创征文 | DevOps运维的10个日常使用工具分享 一.DevOps介绍 1.DevOps的简介 2.个人分享的10个工具导航 二.jenkins 1.jenkins介绍 2.jenkins的优点 ...

最新文章

  1. 无线节能信标核心板V4-测试-2021-4-3
  2. 《说服力——让你的PPT会说话》读书笔记02
  3. nginx匹配规则_Nginx系列之server_name定义与匹配规则
  4. Non-resolvable parent POM
  5. php post登陆 json,php 之 post json 数据
  6. 定制自己的Windows CE 5.0 ARM中文模拟器(转)
  7. Go (interface)接口二
  8. Base64原理及魔改更换码表
  9. 经典的哲学家就餐问题
  10. 广义最小二乘法的基本思想是什么_解决异方差问题的方法可行广义最小二乘法fgls法.ppt...
  11. 解决谷歌无法加载扩展程序
  12. vue即时通讯,一个很好用的插件
  13. 为什么很多企业要自研CRM系统,而不够买SAAS云服务提供的CRM系统或SCRM系统?...
  14. 表达式计算: 分析与设计
  15. 【玩转开源】Linux C 检测网口热插拔
  16. 生活琐事随感 (r5笔记第43天)
  17. 信号发生器输出电阻与负载电阻问题,影响实际的信号输出
  18. arcgis js(九)天际线分析
  19. 利用 CPU 流水线加快数据处理
  20. 合肥市2023年度高校毕业生“双千培养工程”培训项目学员招募公告

热门文章

  1. 苹果电脑卡在进度条,进不了系统
  2. Android 组件化面试必备,android输入法开发源码
  3. 绿色版免费PDF转换器
  4. IOS捷径、微信技巧、玩机巧计交流群
  5. 凯斯西储轴承数据CWRU数据集制作十分类
  6. 用Vue2.x + Mint-UI实现智能家居app demo
  7. 科普:什么是处理器微架构?
  8. 超好看的辅助网站html源码 记事本修改即可
  9. mysql thd_MySQL 5.7: 数据库THD连接管理重构
  10. linux 反射拒绝服务,浅谈拒绝服务攻击的原理与防御(2):反射型DDOS