来源:互联网 发布:淘宝冷冻芝心薯球 编辑:程序博客网 时间:2024/04/28 22:30

//Boat.java

import java.util.*;
import java.awt.*;
import java.awt.event.*;

public class Boat
{
 /*Boat的默认值*/
 private static final int DEFAULT_SPEED=15;
 /*尺寸*/
 private static final int WIDTH=65;
 private static final int THICKNESS=3;
 /*Boat的活动范围*/
 private int minX;
 private int maxX;
 /*Boat矩形的左上角坐标*/
 private int X;
 private int Y;
 /*船的默认速度*/
 private int speed=DEFAULT_SPEED;
 /*船颜色*/
 private Color color=Color.BLUE;
 /*天空下边界*/
 private int skyDown;
 /*构造方法,参数定义了范围*/
 
 public Boat(int left,int down,int screenWidth)
 {
  minX=left;
  maxX=minX+screenWidth-WIDTH;
  this.skyDown=down;
 }
 
    public void initBoat()
    {
     X=(minX+maxX)/2;
     Y=skyDown-THICKNESS;
    }
   
    //Boat向左移动
    public synchronized void left()
    {
     X-=speed;
     /*检查边界*/
     if(X<minX)
     {
      X=minX;
     }
    }
   
    //Boat向右移动
    public synchronized void right()
    {
     X+=speed;
     /*检查边界*/
     if(X<maxX)
     {
      X=maxX;
     }
    }
   
    //设置船速
    public void setSpeed(int speed)
    {
     this.speed=speed*5;
    }
   
    //画Boat
    public synchronized void paint(Graphics g)
    {
     g.setColor(color);
     g.fillRect(X,Y,WIDTH,THICKNESS);
    }
   
    //对类成员的访问封装
 public int getX()
 {
  return X;
 }
 
 public int getY()
 {
  return Y;
 }
 
 public int getRightX()
 {
  return X+WIDTH;
 }
 
 public int getWaterLine()
 {
  return Y+THICKNESS;
 }
 
 public void moveUp()
 {
  Y-=1;
 }
}//end class

//Rain.java

import java.util.*;
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;

public class Rain extends Applet implements ActionListener,ItemListener{
 /**游戏画面屏幕*/
 private Screen screen;
 /**控制面板*/
 private Panel ctrlPanel;
 /*"雨速" "船速"下拉框 "左"/"右"/"开始/重玩" "帮助"按钮,分数标签*/
 private Choice rainSpeedCHIC=new Choice();
 private Choice boatSpeedCHIC=new Choice();
 private Button leftBTN=new Button("<");
 private Button rightBTN=new Button(">");
 private Button playBTN=new Button("开始");
 private Label scoreLBL=new Label("得分:0");
    /**初始化控制面板,并创建Screen实例*/
 public void init()
 {
  setLayout(new BorderLayout());
  /*该应用是为了screen通知ctrlPanel上的界面变化
   * 1.得分的改变
   * 2.开始/重玩 显示 的切换*/
  screen=new Screen(this);
  add("Center",screen);
  ctrlPanel=new Panel();
  add("South",ctrlPanel);
  //初始化交互组件
  boatSpeedCHIC.addItem("船速");
  boatSpeedCHIC.addItem("1");
  boatSpeedCHIC.addItem("2");
  boatSpeedCHIC.addItem("3");
  boatSpeedCHIC.addItem("4");
  boatSpeedCHIC.addItem("5");
  //在ctrlPanel上加入交互组件
  ctrlPanel.add(boatSpeedCHIC);
  ctrlPanel.add(leftBTN);
  ctrlPanel.add(rightBTN);
  ctrlPanel.add(playBTN);
  ctrlPanel.add(scoreLBL);
  //加入事件监听,由本类监听
  boatSpeedCHIC.addItemListener(this);
  leftBTN.addActionListener(this);
  rightBTN.addActionListener(this);
  playBTN.addActionListener(this);
 }//end init()
 
 public void initGame()
 {
  playBTN.setLabel("开始");
  scoreLBL.setText("得分:0");
  screen.initGame();
 }
 
 public void start()
 {
  //启动Screen,但不代表开始游戏(要等按"开始"play())
  screen.start();
 }
 
