Java做一个哄女朋友开心的小程序-真·面向对象编程

发布于 2020-12-31 16:42
浏览
0收藏

最近女朋友天天找我吵架得想着办法哄哄她,恰巧我还在找Java面向对象练手的小程序,两个需求一结合,ok,这个小程序诞生了。

Java做一个哄女朋友开心的小程序-真·面向对象编程-开源基础软件社区主要目的:做一个以女朋友照片为背景的画布,装饰点小花小草小气球小爱心,另设一个女朋友的小图片可以自由的移动.
那么就需要创建一个小花类一个气球类,一个爱心类一个移动的人物类。想要实现小图片可以发射爱心,目前还没实现。。

分别创建四个类,这里我放一起了:

//创建移动的人物类
public class people
 private int x;
 private int y;
 private int width;
 private int height;
 private int speed;
 private String dir;
 private GameClient gameClient;
 private List<heart> heartLists = new ArrayList<();
//创建爱心类
public class heart
 private int x;
 private int y;
 private int width;
 private int height;
 private int speed;
 private GameClient gameClient;
//创建花朵类
public class flower
 private int x;
 private int y;
 private int width;
 private int height;
 private GameClient gameClient;
//创建气球类
public class balloon
 private int x;
 private int y;
 private int width;
 private int height;
 private GameClient gameClient;

这几个类参数分别有xy坐标高度宽度,游戏控制台类型的参数gameClient。people类参数还有speed(速度),dir(控制移动方向),装heart类型的哈希表heartlists。
首先我们要知道xy是控制什么的,我们要先知道windows界面的坐标轴

Java做一个哄女朋友开心的小程序-真·面向对象编程-开源基础软件社区这几个类创建完了,那么还缺什么呢?对了就是画在画布上的图片,如果没有图片 那么传进去的参数x、y、width、height等等是描述什么的呢?

 

我们需要先获取图片流,那么怎么获取呢?
我们就要先创建一个获取图片流的功能类啦:

public class CommonUtils {
/*
 * 读取图片资源,转变为Java对象 Image
 */
 public static Image getImage(String imgPath) {
  ImageIcon imageIcon = new ImageIcon(imgPath);
  return imageIcon.getImage();
 }
}

然后就可以使用这个功能类分别在各自的类中来获取图片:

//传入people图片
public static final Image RENWU_IMAGE = CommonUtils.getImage("人物.jpg");
//传入爱心图片
public static final Image HEART_IMAGE = CommonUtils.getImage("th.jpg");
//传入花朵图片
public static final Image FLOWER_IMAGE = CommonUtils.getImage("花.jpg");
//传入气球图片
public static final Image BALLOON_IMAGE = CommonUtils.getImage("气球.jpg");

好的现在图片都已经加载进去了,那么我们怎么把图片画在画布上呢?如果计算机仅仅读取到图片却不把它放在画布上那不就没啥用了吗,所以我们要定义一个paint方法来将图片画出来:

分别在各自的类中创建paint方法:

//people类中定义的paint方法
public void paint(Graphics g) {
  g.drawImage(RENWU_IMAGE, this.x, this.y, this.width, this.height, this.gameClient);
 }
//heart类中定义的paint方法
public void paint(Graphics g) {
 g.drawImage(HEART_IMAGE, this.x, this.y, this.width, this.height, this.gameClient);
}
//flower类中定义的paint方法
public void paint(Graphics g) {
 g.drawImage(FLOWER_IMAGE, this.x, this.y, this.width, this.height, this.gameClient);
}
//balloon类中定义的paint方法
public void paint(Graphics g) {
 g.drawImage(BALLOON_IMAGE, this.x, this.y, this.width, this.height, this.gameClient);
 }

现在我们已经写完了每个类中的画出图片的方法了,那么怎么去实现呢?如果一个方法不能被实现,那这个方法和咸鱼有什么区别
所以我们需要一个控制台:GameClient类
我们要在这个类中画出女朋友的背景图片,小花图,爱心图和气球图当然还有我女朋友的照片。

public class GameClient extends Frame{
 public static final String BG_PATH="背景.jpg";
 
 private static Image image;
 

