目录

一、游戏概述

二、需求分析

三、运行环境

四、详细设计

1.游戏初始化界面

2.单人闯关模式的设计

3.双人合作模式

4.数据库连接与操作

5.数据库连接,排行榜

五、总结


说明

该课设一共分成8个类,分别是Check_mark、Double_Login、Double_People、Login、Mark_user、MUSIC、prinBall、主页面。另外还有一个放在桌面的文件夹存放音乐文件和主界面的背景图和连接mysql的数据库,具体说明放后面这样程序才能完全运行

一、游戏概述

弹珠传说是一个基于java swing的弹球小游戏,运行程序后允许用户选择执行选项菜单。双缓冲就是在内存中开辟一片区域,作为后台图像,程序对他进行更新、修改绘制完成后再显示到屏幕上。可以简单地这样理解,将开辟区域可以理解为新建一个图层,然后将之前所建立的图片图层都放在这个图层上面,然后最他们进行合并图层合并成一个图层,然后不管再怎样刷新渲染,几个图像组件都是保持一致的,出现频率不一样的情况也就不会出现了。本设计的主要实现功能是通过双缓冲技术绘制弹珠小球,键盘控制滑块让弹珠能够弹射到墙面得分,并不断升级游戏难度,记录最终得分上传至数据库中进行排序,实现了单人模式和双人合作模式。

二、需求分析

当前各种游戏层出不穷,因为游戏的开发成本非常大,所以游戏开发具有一定的风险性,但是一些小游戏的开发成本具有成本小、编写简单、易上手的优势,所以这些小游戏的开发也在市场占有一席之地。在这类小游戏中包括换装类,益智类,动作类等等,它以画面精美、操作简单得到大家认可,使人们在休息时间可以得到适当的放松。针对这个情况,我们选择了弹珠传说作为我们的小组课程设计。通过拖动滑块使弹球反弹到墙壁,并提前预判其下落的位置等玩法,从而提高人们的观察能力、反应能力与计算能力。

三、运行环境

本项目的开发环境如下:

操作系统:Windows 10。

开发工具:IntelliJ IDEA JDK17、MySQL 。

开发语言:JAVA语言。

四、详细设计

1.游戏初始化界面

代码展示