  // 出来按键
 public void actionPerformed(ActionEvent e)
 {
  Object src=e.getSource();
  if(src==leftBTN)
  {
   screen.boatMoveLeft();
   return;
  }
  if(src==rightBTN)
  {
   screen.boatMoveRight();
   return;
  }
  if(src==playBTN)
  {
   //开始游戏,如果在游戏中,也会重新启动游戏
   if(playBTN.getLabel().equals("重玩"))
    initGame();
   else //"开始"
    screen.play();
   return;
  }
 }//end actionPerformed()
 
 //处理下拉框
 public void itemStateChanged(ItemEvent e)
 {
  Object src=e.getSource();
  String item=(String)(e.getItem());
  if(src==boatSpeedCHIC)
  {
   if(item.equals("船速"))
   {
    item="1";
   }
   int id=Integer.parseInt(item);
   screen.setBoatSpeed(id);
   return;
  }
 }//end itemStateChanged()
 
 public void setScore(int score)
 {
  scoreLBL.setText("得分:"+score);
 }
 
 public void changePlayBTNDisplay()
 {
  playBTN.setLabel("重玩");
 }
 
 public void stop()
 {
  screen.stop();
 }
 
 public String getAppletInfo()
 {
  return "Rain";
 }
 
 public void destroy()
 {
  remove(screen);
  remove(ctrlPanel);
 }
}//end class

//Raindrop.java

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;

class Raindrop
{
 /*随机数产生器*/
 private static Random random=new Random();
 /*产生雨点的范围*/
 private int minGX;
 private int maxGX;
 private int minGY;
 private int maxGY;
 /*雨点的位置,圆的正外切正方形的左上角坐标*/
 private int X;
 private int Y;
 /*尺寸,半径,直径*/
 private static final int MIN_RADIUS=2;
 private static final int MAX_RADIUS=4;
 private int radius;
 /*雨点下落速度*/
 private static final int MIN_SPEED=2;
 private static final int MAX_SPEED=5;
 private int speed;
 /*雨点颜色*/
 private Color color;
 /*接住该雨点得到的分数*/
 private int score;
 /*Boat*/
 private Boat boat;
 private int deadLine;
 //建立雨点实例,参数传入范围
 public Raindrop(Boat boat,int left,int top,int skyWidth,int skyThickness)
 {
  this.boat=boat;
  /*设置雨点产生的范围*/
  minGX=left;
     minGY=top+skyThickness/2;
     maxGX=minGX+skyWidth-MAX_RADIUS*2;
     maxGY=minGY+skyThickness-MAX_RADIUS*2;
     deadLine=top+skyThickness;
 }
 
 //随机产生初始雨点信息
  public void initDrop()
  {
   X=((random.nextInt()>>>1)%(maxGX-minGX))+minGX;
   Y=((random.nextInt()>>>1)%(deadLine-minGY))+minGY;
   speed=((random.nextInt()>>>1)%(MAX_SPEED-MIN_SPEED))+MIN_SPEED;
   radius=((random.nextInt()>>>1)%(MAX_RADIUS-MIN_RADIUS))+MIN_RADIUS;
     color=new Color((random.nextInt()>>>1)%0xffffff);
        //分值为半径加速度
     score=radius+speed;
  }
 
 /*雨点下落一次
  * @return 0:没达到 1:接着了 2:没接着*/
  public int fall()
  {
   Y+=speed;
   /*检查是否到达检查线(船的上位置)*/
   if((Y+radius)<boat.getY())
    return 0;
   /*判断是否落在船上*/
   int dropRightX=X+radius*2;
   boolean isHit=(X>boat.getRightX())||(dropRightX<boat.getX());
        //让该雨点重新从上面掉,并重新计算雨点信息
   initDrop();
   return isHit? 2:1;
  }//end fall()
   //画雨点
     void paint(Graphics g)
     {
      g.setColor(color);
      g.fillArc(X,Y,radius*2,radius*2,0,360);
     }
    
     public int getScore()
     {
      return score;
     }
}//end class

//Screen.java

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;

import java.net.MalformedURLException;

class Screen extends Panel implements Runnable{
 //代表本线程
 private Thread me;
 //引用Rain实例
 private Rain rain;
 //重画间隔时间
 private static final int SPEED_TEPAINT=70;
 //雨点的个数
 private static final int DROP_NUM=9;
 //游戏状态标识
 private static final int STATUS_INIT=1;
 private static final int STATUS_PLAYING=2;
 private static final int STATUS_DEAD=3;
 private int status;
 //总分数
 private int score;
 //船引用
 private Boat boat;
 /*雨点数组*/
 private Raindrop[] dropArr=new Raindrop[DROP_NUM];
 /*屏幕尺寸*/
 private int X=0;
 private int Y=0;
 private int W;
 private int H;
 /*颜色*/
 private Color bgColor=Color.white;
 private Color borderColor=Color.black;
 private Color deadLineColor=Color.blue;
 private Color waterColor=Color.red;
 private Color textColor=Color.black;
 //死亡线
 private int deadLine;
 //显示消息的坐标
 private int msgX;
 private int msgY;
 //雨点计数,为了画水
 private int waterCount;
 //主路径,为了播放音乐
 private URL base;
 //是否刚开始游戏,用于第一次擦除屏幕
 private boolean isFirst;
 
 //构造方法
 public Screen(Rain rain)
 {
  super();
  this.base=rain.getCodeBase();
  this.rain=rain;
 }
 
 //第一次启动
 public void start()
 {
//  计算 Screen的各种初值(***)
  countSize();
  initGame();
  me=new Thread(this);
  me.start();//进入run()
 }
 
 public void initGame()
 {
  status=STATUS_INIT;
  isFirst=true;
  //初始化船位置,雨点数组
  boat.initBoat();
  for(int i=0;i<dropArr.length;i++)
   dropArr[i].initDrop();
  score=0;
  repaint();
 }
 
 public void countSize()
 {
  W=getSize().width;
  H=getSize().height;
  boat=new Boat(X,H,W);
  deadLine=H/4;
  msgX=X+15;
  msgY=Y+15;
  for(int i=0;i<dropArr.length;i++)
   dropArr[i]=new Raindrop(boat,X,Y,W,deadLine);
  setBackground(bgColor);
 }
 
 public void play()
 {
  status=STATUS_PLAYING;
  rain.changePlayBTNDisplay();
  repaint();
 }
 
 //主要执行方法
 public void run()
 {
  while(true)
  {
   try
   {
    Thread.sleep(SPEED_TEPAINT);
   }
   catch(InterruptedException e){}
   //如果死亡/等待,则继续循环
   if((STATUS_INIT==status)||(STATUS_DEAD==status))
    continue;
   //移动所以雨点
   waterCount=0;
   for(int i=0;i<dropArr.length;i++)
   {
    int rtn=dropArr[i].fall();
    if(0==rtn)
     continue;
    if(1==rtn)
    {
     //接着了
     score+=dropArr[i].getScore();
     rain.setScore(score);
     //播放音效
     rain.play(base,"au/ok.au");
     continue;
    }
    //播放音效
    rain.play(base,"au/ng.au");
    //没接着
    boat.moveUp();
    waterCount++;
    if(boat.getY()<deadLine)
    {
     status=STATUS_DEAD;
     rain.changePlayBTNDisplay();
    }
   }
   //更新画面
   repaint();
  }
 }//end run()
 
 public synchronized void update(Graphics g)
 {
  int waterLine=boat.getWaterLine();
  //清除
  g.setColor(bgColor);
  if(isFirst)
  {
   g.fillRect(0,0,W,H);
   isFirst=false;
  }
  else
   g.fillRect(1,deadLine/2,W-2,waterLine-deadLine/2);
  //画边界和deadline
  g.setColor(borderColor);
  g.drawRect(X,Y,W-1,H-1);
  g.setColor(deadLineColor);
  g.drawLine(X,deadLine,W,deadLine);
  //画水
  if(waterCount!=0)
  {
   g.setColor(waterColor);
   g.fillRect(X,waterLine,W,waterCount);
  }
 
 //如果船移动,则重画
 boat.paint(g);
 //画移动的雨点的新值
 for(int i=0;i<dropArr.length;i++)
 
  dropArr[i].paint(g);
  if(status==STATUS_DEAD)
  {
   g.setColor(textColor);
   g.drawString("你被淹死了,游戏结束.",msgX+30,msgY);
  }
  else
  {
   g.setColor(waterColor);
   g.drawString("雨",msgX,msgY);
  }
 }//end update()
 
 public void boatMoveLeft()
 {
  boat.left();
  repaint();
 }
 
 public void boatMoveRight()
 {
  boat.right();
  repaint();
 }
 
 public void setBoatSpeed(int speed)
 {
  boat.setSpeed(speed);
 }
 public void stop()
 {
  me=null;
 }
}//end class

原创粉丝点击