黄金矿工java实现

项目价值:

1.可以熟悉下java的可视化界面编程,整个项目并没有使用封装、多台的相关知识,继承性和重写用到了。

2.整个项目只用到了JavaSE的基础知识,更多的是对JFrame类中pain方法的重写。

3.我对着视频手敲一遍用了6个小时左右,视频在的部分章节存在问题,我在评论区留言了,没有时间的不建议,对于学习Java意义不大,但是可能会增加学习Java的兴趣。


项目用到的图片

imags文件下的图片


项目代码:

背景类BackGroundImgs:

package GoldMiner.com.ALi;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;

/**
 * @author :ALi
 * @date :Created in 2021/10/31 9:36
 * @description:背景图片加载类
 * @modified By:
 * @version: $
 */
public class BackGroundImgs {
    /**
     * 获取图片
     * @param backGround为加载的背景图片
     */
    private Image backGround = Toolkit.getDefaultToolkit().getImage("imgs/bg.jpg");
    private Image backGround_sky = Toolkit.getDefaultToolkit().getImage("imgs/bg1.jpg");
    private Image backGround_person = Toolkit.getDefaultToolkit().getImage("imgs/peo.png");
    private Image backGround_water = Toolkit.getDefaultToolkit().getImage("imgs/water.png");
    //总分
    protected static int count = 0;
    //药水数量:初始值为3
    protected static int WaterNamber = 3;
    //药水状态 false为未使用
    protected static boolean WaterFlag = false;
    //关卡数
    protected static int level = 1;
    //关卡目标得分
    protected static int goal = level*15;
    //开始时间
    protected static long startTime;
    //关闭时间
    protected static long endTime;
    //药水价格
    protected int price = (int)(Math.random()*10);
    //是否进入商店
    protected boolean shop = false;
    /**
     * 将图片画在窗口上
     * @param graphics 画笔
     */
    void painImgs(Graphics graphics){

        //绘制背景图片(人,天空,地下)
        graphics.drawImage(backGround,0,200,null);
        graphics.drawImage(backGround_sky,0,0,null);
        switch (GameWin.state){
            case 0:
                drawWord(graphics,70,"右键进入游戏",170,400,Color.BLACK);
                break;
            case 1:
                graphics.drawImage(backGround_person,310,50,null);
                //药水
                graphics.drawImage(backGround_water,450,40,null);
                drawWord(graphics,30,"*"+WaterNamber,510,70,Color.BLACK);

                drawWord(graphics,30,"积分:"+count,30,150,Color.BLACK);

                //绘制关卡数
                drawWord(graphics,20,"第:"+level+" 关",30,60,Color.BLACK);
                //显示积分
                drawWord(graphics,30,"目标:"+goal,30,110,Color.BLACK);
                //实时赋值
                endTime = System.currentTimeMillis();
                long tim = 20 - (endTime - startTime)/1000;
                drawWord(graphics,30,"时间:"+(tim>0?tim:0),520,150,Color.BLACK);

                break;
            case 2:
                graphics.drawImage(backGround_water,300,400,null);
                //显示积分
                drawWord(graphics,30,"价格:"+price,300,500,Color.BLACK);
                drawWord(graphics,30,"是否购买:",300,550,Color.BLACK);
                if(shop){
                    count = count - price;
                    WaterNamber++;
                    shop = false;
                    GameWin.state = 1;
                    startTime = System.currentTimeMillis();
                }
                break;
            case 3:
                drawWord(graphics,80,"失败",250,350,Color.red);
                drawWord(graphics,80,"积分:"+count,200,450,Color.red);
                break;
            case 4:
                drawWord(graphics,80,"成功",250,350,Color.green);
                drawWord(graphics,80,"积分:"+count,200,450,Color.green);
                break;
            default:
        }



    }
    /**
     * create by: ALi
     * description: 打印字符串
     * create time: 2021/10/31 13:57
     * @Param: null
     * @return
     */
    public static void drawWord(Graphics graphics,int size,String str,int x,int y,Color color){
        //显示积分
        graphics.setColor(color);
        graphics.setFont(new Font("仿宋",Font.BOLD,size));
        graphics.drawString(str,x,y);
    }

    /**
     * create by: ALi
     * description: 判断是否完成关卡
     * create time: 2021/10/31 15:28
     *
      * @Param: null
     * @return
     */
    public boolean gameTime(){
        long tim = (endTime - startTime)/1000;
        if (tim >20){
            return true;
        }else{
            return false;
        }
    }