package JAVA_Lesson_Myprocess;
import javax.sound.sampled.*;
import javax.swing.*;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;public class 主页面{public static JFrame frame=new JFrame("弹珠传说");public void  run() throws Exception{
frame.setResizable(false);//插入背景图片ImageIcon icon1 = new ImageIcon("C:\\Users\\Lenovo\\Desktop\\Music\\background.jpg");JLabel label1 = new JLabel(icon1);label1.setBounds(0, 0, icon1.getIconWidth(), icon1.getIconHeight());frame.setDefaultCloseOperation(3);frame.getLayeredPane().add(label1, new Integer(Integer.MIN_VALUE));JPanel panel = new JPanel();JPanel panelTop = new JPanel();panelTop = (JPanel) frame.getContentPane();//panel和panelTop设置透明panelTop.setOpaque(false);panel.setOpaque(false);//----------------------------------------------------------------------------------------JPanel jPanel = new JPanel();jPanel.setLayout(null);//三个按钮对应三种模式JButton jButton_Person = new JButton("单人闯关");JButton jButton_Double = new JButton("双人合作");JButton jButton_Check = new JButton("排行榜");jButton_Person.setSize(90, 50);jButton_Double.setSize(90, 50);jButton_Check.setSize(90, 50);jButton_Person.setLocation(100, 200);jButton_Double.setLocation(100, 300);jButton_Check.setLocation(100, 400);jPanel.setOpaque(false);
//按钮获取焦点的事件触发音效jButton_Person.addMouseListener(new MouseListener() {@Overridepublic void mouseClicked(MouseEvent e) {}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {new MUSIC().focus();}@Overridepublic void mouseExited(MouseEvent e) {}});jButton_Check.addMouseListener(new MouseListener() {@Overridepublic void mouseClicked(MouseEvent e) {}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {new MUSIC().focus();}@Overridepublic void mouseExited(MouseEvent e) {}});jButton_Double.addMouseListener(new MouseListener() {@Overridepublic void mouseClicked(MouseEvent e) {}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {new MUSIC().focus();}@Overridepublic void mouseExited(MouseEvent e) {}});//三个按钮跳转到分别不同的界面 先跳转再关闭当前窗口jButton_Person.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {new Login().init();} catch (Exception ex) {throw new RuntimeException(ex);}frame.dispose();}});jButton_Double.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {new Double_Login().init();} catch (Exception ex) {throw new RuntimeException(ex);}frame.dispose();}});jButton_Check.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {new Mark_user().run();frame.dispose();} catch (Exception ex) {throw new RuntimeException(ex);}}});//设置界面布局frame.setLocation(500,300);jPanel.add(jButton_Person);jPanel.add(jButton_Double);jPanel.add(jButton_Check);frame.add(jPanel);frame.setSize(900, 565);jPanel.requestFocus();//获取界面焦点frame.setVisible(true);}public static void main(String[] args)  {//主界面执行try {new 主页面().run();} catch (Exception e) {throw new RuntimeException(e);}}}

初始化界面调用的音乐类

package JAVA_Lesson_Myprocess;import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import java.io.File;
import java.net.URI;public class MUSIC {public void focus(){try{File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Jump1.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn= AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception e){e.printStackTrace();}}public void defeat(){try{File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Defeat1.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn= AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception e){e.printStackTrace();}}}

2.单人闯关模式的设计

开始单人闯关前需先注册用户名方便上传到数据库保存成绩,通过键盘事件监听使木板在画板上的坐标移动,小球使通过一帧一帧改变横坐标和纵坐标重绘出来的,使用双缓冲技术实现小球在页面中移动得更丝滑,调用定时器Timer实现关卡自动升级,3000ms为一个关卡,在第三关时会有另一个小球出现。超级模式即是在木板的右边无限延长需要用户来判断哪个时机适合接小球,空格键触发,一共只能用3次。在初始界面点击单人闯关即可进入游戏,当未接到小球时则会结束游戏显示排行榜上的名次,点击右上角即可返回主菜单。

界面展示

代码展示

我们先是跳转到一个输入用户界面的源代码

package JAVA_Lesson_Myprocess;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class Login {public  String username;public void init(){//初始化组件JFrame frame1=new JFrame("弹珠传说");JLabel label_uername=new JLabel("用户名称:");JButton jButton=new JButton("确定");JPanel panel=new JPanel();JTextField jTextField=new JTextField(8);frame1.setResizable(false);//设置不可改变jTextField.setMaximumSize(new Dimension(100,50));frame1.setLayout(new BorderLayout());//设置布局panel.add(label_uername,BorderLayout.WEST);panel.add(jTextField,BorderLayout.CENTER);panel.add(jButton,BorderLayout.SOUTH);frame1.add(panel);jButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {username=jTextField.getText();System.out.println(username);try {prinBall p=new prinBall();p.setUsername(username);//这里调用setter方法传参到prinBall界面去p.init();frame1.dispose();} catch (Exception ex) {throw new RuntimeException(ex);}}});frame1.setBounds(500,300,300,100);frame1.setVisible(true);}}

这边我们先说一下双缓冲技术,所谓的双缓冲就是先画一个等比例大小的画布再盖上去这里话不多说直接上代码

private static Image offScreenImage = null;//用于实现双缓冲
//以下在画布中重写public void update(Graphics g) {if(offScreenImage == null) {offScreenImage = this.createImage(TABLE_WIDTH, TABLE_HEIGHT);//创建一张大小和窗口大小一样的虚拟图片}Graphics gOffScreen = offScreenImage.getGraphics();//获得画笔//刷新背景,否则物体运动痕迹会保留Color c = gOffScreen.getColor();gOffScreen.setColor(Color.white);gOffScreen.fillRect(0, 0,TABLE_WIDTH, TABLE_HEIGHT);gOffScreen.setColor(c);paint(gOffScreen);//画到虚拟图片上g.drawImage(offScreenImage, 0, 0, null);//把图片画到屏幕上

这里的update一定要重写,具体的你们可以去看下其他博主写的update与paint的关系,update与paint重写与画布中,每当重绘的时候都要取前景色设置前景色

            Color c = g.getColor();//取出原前景色g.setColor(Color.RED);//设置前景色

然后在你每次绘制完一个图形之后要恢复它

 g.setColor(c);//恢复原前景色

具体可以看下单人闯关整个界面的源代码展示

package JAVA_Lesson_Myprocess;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.sql.*;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;public class prinBall {private int line;//初始化数据 为连接数据库做准备private static String url="jdbc:mysql://localhost:3306/ceshi";private int mingci;private static String username_mysql="root";private static String password_mysql="123456";private String username;private int user_mark;private  JFrame frame=new JFrame("弹珠传说-单人闯关");private  int count=3;//是否为两个小球,两个小球的横纵坐标是不一样的,因此我们可以可以看到是不同轨迹运动private boolean isTwo=false;public void setUsername(String username) {this.username= username;}private boolean isbegin=false;public int mark=0;public  int guan=0;//这里代表关卡每过3s为一关 底下会设置//桌面高度宽度private final int TABLE_WIDTH=500;private final  int TABLE_HEIGHT=700;//球拍高度宽度private   int RACKET_WIDTH=100;private final  int RACKET_HEIGHT=20;//小球大小private final int BALL_SIZE=30;//小球坐标//随机数出现坐标Random a=new Random();private int ballX=a.nextInt(200);private int ballY=a.nextInt(500);//第二个小球private int ballX2=a.nextInt(300);private int ballY2=a.nextInt(200);public int speedX2=5;public int speedY2=4;//小球速度public int speedX=5;public int speedY=6;//球拍的坐标private  int recketX=120;private final  int recketY=540;private boolean isOver=false;private static Image offScreenImage = null;//用于实现双缓冲private Timer timer;//开始画小球private class MyCanvas extends Canvas{@Overridepublic void update(Graphics g) {if(offScreenImage == null) {offScreenImage = this.createImage(TABLE_WIDTH, TABLE_HEIGHT);//创建一张大小和窗口大小一样的虚拟图片}Graphics gOffScreen = offScreenImage.getGraphics();//获得画笔//刷新背景,否则物体运动痕迹会保留Color c = gOffScreen.getColor();gOffScreen.setColor(Color.white);gOffScreen.fillRect(0, 0,TABLE_WIDTH, TABLE_HEIGHT);gOffScreen.setColor(c);paint(gOffScreen);//画到虚拟图片上g.drawImage(offScreenImage, 0, 0, null);//把图片画到屏幕上}//这里代表着每一帧一帧地重绘@Overridepublic void paint(Graphics g) {Color c = g.getColor();//取出原前景色g.setColor(Color.RED);//设置前景色if (isOver){//判断是否结束如果结束就上传用户名以及成绩到数据库中//overuser_mark=mark;g.setColor(Color.RED);g.setFont(new Font("Times",Font.BOLD,30));//播放音效new MUSIC().defeat();try{Class.forName("com.mysql.cj.jdbc.Driver");Connection conn= DriverManager.getConnection(url,username_mysql,password_mysql);String sql="INSERT INTO mark_table(username,mark) VALUES(?,?)";PreparedStatement ps=conn.prepareStatement(sql);ps.setString(1,username);ps.setInt(2,user_mark);ps.executeUpdate();ps.close();conn.close();//关闭数据库}catch (Exception e1){e1.printStackTrace();}try{mingci= new Check_mark().run_person(username);}catch (Exception a1){a1.printStackTrace();}g.drawString("游戏结束!您当前分数为"+user_mark,80,200);g.drawString("排行为"+mingci+"名",200,250);g.setColor(c);//恢复原前景色}else{g.setColor(Color.BLACK);g.fillOval(ballX,ballY,BALL_SIZE,BALL_SIZE);g.setColor(c);//恢复原前景色if (isTwo) {g.setColor(Color.PINK);//设置颜色g.fillOval(ballX2, ballY2, BALL_SIZE, BALL_SIZE);//画一个实心圆g.setColor(c);//恢复原前景色}//球拍g.setColor(Color.BLACK);g.fillRect(recketX,recketY,RACKET_WIDTH,RACKET_HEIGHT);//画一个实心长方体g.setColor(c);//恢复原前景色}}}MyCanvas drawArea=new MyCanvas();//新建画布对象public void init() throws Exception {//   System.out.println(username);
//触发音效System.out.println(username);File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Dungeon2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn= AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();//最关键的就是这一步操作我们设置监听然后每过100ms木板就会根据我们的按键改变横纵坐标//球拍坐标的变化KeyListener listener=new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();if (keyCode==KeyEvent.VK_LEFT){if(recketX>0)recketX-=20;}if(keyCode==KeyEvent.VK_RIGHT){if(recketX<(TABLE_WIDTH-RACKET_WIDTH))recketX+=20;}if (keyCode==KeyEvent.VK_SPACE&&count>0){if (RACKET_WIDTH==100)RACKET_WIDTH=10000;count--;}}};frame.addKeyListener(listener);drawArea.addKeyListener(listener);//判断小球是否已经碰壁或者碰到木板或者超出木板的范围ActionListener task=new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//速度修正if(ballX<=0||ballX>=(TABLE_WIDTH-BALL_SIZE)){//---------------------------------------------------------------try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}//触发音效//-----------------------------------------------------------------------speedX=-speedX;mark++;}if(ballY<=0||(ballY>recketY-BALL_SIZE&&ballX>recketX&&ballX<recketX+RACKET_WIDTH)){//---------------------------------------------------------------------try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}//触发音效//--------------------------------------------------speedY=-speedY;//碰撞到就等于反向速度mark++;}if (ballY>recketY-BALL_SIZE&&(ballX<recketX||ballX>recketX+RACKET_WIDTH)){//timer.stop();isOver=true;drawArea.repaint();//画布的重绘}//判断第二个小球if (isTwo){if(ballX2<=0||ballX2>=(TABLE_WIDTH-BALL_SIZE)){try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}speedX2=-speedX2;mark++;}if(ballY2<=0||(ballY2>recketY-BALL_SIZE&&ballX2>recketX&&ballX2<recketX+RACKET_WIDTH)){try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}speedY2=-speedY2;mark++;}if (ballY2>recketY-BALL_SIZE&&(ballX2<recketX||ballX2>recketX+RACKET_WIDTH)){isOver=true;drawArea.repaint();}ballX2+=speedX2;ballY2+=speedY2;}//更新坐标ballX+=speedX;ballY+=speedY;drawArea.repaint();}};//定时器javax.swing.Timer timer=new javax.swing.Timer(90,task);//定时器让他每一帧一帧重绘出来timer.start();frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});drawArea.setPreferredSize(new Dimension(TABLE_WIDTH,TABLE_HEIGHT));//设置最大尺寸frame.add(drawArea);Panel p=new Panel();p.setLayout(new FlowLayout(0));
//------------------------------头上显示标签-----------------------------------------------------------------------------JButton fanhui=new JButton("返回");JLabel label=new JLabel();JLabel mark_JLabel=new JLabel();JLabel speed_x=new JLabel();JLabel speed_y=new JLabel();JLabel count_mark=new JLabel();Timer time=new Timer();Timer time_mark=new Timer();//返回主界面监听事件fanhui.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {clip.close();try {timer.stop();time.cancel();time_mark.cancel();frame.dispose();Thread.sleep(300);new 主页面().run();} catch (Exception ex) {throw new RuntimeException(ex);}}});//这边是定时器,递增或递减速度time.schedule(new TimerTask() {@Overridepublic void run() {if (speedX>0){speedX+=2;}else{speedX-=2;}if (speedY>0){speedY+=2;}else {speedY-=2;}if (isTwo) {if (speedX2 > 0) {speedX2 += 2;} else {speedX2 -= 2;}if (speedY2 > 0) {speedY2 += 2;} else {speedY2 -= 2;}}guan++;label.setText("第"+guan+"关");if (guan==3)isTwo=true;}},100,3000);
//--------------------------标签更新---------------------------------------------------------time_mark.schedule(new TimerTask() {@Overridepublic void run() {mark_JLabel.setText("当前分数为" + mark);speed_x.setText("x速度为:" + speedX);speed_y.setText("y速度为:" + speedY);count_mark.setText("超级模式:" + count);if (isOver) {speedX = 0;speedY = 0;timer.stop();time.cancel();time_mark.cancel();}//-------------------这里有个技能能使木板边长,但是仅此只有一秒钟因此我们要延迟一秒就让其回复原样----if (RACKET_WIDTH == 10000) {{try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}RACKET_WIDTH = 100;}}},100,100);p.add(fanhui);p.add(count_mark);p.add(speed_x);p.add(speed_y);p.add(mark_JLabel);p.add(label);frame.setLocation(500,100);frame.add(p,BorderLayout.NORTH);frame.pack();frame.setResizable(false);//  frame.requestFocus();drawArea.requestFocus();frame.setVisible(true);}public static void main(String[] args) throws Exception {new prinBall().init();}}

3.双人合作模式

双人合作模式就和单人闯关一样的原理,只是代码有点长。超级模式也是在木板的右边无限延长需要用户来判断哪个时机适合接小球,核心内容万变不离其宗,我只是添加了两个画布然后两个监听就能实现本地双人游戏的进行,下面就简单展示一下:

在这点进去之前还是有一个需要输入用户名的界面

代码如下:

package JAVA_Lesson_Myprocess;import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class Double_Login {public  String username;public void init(){JFrame frame1=new JFrame("弹珠传说");JLabel label_uername=new JLabel("用户名称:");JButton jButton=new JButton("确定");JPanel panel=new JPanel();JTextField jTextField=new JTextField(8);jTextField.setMaximumSize(new Dimension(100,50));frame1.setLayout(new BorderLayout());panel.add(label_uername,BorderLayout.WEST);panel.add(jTextField,BorderLayout.CENTER);panel.add(jButton,BorderLayout.SOUTH);frame1.add(panel);jButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {username=jTextField.getText();System.out.println(username);try {Double_People p2=new Double_People();p2.setUsername(username);p2.init();frame1.dispose();} catch (Exception ex) {throw new RuntimeException(ex);}}});// frame1.setLocation(500,300);frame1.setBounds(500,300,300,100);frame1.setResizable(false);frame1.setVisible(true);}}

下面是双人合作的界面及源代码:

玩家先结束的一方会等到另一方结束才开始上传到数据库

package JAVA_Lesson_Myprocess;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.net.URI;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class Double_People {private static String url="jdbc:mysql://localhost:3306/ceshi";private int o=0;private int mingci;private static String username_mysql="root";private static String password_mysql="123456";private String username;private int count_over=0;public int user_mark;public void setUsername(String username) {this.username = username;}private JFrame frame=new JFrame("弹珠传说-双人合作");//判断是否第四关private  int count=5;private boolean isTwo=false;private boolean isbegin=false;public int mark=0;public  int guan=0;//桌面高度宽度private final int TABLE_WIDTH=500;private final  int TABLE_HEIGHT=700;//球拍高度宽度private   int RACKET_WIDTH=100;private final  int RACKET_HEIGHT=20;//小球大小private final int BALL_SIZE=30;//小球坐标//随机数出现坐标Random a=new Random();private int ballX=a.nextInt(200);private int ballY=a.nextInt(500);//第二个小球private int ballX2=a.nextInt(300);private int ballY2=a.nextInt(200);public int speedX2=5;public int speedY2=4;//小球速度public int speedX=5;public int speedY=6;//球拍的坐标private  int recketX=120;private final  int recketY=540;private boolean isOver=false;private static Image offScreenImage = null;//用于实现双缓冲//双人小游戏的第二个界面***************************************************************************************private int ballX_2=a.nextInt(200);private int ballY_2=a.nextInt(500);//第二界面的第二个小球---------------------------------------------------------------------------------private int ballX2_2=a.nextInt(300);private int ballY2_2=a.nextInt(200);//-----------------------------------------------------public int speedX_2=5;public int speedY_2=6;public int speedX_2_2=5;public int speedY_2_2=4;//球拍的坐标private  int recketX_2=120;private final  int recketY_2=540;private boolean isOver_2=false;//球拍的大小宽度private boolean isTwo_2=false;private   int RACKET_WIDTH_2=100;private final  int RACKET_HEIGHT_2=20;private static Image offScreenImage_2 = null;//用于实现双缓冲//开始画小球***********************************************************************************************private class MyCanvas extends Canvas{@Overridepublic void update(Graphics g) {if(offScreenImage == null) {offScreenImage = this.createImage(TABLE_WIDTH, TABLE_HEIGHT);//创建一张大小和窗口大小一样的虚拟图片}Graphics gOffScreen = offScreenImage.getGraphics();//获得画笔//刷新背景,否则物体运动痕迹会保留Color c = gOffScreen.getColor();gOffScreen.setColor(Color.white);gOffScreen.fillRect(0, 0,TABLE_WIDTH, TABLE_HEIGHT);gOffScreen.setColor(c);paint(gOffScreen);//画到虚拟图片上g.drawImage(offScreenImage, 0, 0, null);//把图片画到屏幕上}@Overridepublic void paint(Graphics g) {Color c = g.getColor();//取出原前景色g.setColor(Color.RED);//设置前景色if (isOver){//overcount_over++;if (count_over==2) {user_mark=mark;try {Class.forName("com.mysql.cj.jdbc.Driver");Connection conn = DriverManager.getConnection(url, username_mysql, password_mysql);String sql = "INSERT INTO double_people(username,mark) VALUES(?,?)";PreparedStatement ps = conn.prepareStatement(sql);ps.setString(1, username);ps.setInt(2, user_mark);ps.executeUpdate();ps.close();conn.close();} catch (Exception e1) {e1.printStackTrace();}g.setColor(Color.RED);g.setFont(new Font("Times",Font.BOLD,30));g.drawString("游戏结束!您当前的分数为"+mark,50,200);new MUSIC().defeat();try {mingci=new Check_mark().run(username);g.drawString("排第"+mingci+"名",150,250);} catch (Exception e) {throw new RuntimeException(e);}}else {g.setFont(new Font("Times",Font.BOLD,30));g.drawString("请等待另一个玩家结束",100,300);}g.setColor(c);//恢复原前景色}else{g.setColor(Color.BLACK);g.fillOval(ballX,ballY,BALL_SIZE,BALL_SIZE);g.setColor(c);//恢复原前景色if (isTwo) {g.setColor(Color.PINK);g.fillOval(ballX2, ballY2, BALL_SIZE, BALL_SIZE);g.setColor(c);//恢复原前景色}//球拍g.setColor(Color.BLACK);g.fillRect(recketX,recketY,RACKET_WIDTH,RACKET_HEIGHT);g.setColor(c);//恢复原前景色}}}//第二个界面private class MyCanvas_2 extends Canvas{@Overridepublic void update(Graphics g) {if(offScreenImage_2 == null) {offScreenImage_2 = this.createImage(TABLE_WIDTH, TABLE_HEIGHT);//创建一张大小和窗口大小一样的虚拟图片}Graphics gOffScreen_2 = offScreenImage_2.getGraphics();//获得画笔//刷新背景,否则物体运动痕迹会保留Color c = gOffScreen_2.getColor();gOffScreen_2.setColor(Color.white);gOffScreen_2.fillRect(0, 0,TABLE_WIDTH, TABLE_HEIGHT);gOffScreen_2.setColor(c);paint(gOffScreen_2);//画到虚拟图片上g.drawImage(offScreenImage_2, 0, 0, null);//把图片画到屏幕上}@Overridepublic void paint(Graphics g) {Color c = g.getColor();//取出原前景色g.setColor(Color.RED);//设置前景色if (isOver_2){//overcount_over++;if (count_over==2) {user_mark=mark;try {Class.forName("com.mysql.cj.jdbc.Driver");Connection conn = DriverManager.getConnection(url, username_mysql, password_mysql);String sql = "INSERT INTO double_people(username,mark) VALUES(?,?)";PreparedStatement ps = conn.prepareStatement(sql);ps.setString(1, username);ps.setInt(2, user_mark);ps.executeUpdate();ps.close();conn.close();} catch (Exception e1) {e1.printStackTrace();}g.setColor(Color.RED);g.setFont(new Font("Times",Font.BOLD,30));g.drawString("游戏结束!您当前的分数为"+mark,50,200);new MUSIC().defeat();try {mingci=new Check_mark().run(username);g.drawString("排第"+mingci+"名",150,250);} catch (Exception e) {throw new RuntimeException(e);}}else {g.setFont(new Font("Times",Font.BOLD,30));g.drawString("请等待另一个玩家结束",100,300);}//  g.drawString("排第"+"454"+"名",200,250);g.setColor(c);//恢复原前景色}else{g.setColor(Color.BLACK);g.fillOval(ballX_2,ballY_2,BALL_SIZE,BALL_SIZE);g.setColor(c);//恢复原前景色if (isTwo_2) {g.setColor(Color.PINK);g.fillOval(ballX2_2, ballY2_2, BALL_SIZE, BALL_SIZE);g.setColor(c);//恢复原前景色}//球拍g.setColor(Color.BLACK);g.fillRect(recketX_2,recketY_2,RACKET_WIDTH_2,RACKET_HEIGHT_2);g.setColor(c);//恢复原前景色}}}MyCanvas drawArea=new MyCanvas();MyCanvas_2 drawArea_2=new MyCanvas_2();//--------------------------------------------------------------------------------------------------------------------------------public void init() throws Exception {System.out.println(username);File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Dungeon2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn= AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();//球拍坐标的变化KeyListener listener=new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();switch (keyCode){case KeyEvent.VK_A:if(recketX>0)recketX-=30;break;case KeyEvent.VK_D:if(recketX<(TABLE_WIDTH-RACKET_WIDTH))recketX+=30;break;case KeyEvent.VK_SPACE:if (RACKET_WIDTH==100&&count>0)RACKET_WIDTH=10000;count--;break;}}};//球拍2坐标的变化KeyListener listener_2=new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();switch (keyCode) {case KeyEvent.VK_LEFT:if (recketX_2 > 0)recketX_2 -= 30;break;case KeyEvent.VK_RIGHT:if (recketX_2 < (TABLE_WIDTH - RACKET_WIDTH_2))recketX_2 += 30;break;case KeyEvent.VK_ENTER:if (RACKET_WIDTH_2 == 100 && count > 0)RACKET_WIDTH_2 = 10000;count--;break;}}};//zhuceframe.addKeyListener(listener);frame.addKeyListener(listener_2);drawArea.addKeyListener(listener);drawArea_2.addKeyListener(listener_2);//ball----------------------------------------------one----------------------------------------------------ActionListener task=new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//速度修正if(ballX<=0||ballX>=(TABLE_WIDTH-BALL_SIZE)){//---------------------------------------------------------------try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}//-----------------------------------------------------------------------speedX=-speedX;mark++;}if(ballY<=0||(ballY>recketY-BALL_SIZE&&ballX>recketX&&ballX<recketX+RACKET_WIDTH)){//---------------------------------------------------------------------try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}//--------------------------------------------------speedY=-speedY;mark++;}if (ballY>recketY-BALL_SIZE&&(ballX<recketX||ballX>recketX+RACKET_WIDTH)){//timer.stop();isOver=true;drawArea.repaint();}//判断第二个小球if (isTwo){if(ballX2<=0||ballX2>=(TABLE_WIDTH-BALL_SIZE)){try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}speedX2=-speedX2;mark++;}if(ballY2<=0||(ballY2>recketY-BALL_SIZE&&ballX2>recketX&&ballX2<recketX+RACKET_WIDTH)){try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}speedY2=-speedY2;mark++;}if (ballY2>recketY-BALL_SIZE&&(ballX2<recketX||ballX2>recketX+RACKET_WIDTH)){isOver=true;drawArea.repaint();}ballX2+=speedX2;ballY2+=speedY2;}//更新坐标ballX+=speedX;ballY+=speedY;
//                if (isTwo)
//                drawArea.repaint();drawArea.repaint();}};//第二个界面的定时任务*-----------------------------------------------------------------------**************************ActionListener task_2=new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {//速度修正if(ballX_2<=0||ballX_2>=(TABLE_WIDTH-BALL_SIZE)){//---------------------------------------------------------------try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}//-----------------------------------------------------------------------speedX_2=-speedX_2;mark++;}if(ballY_2<=0||(ballY_2>recketY_2-BALL_SIZE&&ballX_2>recketX_2&&ballX_2<recketX_2+RACKET_WIDTH_2)){//---------------------------------------------------------------------try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}//--------------------------------------------------speedY_2=-speedY_2;mark++;}if (ballY_2>recketY_2-BALL_SIZE&&(ballX_2<recketX_2||ballX_2>recketX_2+RACKET_WIDTH_2)){//timer.stop();isOver_2=true;drawArea_2.repaint();}//判断第二个小球if (isTwo_2){if(ballX2_2<=0||ballX2_2>=(TABLE_WIDTH-BALL_SIZE)){try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}speedX_2_2=-speedX_2_2;mark++;}if(ballY2_2<=0||(ballY2_2>recketY_2-BALL_SIZE&&ballX2_2>recketX_2&&ballX2_2<recketX_2+RACKET_WIDTH_2)){try {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\Absorb2.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn=AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();}catch (Exception a){a.printStackTrace();}speedY_2_2=-speedY_2_2;mark++;}if (ballY2_2>recketY_2-BALL_SIZE&&(ballX2_2<recketX_2||ballX2_2>recketX_2+RACKET_WIDTH_2)){isOver=true;drawArea_2.repaint();}ballX2_2+=speedX_2_2;ballY2_2+=speedY_2_2;}//更新坐标ballX_2+=speedX_2;ballY_2+=speedY_2;
//                if (isTwo)
//                drawArea.repaint();drawArea_2.repaint();}};//定时器JPanel p1=new JPanel();JPanel p2=new JPanel();javax.swing.Timer timer=new javax.swing.Timer(100,task);javax.swing.Timer timer_2=new javax.swing.Timer(100,task_2);new Thread(new Runnable() {@Overridepublic void run() {timer_2.start();}}).start();new Thread(new Runnable() {@Overridepublic void run() {timer.start();}}).start();frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});drawArea.setPreferredSize(new Dimension(TABLE_WIDTH,TABLE_HEIGHT));drawArea_2.setPreferredSize(new Dimension(TABLE_WIDTH,TABLE_HEIGHT));p1.add(drawArea);p2.add(drawArea_2);frame.setLayout(new BorderLayout(10,30));frame.add(p1,BorderLayout.WEST);frame.add(p2,BorderLayout.EAST);Panel p=new Panel();//------------------------------头上显示标签-----------------------------------------------------------------------------JLabel label=new JLabel();JLabel mark_JLabel=new JLabel();JLabel speed_x=new JLabel();JLabel speed_y=new JLabel();JLabel count_mark=new JLabel();Timer time=new Timer();Timer time_mark=new Timer();JButton fanhui=new JButton("返回");JLabel jLabel_kong=new JLabel("                                                                                               ");fanhui.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {clip.close();try {timer.stop();timer_2.stop();frame.dispose();Thread.sleep(300);new 主页面().run();} catch (Exception ex) {throw new RuntimeException(ex);}}});time.schedule(new TimerTask() {@Overridepublic void run() {if (speedX>0){speedX+=2;}else{speedX-=2;}if (speedY>0){speedY+=2;}else {speedY-=2;}if (isTwo) {if (speedX2 > 0) {speedX2 += 2;} else {speedX2 -= 2;}if (speedY2 > 0) {speedY2 += 2;} else {speedY2 -= 2;}}if (speedX_2>0){speedX_2+=2;}else{speedX_2-=2;}if (speedY_2>0){speedY_2+=2;}else {speedY_2-=2;}if (isTwo) {if (speedX_2_2 > 0) {speedX_2_2 += 2;} else {speedX_2_2 -= 2;}if (speedY_2_2> 0) {speedY_2_2+= 2;} else {speedY_2_2-= 2;}}guan++;label.setText("第"+guan+"关");if (guan==3){   isTwo=true;isTwo_2=true;}}},100,3000);
//--------------------------标签更新---------------------------------------------------------time_mark.schedule(new TimerTask() {@Overridepublic void run() {mark_JLabel.setText("当前分数为" + mark);speed_x.setText("x速度为:" + speedX);speed_y.setText("y速度为:" + speedY);count_mark.setText("超级模式:" + count);if (isOver) {speedX = 0;speedY = 0;timer.stop();}if(isOver_2){timer_2.stop();speedX_2 = 0;speedY_2 = 0;}if (isOver&&isOver_2){time.cancel();time_mark.cancel();}//-----------------------if (RACKET_WIDTH == 10000) {{try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}RACKET_WIDTH = 100;}if (RACKET_WIDTH_2 == 10000) {{try {Thread.sleep(1000);} catch (InterruptedException a) {throw new RuntimeException(a);}}RACKET_WIDTH_2 = 100;}}},0,100);p.setLayout(new FlowLayout(0));p.add(fanhui);p.add(jLabel_kong);p.add(count_mark);p.add(speed_x);p.add(speed_y);p.add(mark_JLabel);p.add(label);///-------------------------------------------标签说明----------------------------------------------------------JPanel explain=new JPanel();;JLabel jLabel_explain=new JLabel("<html><body>"+"按键说明:"+"<br/>"+"玩家1 左(p1):A键+D键+空格键"+"<br/>"+"玩家2 右(p2):←键 + →键+Enter键"+"<body></html>");// JLabel jLabel_explain_p2=new JLabel("p2:← → Enter");// explain.setSize(50,50);// explain.add(jLabel_explain_p2);explain.add(jLabel_explain);frame.add(explain,BorderLayout.SOUTH);frame.add(p,BorderLayout.NORTH);frame.pack();// frame.requestFocus();Timer time_3=new Timer();time_3.schedule(new TimerTask() {@Overridepublic void run() {if (count_over==2)time_3.cancel();if (o==1) {drawArea.requestFocus();o=0;}else{drawArea_2.requestFocus();o=1;}System.out.println(o);}},0,60);frame.setLocation(500,100);frame.setResizable(false);frame.setVisible(true);}}

4.数据库连接与操作

在这成绩上传到数据库之前记得要设置好数据库,由于单人闯关模式和双人合作模式在结束时都会显示排名,因此我们需要新建一个类来调用它的方法遍历数据库的内容再对成绩排序,然后遍历每个数组找到相符合的用户名再返回相关排名,一般情况下我们是放到一个二维数组里面去的

接下来就是代码展示

package JAVA_Lesson_Myprocess;
import javax.swing.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Arrays;
import java.util.Comparator;
public class Check_mark {public int run_person(String user) throws Exception{String url = "jdbc:mysql://localhost:3306/ceshi";String username = "root";String password = "123456";Class.forName("com.mysql.cj.jdbc.Driver");JFrame frame = new JFrame("排行榜");JPanel panel = new JPanel();JLabel label_1 = new JLabel("单人闯关排行榜");JLabel label_2 = new JLabel("双人合作排行榜");Object[] titles = {"排名", "用户名", "成绩"};Connection conn = DriverManager.getConnection(url, username, password);//连接数据库String sql = "SELECT * FROM mark_table";//选择表Statement stat = conn.createStatement();ResultSet rs = stat.executeQuery(sql);// ResultSet rs_2=stat.executeQuery(sql);
//查询所有的数据,先遍历一共有几行int line=0;while (rs.next()) {line++;}rs.close();rs = stat.executeQuery(sql);//清空之后回到原点先将数据存储在数组中Object[][] data = new Object[line][];for (int i = 0; rs.next(); i++) {// number = i + 1;data[i] = new Object[]{0, rs.getString("username"), rs.getInt("mark"),};}rs.close();Arrays.sort(data, new Comparator<Object[]>() {@Overridepublic int compare(Object[] o1, Object[] o2) {return (Integer) o2[2]-(Integer)o1[2];}});//定义一个二维数组的比较器 降序排序for (int i = 0; i < line; i++) {data[i][0]=i+1;}//重新给它排名赋值for (int i = 0; i < line; i++) {if (user.equals(data[i][1])){return (Integer) data[i][0];//查询相符合的用户名称就返回}}return 0;}public int run (String user) throws Exception {String url = "jdbc:mysql://localhost:3306/ceshi";String username = "root";String password = "123456";Class.forName("com.mysql.cj.jdbc.Driver");JFrame frame = new JFrame("排行榜");JPanel panel = new JPanel();JLabel label_1 = new JLabel("单人闯关排行榜");JLabel label_2 = new JLabel("双人合作排行榜");Object[] titles = {"排名", "用户名", "成绩"};Connection conn = DriverManager.getConnection(url, username, password);String sql = "SELECT * FROM mark_table";Statement stat = conn.createStatement();int line = 0, number;number = 0;conn = DriverManager.getConnection(url, username, password);ResultSet rs = stat.executeQuery(sql);sql = "SELECT * FROM Double_people";stat = conn.createStatement();rs = stat.executeQuery(sql);// ResultSet rs_2=stat.executeQuery(sql);line = 0;while (rs.next()) {line++;}System.out.println(line);rs.close();rs = stat.executeQuery(sql);Object[][] data_2 = new Object[line][];for (int i = 0; rs.next(); i++) {// number = i + 1;data_2[i] = new Object[]{0, rs.getString("username"), rs.getInt("mark"),};}rs.close();Arrays.sort(data_2, new Comparator<Object[]>() {@Overridepublic int compare(Object[] o1, Object[] o2) {return (Integer) o2[2]-(Integer)o1[2];}});for (int i = 0; i < line; i++) {data_2[i][0]=i+1;}for (int i = 0; i < line; i++) {if (user.equals(data_2[i][1])){return (Integer) data_2[i][0];}}return 0;}
}

5.数据库连接,排行榜

Navicat 管理mysql

排行榜界面

代码展示如下,上面的原理都讲过了,看一下就能懂

package JAVA_Lesson_Myprocess;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.sql.*;
import java.util.Arrays;
import java.util.Comparator;
public class Mark_user {public void run()throws Exception {File file=new File("C:\\Users\\Lenovo\\Desktop\\Music\\排行榜音效.wav");URI uri=file.toURI();System.out.println(uri);AudioInputStream audioIn= AudioSystem.getAudioInputStream(file);Clip clip=AudioSystem.getClip();clip.open(audioIn);clip.start();int line = 0, number;String url = "jdbc:mysql://localhost:3306/ceshi";String username = "root";String password = "123456";Class.forName("com.mysql.cj.jdbc.Driver");JFrame frame = new JFrame("排行榜");JPanel panel = new JPanel();JLabel label_1 = new JLabel("单人闯关排行榜");JLabel label_2 = new JLabel("双人合作排行榜");Object[] titles = {"排名", "用户名", "成绩"};Connection conn = DriverManager.getConnection(url, username, password);String sql = "SELECT * FROM mark_table";Statement stat = conn.createStatement();ResultSet rs = stat.executeQuery(sql);// ResultSet rs_2=stat.executeQuery(sql);frame.setResizable(false);while (rs.next()) {line++;}rs.close();rs = stat.executeQuery(sql);Object[][] data = new Object[line][];for (int i = 0; rs.next(); i++) {// number = i + 1;data[i] = new Object[]{0, rs.getString("username"), rs.getInt("mark"),};}rs.close();//SORTArrays.sort(data, new Comparator<Object[]>() {@Overridepublic int compare(Object[] o1, Object[] o2) {return (Integer) o2[2]-(Integer)o1[2];}});for (int i = 0; i < line; i++) {data[i][0]=i+1;}number = 0;conn = DriverManager.getConnection(url, username, password);sql = "SELECT * FROM Double_people";stat = conn.createStatement();rs = stat.executeQuery(sql);// ResultSet rs_2=stat.executeQuery(sql);line = 0;while (rs.next()) {line++;}//先确定一共有几行System.out.println(line);rs.close();//重启 因为要从原点出发rs = stat.executeQuery(sql);Object[][] data_2 = new Object[line][];for (int i = 0; rs.next(); i++) {data_2[i] = new Object[]{0, rs.getString("username"), rs.getInt("mark"),};}rs.close();Arrays.sort(data_2, new Comparator<Object[]>() {@Overridepublic int compare(Object[] o1, Object[] o2) {return (Integer) o2[2]-(Integer)o1[2];}});for (int i = 0; i < line; i++) {data_2[i][0]=i+1;}conn.close();stat.close();rs.close();panel.setLayout(new FlowLayout(0));javax.swing.JTable jTable = new javax.swing.JTable(data, titles);javax.swing.JTable jTable_2 = new javax.swing.JTable(data_2, titles);JPanel Panel_1=new JPanel();JLabel kong=new JLabel("                                    ");JLabel kong_2=new JLabel("                                                              ");Panel_1.setLayout(new FlowLayout(0));JButton jButton=new JButton("返回");jButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {try {clip.close();clip.flush();audioIn.close();frame.dispose();} catch (IOException ex) {throw new RuntimeException(ex);}try {Thread.sleep(300);new 主页面().run();} catch (Exception ex) {throw new RuntimeException(ex);}}});Panel_1.add(jButton);Panel_1.add(kong);Panel_1.add(label_1);panel.add(Panel_1);panel.add(new JScrollPane(jTable));panel.add(kong_2);panel.add(label_2);panel.add(new JScrollPane(jTable_2));frame.add(panel);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(500, 1000);frame.setLocation(500,20);frame.setVisible(true);}}

五、总结

把每份代码都复制下来放到同一个包里面,改改数据库连接,音乐文件路径,就能运行。通过本次的课设实践使我更加认识java的实用性,本次使用的版本为JDK17。从界面的绘画、音效素材的寻找与设置、游戏关卡设置、数据库连接,让我更加对一整个游戏体系有了不一样的认识,再者每当我调试自己亲手做的游戏时都会有一种喜悦的心情,我体会到了作为开发者的乐趣。一开始我是使用AWT来绘画的,但是由于画面太过于闪烁于是我找遍各种论坛,经过一下午的学习我了解到了计算机图形基础—双缓存原理。从概念到实践我终于在程序中使用了双缓冲的技术,这是我在本次开发以来最为开心的一件事。游戏音效则是通过RPG Maker MZ一个RPG 的游戏引擎的音效素材库来寻找的,通过事件监听,来使小球碰撞发出声音,给用户一种身临其境的感受。每当用户接不到小球结束时我们设置的是victory的音效,因为在我们看来每个人都是成功的,我们选择音效时都有不同的含义。数据库连接则是通过JTable来实现的,通过一个二维数组和我们对二维数组进行排列来使得内容呈降序呈现,再放入到JTable中。还有就是JFrame的布局,我们采用最多的就是流体式布局和绝对布局,再这布局中我们了解到了每一个组件。

大一下期末javaGUI课设之swing+MYSQL实现“弹珠传说”弹球小游戏相关推荐

  1. 飞机订票系统 python实现(大二上数据结构课设)

    说明: 本博客是从课设报告中截取的重要部分.这个飞机订票系统是本人大二上的数据结构课设,功能相对完善,界面相对美观.图形界面,本来想用Qt5(python中一个图形界面的类库,风格偏向于win10)去 ...

  2. 【C++期末大作业】数据结构课设 | 智能公交车查询系统

    补发一下老东西(未优化) 目录 设计具体内容: 功能模块图: 各模块流程图: 运行效果图: 源码: 设计具体内容: 应用相关数据结构及算法,设计并实现一个具有查询功能的城市公交查询系统.设计其信息数据 ...

  3. Java课设之Swing学生信息管理系统(源码)

    前言: 这是我学java时,写的一个练手项目,主要用来巩固知识,还有很多地方并不完善,有很多不足之处,仅供参考. 另外,如果直接按着我的代码敲很可能会出现bug.这大概率时JDK或MySQL的版本问题 ...

  4. 『收藏向 期末SSM课设救急』 教你从搭建到测试运行手撸一个SSM项目实战,附带源码,前端页面、解析和一般遇到的问题(排雷)

  5. 医药管理系统(大一下C语言课设)

    医院药品管理系统 基本内容 实现了账号的注册,登陆,找回密码和修改密码,药品信息包括药品名,编号,类型,成本,价格和数量.可以对药品进行增删改查,可以对药品进行排序. 关键代码 while (scan ...

  6. 『Java课设』JavaSwing+MySQL实现医院智慧点餐系统

  7. 数据库课设--基于Python+MySQL的餐厅点餐系统

    文章目录 一.系统需求分析 二.系统设计 1. 功能结构设计 2.概念设计 2.2.1 bill_food表E-R图 2.2.2 bills表E-R图 2.2.3 categories E-R图 2. ...

  8. (毕设课设)基于SSM的食堂订餐小程序(微信小程序+后台管理系统)

    本系统基于SSM的食堂订餐小程序系统的设计与实现的过程,运用了B/S架构,JAVA的SSM框架,前后端分离等设计模式,使用了mysql管理数据库,微信开发者工具开发小程序前端,eclipse开发系统后 ...

  9. Java Swing编写的一个猜拳小游戏

    18年在学校时候写的,整理目录发现的,这个游戏当时是模仿一个微信小程序 效果截图: 里面所用到的四张图片放在百度云: 链接:https://pan.baidu.com/s/1pnbcOCDpHzA-h ...

最新文章

  1. oracle log block size,案例:Oracle无法启动报错ORA-00218: block size 0 重建控制文件
  2. opencv_python 读取4通道png图片
  3. mysql killed 不掉,解决:kernel: Out of memory: Killed process 15967, UID 27, (mysqld).
  4. php 订单取消,php – 当订单状态从挂起更改为已取消时发送电子邮件通知
  5. javaweb学习总结(四十三)——Filter高级开发
  6. delphi中combobox键值对
  7. junit版本_Junit-jupiter-api 和 junit-jupiter-engine 的区别是什么
  8. Maven - 继承和聚合
  9. linux文件删除恢复
  10. Unity3D手游开发日记(6) - 适合移动平台的水深处理
  11. iphone怎么重启_iPhone看完这个都要卡死机!这串神秘代码,是真的有毒
  12. 转载一个 mui 等待动画 mui.showLoading
  13. 导航网站合集 | 你想要的资源它都有
  14. 解决问题#Word导出PDF出现空白页
  15. 发现一个提供免费英文软件类书籍的网站[xgluxv]
  16. 【转1】 OpenWrt Chaos Calmer 15.05使用mwan3单线多拨教程
  17. ajax加载txt文件,ajax读取txt文件
  18. 苹果id是什么格式的_可以修改微信号了,怎样起一个好看又好记的微信号ID?...
  19. 使用uniapp编写词霸每日一句页面
  20. Joel Spolsky在耶鲁大学的演讲

热门文章

  1. 暴力匹配与FLANN
  2. iconfont通过font class引入显示小方块bug
  3. NR/5G - URLLC UL
  4. 303_S32K144运行模式切换
  5. php计算器按钮功能,php实现计算器功能的案例
  6. 【HTML】简易计算器
  7. MFC CString转换为char*
  8. mate10pro android9,华为Mate10 pro和mate9 pro哪个好?华为mate9pro和Mate10pro对比区别评测...
  9. 通讯行业SRM供应商协同管理系统:平台数据信息共享,助力供应商系统降本增效
  10. [转]女孩,看完之后请别流下幸福的眼泪(图组)