idea学习第五天

解决组件闪动问题

在前面的代码中,由于组件不停的分别绘制,会出现明显闪动问题,若将所有组件绘制到同一个画布里,重新绘制时绘制整个画布,就可以有效解决闪动问题。

在窗体中定义一个画布

Image offScreenImage;//定义画布

在绘制函数中将所有的组件都绘制到画布中,并绘制整个画布

public void paint(Graphics g) {//调用绘制函数

        offScreenImage=this.createImage(768,1000);
        Graphics gImage=offScreenImage.getGraphics();

        bg.paintSelf(gImage);
        line.paintSelf(gImage);
        gold.paintSelf(gImage);

        g.drawImage(offScreenImage,0,0,null);
    }

由于前期创建背景类时使用了bg,为避免混淆,今天把它改为了Bg,修改类名时不小心把绘制部分中调用的Bg类中的变量bg也改掉了,导致背景中绘制自己的函数出错。调用时要使用前面定义的变量。还有就是,如果重新写了程序,请一定要记得把外部的图片等素材复制进去,,,

金块抓取收回

为金块添加一个状态3,抓取收回,当线的endx和endy在金块的坐标内时状态为3

//状态 0 摇摆  1 向下抓取  2 收回  3抓取返回
    int state;

    GameWin frame;//使线类可以接收到主窗口中的元素

    Line(GameWin frame){this.frame=frame;}

    void logic(){
        if (endx>this.frame.gold.x && endx<this.frame.gold.x+this.frame.gold.width
                && endy>this.frame.gold.y && endy<this.frame.gold.y+this.frame.gold.height){
            state=3;
        }


void paintSelf(Graphics g){
        logic();
    switch (state){
        //状态0,1,2省略
            case 3:
                if (length>100) {
                    length = length - 10;
                    lines(g);
                    this.frame.gold.x=endx-26;
                    this.frame.gold.y=endy;
                }else {
                    this.frame.gold.x=-150;
                    this.frame.gold.y=-150;
                    state=0;
                }
                break;
    }

多个金块

public class GameWin extends JFrame {          //创建窗口

    List<Object> objectList = new ArrayList<>();//存储金块,石块
    Bg bg=new Bg();
    Line line=new Line(this);

    {//不能直接在类中使用for循环,可以构造无参构造或代码块
        for (int i = 0; i < 3; i++) {
            objectList.add(new Gold());
        }
    }

    Image offScreenImage;//定义画布

    void launch(){
        this.setVisible(true);                //设置窗口是否可见
        this.setSize(768,700);   //直接输入数字即可
        this.setLocationRelativeTo(null);     //窗口居中
        this.setTitle("黄金矿工");             //窗口名称

        setDefaultCloseOperation(EXIT_ON_CLOSE);//关闭窗口

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                if(e.getButton()==1);//左轮为e
                {line.state=1;}
            }
        });

        while(true){//死循环
            repaint();//使线段不停的重新绘制,即使线可以进行摇摆

            try {
                Thread.sleep(10);//设置时延
            } catch (InterruptedException e) {
                e.printStackTrace();//编写时会发生异常,直接选择try catch解决
            }
        }
    }

    @Override
    public void paint(Graphics g) {//调用绘制函数

        offScreenImage=this.createImage(768,700);
        Graphics gImage=offScreenImage.getGraphics();

        bg.paintSelf(gImage);
        line.paintSelf(gImage);

        for (Object obj:objectList){//增强for循环
            obj.paintSelf(gImage);
        }

        g.drawImage(offScreenImage,0,0,null);
    }

    public static void main(String[] args) { //输入psvm直接声明主函数
        GameWin gameWin=new GameWin();
        gameWin.launch();                    //new一个类后才能调用这个类
    }
}

 线类中

Line(GameWin frame){this.frame=frame;}

    void logic(){
        for (Object obj:this.frame.objectList){//增强for循环
            if (endx>obj.x && endx<obj.x+obj.width
                    && endy>obj.y && endy<obj.y+obj.height){
                state=3;
            }
        }

    }
//前后不再写,直接写case 3
            case 3:
                if (length>100) {
                    length = length - 10;
                    lines(g);
                    for (Object obj:this.frame.objectList) {//增强for循环
                        obj.x=endx-26;
                        obj.y=endy;
                        if (length<=100){
                            obj.x=-150;
                            obj.y=-150;
                            state=0;
                        }
                    }
                }
                break;

多次使用循环增强,感觉冗余度有点高,使用无参构造应该好一点。 

金块类

public class Gold extends Object{
    Gold(){//金块生成位置,因此要设置为变量,使用随机数
        this.x=(int) (Math.random()*700);//窗体大小为768,设置为700防止金块生成在窗体外
        this.y=(int) (Math.random()*400+210);//防止金块生成在天上
        this.width=52;
        this.height=52;
        this.img= Toolkit.getDefaultToolkit().getImage("imgs/gold1.gif");
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值