弹球游戏分步解析(二)——让小球飞
之前跟大家说要把事件监听器和多线程分开来讲,不过之后发现事件监听器要涉及到很多小球运动的操作,所以,决定将两个知识点合起来说,这样会更便于大家理解:
实现小球在我们所绘制的窗体上运动就必须要用到多线程;让小球类继承Thread类,再重写void run(){}方法即可;
先上代码:
(注:浅蓝色字体不是本节要讲的内容,可以忽略)
package jumpingBall;
import java.awt.Color;
import java.awt.Graphics;
import java.util.List;
import java.util.Random;
import javax.swing.JPanel;
//小球类是此游戏的关键,我们首先要分析他应该具备什么样的属性,实现什么样的方法
public class BallThread extends Thread {
private static final int North = 1;//用四个整形的数据代表四个方向
private static final int West = 2;
private static final int South = 3;
private static final int East = 4;
private int Xdirection = West;//记录小球在X轴上的方向
private int Ydirection = North;//记录小球在y轴上的方向
private int radios;//半径
private Color color;//颜色
private int Xspeed;//x方向速度
private int Yspeed;//y方向速度
private int X;//当前位置x
private int Y;//当前位置y
private int LastX;//最后位置x
private int LastY;//最后位置y
private int xband;
private int yband;
private JPanel jp;//面板
private Graphics g;//画布
private boolean pauseFlag = false;//暂停标志(默认值否)
private boolean stopFlag = false;//停止标志(false——表示存在)
private boolean beread = false;//是否被储存在文件里过(默认值否)
public BallThread(JPanel jp){
this.jp = jp;
this.g = jp.getGraphics();
}
public void run(){
banLlistener band =new banLlistener(jp);//定义滑块
jp.addMouseMotionListener(band);//给滑块加入鼠标监听器
if(beread==false){//如果没有被储存在文件里过
this.setprivate();//方法作用:随机生成它的部分属性
}
//实现小球运动的思路为:才窗体上沿小球运动路线不断绘制小球,并将之前的小球擦掉
while(true){//永真表示球会一直运动
try{
sleep(30);
}catch(InterruptedException e){
e.printStackTrace();
}
if(stopFlag==true){//如果停止标示为true,停止该线程
clearBall();
return;
}
if(pauseFlag==true){//如果暂停标示为真,跳过之后的步骤进入下次循环
continue;
}
this.clearBall();//清除原来位置的小球
this.move();//小球运动
this.drawBall();//在新的位置画出小球
}
}
public void clearBall(){//清除小球
Color color = jp.getBackground();//
g.setColor(color);//
g.fillOval(X, Y, radios*2, radios*2);//用背景色,填充之前小球的印记
}
public void drawBall(){
g.setColor(color);//
g.fillOval(X, Y, radios*2, radios*2);
}
public void setprivate(){//设置小球属性
Random random = new Random();//随机
radios = 10+random.nextInt(10);//半径
color=newColor(random.nextInt(255),random.nextInt(255),random.nextInt(255));//颜色
Xspeed = 2 + random.nextInt(10);//x方向速度
Yspeed = 2+random.nextInt(10);//y方向速度
}
public void exit(boolean flag){//设置停止标示
stopFlag = flag;
}
public void setpause(boolean flag){//设置暂停标示
pauseFlag = flag;
}
public void move(){//让我们的小球在面板中飞起来,同时碰到边界被弹回
switch(Xdirection){//对于x方向
case 2:X = X - Xspeed;break;//如果小球的运动方向向西,X值减小
case 4:X = X + Xspeed;break;//如果小球的运动方向向东,X值增大
}
switch(Ydirection){//对于y方向
case 1:Y = Y - Yspeed;break;//如果小球的运动方向向北,Y值减小
case 3:Y = Y + Yspeed;break;//如果小球的运动方向向难,Y值增大
}
//如果碰到边界,方向改变
if(X<0+radios*2){
Xdirection = 4;
}
if(X>jp.getWidth()-radios*2){
Xdirection = 2;
}
if(Y<0+radios*2){
Ydirection = 3;
}
//如果掉到下面,该小球线程结束
if(Y>jp.getHeight()-radios*2){
//Ydirection = 1;
BallThread ball = new BallThread(jp);
this.exit(true);
for(int i = 0;i<Date.allBall.size();i++){
ball=Date.allBall.get(i);
if(X == ball.X&&Y == ball.Y){
Date.allBall.remove(i);
}
}
}
//如果碰到滑块,弹回
if(Y<500+radios/2&&Y>490-radios*2&&X>=Date.xband&&X<=(Date.xband+100)){
Ydirection = 1;
}
}
//下面全是get和set方法(定义以下方法主要在文件操作时用到):
public int getXdirection() {
return Xdirection;
}
public void setXdirection(int xdirection) {
Xdirection = xdirection;
}
public int getYdirection() {
return Ydirection;
}
public void setYdirection(int ydirection) {
Ydirection = ydirection;
}
public int getRadios() {
return radios;
}
public void setRadios(int radios) {
this.radios = radios;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getXspeed() {
return Xspeed;
}
public void setXspeed(int xspeed) {
Xspeed = xspeed;
}
public int getYspeed() {
return Yspeed;
}
public void setYspeed(int yspeed) {
Yspeed = yspeed;
}
public int getX() {
return X;
}
public void setX(int x) {
X = x;
}
public int getY() {
return Y;
}
public void setY(int y) {
Y = y;
}
public int getLastX() {
return LastX;
}
public void setLastX(int lastX) {
LastX = lastX;
}
public int getLastY() {
return LastY;
}
public void setLastY(int lastY) {
LastY = lastY;
}
public int getXband() {
return xband;
}
public void setXband(int xband) {
this.xband = xband;
}
public int getYband() {
return yband;
}
public void setYband(int yband) {
this.yband = yband;
}
public boolean isPauseFlag() {
return pauseFlag;
}
public boolean savePauseFlag() {
return false;
}
public void setPauseFlag(boolean pauseFlag) {
this.pauseFlag = pauseFlag;
}
public boolean isStopFlag() {
return stopFlag;
}
public void setStopFlag(boolean stopFlag) {
this.stopFlag = stopFlag;
}
public boolean isBeread() {
return beread;
}
public void setBeread(boolean beread) {
this.beread = beread;
}
public boolean saveBeread() {
return true;
}
public JPanel getJp() {
return jp;
}
public void setJp(JPanel jp) {
this.jp = jp;
}
}
定义了小球类之后,我们要考虑的另一个问题就是,我们什么时候要让小球在界面上飞,作为一个游戏,至少需要有开始按钮,当按钮被触发,游戏开始,所以我们需要用到的另一个工具就是事件监听器:
除了开始按钮,我们还为这个游戏做了其他功能:暂停,加一球,减一球;
接下来是代码:
文件一:Date,将小球使用一个链表存起来:
package jumpingBall;
import java.util.ArrayList;
import java.util.List;
public class Date {//此类专门存放全局变量
public static int xband;
public static int yband;
public static List<BallThread> allBall = new ArrayList<BallThread>();//将链表声明为全局变量
}
package jumpingBall;
import java.awt.event.ActionEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import sun.net.www.content.audio.x_aiff;
public class ActionListener implements java.awt.event.ActionListener{
//private List<BallThread> allBall = new ArrayList<BallThread>();
private JPanel jpanel;
private int xband;
private int yband;
public ActionListener(JPanel jpanel){//构造方法
//this.allBall = allBall;
this.jpanel = jpanel;
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String cmd = e.getActionCommand(); //
//选择开始选择
if(cmd.equals("Play")){
//如果场上没球,添加一个
if(Date.allBall.size()==0){
BallThread ball = new BallThread(jpanel);
Date.allBall.add(ball);
ball.start();
System.out.println("增加一个小球,场上小球个数变为:"+Date.allBall.size());
}
//如果场上有球,让所有静止的球动起来
for(int i = 0;i<Date.allBall.size();i++){
BallThread ball= Date.allBall.get(i);
ball.setpause(false);
}
// banLlistener band = new banLlistener(jpanel);
//jpanel.addMouseMotionListener(band);
}
//选择暂停选项
if(cmd.equals("Pause")){
//遍历场上所有小球,修改ball的pause属性
for(int i = 0;i<Date.allBall.size();i++){
BallThread ball= Date.allBall.get(i);
ball.setpause(true);
}
}
//选择增球
if(cmd.equals("Add")){
BallThread ball = new BallThread(jpanel);
Date.allBall.add(ball);
ball.start();//运行线程
System.out.println("增加一个小球,场上小球个数变为:"+Date.allBall.size());
}
//选择减一球选项
if(cmd.equals("Delet one ball")&&Date.allBall.size()!=0){
BallThread ball = Date.allBall.get(Date.allBall.size()-1);
ball.exit(true);//修改存在选项(设置其消失)
Date.allBall.remove(Date.allBall.size()-1);//减一球
System.out.println("减少一个小球,场上小球个数变为:"+Date.allBall.size());
}
}
}
此外还要在界面类中敲上以下代码(黑色加粗部分)
//javax.swing.JFileChooser使用此来选择文件
package jumpingBall;
import java.awt.Toolkit;
import java.awt.BorderLayout;
import java.awt.Menu;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSeparator;
public class JFjumpingBall extends JFrame{
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
JFjumpingBall ballgame = new JFjumpingBall();
ballgame.JFshow();
}
public void JFshow(){
//建立一个窗体:
double width = Toolkit.getDefaultToolkit().getScreenSize().width;//定义width获取显示器在该分辨率下的宽
double height = Toolkit.getDefaultToolkit().getScreenSize().height;//定义height获取显示器在该分辨率下的高
this.setSize((int)width,(int)height);//设置窗体大小
this.setTitle("小鱼躲气泡");//设置标题
this.setLocationRelativeTo(null);//设置窗口居中
this.setDefaultCloseOperation(3);//设置关闭窗口程序停止运行
this.setLayout(new BorderLayout());//设置窗体布局(边框式布局)
JPanel northPanel = new JPanel();//北部面板
JPanel jpanel = new JPanel();//面板
JPanel southjpanel = new JPanel();//南部面板
northPanel.setLayout(new BorderLayout());//设置北部面板布局方式
JPanel northLeftPanel = new JPanel();//北部面板左边
JPanel northRightPanel = new JPanel();//……右边
JPanel northCenterPanel = new JPanel();//……中间
northLeftPanel.setSize(100,100); //
northRightPanel.setSize(100, 100);//
JButton jbplay = new JButton("Play");//放置游戏按钮(开始游戏)
JButton jbPause = new JButton("Pause");//放置游戏按钮(游戏暂停)
JButton jbAdd = new JButton("Add");//放置游戏按钮(增加)
JButton deletone = new JButton("Delet one ball");//放置游戏按钮(减少一个小球)
northCenterPanel.add(jbplay);//将按钮放置在北部面板的中间面板
northCenterPanel.add(jbPause);//同上
northCenterPanel.add(jbAdd);//同上
northCenterPanel.add(deletone);//同上
northPanel.add(northCenterPanel,BorderLayout.CENTER);//将北部面板的各部分面板加在北部面板里
northPanel.add(northLeftPanel,BorderLayout.WEST);//
northPanel.add(northRightPanel,BorderLayout.EAST);//
this.add(northPanel,BorderLayout.NORTH);//布置窗体
this.add(jpanel,BorderLayout.CENTER);//
this.add(southjpanel,BorderLayout.SOUTH);//
this.setJMenuBar(JMenuline(jpanel));//给窗体添加菜单栏(菜单栏方法:JMenuline;方法声明在下部)
this.setVisible(true);//设置窗体可见
//List<BallThread> allBall = new ArrayList<BallThread>();//
ActionListener l = new ActionListener(jpanel);//动作监听器
jbplay.addActionListener(l);//jbplay添加动作监听器
jbPause.addActionListener(l);//jbPause添加动作监听器
jbAdd.addActionListener(l);//jbAdd添加动作监听器
deletone.addActionListener(l);//delete添加动作监听器
}
public JMenuBar JMenuline(JPanel jpanel){
JMenuBar jme =new JMenuBar();//定义菜单栏
JMenu menuF = new JMenu("文件(F)");//菜单栏按钮
JMenuItem jmiFO = new JMenuItem("保存(save)");//定义菜单栏按钮的选项(保存)
JMenuItem jmiIO = new JMenuItem("读取(login)");//定义菜单栏按钮的选项(读取)
foListener listener = new foListener();//定义保存监听器
ioListener listener2 = new ioListener(jpanel);//定义读取监听器
jmiFO.addActionListener(listener);//将保存监听器加在jmiFO
jmiIO.addActionListener(listener2);//将读取监听器加在jmiIO
menuF.add(jmiFO);//将(保存)菜单栏按钮加在menuF里
JSeparator jSeparator = new JSeparator();//定义水平分割线
menuF.add(jSeparator);//将水平分割线加在menuF里
menuF.add(jmiIO);//将(读取)菜单栏按钮加在menuF里
jme.add(menuF);//讲此菜单栏按钮加在jme里
return jme;
}
}
相关推荐
在本篇【弹球游戏分步解析(五)——阶段性总结】中,我们将对一个基于Java实现的弹球游戏进行深入探讨。这个弹球游戏的源代码提供了丰富的学习材料,帮助开发者了解游戏开发的基本概念和技术。博文链接为,可以在...
在本项目中,我们探索的是一个使用C语言编写的弹球游戏的核心代码。这款小游戏是基于WIN32框架构建的,对于想要学习游戏编程初学者来说,这是一个很好的起点。通过这个简洁的代码实现,我们可以了解到游戏开发的一些...
Scratch创意编程——弹球游戏 学历案.pdf
PONG是一款简单的双人对战游戏,两个玩家各控制一个垂直移动的挡板,试图让一个小球在屏幕上反弹并使对方无法接到球。 首先,我们要了解pgzero库。pgzero是基于pygame库的一个简化版本,专为初学者设计,提供了一些...
《Android弹球游戏源码解析》 Android平台上的游戏开发是一项充满挑战与乐趣的工作,而“Android弹球游戏”作为一款简单的单机游戏,为初学者提供了很好的学习实例。这款游戏的核心在于挡板与小球之间的碰撞反弹,...
该程序实现了linux下弹球游戏,设置时间中断信号,小球随机运动,通过移动木板接球,没有接到小球则失败
《弹球游戏(Flash编写):深入解析与技术探讨》 在数字娱乐领域,Flash曾是制作互动内容的主流工具,尤其是对于小游戏的开发。本文将深入探讨一款名为“弹球游戏”的Flash作品,该作品提供了源代码和最终的SWF文件...
QT开发的弹球游戏是一种基于QT框架的简单计分计时型休闲娱乐程序。QT是一个跨平台的应用程序开发框架,由Trolltech公司(现为Nokia)开发,广泛应用于桌面应用、移动设备以及嵌入式系统。它支持C++语言,并提供了...
java弹球游戏java弹球游戏java弹球游戏 java弹球游戏java弹球游戏java弹球游戏 java弹球游戏java弹球游戏java弹球游戏 java弹球游戏java弹球游戏java弹球游戏 java弹球游戏java弹球游戏java弹球游戏 java弹球游戏...
【OpenCV下的弹球游戏】是一个基于Visual Studio(VS)开发环境,利用OpenCV库创建的简单游戏项目。OpenCV,全称为Open Source Computer Vision Library,是一个开源的计算机视觉库,它包含了大量的图像处理和计算机...
《C#实现简单弹球游戏源码解析》 在编程世界中,开发一款简单的游戏是初学者们常常选择的实践项目。本篇文章将详细解析一个使用C#语言编写的弹球游戏源码,旨在帮助读者了解游戏开发的基本原理,以及C#在图形用户...
在弹球游戏中,Canvas被用来绘制游戏场景,包括弹球、挡板以及背景。 2. **碰撞检测**:游戏中的关键部分是弹球与不同物体之间的碰撞检测。这通常涉及到几何学和物理原理,例如判断两个圆形是否相交,或者判断一个...
本资源是山东大学软件学院图形学课程设计实验二
本文将深入探讨如何使用Visual Basic(VB)编写一个弹球游戏,结合提供的完整源码,我们将一步步解析其背后的逻辑与实现细节。 一、VB基础介绍 Visual Basic,简称VB,是由微软公司推出的一种面向对象的编程语言,...
弹球游戏是计算机游戏中的一种经典类型,通常涉及到一个小球在屏幕内反弹,玩家通过控制平台来防止球掉出屏幕。 在这个“C#弹球游戏”源码中,我们可以学习到以下几个关键知识点: 1. **图形用户界面(GUI)设计**...
游戏分为三个等级——简单,中等,困难。 其中,简单对应一个球,速度设置为30,即对应线程暂停30/1000秒; 中等对应两个球,速度设置为40,即对应线程暂停40/1000秒; 困难对应两个球,速度设置为30,即对应线程...
《VB源码实现的弹球游戏详解》 在IT领域,编程是一项基本技能,而用Microsoft Visual Basic 6.0(简称VB6)编写游戏,是初学者掌握基础编程概念和提升技能的好方法。本篇将详细介绍利用VB6实现的弹球游戏的编程知识...
在本次实验中,Swing被用来构建弹球游戏的界面,包括游戏窗口、小球的绘制、计时器的显示等。 - **组件**: JFrame用于创建主窗口,JPanel用于添加游戏的画板区域。 - **事件监听**: 通过MouseListener和...
弹球游戏弹球游戏弹球游戏弹球游戏弹球游戏弹球游戏弹球游戏弹球游戏
实验任务是设计并实现一个弹球游戏,用户可以通过 GUI 组件指定生成小球的数量,每个小球将从随机的位置出现,并具有随机颜色、随机速度和随机的运动方向。 一、实验目的 1. 掌握 Swing 图形用户界面编程和事件...