在Java
D場景中插入動畫片段使
D內容更加有趣充實
一段動畫可以在更令人信服的背景下展示
例如飄動的雲
繁忙的城市街道
或者是從窗向外看的效果
動畫可以在屏幕效果和游戲效果之間任意轉換
這篇文章被分為兩個部分
描寫我怎樣實現一個Java
D動畫屏幕效果
在這個部分
我將說明我怎樣利用JMF(Java Media Framework)
特別是在JMF Performance Pack for Windows v
e情況下
我的另外兩個工具是J
SE
和Java
D
我將討論另外的使用Quicktime for Java的動畫屏幕版本
圖
是應用JMF Movie
D在不同時間截取的兩幅截屏
右邊截屏是從屏幕後看的效果
圖 MovieD應用截屏 此應用程序中重點
JMF和Java
D的集成
屏幕以任意尺寸成倍增加在一個應用程序
由於屏幕是Java
D的Shape
D類的一個子類
因此它可以很容易的統一到各種Java
D場景中
程序執行使用Model
View
Controller設計模式
屏幕是一個視頻元素
由JMFMovieScreen類描述
動畫是一個由JMFSnapper類控制的模型部分
一個Java
D Behavior類
TimeBehavior
控制動畫定時定期更新
所有JMF編碼都存放在JMFSnapper類
可以很方便的測試各種變化
這篇文章的第二部分JMFSnapper由QuickTime for Java版本中的QTSnapper取代
Java
D 的使用將會使動畫的播放速度毫無困難的上升到
幀/秒
使用JMF出現問題的討論
問題是我首選解決方案將不會工作
JMF有可能變為一個巨大的API
但在其內部仍有一些程序沒有及時運行
我坐在山上 事實上
我正坐在一個冰冷的辦公室
我真正的意思是說這篇文章建立在大量Java
D和JMF背景知識之上
我將不會細致地解釋Java
D的基礎知識
因為它們都可以在O
Reilly文章Killer Game Programming in Java(以下簡稱KGPJ)中找到
例如
圖
場景效果圖是其第
章中的輕微改良Checkers
D的版本實例
我再生了這些編碼以生成底版
藍天和燈光
假如你不想買這本書
沒關系
所有篇章的初稿和所有編碼都可以在此書的站點查閱
在此文章中
我將會解釋我用來從動畫中抽取幀的JMF技術
我將不會討論流媒體或者編碼轉換
應用簡述 動畫由JMFSnapper類加載播放
並且不斷的循環播放直到被停止
JMFMovieScreen生成動畫屏幕
並在底版上控制Java
D四邊形
圖
顯示這些類的應用(該場景圖說明場景中Java
D節點怎樣連接在一起)
圖MovieD場景圖 圖
種的很多細節可以被忽略
此圖KGPJ
章中的得Checkers
D實例有很多相似之處
只有特殊動畫的節點是新的
由於節點關系
JMFMovieScreen和TimeBehavior對象以三角形表示
JMFSnapper對象不屬於這張圖
但由JMFMovieScreen調用
每
毫秒
TimeBehavior對象調用JMFMovieScreen類中的nextFrame()方法
接下來調用JMFSnapper中的getFrame()方法獲取動畫中當前播放的幀
由JMFMovieScreen控制成像
TimeBehavior是Java
D的Behavior類的子類
它是Java
D應用的計時器
它與KGPJ
章中的
D sprites實例中的TimeBehavior類十分相似
觀察應用過程的另一種方式就是察看它的UML類圖表
圖
給出
類中的公共方法被顯示
圖MovieD類圖表 Movie
D的子類JFrame
WrapMovie
D是JPanel的一個子類
圖
展示了WrapMovie
D如何構建場景圖
和將其譯成應用的JPanel
他使用CheckerFloor 和ColouredTiles類構建底版
JMFMovieScreen創建動畫屏幕
將其加入場景中
通過創建一個JMFSnapper對象開始動畫
TimeBehavior每
毫秒調用JMFMovieScreen中的nextFrame()方法
nextFrame()調用JMFSnapper中的getFrame()得到當前幀
這個例子中的所有編碼
此文章的早期版本可以在KGPJ網點查詢
准備動畫 動畫
它的屏幕和更新屏幕的TimeBehavior對象
都是由WrapMovie
D中的addMovieScreen()方法創立
// globalsprivate BranchGroup sceneBG;private JMFMovieScreen ms;
// the movie screenprivate TimeBehavior timer;
// to update screenprivate void addMovieScreen(String fnm){ // put the movie in fnm onto a movie screen ms = new JMFMovieScreen( new Point
f(
f
)
f
fnm);
sceneBG
addChild(ms);
// set up the timer for animating the movie timer = new TimeBehavior(
ms);
// update movie every
ms (==
frames/sec) timer
setSchedulingBounds(bounds);
sceneBG
addChild(timer);}
兩個Java
D addChild()方法調用JMFMovieScreen和TimeBehavior節點間的連接
setSchedulingBounds()激活TimeBehavior節點
創建動畫屏幕 JMFMovieScreen是Java
D的Shape
D類的一個子類
所以必須仔細說明它的外形的幾何形狀和外觀
幾何形狀是指動畫圖像的四個邊尺寸上成比例
它的最大尺寸(高 寬)必須向構造器仔細說明
這個四方形是垂直的
朝向Z軸正方向
可以在底版的任何位置被定位
四方形外觀是雙面
允許從前或後觀看動畫
結構是用雙線性插值
可以降低動畫圖像的像素化
大多數的功能是從KGPJ
章中的FPS(first
person shooter)實例中的ImageCsSeries類拷貝而來
ImageCsSeries在一個區域中顯示一系列的GIF圖片
為了簡短起見
我僅描述了JMFMovieScreen與ImageCsSeries的不同特征
高效顯示圖像
動畫中的一個幀被轉換結構擴大四倍
分為兩個步驟
第一步 提供的BufferedImage傳給Java
D的ImageComponent
D對象
然後傳給Java
D Texture
D
區域的圖像更新非常快
每秒更新
幀
要求結構更新
次
因此結構有效率的更新非常的重要
這種高效率在利用BufferedImage和ImageComponent
D對象進行格式化的情況下是可能的
JMFMovieScreen使用的ImageComponent
D對象以以下方式聲明
ImageComponent
D ic = new ImageComponent
D( ImageComponent
D
FORMAT_RGB
FORMAT_SIZE
FORMAT_SIZE
true
true);
構造器剩余兩個需要說明的討論點是它使用
by reference
和
Y
up
模式
這些模式降低了存儲結構圖像的內存大小
因為Java
D避免將圖像從應用空間拷貝到圖形內存
在Windows OS環境下
使用OpenGL作為Java
D優先圖像引擎
ImageComponent
D格式應是ImageComponent
D
FORMAT_RGB
BufferedImage格式應是BufferedImage
TYPE_
BYTE_BGR
BufferedImage格式在JMFSnapper中確定
此項技術的更多細節可以在中查詢
將紋理加進區域
通常在一個區域中確定一幅圖像的方法是將圖像的坐下角連接到區域的左下角
然後逆時針連接剩余的幾個角
圖
說明這種方法
圖圖像與區域之間的標准連接 圖像坐標區間在X Y軸的
之間
Y軸正方向
例如
圖像左下點坐標為(
)
右上點為(
)
當
Y
up
模式使用
圖像坐標Y軸翻轉
負方向
意味著(
)代表圖像左上點
(
)指向右下
當
Y
up
模式建立
圖像坐標必須分配給區域中不同點以便獲得圖像的相同定位
圖
顯示了最新配置
圖Yup模式使用時圖像與區域之間的連接 連接區域點與圖像定位的JMFMovieScreen編碼是
TexCoord
f q = new TexCoord
f();
q
set(
f
f);
plane
setTextureCoordinate(
q);
// (
) tex coord
> top left quad point (p
)q
set(
f
f);
plane
setTextureCoordinate(
q);
// (
)
> top right (p
)q
set(
f
f);
plane
setTextureCoordinate(
q);
// (
)
> bottom right (p
)q
set(
f
f);
plane
setTextureCoordinate(
q);
// (
)
> bottom left (p
)
PLANE對象指代區域
更新圖像
以上所講
TimeBehavior是被設置用來被
毫秒調用JMFMovieScreen的nextFrame()方法
nextFrame()調用JMFSnapper對象中的getFrame()方法獲得被看作BufferedImage對象的當前動畫幀
指派給一個mageComponent
D對象
然後傳給區域圖像
nextFrame()是
// globalsprivate Texture
D texture;
// used by the quadprivate ImageComponent
D ic;
private JMFSnapper snapper;
// to take snaps of the movieprivate boolean isStopped = false;
// is the movie stopped?public void nextFrame(){ if (isStopped) // movie has been stopped return; BufferedImage im = snapper
getFrame();
// get current frame if (im != null) {
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26618.html