//★ 自機から弾丸を連射 前田 稔
// appletviewer appletshot1.htm
import java.applet.*;
import java.awt.*;
import java.io.*;
import javax.imageio.ImageIO;
import java.net.URL;
import java.awt.event.*;
import java.util.*;
public class appletshot1 extends Applet implements Runnable, KeyListener
{ // MyShip の領域
int key_t[] = { 0,0,0,0,0 }; //UP, RIGHT, DOWN, LEFT, SPACE
Image ship= null; //Ship の画像
int x= 300, y= 380; //Ship の座標
// shot 弾丸の領域
sprite dangan= null; //弾丸の切り分け
ArrayList<shot> list; //弾丸の登録
shot shotw= new shot(); //shot のワーク
long nowTime,drawTime,shotTime;
// Double Buffer
Dimension size;
Image back= null;
Graphics buffer;
// Initialize
public void init()
{ //画像ロード
ship = getImage(getDocumentBase(),"ship.png");
dangan = new sprite(getCodeBase().toString() + "tama4.png",32,32);
setBackground(Color.gray);
list = new ArrayList<shot>();
shotTime= 0;
size = getSize();
back= createImage(size.width, size.height);
if (back==null) System.out.print("createImage Error");
drawTime= System.currentTimeMillis()+500;
addKeyListener(this);
requestFocus();
Thread t = new Thread(this);
t.start();
}
// Message Loop
public void run()
{ { while(true)
{ nowTime= System.currentTimeMillis();
if (drawTime<nowTime)
{ drawTime= nowTime+30;
action();
Update();
repaint();
}
}
}
}
// Paint
public void paint(Graphics g)
{ if (back==null) return;
buffer= back.getGraphics();
if (buffer==null) return;
size = getSize();
buffer.setColor(getBackground());
buffer.fillRect(0, 0, size.width, size.height);
if (ship!=null)
{ buffer.drawImage(ship,x,y,this); }
for(int i=0; i<list.size(); i++) // 弾丸の描画
dangan.View(buffer,list.get(i).Sp_no,(int)list.get(i).posX,(int)list.get(i).posY);
g.drawImage(back,0,0,this);
}
// 座標の更新&弾の削除
public void Update()
{ for(int i=0; i<list.size(); i++)
{ list.get(i).Update(); }
for(int i=list.size()-1; i>=0; i--)
if (list.get(i).Sp_no==99) list.remove(i);
}
// シップの移動
public void action()
{ if (key_t[0]==1) y=y-4; // UP
if (key_t[1]==1) x=x+4; // RIGHT
if (key_t[2]==1) y=y+4; // DOWN
if (key_t[3]==1) x=x-4; // LEFT
if (key_t[4]==1) // Space で連射
{ if (shotTime<nowTime)
{ shotTime= nowTime+200;
shotw = new shot();
shotw.Set(1,x+20,y,0,-8);
list.add(shotw);
}
}
}
// KeyEvent Listener
public void keyPressed(KeyEvent e)
{
switch(e.getKeyCode( ))
{ case KeyEvent.VK_UP : key_t[0]= 1; break;
case KeyEvent.VK_RIGHT: key_t[1]= 1; break;
case KeyEvent.VK_DOWN : key_t[2]= 1; break;
case KeyEvent.VK_LEFT : key_t[3]= 1; break;
case KeyEvent.VK_SPACE: key_t[4]= 1; break;
}
}
public void keyReleased(KeyEvent e)
{ switch(e.getKeyCode( ))
{ case KeyEvent.VK_UP : key_t[0]= 0; break;
case KeyEvent.VK_RIGHT: key_t[1]= 0; break;
case KeyEvent.VK_DOWN : key_t[2]= 0; break;
case KeyEvent.VK_LEFT : key_t[3]= 0; break;
case KeyEvent.VK_SPACE: key_t[4]= 0; break;
}
}
public void keyTyped(KeyEvent e) { }
}
//★ 画像を切り分けるクラス
class sprite extends Applet
{ private Image Img; // Sprite Image
private int Width,Height; // Sprite の幅,高さ
private int Wnum,Hnum; // Sprite 横枚数,縦枚数
private int frameNum; // Wnum*Hnum
int Sp_no; // Sprite の番号
float posX, posY; // Sprite の座標
float vectX, vectY; // Sprite の移動量
long chgTime; // Sprite を切り替えた時刻
int Left,Top; // Window 左,上
int Right,Bottom; // Window 下,右
// Constructor
sprite(String path, int ws, int hs)
{ Width= ws;
Height= hs;
Wnum=Hnum= 1;
Sp_no= 99; // flag:OFF
posX=posY= 0f; //座標
vectX=vectY= 0f; //移動量
chgTime= 0; //Sprite の切替
Left=Top= 0; //仮の枠(0,0,800,600)
Right= 800;
Bottom= 600;
Img= null;
try
{ URL u = new URL(path);
Img = ImageIO.read(u);
}
catch (IOException e)
{ System.out.println("Image File Load Error");
return;
}
Wnum= Img.getWidth(null)/Width;
Hnum= Img.getHeight(null)/Height;
frameNum = Wnum*Hnum;
if (Wnum<1 || Hnum<1) System.out.println("Image File Error");
}
// Sprite View
public void View(Graphics g, int n, int dx, int dy)
{ int sx, sy;
if (n >= frameNum) return;
sx = (n % Wnum) * Width;
sy = (n / Wnum) * Height;
if (Img != null)
{ g.drawImage(Img,dx,dy,dx+Width,dy+Height,sx,sy,sx+Width,sy+Height,this); }
}
public void View(Graphics g)
{ View(g, Sp_no, (int)posX, (int)posY);
}
// Sprite 番号と座標の設定
public void Set(int num,float xp,float yp,float xv,float yv)
{ Sp_no= num;
posX= xp;
posY= yp;
vectX= xv;
vectY= yv;
}
// 次の画像に切り替える
public void Next(long Tim)
{ if (Sp_no < frameNum)
{ long nowTime = System.currentTimeMillis();
if (chgTime+Tim < nowTime)
{ chgTime= nowTime;
Sp_no++;
}
}
else Sp_no = 99;
}
public void Loop(long Tim)
{ long nowTime = System.currentTimeMillis();
if (Sp_no < frameNum && chgTime+Tim < nowTime)
{ chgTime= nowTime;
Sp_no = (Sp_no + 1) % frameNum;
}
}
// Window Rect の設定
// Update(), Bound() を使うときは設定する
public void SetRect(int lt, int tp, int rt, int bm)
{ Left= lt;
Top= tp;
Right= rt;
Bottom= bm;
}
// Update method
// 枠とvectを設定すること
public void Update()
{ if (Sp_no==99) return;
posX+= vectX;
posY+= vectY;
if (posX>Right || posX<Left || posY>Bottom || posY<Top) Sp_no= 99;
}
// Bound method
// 枠とvectを設定すること
public void Bound()
{ if (Sp_no==99) return;
posX+= vectX;
posY+= vectY;
if (posX>Right || posX<Left) vectX= 0-vectX;
if (posY>Bottom || posY<Top) vectY= 0-vectY;
}
//当たり判定
public boolean Hit(float targetx, float targety, float len)
{ float dist,wx,wy;
if (Sp_no==99) return false;
wx = posX - targetx;
wy = posY - targety;
dist = (float)Math.sqrt((double)(wx * wx + wy * wy));
if (dist<len) return true;
return false;
}
}
//★ 弾丸の座標を管理するクラス
class shot
{ float posX, posY; //弾の座標
float vectX, vectY; //弾の移動
int Sp_no; //Sprite の番号
// Constructor
public shot()
{ posX=posY= 0;
vectX=vectY= 0;
Sp_no= 99; //flag:OFF
}
// Set method
public void Set(int num,float xp,float yp,float xv,float yv)
{ Sp_no= num;
posX= xp;
posY= yp;
vectX= xv;
vectY= yv;
}
// Update method
public void Update()
{ if (Sp_no==99) return;
posX+= vectX;
posY+= vectY;
if (posX>800 || posX<0 || posY>600 || posY<0) Sp_no= 99;
}
// 円状に弾の移動を設定
public void Rot(float rt, float len)
{ vectX = (float)(Math.sin(rt / 180 * 3.14)) * len;
vectY = (float)(Math.cos(rt / 180 * 3.14)) * len;
}
}
|