 private people renwu = new people(400,300,this);

 private heart heart = new heart(1050,400,this);


 private flower flower_v1 = new flower(300,80,50,50,this);

 private flower flower_v2 = new flower(1050,100,50,50,this);

 private flower flower_v3 = new flower(300,350,50,50,this);

 private flower flower_v4 = new flower(800,100,50,50,this);

 private flower flower_h1 = new flower(500,560,50,50,this);
 

 private balloon balloon = new balloon(150,600,this);
 
 //加载一次背景资源
 static {
  image = CommonUtils.getImage(BG_PATH);
 }
 
 public void paint(Graphics g) {
  //画背景
  g.drawImage(image, 0, 0, 1440, 1080, this);
  //画人物
  renwu.paint(g);
  //画爱心
  heart.paint(g);
  //画花
  flower_v1.paint(g);
  flower_v2.paint(g);
  flower_v3.paint(g);
  flower_v4.paint(g);
  flower_h1.paint(g);
  //画气球
  balloon.paint(g);
 }
}

ok,到这我们就把我们所有要呈现在画布上的图片画出来啦!
那我们的需求是什么呢?我们想要让女朋友能漫步在这花花草草和气球里,所以要怎么做,我们要让女朋友能动起来!那就又要在people类里增加功能了:

我们先在people类里定义五个布尔变量,分别是键盘上的上下左右和ctrl:

boolean UP = false;
 boolean DOWN = false;
 boolean LEFT = false;
 boolean RIGHT = false;
 boolean CONTROL = false;

这是默认这五个键都没有被按下的,如果不是false,那女朋友的照片不就会来回乱跑了吗,哈哈哈,这个ctrl键被按下,我们想要让地图上的爱心增加1个,同时下方字幕也显示增加一个爱心。
那么怎么随着按下键盘能创建一个新的爱心呢?我们就要构造一个方法了:

public heart createheart() {
  return new heart(this.x,this.y,this.gameClient);
 }

准备工作做完了,那么接下来就是实现上下左右控制女朋友移动了,这里我们就要用到键盘监听器,KeyEvent键盘事件等功能,我们先定义一个方法控制松开键盘。

public void okDirReleased(int KeyCode) {
  switch(KeyCode) {
  case KeyEvent.VK_UP:
   UP = false;
   break;
  case KeyEvent.VK_DOWN:
   DOWN = false;
   break;
  case KeyEvent.VK_LEFT:
   LEFT = false;
   break;
  case KeyEvent.VK_RIGHT:
   RIGHT = false;
   break;
  case KeyEvent.VK_CONTROL:
   CONTROL = false;
   break;
  }
 }

然后再定义一个方法来接收我们按下键盘的指令

public void okDirPressed(int KeyCode) {
  switch(KeyCode) {
  case KeyEvent.VK_UP:
   System.out.println("向上走");
   String dir = "UP";
   UP = true;
   this.setDir(dir);
   break;
  case KeyEvent.VK_DOWN:
   System.out.println("向下走");
   DOWN = true;
   this.setDir("DOWN");
   break;
  case KeyEvent.VK_LEFT:
   System.out.println("向左走");
   LEFT = true;
   this.setDir("LEFT");
   break;
  case KeyEvent.VK_RIGHT:
   System.out.println("向右走");
   RIGHT = true;
   this.setDir("RIGHT");
   break;
  case KeyEvent.VK_CONTROL:
   System.out.println("放置爱心");
   heart heart = this.createheart();
   //将爱心放入容器中()
   this.heartLists.add(heart);
   CONTROL = true;
   this.setDir("CONTROL");
   
   //看容器中还有多少爱心
   System.out.println("爱心数量"+this.heartLists.size());
   break;
  }
  //判断左上左下右上右下
  if(UP&&RIGHT) {
   this.setDir("UR");
  }
  if(UP&&LEFT) {
   this.setDir("UL");
  }
  if(DOWN&&RIGHT) {
   this.setDir("DR");
  }
  if(DOWN&&LEFT) {
   this.setDir("DL");
  }
  this.move(this.getDir());
 }
}

