You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于NoApplet实现小球膨胀收缩循环动画?

基于NoApplet实现小球缩放循环动画

我是Java框架新手,想要基于NoApplet实现一个简单动画:让小球逐渐变大,碰到屏幕边界后开始缩小,循环往复。下面是我初步写的Balloon类代码,还有一段滚动横幅的示例代码,但不知道怎么改成小球动画的逻辑:

我编写的初始Balloon类代码

import java.awt.*;
import java.awt.event.*;
import java.util.Objects;
import javax.swing.*;
import noapplet.NoApplet;

public class Balloon extends NoApplet{
//Field declarations? Not really sure what declarations would I use. 
    protected int delay = 100;
    protected Dimension dim;
    protected int x, y;
    protected Timer timer;
    protected int offset = 10;
    public Balloon() {
    }
    public void init(){
//initialization and have parameter 
        dim = getSize();
        x = dim.width;
        y = dim.height;

    }
    protected void paintComponent(Graphics g) {
        g.setColor(Color.BLACK);
//start making the screen black and then make the animation 


    }
    public static void main (String[]args){
        new Balloon().run();

参考的滚动横幅代码

package noapplet.assigment;
import java.awt.*;
import java.awt.event.*;
import java.util.Objects;
import javax.swing.*;
import noapplet.NoApplet;
import noapplet.example.Omok;

public class ScrollingBanner extends NoApplet {

    protected String text;
    protected Font font =  new java.awt.Font("Sans-serif", Font.BOLD, 24);
    protected Dimension dim;
    protected int x, y;
    protected int delay = 100; // millis
    protected int offset = 10;
    protected Timer timer; // animation timer

    public void init() {
        // get parameters "delay" and "text"
        String att = getParameter("delay");
        if (att != null) {
            delay = Integer.parseInt(att);
        }
        att = getParameter("text");
        text = Objects.requireNonNullElse(att, "Lets Go");

        // set the initial position of the text
        dim = getSize();
        x = dim.width;
        y = font.getSize();

        // initialize the animation timer
        timer = new Timer(delay, e -> repaint());
    }
    protected void paintComponent(Graphics g) {
        // get the font metrics to determine the length of the text
        g.setFont(font);
        FontMetrics fm = g.getFontMetrics();
        int length = fm.stringWidth(text);

        // adjust the position of the text from the previous frame
        x -= offset;
        // if the text is completely off to the left end
        // move the position back to the right end
        //if (x < -length) { x = -dim.width; }
        if (x < -length) { x = dim.width; }

        // set the pen color and draw the background
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, dim.width, dim.height);

        // set the pen color and then draw the text
        g.setColor(Color.GREEN);
        g.drawString(text, x, y);
    }
    public void start() {
        timer.start();
    }
    public void stop() {
        timer.stop();
    }
    public static void main (String [] args){
        new ScrollingBanner().run();
    }
}

目标效果

小球像气球一样,先逐渐膨胀,直到触碰到窗口的上下左右任意边界后开始收缩,收缩到一定大小后再次膨胀,循环往复。


修改后的完整Balloon类代码

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import noapplet.NoApplet;

public class Balloon extends NoApplet {
    protected int delay = 100;
    protected Dimension dim;
    protected int centerX, centerY;
    protected int radius;
    protected boolean growing; // 标记当前是放大还是缩小状态
    protected Timer timer;
    protected int step = 5; // 每次缩放的步长

    public Balloon() {}

    public void init() {
        // 获取窗口尺寸
        dim = getSize();
        // 初始化小球中心为窗口中心
        centerX = dim.width / 2;
        centerY = dim.height / 2;
        // 初始半径
        radius = 10;
        // 默认开始放大
        growing = true;

        // 初始化动画计时器,每隔delay毫秒触发重绘
        timer = new Timer(delay, e -> repaint());
    }

    protected void paintComponent(Graphics g) {
        // 绘制黑色背景,清空上一帧画面
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, dim.width, dim.height);

        // 根据状态调整半径
        if (growing) {
            radius += step;
            // 检查是否触碰到边界:小球边缘碰到窗口任意一边就切换状态
            if (centerX + radius >= dim.width || centerX - radius <= 0 
                || centerY + radius >= dim.height || centerY - radius <= 0) {
                growing = false;
            }
        } else {
            radius -= step;
            // 缩小到最小半径后切换回放大状态
            if (radius <= 10) {
                growing = true;
            }
        }

        // 设置小球颜色并绘制
        g.setColor(Color.RED);
        g.fillOval(centerX - radius, centerY - radius, radius * 2, radius * 2);
    }

    // 启动动画计时器
    public void start() {
        timer.start();
    }

    // 停止动画计时器
    public void stop() {
        timer.stop();
    }

    public static void main(String[] args) {
        new Balloon().run();
    }
}

关键修改说明

  1. 新增字段:添加radius记录小球当前半径,growing标记缩放方向,centerX/centerY固定小球中心位置,step控制每次缩放的幅度
  2. 初始化逻辑:init方法中设置小球初始位置为窗口中心,初始半径设为10,同时初始化动画计时器
  3. 动画逻辑:在paintComponent中,先清空背景,然后根据growing状态调整半径,触碰到窗口边界时切换缩放方向,最后绘制当前状态的小球
  4. 计时器控制:实现start和stop方法,控制动画的启停,和滚动横幅示例的逻辑一致

内容的提问来源于stack exchange,提问作者Pipopi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 02:46:05