在現代,摒棄傳統的會話方式,很多的圖形廣告或遊戲采用了[逐字列印]的效果來展示文字,當然,這樣做的目的無非是為了突出内容或吸引眼球。
但是這種實作方式卻是值得借鑒的,以下,我給出一個JAVA實作的簡單用例,需要者可以自行擴充。
代碼實作:
package org.test;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.image.BufferedImage;
import org.loon.framework.game.helper.ImageHelper;
/** *//**
* <p>
* Title: LoonFramework
* </p>
* Description:JAVA實作對話逐字列印(由Loonframework提供)
* Copyright: Copyright (c) 2007
* Company: LoonFramework
*
* @author chenpeng
* @email:[email][email protected][/email]
* @version 0.1
*/
public final class WriterType extends Panel implements Runnable {
// 最大對話數
private int _MAX_COUNT = 10;
//間隔标記
private char _flag='|';
private Image _screen;
private Graphics _bg;
private Thread _L_WriterType;
private static Color _L_fClr;
private static Color _L_bClr;
private static String _M_Text[];
private int _S_COUNT;
private Font _L_TTF;
private int _L_Speed;
private int _L_Delay;
private String _C_Text[];
private static int _L_COUNT;
private static int _F_COUNT;
private static int _T_COUNT;
private static int _N_Text;
private String _FontName;
private final static int _WIDTH = 500;
private final static int _HEIGHT = 375;
private static int _FontStyle;
private static int _FontSize;
private static Image _back = null;
/** *//**
*
*/
private static final long serialVersionUID = 1L;
private boolean _isRun;
* 析構函數,注入背景圖,循環顯示的文字數組,速度,延遲
* @param img
* @param strContent
* @param speed
* @param delay
public WriterType(Image img,String[] strContent, int speed, int delay) {
init(img,strContent, speed, delay);
}
private WriterType() {
public void init(Image img,String[] strContent, int speed, int delay) {
//初始背景色
setBackground(Color.BLACK);
// 原始對話資訊
_M_Text = new String[_MAX_COUNT];
// 緩存對話資訊
_C_Text = new String[_MAX_COUNT];
_back=img;
_FontName = "宋體";
_FontStyle = 0;
_FontSize = 15;
_L_TTF = new Font(_FontName, _FontStyle, _FontSize);
_L_bClr = Color.BLACK;
_L_fClr = new Color(250, 250, 250);
int length = strContent.length;
// 循環次數
_N_Text = strContent.length - 1;
// 直接copy String數組
System.arraycopy(strContent, 0, _M_Text, 0, length);
//速度及延遲設定
_L_Speed = speed;
_L_Delay = delay;
//緩存區域
_screen = new BufferedImage(_WIDTH, _HEIGHT, 1);
_bg = _screen.getGraphics();
//開啟線程
_isRun = true;
_L_WriterType = new Thread(this);
_L_WriterType.start();
* 停止線程
*
public void stop() {
_S_COUNT = 0;
_L_COUNT = 0;
_F_COUNT = 0;
if (_L_WriterType != null) {
_isRun = false;
_L_WriterType = null;
}
* 繪制圖形
public void paint(Graphics g) {
_bg.setColor(_L_bClr);
_bg.fillRect(0, 0, _WIDTH, _HEIGHT);
_bg.setColor(_L_fClr);
_bg.setFont(_L_TTF);
_bg.drawImage(_back, 0, 0, this);
for (int i = 0; i <= _L_COUNT; i++) {
//轉換目前字型top位置
Double top = new Double((double) _FontSize
* (3.0D + 2.0D * (double) i));
if (_C_Text[i] != null) {
_bg.drawString(_C_Text[i], 50, top.intValue());
}
g.drawImage(_screen, 0, 0, this);
* 圖形變更
public void update(Graphics g) {
paint(g);
* 重新開始
private void begin() {
//清除所有緩存資料。
for (int i = 0; i < _C_Text.length; i++) {
_C_Text[i] = null;
_T_COUNT++;
if (_T_COUNT > _N_Text) {
_T_COUNT = 0;
repaint();
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();
}
//比對辨別設定緩存對話
if (_M_Text[_T_COUNT].charAt(_S_COUNT) != _flag) {
_S_COUNT)
+ "_";
} else {
//用以分辨是否轉化對話組時的不同延遲
boolean shortSleep;
//當'|'辨別存在時執行
if (_M_Text[_T_COUNT].charAt(_S_COUNT) == _flag) {
_L_COUNT++;
_S_COUNT++;
_F_COUNT = _S_COUNT;
shortSleep = true;
shortSleep = false;
//重新整理
repaint();
//判斷速度
if (!shortSleep) {
Thread.sleep(_L_Speed);
Thread.sleep(10 * _L_Speed);
} catch (InterruptedException e) {
stop();
public int getMaxCount() {
return _MAX_COUNT;
public void setMaxCount(int max_count) {
_MAX_COUNT = max_count;
public static void main(String[] args) {
String[] abracadabra = new String[] {
"身為劍體,|鋼鐵之血灼璃之心.|手創千劍,身經百戰;|無一敗績,無一知己.|常一人自醉于劍丘之巅;|此生亦無任何意義;|故此身,定為無限劍成;|故此命,定為無限劍制.",
"I am the bone of my sword;|Steel is my body, and fire is my blood.|I have created over a thousand blades.|Have withstood pain to create many weapons.|Yet,those hands will never hold anything.|So as I pray, unlimited blade works." };
Frame frm = new Frame();
frm.setTitle("Java圖形程式中的對話逐字顯示(由Loonframework提供)");
frm.setSize(_WIDTH, _HEIGHT + 20);
frm.setResizable(false);
frm.add(new WriterType(ImageHelper
.loadImage("d:/back.jpg", true),abracadabra,50,5000));
frm.setVisible(true);
}
本例自動循環String數組中所有資料,每行顯示對話由'|'标記分割,背景圖如下:
效果圖1:
效果圖2:
PS:ImageHelper隻是一個圖檔加載用類,完全可以用ImageIcon或者ImageIO替代,原來的部落格來有人問,兄弟在這聲明一下。
本文轉自 cping 51CTO部落格,原文連結:http://blog.51cto.com/cping1982/116714