多线程的弹球游戏实现

大二开始学习Java的时候做的一个弹球游戏,共享于此。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class BallGame extends JApplet {
    private JMenu controlBar,speedBar;;// 3个主控菜单
    private JMenuItem startItem,exitItem;// control下的开始结束菜单
    private JRadioButtonMenuItem stepItem[];// 难易程度
    private ButtonGroup Group,speedGroup;//组件组
    private JPanel gameJP;// 添加游戏区容器
    private int dx,dy,randomNum;// 球的移动量和球撞到滑板上的随机量
    private JButton RecBox;//滑板作为Button来操作,好处在于可以直接对此组                                                                                                                                                                                            件添加KeyListener
    private Rectangle Rect;//滑板矩形框的定义
    private ImageIcon backGround;//背景图片声明
    private int xRec,widRec,SPEED,heiRec,
width,height,Height,delay,xcenter,ycenter,r,marks;// parament                                                                 // of drawings
    public BallGame(){
        xcenter=200;ycenter=25;r=10;// 球的参数
        dx=0;dy=0;// 球的移动量
        randomNum=(int)Math.random()*5;//调节小球碰到滑板时的随机反弹
        SPEED=20;delay=SPEED;// 速度因数,delay变量,speed常量
        width=400;height=300;Height=275;// JFrame框长宽,Height表示游   戏框的高(菜单栏占了25的高度)
        xRec=160;widRec=80;heiRec=15;// 滑板框参数
        marks=0;// 初始得分
        RecBox=new JButton();
        backGround=new ImageIcon("Thank.gif");
        Rect=new Rectangle(xRec,realY(heiRec),widRec,heiRec);
        RecBox.setBounds(Rect);
        RecBox.setBackground(Color.black);
    }
    public void init(){
        setSize(width,height);//背景图片
        gameJP=new JPanel(){// 只有把 JPanel当作一个组件来加入到Applet
才能和菜单栏共存,
                            // 否则paint()所画图形会被菜单界面盖住~~~~
            public void paint(Graphics g){
                backGround.paintIcon(this, g, 0, 0);
                g.setColor(Color.red);
                g.drawArc(xcenter-r,realY(ycenter+r),
2*r,2*r,0,360);// 画圆球
                g.fillArc(xcenter-r,realY(ycenter+r),2*r,2*r,0,360);
                String tag="******Your Marks******* ";
                g.drawString(tag, 280, 10);
                String mark=Integer.toString(marks);
                g.drawString(mark, 330, 20);
            }
        };
        add(RecBox);
        add(gameJP);
        // 向menuJP板中添加controlBar
        controlBar=new JMenu("Console");// 创建主控
        controlBar.setMnemonic('C');
        Group=new ButtonGroup();
        startItem=new JMenuItem("Start");
        startItem.setMnemonic('S');
        startItem.addActionListener(
            new ActionListener(){
                public void  actionPerformed(ActionEvent evt){
                    dx=0;dy=0;
                    BallThread Ball=new BallThread();
                    Ball.start();// 球的线程启动
                    KeyThr board=new KeyThr();
                    board.start();
                }
            }
        );
        Group.add(startItem);
        controlBar.add(startItem);
        // 向controlBar中添加speed
        speedGroup=new ButtonGroup();
        speedBar=new JMenu("Speed");
        speedBar.setMnemonic('S');
        
        String StepValues[]={"1 level","2 level","3 level"};// 添加速度的选择项
        stepItem=new JRadioButtonMenuItem[StepValues.length];
        for(int count=0;count<stepItem.length;count++){
            stepItem[count]=new JRadioButtonMenuItem(StepValues[count]);
            speedBar.add(stepItem[count]);
            speedGroup.add(stepItem[count]);
            stepItem[count].addActionListener(new SpeedHandler());
        }
        stepItem[0].setSelected(true);
        
        controlBar.add(speedBar);
        controlBar.addSeparator();// 添加分隔线
        
        exitItem=new JMenuItem("Exit");// 添加退出选项
        exitItem.setMnemonic('E');
        exitItem.addActionListener(// 响应退出事件
            new ActionListener(){
                public void actionPerformed(ActionEvent evt){
                    System.exit(0);
                }
            }
        );
        
        
        Group.add(exitItem);
        controlBar.add(exitItem);
        JMenuBar Bar=new JMenuBar();
        setJMenuBar(Bar);
        Bar.add(controlBar);
        setVisible(true);
        showStatus("Goal: "+marks);
    }
    public int realY(int a){return height-25-a;}
    // 球的响应事件线程
    class  BallThread extends Thread{
        
        @SuppressWarnings("deprecation")
        public synchronized void run(){
            for(;;){
              try{Thread.sleep(delay);
               }catch(InterruptedException e){return;}
              if(dx==0&&dy==0){// 起步时
                  double a=(-101+Math.random()*200);
                  if(a==0) a=(-101+Math.random()*200);
                  double b=(1+Math.random()*100);
                  double ang=Math.abs(a)<=b?a/b:b/a;
                  double Angle=Math.acos(ang);
                  dx=(int)(Math.cos(Angle)*5);
                  dy=(int)(Math.sin(Angle)*5);
                  xcenter=xcenter+dx;
                  ycenter=ycenter+dy;
                  repaint();
              }
              else{
                  if(xcenter-r>=0&&xcenter+r<=width
&&ycenter+r<=Height&&ycenter-r>0){
                      xcenter=xcenter+dx;
                      ycenter=ycenter+dy;
                      repaint();
                  }
                  else if(xcenter-r<=0||xcenter+r>=width){// 超出左右边界
                      ycenter=ycenter+dy;
                      xcenter=xcenter-dx;
                      dx=(-dx);
                      repaint();
                  }
                  else if(ycenter+r>=Height){// 超出上界
                      ycenter=ycenter-dy;
                      xcenter=xcenter+dx;
                      dy=(-dy);
                      repaint();
                  }
                  else if(xcenter+r>=xRec && xcenter-r<=xRec+widRec && ycenter-r<=r+heiRec){// 弹到滑板上
                      ycenter=ycenter-dy;
                      if(dx>0){
                        xcenter=xcenter+dx+randomNum;
                        dy=(-dy+randomNum);
                      }
                      else {
                          xcenter=xcenter+dx-randomNum;
                          dy=(-dy-randomNum);
                      }
                      marks+=10;
                      repaint();
                  }
                  else if(ycenter<=r){// 超出下界
                      JOptionPane.showMessageDialog(null, "Game     over","Game result",JOptionPane.INFORMATION_MESSAGE);
            marks=0;xcenter=200;ycenter=25;                        BallGame.this.RecBox.setLocation(160,realY(15));
                      repaint();
                     interrupt();
                  }
              }
           }
        }
    }
    public  class SpeedHandler implements ActionListener{
        public void actionPerformed(ActionEvent evt){
            for(int count=0;count<stepItem.length;count++){
                if(stepItem[count].isSelected()){
                   if(marks>50&&marks<=600)
                       delay=SPEED/(count+1)-marks/50;//随着分数的越来越高,球运动的也越来越快
                   else delay = SPEED/(count+1);
                }
            }
       }
    }
        
    public class KeyThr extends Thread {//滑板移动线程
        public void run(){
           RecBox.addKeyListener(new Keyhandler());
        }
    }
    //滑板的移动响应事件
    public class Keyhandler extends KeyAdapter {
        
        public void keyPressed(KeyEvent evt){
        JButton button=(JButton)evt.getSource();//evt.getSource()表示返回最初发生event的对象,即RecBox滑板
       xRec=button.getBounds().x;//xRec必须是全局变量,因为有另一个线程调用此变量
             if (evt.getKeyCode() == KeyEvent.VK_RIGHT) {
                xRec=xRec+4;
                if(xRec>=width-widRec) xRec=width-widRec;
                button.setLocation(xRec,realY(heiRec));
                repaint();
             }
             else if (evt.getKeyCode() == KeyEvent.VK_LEFT) {
                 xRec=xRec-4;
                 if(xRec<=0) xRec=0;
                 button.setLocation(xRec,realY(heiRec));
                 repaint();
             }
             
        }
    }
    public void update(Graphics g){paint(g);}//消除抖动
}

你可能感兴趣的:(多线程,游戏,swing,360,JavaFX)