首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 圖形界面實現打字機逐字顯示動畫效果

     編輯:Java 相關知識

項目背景

在遊戲開發、多媒體展示等場景中,「逐字打印」效果能顯著提升用戶體驗。本文基於 Loon Framework 實現一個可復用的打字機動畫組件,支持多行文本、自定義速度、背景圖片等特性。

核心類設計:WriterType

繼承 Panel 並實現 Runnable,採用雙緩衝繪圖技術消除閃爍。

關鍵屬性

private static final int _WIDTH = 500;
private static final int _HEIGHT = 375;
private int _MAX_COUNT = 10;      // 最大對話數
private char _flag = '|';         // 換行分隔符
private Image _screen;            // 雙緩衝圖像
private Graphics _bg;             // 後台繪圖上下文
private Thread _L_WriterType;     // 動畫線程
private String[] _M_Text;         // 原始文本數組
private String[] _C_Text;         // 緩存顯示文本
private int _L_Speed;             // 打字速度(ms)
private int _L_Delay;             // 行間延遲(ms)

初始化與線程啟動

public WriterType(Image img, String[] strContent, int speed, int delay) {
    init(img, strContent, speed, delay);
}

private void init(Image img, String[] strContent, int speed, int delay) {
    // 背景與字體設置
    setBackground(Color.BLACK);
    _back = img;
    _L_TTF = new Font("宋體", 0, 15);
    _L_fClr = new Color(250, 250, 250);
    
    // 文本數組拷貝
    System.arraycopy(strContent, 0, _M_Text, 0, strContent.length);
    _N_Text = strContent.length - 1;
    
    // 雙緩衝初始化
    _screen = new BufferedImage(_WIDTH, _HEIGHT, BufferedImage.TYPE_INT_ARGB);
    _bg = _screen.getGraphics();
    
    // 啟動動畫線程
    _isRun = true;
    _L_WriterType = new Thread(this);
    _L_WriterType.start();
}

動畫核心邏輯:run() 方法

public void run() {
    while (_isRun) {
        try {
            _S_COUNT++;  // 字符累加計數
            
            // 當前行文本完成
            if (_S_COUNT == _M_Text[_T_COUNT].length()) {
                _C_Text[_L_COUNT] = _M_Text[_T_COUNT].substring(_F_COUNT, _S_COUNT);
                begin();  // 重置狀態準備下一行
                Thread.sleep(_L_Delay);
                repaint();
            }
            
            // 判斷是否為分隔符
            boolean shortSleep = false;
            if (_M_Text[_T_COUNT].charAt(_S_COUNT) == _flag) {
                _L_COUNT++;
                _S_COUNT++;
                _F_COUNT = _S_COUNT;
                shortSleep = true;  // 分隔符處延長停頓
            }
            
            // 更新緩存文本(帶游標效果)
            _C_Text[_L_COUNT] = _M_Text[_T_COUNT].substring(_F_COUNT, _S_COUNT) 
                                + (shortSleep ? "" : "_");
            
            repaint();
            Thread.sleep(shortSleep ? 10 * _L_Speed : _L_Speed);
        } catch (InterruptedException e) {
            stop();
        }
    }
}

繪圖邏輯:paint() 方法

public void paint(Graphics g) {
    // 清空背景
    _bg.setColor(_L_bClr);
    _bg.fillRect(0, 0, _WIDTH, _HEIGHT);
    
    // 繪製背景圖
    _bg.drawImage(_back, 0, 0, this);
    
    // 逐行繪製文本
    _bg.setColor(_L_fClr);
    _bg.setFont(_L_TTF);
    for (int i = 0; i <= _L_COUNT; i++) {
        if (_C_Text[i] != null) {
            int top = (int) (_FontSize * (3.0 + 2.0 * i));
            _bg.drawString(_C_Text[i], 50, top);
        }
    }
    
    // 雙緩衝輸出
    g.drawImage(_screen, 0, 0, this);
}

主程序啟動示例

public static void main(String[] args) {
    String[] dialogues = new String[] {
        "身為劍體,|鋼鐵之血灼璃之心.|手創千劍,身經百戰;|無一敗績,無一知己.|",
        "I am the bone of my sword;|Steel is my body, and fire is my blood.|"
    };
    
    Frame frm = new Frame();
    frm.setTitle("Java 逐字打印動畫演示");
    frm.setSize(_WIDTH, _HEIGHT + 20);
    frm.setResizable(false);
    
    // 載入背景圖(需替換為實際路徑)
    Image bgImg = ImageHelper.loadImage("background.jpg", true);
    frm.add(new WriterType(bgImg, dialogues, 50, 5000));
    frm.setVisible(true);
}

關鍵技術點總結

  1. 雙緩衝技術:BufferedImage 作為後台緩衝區,消除繪圖閃爍
  2. 游標模擬:在非分隔符位置追加 _ 字符模擬打字游標
  3. 分隔符控制:使用 | 實現多行文本的分段顯示與停頓
  4. 線程安全停止:_isRun 標志位配合 interrupt() 實現優雅關閉
  5. 圖片加載解耦:ImageHelper 可替換為 ImageIO 或 ImageIcon

擴展建議

  • 支持富文本樣式(顏色、字體變化)
  • 添加音效同步(按鍵聲、完成提示音)
  • 實現跳過/加速播放功能
  • 適配 Swing 組件(JPanel 替代 Panel)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved