弹球游戏分步解析(二)——让小球飞_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 弹球游戏分步解析(二)——让小球飞

弹球游戏分步解析(二)——让小球飞

 2013/7/22 18:40:28  香煎马鲛鱼  程序员俱乐部  我要评论(0)
  • 摘要:弹球游戏分步解析(二)——让小球飞之前跟大家说要把事件监听器和多线程分开来讲,不过之后发现事件监听器要涉及到很多小球运动的操作,所以,决定将两个知识点合起来说,这样会更便于大家理解:实现小球在我们所绘制的窗体上运动就必须要用到多线程;让小球类继承Thread类,再重写voidrun(){}方法即可;先上代码:(注:浅蓝色字体不是本节要讲的内容,可以忽略)packagejumpingBall;importjava.awt.Color;importjava.awt.Graphics
  • 标签:游戏 解析

class="MsoNormal" style="text-align: center; margin: 0cm 0cm 0pt;">弹球游戏分步解析(二)——让小球飞

之前跟大家说要把事件监听器和多线程分开来讲,不过之后发现事件监听器要涉及到很多小球运动的操作,所以,决定将两个知识点合起来说,这样会更便于大家理解

实现小球在我们所绘制的窗体上运动就必须要用到多线程;让小球类继承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;

??? ?????? ???}

?????? }

? ????????//下面全是getset方法(定义以下方法主要在文件操作时用到):

?????? 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")){

????????????????????????? ? //遍历场上所有小球,修改ballpause属性

????????????????????????? ? 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;

?????? }

?

}

发表评论
用户名: 匿名