Java项目黄金矿工小游戏

一、功能点

本项目分为15个功能点:1.窗口绘制2.勾爪往返旋转3.物体批量绘制4.双缓存解决闪动问题5.点和矩形碰撞检测6.多种类物体随机生成7.物体堆叠检测8.多种类抓取速度判定9.积分设置10.关卡设置11.重新开始12.单关卡倒计时13.金块的快速拉取14.石块爆破15.商店购物。

二、项目结构

代码结构:

 结构体:

功能实现:

在Game类中继承JFrame,对屏幕上window的对象,能够最大化、最小化、关闭。

设置了5种游戏状态(参数为state)
        0:游戏未开始
        1:游戏运行中
        2:进入商店
        3:游戏失败
        4:游戏胜利

创建石块,金块的列表集合,随机生成石块,金块,同时判断是否发生了重叠,如重叠则不可生成。

初始化窗口信息,大小、位置、标题等,根据游戏的状态应用鼠标点击,具体为左右摇摆,点击左键,抓取返回,点击右键。

当满足本关卡获胜条件,通过重复绘制图片游戏进入下一关。

调用画笔类绘制金块,石块。

三:类

主类:Game

背景类:BackGround

绳索类:Rope

父类:Object

子类:Rock,Gold

四:代码解读:

主类Game类:

public class Game extends JFrame {
    //0未开始,1表示运行中,2表示商店,3表示失败,4表示胜利
    static int state;
    //存储金块,石块
    List<Object> objectList = new ArrayList<>();

    //将图片载入到程序当中
   BackGround bg = new BackGround();
   Rope line = new Rope(this);
    {
        //是否可以放置
        boolean isPlace = true;
        for (int i=0;i<11;i++){
            double random = Math.random();
            Gold gold;//存放当前生成的金块
            if(random<0.3){
                gold = new SmallGold();
            }else if(random<0.7){
                gold = new Gold();
            }else {
                gold = new BigGold();
            }
           for (Object obj:objectList){
               if(gold.getRec().intersects(obj.getRec())){
                   //不可放置,需重新生成
                   isPlace = false;
                   i--;
               }
           }
           if (isPlace){
               objectList.add(gold);
           }else {
               isPlace = true;
               i--;
           }
        }
        for (int i=0;i<3;i++){
            Rock rock = new Rock();
            for (Object obj:objectList){
                if (rock.getRec().intersects(obj.getRec())){
                    isPlace = false;
                }
            }
            if (isPlace){
                objectList.add(rock);
            }else {
                isPlace = true;
                i--;
            }
        }
    }

   Image offScreenImage;

