imgbak = javax.imageio.ImageIO.read(
new java.io.File("testsprite/aqua00.jpg"));
のよう読み取り方法はアプレットで使えません。
また、イメージの読み取り処理が完結しないくても、リターンする場合があります。
コンポーネントに使う場合に問題ありませんが、
この完結していないImageオブジェクトをdrawImageメソッドで使うと失敗します。
そこで、完全にイメージの読み取りが終わるまで待つ必要があります。
以下ではそれを考慮し、MediaTrackerクラスを利用しています。
しかもアプレットやリソースからの読み取りも可能なToolkitのgetImageメソッドを使っています。
//イメージファイルを読み取るユーティリティクラス
package sprite;//パッケージ名
import java.awt.image.*;//BufferedImage,ImageObserverなど用
import java.awt.*;//Graphicsなど用
public class ImgUtil{
//引数ファイル名の画像のイメージを返します。(ファイル名の位置はobserverのクラスと同じ位置)
public static Image getImageBy(String fileName, Component observer){
java.net.URL url = null;
Image img = null;
java.awt.MediaTracker tracker = null;
try{
url = observer.getClass().getResource(fileName);
if (url == null){
throw new Exception("リソースが見つかりません:" + fileName);
}
img = observer.getToolkit().getImage(url);
tracker = new java.awt.MediaTracker(observer);//イメージの呼び出しを監視
tracker.addImage(img, 0);//監視リストに追加
tracker.waitForID(0, 20000);//イメージ読み込みが完了するまで最大20秒待つ。
int status = tracker.statusID(0, false);
if (status != java.awt.MediaTracker.COMPLETE){
throw new Exception("イメージ画像取得に失敗:" + fileName);
}
}
catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(observer, e.toString(),
"イメージ画像取得に失敗", javax.swing.JOptionPane.ERROR_MESSAGE);
}
return img;
}
//引数ファイル名の変更可能なイメージを返します。(ファイル名の位置はobserverのクラスと同じ位置)
public static BufferedImage getImageBy(Image img, Component observer){
BufferedImage imgRtn = null;
int width = img.getWidth(observer);
int height = img.getHeight(observer);
imgRtn = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics g = imgRtn.getGraphics();
g.drawImage(img, 0, 0, observer);
return imgRtn;
}
}
2つstaticメソッドが用意されていますが、Imageを返す方が編集できないImageを返します。
これは、gifアニメーションファイルにも対応しています。
ファイル名 と監視オブジェクトを指定します。監視オブジェクトは描画対象のコンポーネントを指定しますが
同時に、そのクラスのロード位置(ディレクトリ)が、読み取るファイル位置で、
ファイル名は、この位置を基準とした相対パスを指定できます。
もう一方は、引数のImageから編集可能なBufferedImageを取得するメソッドで、イメージ複製にも使えます。
以下で、前回の作品を、これを使う方法に
変更したアプレット版例を示します。
(フレーム版でも使えます)
package testsprite;
import sprite.*;//Sprite,SpriteBasic,SpriteThreadのパッケージ
import java.awt.*;//Imageなどのパッケージ
import javax.swing.*;//JPanel,JFrameなどのパッケージ
public class TestSprite1 extends JApplet//アプレットクラス
{
MainPanel panel;//上記のパネル
public void init(){//start前に呼び出されます(ダウンロードが完了時)。
this.setContentPane(panel = new MainPanel());
}
public void stop(){//webブラウザから、閉じる時、ブラウザからよびだされる命令
this.panel.spriteThread.stop();//描画スレッド停止
}
}
//メインパネル
class MainPanel extends JPanel {
static MainPanel main; //この作品のパネル(グローバル変数のように扱える)
static Image imgbak; //背景素材イメージ
static Image img1; //素材1イメージ
static Image img2; //素材2イメージ
SpriteThread spriteThread; // 描画、アニメーションスレッド
SpriteBasic spriteBak;//背景管理用
SpriteBasic sprite1;//素材1
SpriteBasic sprite2;//素材2
MainPanel() {//コンストラクタ
MainPanel.main = this;
//素材画像ファイル読み取り
imgbak = ImgUtil.getImageBy("aqua00.jpg", this);//背景
img1 = ImgUtil.getImageBy("sanma00.gif", this);//素材1イメージ
//スレッド初期化、描画対象(panel)の設定とイメージサイズ指定
int w = imgbak.getWidth(this);//背景画像サイズ取得
int h = imgbak.getHeight(this);
spriteThread = new SpriteThread(w, h, this); //描画対象をpanelとして、背景画像サイズに合わせる
spriteThread.add( new SpriteBasic(bg) );//背景を追加
spriteThread.add( new SpriteBasic(ch) );//魚追加
spriteThread.subSprite.get(1).x=10;//2番目に追加したSpriteの位置を変更
spriteThread.subSprite.get(1).y=100;
spriteThread.start(10);//0.01秒のアクションスレッド スタート
}
public void paintComponent(Graphics g){//上記スレッド起動時の間隔(0.01秒)で呼び出される。
super.paintComponent(g);
if (spriteThread != null) spriteThread.paintTo(g);
}
}
Image bg;//背景素材イメージ
Image ch;//素材1イメージ
try{
bg = ImageIO.read(new File("aqua00.jpg"));//背景素材イメージ
ch = ImageIO.read(new File("sanma00.gif"));//素材1イメージ
catch(Exception e){
e.printStackTrace();
}
以上をリソース扱いで取得すると、次のようにできます。
Image bg;//背景素材イメージ
Image ch;//素材1イメージ
try{
bg = ImageIO.read(this.getClass().getResource("aqua00.jpg"));//背景素材イメージ
ch = ImageIO.read(this.getClass().getResource("sanma00.gif"));//素材1イメージ
catch(Exception e){
e.printStackTrace();
}
クラス変数の場合はstaticイニシャライザを使います。TestSplitePanel1クラスのstatic変数であれば、次のようにできます。
static Image bg;//背景素材イメージ
static Image ch;//素材1イメージ
static {
try{
bg = ImageIO.read(TestSplitePanel1.class.getResource("aqua00.jpg"));//背景素材イメージ
ch = ImageIO.read(TestSplitePanel1.class.getResource("sanma00.gif"));//素材1イメージ
}
catch(Exception e){
e.printStackTrace();
}
}
このspariteパッケージのライブラリを使う作品のjarを作るバッチファイル例を、参考に示します。
JDKのインストール環境によって変更する箇所はこの色で、
作品ごとに変更する箇所はこの色です。
この実行によって、test.jarのファイルを作成します。
rem ==== fish_shooting.jar を作る。========== echo 作品のソースのルーパス(開発位置でもある)にセット set srcpath=. cd %srcpath% echo mainがあるクラスパッケージ名指定 set pack=fishgame echo mainがあるクラスの名指定 set src=TestSplitePanel1 echo 作成する実行可能ファイル名指定 set mkfile=test.jar echo javaの開発ツール位置設定 set JAVAHOME=H:\jdk1.7.0_80 echo 開発用環境変数設定 set path=%JAVAHOME%\bin;%path% set CLASSPATH=.;sprite.jar;%JAVAHOME%; echo jar作業ディレクトリ作成(ここにクラスを作り、リソースを集める) set temp=WORK mkdir %temp% javac -d %temp% -encoding windows-31j -source 1.6 -target 1.6 %pack%\%src%.java echo コンパイル判定 IF ERRORLEVEL 1 GOTO LEND echo マニフェストファイル作成 echo Main-Class: %pack%.%src%> %temp%\manifest.txt echo Class-Path: %src%.jar .>> %temp%\manifest.txt echo 必要なファイルを作業ディレクトリにコピー copy %pack%\*.css %temp%\%pack% copy %pack%\*.gif %temp%\%pack% copy %pack%\*.png %temp%\%pack% copy %pack%\*.jpg %temp%\%pack% copy %pack%\*.mid %temp%\%pack% copy %pack%\*.wav %temp%\%pack% PUSHD %temp% jar -fx R:\pleiades\workspace\game28\sprite.jar POPD echo jarで圧縮ファイルを作成 jar cmvf %temp%/manifest.txt %mkfile% -C %temp%/. . :LEND rem %temp%ディレクトリを削除します。 rmdir %temp% /S /Q echo jarの実行 java -jar %mkfile% cmd