大二开始学习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[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 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);}//消除抖动
}