// 2-dimensional Floor-Field Model
/*
*/
import java.awt.*;
import java.lang.*;
import java.util.Random;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
public class FloorField02 extends JApplet
implements ActionListener{
// 描画のためのパラメータ
static double frameWidth = 680.0;
static double frameHeight = 680.0;
final static double topMargin = 50.0;
final static double bottomMargin = 50.0;
final static double sideMargin = 50.0;
final static Color bgcolor = Color.white;
final static Color fgcolor = new Color(100,0,200);
final static BasicStroke normalStroke = new BasicStroke(1.0f);
final static BasicStroke thinStroke = new BasicStroke(0.1f);
static double height,width;
// エージェントの情報
static int nAgent = 100;
static int [] agentX = new int [nAgent];
static int [] agentY = new int [nAgent];
// 2次元セル
final static int nCell = 80;
static int [][] cell = new int [nCell][nCell];
static double dx,dy;
// 出口の設定
static int exitX = nCell/2;
static int exitY = 0;
//
static Random rand = new Random();
String param; // パラメータ入力のためのバッファ
static double ks = 1.0; // 近づく傾向の大きさ
// コマ送りの間隔
static int delay = 100;
boolean frozen = false;
Timer timer;
AnimationPane animationPane;
// セルに nAgent 人を配置する
void initCells(){
double r;
for(int i=0;i 0 && cell[y][x-1] == 0){
agentX[i] --;
moved = true;
}
}
else{
if(y > 0 && cell[y-1][x] == 0){
agentY[i] --;
moved = true;
}
}
if(moved){
cell[y][x] = 0;
cell[agentY[i]][agentX[i]] = 1;
g2.setPaint(Color.white);
px = sideMargin + x * dx;
py = topMargin + y * dy;
g2.fill(new Rectangle2D.Double(px,py,dy,dx));
g2.setPaint(Color.red);
px = sideMargin + agentX[i] * dx;
py = topMargin + agentY[i] * dy;
g2.fill(new Rectangle2D.Double(px,py,dy,dx));
}
}
}
// 動かないパラメータの設定はここで行う
void buildUI(Container container){
timer = new Timer(delay, this);
timer.setInitialDelay(0);
timer.setCoalesce(true);
animationPane = new AnimationPane();
container.add(animationPane, BorderLayout.CENTER);
Dimension d = getSize();
frameWidth = d.width;
frameHeight = d.height;
width = frameWidth - 2 * sideMargin;
height = frameHeight - (topMargin + bottomMargin);
dx = width / nCell;
dy = height / nCell;
// Application でのみ反応
animationPane.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
System.out.println("mousePressed");
// マウスクリックに応答する
if (frozen){
frozen = false;
startAnimation();
}else{
frozen = true;
stopAnimation();
}
}
});
}
//Invoked by a browser only.
public void init(){
param = getParameter("ks");
ks = Double.parseDouble(param);
setBackground(bgcolor);
setForeground(fgcolor);
buildUI(getContentPane());
}
//Invoked by a browser only.
public void start() {
startAnimation();
}
//Invoked by a browser only.
public void stop() {
stopAnimation();
}
public synchronized void startAnimation(){
//animationFlag = 0;
System.out.println("startAnimation");
initCells();
if(frozen){
}else{
if(!timer.isRunning()){
timer.start();
}
}
}
public synchronized void stopAnimation(){
//Stop the animating thread.
System.out.println("stopAnimation");
if (timer.isRunning()) {
timer.stop();
}
}
// 以下がアニメーションの1コマに相当:ここで描画処理など。
public void actionPerformed(ActionEvent e){
animationPane.repaint();
}
class AnimationPane extends JPanel{
// Draw the current frame of animation.
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
int x,i,j;
g2.setStroke(thinStroke);
g2.setPaint(fgcolor);
// 枠の矩形を描画する
g2.draw(new Rectangle2D.Double(sideMargin,topMargin,width,height));
goNextStep(g2);
g2.setPaint(Color.green);
g2.fill(new Rectangle2D.Double(sideMargin + exitX * dx,
topMargin + exitY * dy,
dx, dy));
}
}
public static void main(String argv[]) {
JFrame f = new JFrame("Floor Field Model");
final FloorField02 controller = new FloorField02();
// サイズを buildUI の中の getSize()に渡すため。
controller.setSize(new Dimension((int)frameWidth,
(int)frameHeight));
f.setBackground(bgcolor);
f.setForeground(fgcolor);
controller.buildUI(f.getContentPane());
// ウィンドウのボタンを押した時の動作
f.addWindowListener(new WindowAdapter() {
public void windowIconified(WindowEvent e){
controller.stopAnimation();
}
public void windowDeiconified(WindowEvent e){
controller.startAnimation();
}
public void windowClosing(WindowEvent e) {
System.exit(0);}
});
f.pack();
// 表示枠のサイズを決める。
f.setSize(new Dimension((int)frameWidth,
(int)frameHeight));
f.setVisible(true);
// アプリケーションのとき,コマンドライン引数から密度を入力
ks = Double.parseDouble(argv[0]);
controller.startAnimation();
}
}