    void launch(){  //初始化窗口信息
        this.setVisible(true); //设置窗口是否可见
        this.setSize(768,1000);//设置窗口大小
        this.setLocationRelativeTo(null);//设置窗口位置,使窗口居中
        this.setTitle("黄金矿工");//设置窗口标题
        setDefaultCloseOperation(EXIT_ON_CLOSE);//创建关闭窗口的方法

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                switch (state){
                    case 0:
                        if (e.getButton()==3){
                            state = 1;
                            bg.startTime = System.currentTimeMillis();
                        }
                        break;
                    case 1:
                        //左右摇摆,点击左键
                        if (e.getButton()==1 && line.state==0){
                            line.state=1;
                        }
                        //抓取返回,点击右键
                        if (e.getButton()==3 && line.state==3 && BackGround.waterNum>0){
                            BackGround.waterFlag = true;
                            BackGround.waterNum--;
                        }
                        break;
                    case 2:
                        if (e.getButton()==1){
                            bg.shop = true;
                        }
                        if (e.getButton()==3){
                            state = 1;
                            bg.startTime = System.currentTimeMillis();
                        }
                        break;
                    case 3:

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

        //重复绘制图片
        while (true){
            repaint();
            nextLevel();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //下一关
    public void nextLevel(){
        if (bg.gameTime() && state == 1){
            if (BackGround.count>=bg.goal){
                if (BackGround.level == 5){
                    state = 4;
                }else {
                    state=2;
                    BackGround.level++;

                }

            }else {
                state = 3;
            }
            dispose();
            Game gameWin = new Game();
            gameWin.launch();
        }
    }

    //绘制方法
    public void paint(Graphics g){
        offScreenImage = this.createImage(768,1000);
        Graphics gImage = offScreenImage.getGraphics();

        bg.paintSelf(gImage);
        if (state == 1){
            //绘制物体
            for (Object obj:objectList){
                obj.paintSelf(gImage);
            }
            line.paintSelf(gImage);
        }
        g.drawImage(offScreenImage,0,0,null);
    }

    //程序入口
    public static void main(String[] args) {
        Game gameWin = new Game();
        gameWin.launch();
    }
}

背景BackGround类:

 定义关卡数初始化为1,目标得分,总分,药水数量,定义药水状态,默认状态时false,true表示正在使用,开始时间,结束时间,利用函数随机生成药水价格,是否进入商店;

载入背景图片,背景图片1,任务图片,药水图片;

利用paintSelf绘制图片,在游戏状态为0时,绘制准备开始字样;

                                       在游戏状态为1时,绘制药水组件,关卡数,目标积分,时间组件;

                                       在游戏状态为2时,绘制是否购买药水界面;

                                       在游戏状态为3时,绘制游戏失败界面;

                                       在游戏状态为4时,绘制游戏成功界面。        

设计游戏计时功能gameTime,返回true,倒计时完成,返回false则表示正在倒计时。

设计游戏重置元素reGame,对关卡数,目标得分,总分,药水数量,药水状态重置;

绘制字符串,设置游戏中字体的颜色,类别。

public class BackGround {
    //关卡数
    static int level = 1;
    //目标得分
    int goal = level*15;
    //总分
    static int count = 0;
    //药水数量
    static int waterNum = 3;
    //药水状态,默认是false,true表示正在使用
    static boolean waterFlag = false;
    //开始时间
    long startTime;
    //结束时间
    long endTime;
    //药水价格
    int price = (int) (Math.random()*10);
    //是否进入商店
    boolean shop = false;

    //载入图片
    Image bg = Toolkit.getDefaultToolkit().getImage("D:\\JavaLearn\\ProjectOverview\\GoldenMineral\\imgs\\bg.jpg");
    Image bg1 = Toolkit.getDefaultToolkit().getImage("D:\\JavaLearn\\ProjectOverview\\GoldenMineral\\imgs\\bg1.jpg");
    Image peo = Toolkit.getDefaultToolkit().getImage("D:\\JavaLearn\\ProjectOverview\\GoldenMineral\\imgs\\peo.png");
    Image water = Toolkit.getDefaultToolkit().getImage("D:\\JavaLearn\\ProjectOverview\\GoldenMineral\\imgs\\water.png");

    //绘制
    void paintSelf(Graphics g){
        g.drawImage(bg1,0,0,null);
        g.drawImage(bg,0,200,null);
        switch (Game.state){
            case 0:
                drawWord(g,80,Color.green,"准备开始",200,400);
                break;
            case 1:
                g.drawImage(peo,310,50,null);
                drawWord(g,30,Color.BLACK,"积分:"+count,30,150);
                //药水组件
                g.drawImage(water,450,40,null);
                drawWord(g,30,Color.BLACK,"*"+waterNum,510,70);
                //关卡数
                drawWord(g,20,Color.BLACK,"第"+level+"关",30,60);
                //目标积分
                drawWord(g,30,Color.BLACK,"目标"+goal,30,110);
                //时间组件
                endTime = System.currentTimeMillis();
                long tim = 20-(endTime-startTime)/1000;
                drawWord(g,30,Color.BLACK,"时间"+(tim>0?tim:0),520,150);
                break;
            case 2:
                g.drawImage(water,300,400,null);
                drawWord(g,30,Color.BLACK,"药水价格"+waterNum,300,500);
                drawWord(g,30,Color.BLACK,"是否购买"+waterNum,300,550);
                if(shop){
                    count = count-price;
                    waterNum++;
                    shop = false;
                    Game.state = 1;
                    startTime = System.currentTimeMillis();
                }
                break;
            case 3:
                drawWord(g,80,Color.cyan,"失败",250,350);
                drawWord(g,80,Color.cyan,"积分"+count,200,450);
                break;
            case 4:
                drawWord(g,80,Color.red,"成功",250,350);
                drawWord(g,80,Color.red,"积分"+count,200,450);
                break;
            default:
        }

    }
    //true倒计时完成,false正在倒计时
    boolean gameTime(){
        long tim = (endTime-startTime)/1000;
        if(tim>20){
            return true;
        }
        return false;
    }
    //重置元素
    void reGame(){
        //关卡数
        int level = 1;
        //目标得分
        int goal = level*15;
        //总分
        int count = 0;
        //药水数量
        int waterNum = 3;
        //药水状态,默认是false,true表示正在使用
        boolean waterFlag = false;
    }

    //绘制字符串
    public static void drawWord(Graphics g,int size,Color color,String str,int x,int y){
        g.setColor(color);
        g.setFont(new Font("仿宋",Font.BOLD,size));
        g.drawString(str,x,y);

    }
}

父类Object类:

 定义坐标,宽高,图片,标记是否移动,质量,积分,类型。

public class Object {
    //坐标
    int x;
    int y;
    //宽高
    int width;
    int height;
    //图片
    Image img;
    //标记是否能移动
    boolean flag;
    //质量
    int m;
    //积分
    int count;
    //类型1金块,2石块
    int type;

    void paintSelf(Graphics g){
        g.drawImage(img,x,y,null);
    }

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

子类Rock类:

继承父类Object类;

利用函数使石块的位置随机生成 ;

定义石块的基本属性。

public class Rock extends Object{
    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 = 50;
        this.count = 1;
        this.type = 2;
        this.img = Toolkit.getDefaultToolkit().getImage("D:\\JavaLearn\\ProjectOverview\\GoldenMineral\\imgs\\rock1.png");
    }
}

 子类Gold类:

继承父类Object类;

Gold类又细分成Gold类,BigGold类,SmallGold类;

利用函数使金块的位置随机生成 ;

定义金块的基本属性。

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("D:\\JavaLearn\\ProjectOverview\\GoldenMineral\\imgs\\gold1.gif");

    }
}

class SmallGold extends Gold{
    SmallGold(){
        this.width = 36;
        this.height = 36;
        this.m = 15;
        this.count = 2;
        this.img = Toolkit.getDefaultToolkit().getImage("D:\\JavaLearn\\ProjectOverview\\GoldenMineral\\imgs\\gold0.gif");

    }
}
class BigGold extends Gold {
    BigGold() {
        this.x = (int) (Math.random()*650);
        this.width = 105;
        this.height = 105;
        this.m = 60;
        this.count = 8;
        this.img = Toolkit.getDefaultToolkit().getImage("D:\\JavaLearn\\ProjectOverview\\GoldenMineral\\imgs\\gold2.gif");

    }
}

绳索Rope类:

