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