【问题标题】:Loop in a JApplet animation Java在 JApplet 动画 Java 中循环
【发布时间】:2013-10-29 18:33:57
【问题描述】:
import java.awt.Graphics;
import javax.swing.JApplet;
import javax.swing.JPanel;

public class Circle extends JPanel {

    int x = 75;
    int y = 100;
    int diameter = 50;

    public void setAnimationY(int y) {
        this.y = y;
    }

    public int getAnimationY() {
        return y;
    }

    public int getDiameter() {
        return diameter;
    }

    public void setDiameter(int startDiameter) {
        diameter = startDiameter;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawOval(x, y, diameter, diameter);
    }
}


import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JApplet;
import javax.swing.JPanel;
import javax.swing.Timer;

public class BouncingBall extends JApplet {

    private int speed = 5;
    private Timer timer;
    private Circle draw;

    @Override
    public void init() {
        super.init();
        setLayout(new BorderLayout());
        draw = new Circle();
        add(draw);
        timer = new Timer(30, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int y = draw.getAnimationY();
                int diameter = draw.getDiameter();
                int roof = getHeight();
                y += speed;
                if (y < 0) {
                    y = 0;
                    speed *= -1;
                } else if (y + diameter > roof) {
                    y = roof - diameter;
                    speed *= -1;
                }
                draw.setAnimationY(y);
                repaint();
            }
        });
    }

    @Override
    public void start() {
        super.start();
        timer.start();
    }

    @Override
    public void stop() {
        timer.stop();
        super.stop();
    }
}

我正在尝试创建一个 JApplet,其中包含一个上下弹跳的球。到目前为止,我已经能够让球上下移动,但现在我正在努力让球更“栩栩如生”,所以我希望每次球反弹时球的高度都会降低,直到最终停止。

我尝试使用我为 getHeight() 方法创建的屋顶变量执行 while 循环,但由于某种原因,当我尝试使用它时,球根本没有移动,或者循环对球。

我也尝试了 for 循环,但遇到了与 while 循环相同的问题。我认为问题在于我没有将这个 for 循环放在正确的位置以使其正常工作。

提前致谢。

【问题讨论】:

  • 请引用您关于此主题的原始问题,Creating an animation using JApplet;另外,考虑一个hybridapplet/applicaiton。
  • 你的屋顶不是你的屋顶,而是你的地板。 (0,0) 坐标在左上角。

标签: java swing loops timer japplet


【解决方案1】:

对您的代码稍作修改,就可以为您提供一些线索:

            @Override
            public void actionPerformed(ActionEvent e) {
                int y = draw.getAnimationY();
                int diameter = draw.getDiameter();
                int roof = getHeight();
                y += speed;
                //
                // Reduce the ball size at the bottom of the screen
                //
                if(y + diameter > roof) {
                    if(diameter > minDiameter) {
                        diameter -= (roof - y);                 
                    } else {
                        diameter = minDiameter;
                    }                   
                } else if (diameter < maxDiameter) {
                    diameter++;
                }
                draw.setDiameter(diameter);
                if (y < 0) {
                    y = 0;
                    speed *= -1;    
                } else if (y + diameter > roof) {
                    y = roof - diameter;
                    speed *= -1;                    
                }                   
                //  Simulates a little gravity
                speed += 0.5;
                draw.setAnimationY(y);
                repaint();
            }

为了更真实,最好的方法是找到一个方程,它是球位置和球硬度系数的函数,并会给出球的大小。

【讨论】:

  • 嗯,我什至没有想过改变球的大小,这很酷!这是个好主意!好吧,由于某种原因,现在球没有上下移动。这是我在尝试将循环用于“降低屋顶”时遇到的相同问题
【解决方案2】:

让我们继续使用来自your other related question 的@MadProgrammer 的解决方案

在您的DrawPane 类中,我们可以轻松地定义heightgetAnimationHeight()setAnimationHeight(int) 来控制一接触地面的高度降低。请记住,在 java 中 left-top 坐标是 (0, 0)right-bottom 坐标是 (getWidth(), getHeight())。假设它从height = 0(top) 开始。然后它将从y = height(top) 开始,最终移动到容器的getHeight()(bottom)。我们将使用setAnimationHeight() 增加height(顶部y),方法是向当前heightgetAnimationHeight() 将返回)添加一个金额(比如30)。

因此,在您的另一个问题中对@MadeProgrammer 的解决方案 进行的这个小调整将是以下demo

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;

public class Circle extends JApplet {

    private int delta = 8;

    private Timer timer;
    private DrawPane drawPane;

    @Override
    public void init() {
        super.init();
        setLayout(new BorderLayout());
        drawPane = new DrawPane();
        add(drawPane);
        timer = new Timer(100, new ActionListener() {

            int frameCount = 0;

            @Override
            public void actionPerformed(ActionEvent e) {
                int y = drawPane.getAnimationY();
                int diameter = drawPane.getDiameter();
                y += delta;
                if (y < drawPane.getAnimationHeight()) {
                    y = drawPane.getAnimationHeight();

                    delta *= -1;
                } else if (y + diameter > getHeight()) {
                    y = getHeight()- diameter;
                    delta *= -1;

                    int animationHeight =  drawPane.getAnimationHeight();
                    animationHeight = animationHeight + (getHeight() - diameter - animationHeight)/2;

                    drawPane.setAnimationHeight(animationHeight);

                    if(animationHeight + diameter + 2 >= getHeight())
                    {
                        System.out.println("true");
                        drawPane.setAnimationY(getHeight() - diameter);
                       repaint();
                        timer.stop();
                        return;
                    }


                }
                drawPane.setAnimationY(y);
               repaint();



            }
        });
    }

    @Override
    public void start() {
        super.start();
        timer.start();
    }

    @Override
    public void stop() {
        timer.stop();
        super.stop();
    }

    public class DrawPane extends JPanel {

        int x = 100;
        int y = 0;
        int diameter = 50;
        int height = 0;


        public void setAnimationX(int x) {
            this.x = x;
        }

        public void setAnimationY(int y) {
            this.y = y;
        }



        public void setAnimationHeight(int h)
        {
            height = h;
        }

        public int getAnimationHeight()
        {
           return  height;
        }

        public int getAnimationX() {
            return x;
        }

        public int getAnimationY() {
            return y;
        }

        public int getDiameter() {
            return diameter;
        }

        public void setDiameter(int startDiameter) {
            diameter = startDiameter;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawOval(x, y, diameter, diameter);
        }
    }
}

注意:一旦它最终触及底部,您应该停止计时器以摆脱球的闪烁。这个任务留给你一个练习

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 2022-06-19
    • 2013-07-03
    • 2015-07-12
    • 1970-01-01
    相关资源
    最近更新 更多