zoukankan      html  css  js  c++  java
  • 飞机游戏

    这篇是暑假在家写的一个java小游戏,废话不多说,先上图看看具体的效果

    初始化页面,由用户输入子弹的数目和子弹的速度

    用户输入子弹的数目和子弹的速度后,进入游戏页面,比如子弹个数是11子弹速度为3得到如下主页面

    一共11个子弹。用户通过坐上右下方向键控制飞机移动的方向躲避子弹,如果碰到子弹则游戏结束出现如下页面显示用户玩的时间

    和最终的分,击败玩家的百分比

     下面介绍源代码

    飞机类:

    package Mygame;

    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.KeyEvent;

    public class Plane extends GameObject{
    static boolean live =true;
    static int speed=20;
    boolean left,right,up,down;
    public void drawSelf(Graphics g) {//测量飞机的位置并保证飞机不飞向窗口外面
    if(live) {

    g.drawImage(img, (int)x, (int)y,null);
    if(left==true && x>20) {
    x-=speed;
    }
    if(right==true && x+speed<Constant.Game_Width-170) {
    x+=speed;
    }
    if(up==true && y>=10) {
    y-=speed;
    }
    if(down==true && y<Constant.Game_Height-170) {
    y+=speed;
    }

    }
    }
    public Plane(Image img,double x,double y) {//获取飞机的位置和飞机的大小
    this.img=img;
    this.x=x;
    this.y=y;
    this.height=img.getHeight(null);
    this.width=img.getWidth(null);
    }
    public void addDirection(KeyEvent e) {//按下某个键,增加相应的方向
    switch(e.getKeyCode()) {
    case KeyEvent.VK_LEFT:
    left=true;
    break;
    case KeyEvent.VK_RIGHT:
    right=true;
    break;
    case KeyEvent.VK_UP:
    up=true;
    break;
    case KeyEvent.VK_DOWN:
    down=true;
    break;

    }

    }
    public void minuDirection(KeyEvent e) {//松开某个键,取消相应的方向
    switch(e.getKeyCode()) {
    case KeyEvent.VK_LEFT:
    left=false;
    break;
    case KeyEvent.VK_RIGHT:
    right=false;
    break;
    case KeyEvent.VK_UP:
    up=false;
    break;
    case KeyEvent.VK_DOWN:
    down=false;
    break;

    }
    }
    }

    子弹shell类

    package Mygame;

    import java.awt.Color;
    import java.awt.Graphics;

    public class Shell extends GameObject{
    double degree;
    public Shell() {
    x=200;
    y=200;
    width=20;
    height=20;
    speed=FirstWindow.sp;

    degree = Math.random()*Math.PI*2;
    }
    public void draw(Graphics g) {
    Color c=g.getColor();
    g.setColor(c.RED);
    g.fillOval((int)x,(int) y, width, height);
    y+=speed*Math.sin(degree);//炮弹沿着任意角度飞
    x+=speed*Math.cos(degree);
    if(x<0 || x>Constant.Game_Width-20) {//控制子弹反弹
    degree=Math.PI-degree;

    }
    if(y<0 || y>Constant.Game_Height-20) {//控制子弹反弹
    degree=-degree;

    }

    }

    常量类,控制主窗口的大小

    public class Constant {
    public static final int Game_Width=1000;
    public static final int Game_Height=1000;
    }

    加载图片类

    public class GameUtil {
    private GameUtil() {

    }
    public static Image getImage(String path) {
    BufferedImage bi=null;
    try {
    URL u=GameUtil.class.getClassLoader().getResource(path);
    bi=ImageIO. read(u);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return bi;
    }
    }//具体的图片可以自己找,我就不放上去了

    声明游戏物体的父类

    public class GameObject {
    Image img;
    double x,y;
    int speed;
    int height,width;
    public void drawSelf(Graphics g) {
    g.drawImage(img, (int)x, (int)y,null);
    }
    public GameObject() {
    super();
    }
    public GameObject(Image img, double x, double y) {
    super();
    this.img = img;
    this.x = x;
    this.y = y;
    }
    public Rectangle getRect() {//返回物体所在的矩形,判断物体是否相撞
    return new Rectangle((int)x,(int)y,width,height);
    }
    }

    初始化窗口用来初始化子弹的数目和速度

    public class FirstWindow extends JFrame {

    static int sum=0;
    static int sp =0;
    JTextField tf_length;
    JTextField speed;
    static JButton btn;
    static boolean flag=true;

    public FirstWindow() {
    super("初始化");
    this.setBounds(800, 300, 450, 220);
    this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
    this.getContentPane().setLayout(new FlowLayout(FlowLayout.RIGHT));
    JPanel p1=new JPanel();
    p1.add(new JLabel("请输入子弹数"));
    tf_length=new JTextField(5);
    p1.add(tf_length);
    p1.add(new JLabel("请输入子弹速度"));
    speed=new JTextField(5);
    p1.add(speed);
    btn=new JButton("确定");
    btn.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
    try {
    sum=Integer.parseInt(tf_length.getText());
    sp=Integer.parseInt(speed.getText());
    flag=false;
    setVisible(false);
    MyGameWindow my=new MyGameWindow();
    my.launchFrame();
    System.out.println(flag);

    } catch (NumberFormatException e1) {
    // TODO Auto-generated catch block
    System.out.println("输入有误,请重新输入");
    }

    }
    });
    p1.add(btn);
    this.getContentPane().add(p1);
    this.setVisible(true);

    }
    public static void main(String[] args) {
    FirstWindow firstWindow=new FirstWindow();

    }

    }

    飞机类主窗口

    public class MyGameWindow extends Frame {

    Image plane=GameUtil.getImage("Mygame/fly.png");
    Image over=GameUtil.getImage("Mygame/over.jpg");
    Image bg=GameUtil.getImage("Mygame/xingkong.jpg");
    Plane plane1=new Plane(plane,450,700);
    boolean flag=true;
    Shell shell=new Shell();
    FirstWindow firstWindow=new FirstWindow();

    Shell[]shells=new Shell[FirstWindow.sum];
    Date startTime=new Date();
    Date endTime;
    int period;
    int a=0;
    @Override
    public void paint(Graphics g) {//自动被调用,g相当于一个画笔
    g.drawImage(bg, 0, 0, null);

    plane1.drawSelf(g);
    for (int i = 0; i < shells.length; i++) {
    shells[i].draw(g);
    Boolean b=shells[i].getRect().intersects(plane1.getRect());//碰撞检测
    if(b) {
    Plane.live=false;
    flag=false;
    if(a==0)
    a++;
    endTime =new Date();
    period=(int)((endTime.getTime()-startTime.getTime())/1000);
    if(a==1) {
    a=period;
    }
    }
    if(flag==false) {
    g.drawImage(over, 400,400, null);
    Font f=new Font("宋体",Font.BOLD,40);
    g.setColor(Color.yellow);
    g.setFont(f);
    if(a>100) {
    a=100;
    }
    g.drawString("时间:"+ a+"秒,"+"得分:"+a*FirstWindow.sum*FirstWindow.sp+" ",300 ,100);
    g.drawString(" 击败全球"+(a*FirstWindow.sum*FirstWindow.sp)/40.0+"%"+"的玩家", 270, 150);

    }

    }


    }
    class PaintThread extends Thread{
    @Override
    public void run() {
    while(true) {
    repaint();//重画
    try {
    Thread.sleep(40);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    }
    }
    public void launchFrame()
    {
    this.setBackground(Color.yellow);
    this.setTitle("飞机飞行");
    this.setVisible(true);
    this.setBounds(400, 50, Constant.Game_Height,Constant.Game_Width);
    this.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosed(WindowEvent e) {//alt+?给出提示
    System.exit(1);
    }
    });
    new PaintThread().start();
    addKeyListener(new KeyMonitor());
    //初始化多个子弹
    for (int i = 0; i < shells.length; i++) {
    shells[i]=new Shell();
    }
    }
    class KeyMonitor extends KeyAdapter{//定义键盘监听
    @Override
    public void keyPressed(KeyEvent e) {
    plane1.addDirection(e);
    }
    @Override
    public void keyReleased(KeyEvent e) {
    plane1.minuDirection(e);

    }
    }
    public static void main(String[] args) {
    MyGameWindow a=new MyGameWindow();
    a.launchFrame();
    }
    private Image offScreenImage=null;
    public void update(Graphics g) {//利用双缓冲解决闪屏问题

    if(offScreenImage == null)
    offScreenImage =this.createImage(Constant.Game_Height,Constant.Game_Width);
    Graphics gOff=offScreenImage.getGraphics();
    paint(gOff);
    g.drawImage(offScreenImage, 0, 0, null);
    }
    }

  • 相关阅读:
    Android系统启动过程分析
    android的logcat 用法整理
    git 使用详解(10) 远程分支
    android的logcat 用法整理
    android Binder工作流程
    android Binder工作流程
    git log 小结
    linux patch 命令小结
    windows 中 \r\n 区别于 类unix中的\n 疑问 迎刃而解
    Mysql Error Code : 1436 Thread stack overrun
  • 原文地址:https://www.cnblogs.com/henuliulei/p/9428596.html
Copyright © 2011-2022 走看看