    public void reGame(){
        level = 1;
        goal  = level * 15;
        count = 0;
        WaterNamber = 3;
        WaterFlag = false;

    }
}


主窗口GameWin类:

package GoldMiner.com.ALi;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.ArrayList;

/**
 * @author :ALi
 * @date :Created in 2021/10/31 9:11
 * @description:窗口绘制
 * @modified By:
 * @version: $
 */
public class GameWin extends JFrame {

    //加载背景图类
    BackGroundImgs bg = new BackGroundImgs();
    //划线类
    Line l = new Line(this);
    //金块
//    Gold gold = new Gold();//不在需要,直接在金块集合中用
    //画布
    Image offScreenImage;

    //金块集合.存储金块,石块
    List objectList = new ArrayList<>();
    //游戏状态 0:准备开始,1:运行中,2:商店,3:失败,4:胜利
    protected static int state;

    //代码块设置个数
    {
        //是否可以放置
        boolean isPlace = true;
        //金块
        for (int i = 0;i <= 10;i++){
            double random = Math.random();//按照比例生成大小中金块
            Gold gold;//存放到当前金块,来判断位置
            if(random<0.3){
                gold = new GoldMini();

            }else if(random<0.7){
                gold = new Gold();

            }else{
                gold = new GoldPlus();

            }
            for (Object obj:objectList){
                if (gold.getRec().intersects(obj.getRec())){
                    //重叠了不放置,重新生成
                    isPlace = false;
                }
            }
            if(isPlace == true){
                objectList.add(gold);
            }else{
                isPlace = true;
                i--;
            }

        }
        //石块
        for (int i = 0;i <= 2;i++){
            Rock rock = new Rock();
            //判断是否重合
            for(Object obj:objectList){
                if(rock.getRec().intersects(obj.getRec())){
                    isPlace = false;
                }
            }
            if(isPlace == true){
                objectList.add(rock);
            }else {
                isPlace = true;
                i--;
            }

        }
    }



    /**
     * 加载窗口函数
     */
    void launch(){
        this.setVisible(true);//窗口可见
        this.setSize(768,1000);//窗口大小
        this.setLocationRelativeTo(null);//窗口居中
        this.setTitle("黄金矿工");

        setDefaultCloseOperation(EXIT_ON_CLOSE);//点击关闭后关闭窗口

        //鼠标事件
        /**
         * create by: ALi
         * description: 鼠标点击事件
         * create time:  10:13
         * @Param: 1 鼠标左键,2 滚轮,3 鼠标右键
         * @return void
         */
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                switch (state){
                    case 0:
                        //右键开始游戏
                        if(e.getButton() == 3){
                            state = 1;
                            BackGroundImgs.startTime = System.currentTimeMillis();
                        }
                        break;
                    case 1:
                        //左右摇摆,点击左键抓取
                        if(e.getButton() == 1){
                            l.state = 1;
                        }
                        //抓取返回
                        if(e.getButton() == 3 && l.state == 3 && BackGroundImgs.WaterNamber > 0){
                            BackGroundImgs.WaterNamber--;
                            BackGroundImgs.WaterFlag = true;
                        }
                        break;
                    case 2:
                        if(e.getButton() == 1){
                            bg.shop = true;
                        }else if(e.getButton() == 3){
                            state = 1;
                            BackGroundImgs.startTime = System.currentTimeMillis();

                        }
                        break;
                    case 3:
                    case 4:
                        if(e.getButton() == 1){
                            state = 0;
                            bg.reGame();
                            l.reGame();
                        }
                        break;
                    default:
                }

            }
        });

        //一直绘图片
        while(true){
            repaint();
            nextLevel();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * create by: ALi
     * description: 下一关
     * create time: 2021/10/31 14:18
     *
     * @Param: null
     * @return
     */
    public void nextLevel(){
        if(state == 1 && bg.gameTime() == true){

            if (BackGroundImgs.count >= BackGroundImgs.goal){

                if(BackGroundImgs.level == 5){
                    state = 4;//成功
                }else{
                    state = 2;
                    BackGroundImgs.startTime = System.currentTimeMillis();
                    BackGroundImgs.level++;
                    //目标数设置为leve*15
                    BackGroundImgs.goal = BackGroundImgs.level*15;
//                    //当前得分为0;
//                    BackGroundImgs.count = 0;
//                    state = 1;

                }


            }else{
                    state = 3;
            }
            //释放之前的窗体
            dispose();
            GameWin gameWin1 = new GameWin();
            gameWin1.launch();

        }

    }


    /**
     * 重写paint方法,绘制图片。将背景图片与窗口进行关联,并且将起始坐标为(0,0)
     * @param g 画图的参数
     */
    @Override
    public void paint(Graphics g) {
        //定义画布可以解决闪动问题,类似于一层一层画布覆盖了,之前是覆盖背景再画物体,
        //现在是将所有物体画在画布上,然后将画布画在背景上
        offScreenImage = this.createImage(768,1000);
        //给画布添加画笔
        Graphics gImage = offScreenImage.getGraphics();

        //绘制背景图片
        bg.painImgs(gImage);

        //线和物体在游戏中绘制
        if(state ==1 ){
            //从金块集合中画金块(多个金块)
            for (Object obj:objectList){
                obj.PaintLump(gImage);
            }
            //绘制红线
            l.paintLine(gImage);
        }

        //绘制画布
        g.drawImage(offScreenImage,0,0,null);
    }

    public static void main(String [] str){
        GameWin gameWin = new GameWin();
        gameWin.launch();
    }

}