这里我们的String类型的dir变量就派上用场了,我们设置按下上下左右和ctrl键分别给dir传入"UP",“DOWN”,“LEFT”,“RIGHT”,“CONTROL”,如果是左上左下右上右下那么分别是"UL",“DL”,“UR”,“DR”,后面我们会用dir和这些字符串进行比对(equals),这样就可以实现按下键盘操作程序啦,现在我们按下键盘已经得到控制这些功能的字符串了,那么我们怎么利用这些字符串来控制图片移动呢?
我们就要定义一个move方法:

  public void move(String dir) {
  if("UP".equals(dir)) {
   this.y-=this.speed;
  }
  if("DOWN".equals(dir)) {
   this.y+=this.speed;
  }
  if("LEFT".equals(dir)) {
   this.x-=this.speed;
  }
  if("RIGHT".equals(dir)) {
   this.x+=this.speed;
  }
  if("UR".equals(dir)) {
   this.y-=this.speed;
   this.x+=this.speed;
  }
  if("UL".equals(dir)) {
   this.y-=this.speed;
   this.x-=this.speed;
  }
  if("DR".equals(dir)) {
   this.y+=this.speed;
   this.x+=this.speed;
  }
  if("DL".equals(dir)) {
   this.y+=this.speed;
   this.x-=this.speed;
  }
 }

到这里还不算完,我们只是定义了这个方法并且定义了如何使用这些方法,那么我们怎么能让计算机直到我们按下了上下左右ctrl键呢?
我们就要在控制台类里加一个监听器了:

  this.addKeyListener(new KeyAdapter() {
   @Override
   public void keyPressed(KeyEvent e) {
    int KeyCode = e.getKeyCode();
    renwu.okDirPressed(KeyCode);
    
   }
   @Override
   public void keyReleased(KeyEvent e) {
    int KeyCode = e.getKeyCode();
    renwu.okDirReleased(KeyCode);
    renwu.setDir("STOP");
   }
  });

那么这个监听器应该放在哪里呢?也不能把这个方法就扔在控制台里啊,我们要让它发挥作用啊,所以我们就要定义一个开始的方法了,这个方法里要创建窗口,关闭窗口,监听键盘事件:

 public void start() {
  //设置标题
  this.setTitle("老婆大人");
  //设置窗体大小以及边界
  this.setBounds(0,0,1440,1080);
  //关闭游戏窗口
  this.addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent e) {
    System.out.println("Game over");
    System.exit(0);
   }
  });
  //监听键盘事件
  this.addKeyListener(new KeyAdapter() {
   @Override
   public void keyPressed(KeyEvent e) {
    int KeyCode = e.getKeyCode();
    renwu.okDirPressed(KeyCode);
    
   }
   @Override
   public void keyReleased(KeyEvent e) {
    int KeyCode = e.getKeyCode();
    renwu.okDirReleased(KeyCode);
    renwu.setDir("STOP");
   }
  });
  //显示窗体
  this.setVisible(true);
 }

运行一下我们发现问题了,女朋友为什么不动?原来是因为画面没有刷新,女朋友动了但是没显示她动了,所以我们要重新刷新一下画面,那么就要对画面进行重绘了:

public class RepaintThread implements Runnable {
 
 private GameClient gameClient;

 public RepaintThread(GameClient gameClient) {
  this.gameClient = gameClient;
 }
  
 public void run() {
  while(true) {
   try {
    Thread.sleep(100);
    gameClient.repaint();
   }catch(Exception e) {
    e.printStackTrace();
   }
  }
 }

}

然后我们要实现一下重绘画面的方法,那么就要让这个线程工作起来,所以我们如何让这个线程工作呢?大家都知道了,我们应该把这个线程在start()方法中激活:
所以我们要在控制台中的start方法中加入几行代码激活线程并让这个线程运行:

  RepaintThread repaintThread = new RepaintThread(this);
  //创建线程
  Thread thread = new Thread(repaintThread);
  //调用游戏开始方法
  thread.start();

到这基本结束了。还有没解决的功能找机会再实现。代码不全,不重要的没放出来

1
收藏
回复
举报
回复
添加资源
添加资源将有机会获得更多曝光,你也可以直接关联已上传资源 去关联
    相关推荐