java 跟软帝-攀哥学做编程 飞机大战3

package ui;

import javax.swing.*;

/**

  • 游戏窗体 java窗体类JFrame
    */
    public class GameFrame extends JFrame {

    public GameFrame() {
    setTitle(“飞机大战”);

     setSize(500,700);
     setLocationRelativeTo(null);
     setResizable(false);
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    

    }

    public static void main(String[] args) {
    GameFrame frame = new GameFrame();
    GamePanel panel = new GamePanel(frame);//方便面板中添加键盘监听器
    //启动游戏的方法
    panel.action();
    //报错是因为GamePanel构造器没有添加GameFrame frame
    frame.add(panel);
    frame.setVisible(true);

    }
    }


package ui;

import com.sun.xml.internal.ws.api.addressing.AddressingVersion;

import javax.swing.;
import java.awt.
;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.security.spec.ECParameterSpec;
import java.util.ArrayList;
import java.util.List;

/**

  • java 游戏面板 JPanel
    */
    public class GamePanel extends JPanel{
    BufferedImage bg;//背景图

    Hero hero = new Hero();//创建英雄机

    //Ep ep = new Ep();//创建单个敌机
    //创建敌机大本营(所有敌机都在这里出现)
    List eps = new ArrayList();//集合

    /**

    • 开始游戏的方法
      */
      public void action(){//这个最后要到JFrame里被调用
      //创建并启动一个线程 控制游戏场景中物体活动
      //固定格式
      //new Threed(){public void run(){…线程需要做的事情}}.start();
      new Thread(){
      public void run(){
      //写个死循环 让游戏一直运行
      while (true){
      //调用敌机入场的方法
      epEnter();//在下面创建一个方法就不会报错
      //调用让敌机动起来的方法
      epMove();//在下面创建一个方法就不会报错
      //每执行一次 休息一会 即让线程休眠 毫秒数
      //捕获异常
      try {
      Thread.sleep(30);
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      //刷新页面
      repaint();
      }
      }
      }.start();
      }

    /**

    • 敌机动起来的方法
      */
      protected void epMove(){
      //遍历所有敌机
      for (int i = 0;i<eps.size();i++){
      //获取每一个敌机
      Ep e = eps.get(i);
      //让敌机动起来
      e.move();//在敌机EP类里面创建一个方法就不会报错
      }

    }

    //敌机入场的方法;此方法在死循环中调用,所以该方法会一直重复执行
    //解决敌机出现频率太快问题
    int index = 0;//记录方法执行的次数即每隔一段时间释放一个敌机

    protected void epEnter(){
    //记录执行的次数
    index ++;
    if (index>=20){
    //1:创建敌机
    Ep e = new Ep();
    //2:将敌机加入到敌机大本营即上面的集合里
    eps.add(e);
    //将index重新归零
    index = 0;
    }

    }

    public GamePanel(GameFrame frame) {
    setBackground(Color.cyan);
    bg = App.getImg("/img/bg2.jpg");
    //使用鼠标监听器的格式(固定格式)
    //1:创建鼠标适配器
    MouseAdapter adapter = new MouseAdapter(){
    //2:确定需要监听的鼠标事件
    //鼠标的事件
    // 1:mouseMoved() 监听鼠标移动事件
    // 2:mousecliked() 监听鼠标单击事件
    // 3:mousePressed() 监听鼠标按下去事件
    // 4:mouseEntered() 监听鼠标移入游戏界面事件
    // 5:mouseExited() 监听鼠标移出游戏界面事件

         //mouseMoved用法 打出mouseMoved在按alt+回车.再提示里面找
         //MouseEvent e 监视鼠标事件
         @Override
         public void mouseMoved(MouseEvent e) {
             //super.mouseMoved(e);这个可以不用
             //当鼠标在游戏界面移动时会触发的方法
            // System.out.println("移动");测试用的
             //让英雄机的横纵坐标等于鼠标的横纵坐标
             int mx = e.getX();
             int my = e.getY();
             //让英雄机移动到鼠标的位置上,调用英雄机
             hero.moveToMouse(mx,my);
             //刷新界面 否则飞机表面上看不出移动
             repaint();
         }
     };
     //3:将鼠标适配器加入到监听器中
     addMouseListener(adapter);
     addMouseMotionListener(adapter);//镜像
    
     //使用键盘监听器(固定格式)
     //1:创建键盘适配器
     KeyAdapter kd = new KeyAdapter(){
             //2:确定需要监听的键盘事件
             //先打keyPressed 再alt+回车 在提示里面找
             @Override
             public void keyPressed(KeyEvent e) {
             super.keyPressed(e);
             //当按下键盘的按键时,会触发的方法
             //System.out.println("键盘运行了");//测试键盘是否运行
             //监听键盘;每一个按键都对应有一个数字
             //获取键盘上按键的数字
             int keyCode = e.getKeyCode();
             //System.out.println(keyCode);//可以测试按键按下的反应
             //如果按上键 向上移动
             if (keyCode==KeyEvent.VK_UP){
                 hero.moveUP();
             //如果按下键 向下移动
             }else if (keyCode==KeyEvent.VK_DOWN){
                 hero.moveDown();
             }else if(keyCode==KeyEvent.VK_LEFT){
                 hero.moveLeft();
             }else if(keyCode==KeyEvent.VK_RIGHT){
                 hero.moveRight();
             }
             repaint();//重绘即刷新
         }
     };
     //3:将键盘适配器加到窗体的键盘监听器中,现在需要在框架中加入frame
     frame.addKeyListener(kd);//加frame调用
    

    }

    /**

    • 专用画图方法
    • Graphics g 画笔
    • paint方法:先打出paint出来 按alt+回车
    • @param g
      */
      @Override
      public void paint(Graphics g) {
      super.paint(g);
      //画面板图片
      g.drawImage(bg,0,0,500,700,null);
      //画英雄机s
      g.drawImage(hero.img,hero.x,hero.y,hero.w,hero.h,null);
      //画敌机
      //遍历敌机大本营,集合,画出所有的敌机
      for (int i = 0; i<eps.size();i++){
      //获取每一个敌机 从集合里面拿到敌机
      Ep ep = eps.get(i);
      g.drawImage(ep.img,ep.x,ep.y,ep.w,ep.h,null);
      }

    }
    }


package ui;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**

  • 处理图片的工具类 App
    */
    public class App {
    public static BufferedImage getImg(String path){
    try {
    BufferedImage img = ImageIO.read(App.class.getResource(path));
    return img;
    } catch (IOException e) {
    e.printStackTrace();
    }
    return null;
    }
    }

package ui;

import java.awt.image.BufferedImage;
//英雄机
public class Hero extends FlyObject{
//Hero继承了FlyObject

public Hero() {
   img = App.getImg("/img/hero.png");
   x = 200;
   y = 550;
   w = img.getHeight();
   h = img.getWidth();

}
//英雄机移动到鼠标位置上的方法
public void moveToMouse(int mx,int my){
    x = mx-w/2;
    y = my-h/2;

}
//向上移动
public void moveUP(){
    y -= 10;
}
//向下移动
public void moveDown(){
    y += 10;
}
//向左移动
public void moveLeft(){
    x -= 10;
}
//向右移动
public void moveRight(){
    x += 10;
}

}

package ui;

import java.awt.image.BufferedImage;
import java.util.Random;
/**

*敌机
*1:敌机数量很多 java中存放多个数据,1)使用数组,缺点数组必须确定长度,2)使用集合 这里用集合好些
*2:敌机的数量是未知的
*/

public class Ep extends FlyObject {
//Ep 继承了FlyObject

//构造器:给敌机定型
public Ep() {
    //定义一个随机类
    Random rd = new Random();

    //img = App.getImg("/img/ep02.png");//确定敌机显示的固定图片
    //随机产生敌机图片 如果读取图片报错显示input==null 表示图片路径错误
    int index = rd.nextInt(15)+1;
    //System.out.println("/img/ep0"+index+".png");//检查原因
    //三目运算符
    //格式:条件表达式?值1:值2;表示如果条件表达式成立为true就取值1,否则取值2
    //如果index的值小于10就取0,否则就取空;
    //注意(index<10?"0":"")这个括号必须有 否则类型不同会报错
    String path = "/img/ep"+(index<10?"0":"")+index+".png";
    System.out.println(path);
    img = App.getImg(path);
   // x = 100;//位置固定
   // y = 50;//位置固定

    w = img.getWidth();
    h = img.getHeight();
    //定义随机 nextlnt(num) 表示会在[0,num]之间随机生成一个整数
    x = rd.nextInt(500-w);
    y = 0;
}
/**
 * 敌机移动的方法
 * 敌机向下移动
 */
public  void move(){
    y += 10;

}

}

package ui;
/**游戏场景中飞行物类(英雄机 ,敌机,子弹等)

  • 在开发中,常会将具有相同特点的类放在一起,将这些相同的特点抽离出来,形成一个父类

*/

import java.awt.image.BufferedImage;
//飞行物父类
public class FlyObject {
//飞行物的图片
BufferedImage img;
//飞行物的横纵坐标及大小
int x;
int y;
int w;
int h;
}

发布了174 篇原创文章 · 获赞 7 · 访问量 8410

猜你喜欢

转载自blog.csdn.net/weixin_45339692/article/details/105178070