物体Object类(石块和黄金的父类)

注:此类名字尽量不要用Object会与java中的Object同名,最好换一个名字

package GoldMiner.com.ALi;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;

/**
 * @author :ALi
 * @date :Created in 2021/10/31 10:29
 * @description:石块和金块的公共属性类
 * @modified By:
 * @version: $
 */
public class Object {
    //坐标
    protected int x;
    protected int y;
    //宽高
    protected int width;
    protected int height;
    //图片
    protected Image img;
    //标记是否移动 0:不可以移动
    protected boolean flag;
    //质量属性
    protected int m;
    //积分
    protected int count;
    //类型:1 is glod,2 is rock
    protected int type;

    void PaintLump(Graphics graphics){
        graphics.drawImage(img,x,y,null);
    }

    //获取矩阵的宽
    public int getWidth() {
        return width;
    }
    //获取矩形
    public Rectangle getRec(){
        return new Rectangle(x,y,width,height);
    }

}

黄金 Gold类

package GoldMiner.com.ALi;

import javax.tools.Tool;
import java.awt.Toolkit;

/**

●  @author  :ALi  
●  @date  :Created in 2021/10/31 10:34  
●  @description:金块类 
●  @modified  By:  
●  @version: $
*/
public class Gold extends Object {
Gold(){
this.x = (int)(Math.random()*700);
this.y = (int)(Math.random()*550+300);
this.width = 52;
this.height = 52;
this.flag = false;
this.m = 30;
this.count = 4;
this.type = 1;
this.img = Toolkit.getDefaultToolkit().getImage("imgs/gold1.gif");
} 

}
class GoldMini extends Gold{
public GoldMini() {
this.width = 36;
this.height = 36;
this.m = 15;
this.count = 2;
this.img = Toolkit.getDefaultToolkit().getImage("imgs/gold0.gif");
}
}

class GoldPlus extends Gold{
public GoldPlus() {
this.x = (int)(Math.random()*650);
this.width = 105;
this.height = 105;
this.m = 60;
this.count = 8;
this.img = Toolkit.getDefaultToolkit().getImage("imgs/gold2.gif");
}
}

石块Rock类

package GoldMiner.com.ALi;

import java.awt.Toolkit;

/**
 * @author :ALi
 * @date :Created in 2021/10/31 11:27
 * @description:石块类
 * @modified By:
 * @version: $
 */
public class Rock extends Object {
    public Rock() {
        this.x = (int)(Math.random()*700);
        this.y = (int)(Math.random()*550+300);
        this.width = 71;
        this.height = 71;
        this.flag = false;
        this.m = 80;
        this.count = 1;
        this.type = 2;
        this.img = Toolkit.getDefaultToolkit().getImage("imgs/rock1.png");
    }

}

画线Line类

注:这个是项目的核心

package GoldMiner.com.ALi;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;

/**
 * @author :ALi
 * @date :Created in 2021/10/31 9:56
 * @description:划线的类
 * @modified By:
 * @version: $
 */