 定义绳索的起点坐标,终点坐标,绳索长,绳索长最小值,最大值,方向参数,状态0摇摆,1抓取,2收回,3抓取收回,设置勾爪图片;

碰撞检测logic,检测物体是否被抓取;

通过调用绳索的绘制方法绘制绳索的图像;

传入画笔;        

重置绳索。

public class Rope {
    //绳索的起点坐标
    int x = 380;
    int y = 180;
    //终点坐标
    int endx = 500;
    int endy = 500;
    //绳索长
    double length = 100;
    //绳索长最小值
    double MIN_length = 100;
    //绳索长最大值
    double MAX_length = 750;
    double n = 0;
    //方向参数
    int dir = 1;
    //状态0摇摆,1抓取,2收回,3抓取返回
    int state;
    //勾爪图片
    Image hook = Toolkit.getDefaultToolkit().getImage("D:\\JavaLearn\\ProjectOverview\\GoldenMineral\\imgs\\hook.png");


    Game frame;

    Rope(Game frame){
        this.frame = frame;
    }

    //碰撞检测,检测物体是否被抓取
    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;
            }
        }

    }

    //绘制方法
    void lines(Graphics g){
        endx = (int) (x + length * Math.cos(n * Math.PI));
        endy = (int) (y + length * Math.sin(n * Math.PI));
        g.setColor(Color.red);
        g.drawLine(x-1,y,endx-1,endy);
        g.drawLine(x, y, endx, endy);
        g.drawLine(x+1,y,endx+1,endy);
        g.drawImage(hook,endx-36,endy-2,null);
    }


    void paintSelf(Graphics g){  //传入画笔
        logic();
        switch (state){
            case 0:
                //绘制方法
                if (n<0.1){
                    dir = 1;
                }else if (n>0.9){
                    dir = -1;
                }
                n = n+0.005*dir;
               lines(g);
                break;
            case 1:
                if(length<MAX_length) {
                    length = length + 5;
                   lines(g);
                }else {
                    state = 2;
                }
                break;
            case 2:
                if (length>MIN_length) {
                    length = length - 5;
                   lines(g);
                }else {
                    state = 0;
                }
                break;
            case 3:
                int m = 1;
                if (length>MIN_length) {
                    length = length - 5;
                    lines(g);
                    for (Object obj:this.frame.objectList) {
                        if (obj.flag){
                            m = obj.m;
                            obj.x = endx - obj.getWidth()/2;
                            obj.y = endy;
                            if (length <= MIN_length) {
                                obj.x = -150;
                                obj.y = -150;
                                obj.flag = false;
                                BackGround.waterFlag = false;
                                //加分
                                BackGround.count += obj.count;
                                state = 0;
                            }
                            if(BackGround.waterFlag){
                                if(obj.type==1){
                                    m = 1;
                                }
                                if (obj.type==2){
                                    obj.x = -150;
                                    obj.y = -150;
                                    obj.flag = false;
                                    BackGround.waterFlag = false;
                                    state = 2;
                                }
                            }
                        }
                    }
                }
                try {
                    Thread.sleep(m);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;

            default:
        }

    }
    //重置线
    void reGame(){
        n = 0;
        length = 100;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值