Java实现动画逐字打印
生活随笔
收集整理的這篇文章主要介紹了
Java实现动画逐字打印
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在現代,摒棄傳統的會話方式,很多的圖形廣告或游戲采用了[逐字打印]的效果來展示文字,當然,這樣做的目的無非是為了突出內容或吸引眼球。
但是這種實現方式卻是值得借鑒的,以下,我給出一個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.p_w_picpath.BufferedImage;
import org.loon.framework.game.helper.ImageHelper;
/** *//**
* <p>
* Title: LoonFramework
* </p>
* <p>
* Description:JAVA實現對話逐字打印(由Loonframework提供)
* </p>
* <p>
* Copyright: Copyright (c) 2007
* </p>
* <p>
* Company: LoonFramework
* </p>
*
* @author chenpeng
* @email:[email]ceponline@yahoo.com.cn[/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;
????????????????}
????????????????_F_COUNT = 0;
????????????????_S_COUNT = 0;
????????????????_L_COUNT = 0;
????????????????_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) {
????????????????????????????????????????_C_Text[_L_COUNT] = _M_Text[_T_COUNT].substring(_F_COUNT,
????????????????????????????????????????????????????????_S_COUNT)
????????????????????????????????????????????????????????+ "_";
????????????????????????????????} else {
????????????????????????????????????????_C_Text[_L_COUNT] = _M_Text[_T_COUNT].substring(_F_COUNT,
????????????????????????????????????????????????????????_S_COUNT);
????????????????????????????????}
????????????????????????????????//用以分辨是否轉化對話組時的不同延遲
????????????????????????????????boolean shortSleep;
????????????????????????????????//當'|'標識存在時執行
????????????????????????????????if (_M_Text[_T_COUNT].charAt(_S_COUNT) == _flag) {
????????????????????????????????????????_L_COUNT++;
????????????????????????????????????????_S_COUNT++;
????????????????????????????????????????_F_COUNT = _S_COUNT;
????????????????????????????????????????shortSleep = true;
????????????????????????????????} else {
????????????????????????????????????????shortSleep = false;
????????????????????????????????}
????????????????????????????????//刷新
????????????????????????????????repaint();
????????????????????????????????//判斷速度
????????????????????????????????if (!shortSleep) {
????????????????????????????????????????Thread.sleep(_L_Speed);
????????????????????????????????} else {
????????????????????????????????????????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替代,原來的博客來有人問,兄弟在這聲明一下。
但是這種實現方式卻是值得借鑒的,以下,我給出一個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.p_w_picpath.BufferedImage;
import org.loon.framework.game.helper.ImageHelper;
/** *//**
* <p>
* Title: LoonFramework
* </p>
* <p>
* Description:JAVA實現對話逐字打印(由Loonframework提供)
* </p>
* <p>
* Copyright: Copyright (c) 2007
* </p>
* <p>
* Company: LoonFramework
* </p>
*
* @author chenpeng
* @email:[email]ceponline@yahoo.com.cn[/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;
????????????????}
????????????????_F_COUNT = 0;
????????????????_S_COUNT = 0;
????????????????_L_COUNT = 0;
????????????????_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) {
????????????????????????????????????????_C_Text[_L_COUNT] = _M_Text[_T_COUNT].substring(_F_COUNT,
????????????????????????????????????????????????????????_S_COUNT)
????????????????????????????????????????????????????????+ "_";
????????????????????????????????} else {
????????????????????????????????????????_C_Text[_L_COUNT] = _M_Text[_T_COUNT].substring(_F_COUNT,
????????????????????????????????????????????????????????_S_COUNT);
????????????????????????????????}
????????????????????????????????//用以分辨是否轉化對話組時的不同延遲
????????????????????????????????boolean shortSleep;
????????????????????????????????//當'|'標識存在時執行
????????????????????????????????if (_M_Text[_T_COUNT].charAt(_S_COUNT) == _flag) {
????????????????????????????????????????_L_COUNT++;
????????????????????????????????????????_S_COUNT++;
????????????????????????????????????????_F_COUNT = _S_COUNT;
????????????????????????????????????????shortSleep = true;
????????????????????????????????} else {
????????????????????????????????????????shortSleep = false;
????????????????????????????????}
????????????????????????????????//刷新
????????????????????????????????repaint();
????????????????????????????????//判斷速度
????????????????????????????????if (!shortSleep) {
????????????????????????????????????????Thread.sleep(_L_Speed);
????????????????????????????????} else {
????????????????????????????????????????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替代,原來的博客來有人問,兄弟在這聲明一下。
轉載于:https://blog.51cto.com/cping1982/116714
總結
以上是生活随笔為你收集整理的Java实现动画逐字打印的全部內容,希望文章能夠幫你解決所遇到的問題。