public class Line {
    //起点坐标
    private int x = 380;
    private int y = 180;

    //终点坐标
    private int endx = 500;
    private int endy = 500;
    //设置线的长度
    private double length = 100;
    //线的角度(角度在0~π之间,用angle*π来定角度)
    private double angle = 0;
    //判断方向的参数
    private int dir = 1;
    //判断红线的状态 0 左右摇摆,1 抓取 2 收回 不能设置为private,在GameWin中更改了值
    protected int state;
    //主窗口元素.用来判定抓取金块
    protected GameWin frame;
    //狗爪图片
    protected static Image hook = Toolkit.getDefaultToolkit().getImage("imgs/hook.png");
    //设置线的最大最小长度
    protected double min_length = 100;
    protected double max_length = 750;

    //构造函数
    Line(GameWin frame){
        this.frame = frame;
    }

    /**
     * create by: ALi
     * description: 判断红线是否碰到了金块
     * create time: 2021/10/31 10:56
     * @Param: null
     * @return
     */
    void logic(){
        //遍历多个金块进行判断
        for (Object obj:this.frame.objectList){
            if (endx > obj.x && endx < obj.x + obj.width
                    && endy > obj.y && endy < obj.y + obj.height){
                state = 3;
                obj.flag = true;
            }
        }

    }

    /**
     * create by: ALi
     * description: 画线的方法
     * create time: 2021/10/31 10:26
     * @Param: null
     * @return
     */
    void drawline(Graphics graphics){
        endx = (int)(x + length*Math.cos(angle*Math.PI));
        endy = (int)( y + length*Math.sin(angle*Math.PI));
        graphics.setColor(Color.red);
        //将线加粗
        graphics.drawLine(x-1,y-1,endx-1,endy);
        graphics.drawLine(x,y,endx,endy);
        graphics.drawLine(x+1,y+1,endx+1,endy);

        graphics.drawImage(hook,endx-36,endy-2,null);
    }

    /**
     * create by: ALi
     * description: 按照鼠标点击事件选择画线的方式:0 左右摇摆,1 抓取 2 收回 3抓取返回(有速度差别)
     * create time: 2021/10/31 10:27
     *
     * @Param: null
     * @return
     */
    void paintLine(Graphics graphics){
        logic();
        //0 左右摇摆,1 抓取 2 收回
        switch (state){
            case 0:
                //设置角度
                if(angle < 0.1 ){
                    dir = 1;
                }else if(angle > 0.9){
                    dir = -1;
                }
                angle = angle + 0.005*dir;
                drawline(graphics);
                break;
            case 1:
                //线的长度小于500则延长
                if(length < max_length){
                    length = length + 10;
                    drawline(graphics);
                }else{
                    state = 2;
                }
                break;
            case 2:
                //收回线长变小
                if(length > min_length){
                    length =length - 10;
                    drawline(graphics);
                }else{
                    state = 0;
                }
                break;
            case 3:
                int m = 1;//接收金块或石块的质量
                //遍历多个金块
                //碰到金块,收回线长变小
                if(length > min_length){
                        for (Object obj:this.frame.objectList){
                            if(obj.flag == true){
                                m = obj.m;
                                length =length - 10;
                                drawline(graphics);
                                obj.x = endx - obj.getWidth()/2;
                                obj.y = endy;
                                if (length <= min_length){
                                    obj.x = -150;
                                    obj.y = -150;
                                    obj.flag = false;
                                    //计算积分
                                    BackGroundImgs.count+=obj.count;
                                    state = 0;
                                }
                                if(BackGroundImgs.WaterFlag == true){
                                    //glod
                                    if(obj.type == 1){
                                        m=1;
                                        BackGroundImgs.WaterFlag = false;
                                    }
                                    //rock
                                    if(obj.type == 2){
                                        obj.x = -150;
                                        obj.y = -150;
                                        obj.flag = false;
                                        BackGroundImgs.WaterFlag = false;
                                        state = 2;
                                    }
                                }
                            }

                        }

                }
                try {
                    Thread.sleep(m);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            default:
        }


    }
    /**
     * create by: ALi
     * description: 重置线的元素
     * create time: 2021/10/31 16:24
     *
      * @Param: null
     * @return
     */
    public void reGame(){
        angle = 0;
        length = 100;

    }

}

你可能感兴趣的:(java,java,开发语言,后端)