前ページで追加したSpriteBasicライブラリの探索searchメソッドを利用する確認例です。
以前に作成した例のマウスボタンプレス処理(ラベルも表示)を変更し、
移動するSpriteFishAの画像をマウスボタンで押せれば、その動作が止まり、
押せなければ、さかなのSpriteFishAを生成して追加するプログラムに変更しました。
(この色が追加箇所です。比較ください)
package fishgame;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.imageio.*;
import javax.swing.*;
import sprite.Sprite;
import sprite.SpriteBasic;//ライブラリ利用
import sprite.SpriteFrame;
import sprite.SpriteThread;
class SpriteFishA extends SpriteBasic {//右から左に移動するクラス
double speed_x; // 移動速度(1回のactionで変更する横移動量)
SpriteFishA(Image img,int px, int py, int speed){//コンストラクタ
super(img);
this.x = px;//初期位置
this.y = py;
this.speed_x = speed; //速度
}
public void action(){//移動処理(SpriteThreadのanimationIntervalミリ秒ごとに実行される)
super.action();//スーパクラス:SpriteBasicのactionを実行
this.x += this.speed_x;//移動
if(this.x < -100) {//左に隠れたか?
this.x = 680; //右の見えない所に出現させる。
this.y = rand.nextInt(450)+30;;//出現させるY座標は乱数を使う
this.speed_x = -( rand.nextInt(8)+4 );//速度も乱数
}
}
}
public class TestSplitePanel1 extends JPanel implements MouseListener{
static Image bg;//背景素材イメージ
static Image ch;//素材1イメージ
static Image ch2;//素材2イメージ
static {
try{
bg = ImageIO.read(TestSplitePanel1.class.getResource("aqua00.jpg"));//背景素材イメージ
ch = ImageIO.read(TestSplitePanel1.class.getResource("sanma00.gif"));//素材1イメージ
ch2 = ImageIO.read(TestSplitePanel1.class.getResource("jellyfish.gif"));//素材1イメージ
}
catch(Exception e){
e.printStackTrace();
}
}
SpriteThread spriteThread; // 描画、アニメーションスレッド
SpriteBasic back = new SpriteBasic(bg);
SpriteFishA fish1 = new SpriteFishA(ch, 10, 100, -1);
JLabel label = new JLabel("匹います。");
public TestSplitePanel1() throws Exception {
int w = bg.getWidth(this);//背景画像サイズ取得
int h = bg.getHeight(this);
this.setPreferredSize(new Dimension(w,h));
spriteThread = new SpriteThread(w, h, this);
this.add(label);//ラベル追加
label.setFont(new Font("Serif", Font.BOLD, 20));
label.setForeground(Color.white);
spriteThread.add( back );//背景を追加
spriteThread.add( new SpriteBasic(ch2) );//クラゲ追加
spriteThread.add( fish1 );//魚追加
spriteThread.add( new SpriteFishA(ch, 10, 200, -2));//魚追加
spriteThread.start(10);//0.01秒のアクションスレッド スタート
this.addMouseListener(this);
}
public void paintComponent(Graphics g){//間隔(0.01秒)で呼び出される。
super.paintComponent(g);
if (spriteThread != null) spriteThread.paintTo(g);
label.setText(spriteThread.subSprite.size()-2 + " 匹います。");
}
public static void main(String[] arg) throws Exception{
new SpriteFrame(new TestSplitePanel1()) ; //フレーム作品実行
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
Point pt = e.getPoint();
Sprite[] sprites = spriteThread.search(pt.x, pt.y);//探す
boolean hit = false;
for(Sprite s : sprites){
if(s instanceof SpriteFishA) {//魚のSprite
SpriteFishA fish = (SpriteFishA)s;
fish.speed_x = 0;//止める
System.out.println(s);//デバック用表示
hit = true;
}
}
if(! hit){ //魚でクリックできなかった。
SpriteFishA fish = new SpriteFishA(ch,pt.x, pt.y,-2);//Spriteを生成
spriteThread.add(fish);//さかなの追加
}
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
初期のSpriteオブジェクトは、背景、さかな、くらげ、さかなの順でspariteThreadに追加しています。
背景が、パネル全体を覆っているので、sprites=spriteThread.search(pt.x, pt.y);で探した場合、
さかな、くらげをクリックできなかった場合でも、背景がクリックされたことになるので、
どんな場合でも背景Spriteの1つは見つかり、spritesの要素数は1以上になります。
よって、if(sprites.length >= 1)の判定は、背景以外のもう一つ以上が見つかったか?という意味です。
また、searchは、上に重なる順番から探し、最も上層のSpriteオブジェクトが、[0]の要素となる配列で得らます。
上記では、if(s instanceof SpriteFishA) { で魚の判定を行って、それを処理対象にしています。