簡単bingoプログラム in Java

Inspired by 簡単bingoプログラム on Proce55ing - Qu記(仮).
f:id:qnighy:20090409173720p:image

Made for MATHIC spring camp.


qnighy's
gist: 92328 — Gist

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.*;
import javax.swing.*;
import java.io.*;
import java.util.ArrayList;

public class Bingoer extends JFrame implements ActionListener, KeyListener {
    private Timer timer;
    private String current_str;
    private String[] rownames = new String[] {"B","I","N","G","O"};
    private ArrayList<Integer> rest = new ArrayList<Integer>();
    private ArrayList<Integer> hist = new ArrayList<Integer>();
    private int stat = -1;
    private Point2D.Double[] pts;
    private double[] dirs;
    private Color[] ptcolors;
    public Bingoer() {
        super("Bingoer");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        getContentPane().add(bpanel);
        setSize(1100, 700);
        setResizable(false);
        timer = new Timer(100, this);
        addKeyListener(this);
        for(int i = 0; i < 75; i++) {rest.add(i);}
        //current_str = "B";
        //renew();
        Graphics2D g = visimage.createGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());
        pts = new Point2D.Double[1400];
        dirs = new double[pts.length];
        ptcolors = new Color[pts.length];
        for(int i = 0; i < pts.length; i++) {
            pts[i] = new Point2D.Double(Math.random()*siz, Math.random()*siz);
            dirs[i] = Math.random()*Math.PI*2;
            if(Math.random() < 0.5) {
                ptcolors[i] = Color.getHSBColor((float)i/pts.length, 1.0f, 1.0f);
            } else {
                ptcolors[i] = Color.WHITE;
            }
        }
        setVisible(true);
        timer.start();
    }
    private final int siz = 680;
    private BufferedImage visimage = new BufferedImage(siz, siz, BufferedImage.TYPE_INT_ARGB);
    private long currentrenew = 0;
    public void renew() {
        Graphics2D g = visimage.createGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());
        if(current_str.length() > 0) {
            double fsiz = siz / Math.sqrt(current_str.length());
            g.setFont(new Font(g.getFont().getFamily(), Font.PLAIN, (int)fsiz));
            FontMetrics fm = g.getFontMetrics();
            int fh = fm.getHeight();
            int fw = fm.stringWidth(current_str);
            g.setColor(Color.BLACK);
            g.drawString(current_str, (siz-fw)/2, (siz-fh)/2+fm.getAscent());
        }
        currentrenew = System.currentTimeMillis();
    }
    @Override
    public void actionPerformed(ActionEvent evt) {
        if(evt.getSource() == timer) {
            double speed = 6;
            double timedelay = (System.currentTimeMillis()-currentrenew);
            double lspeed = speed / (timedelay / 2000);
            if(timedelay < 2000) {
                lspeed = -speed;
            }
            for(int i = 0; i < pts.length; i++) {
                int x = (int)pts[i].getX();
                int y = (int)pts[i].getY();
                int rgb = 0;
                try{
                    rgb = visimage.getRGB(x,y);
                }catch(ArrayIndexOutOfBoundsException exp) {}
                int r = (rgb>>16)&255;
                int g = (rgb>>8)&255;
                int b = rgb&255;
                if(r == 0) {
                    dirs[i] += 0.01;
                    pts[i].x += Math.sin(dirs[i])*lspeed;
                    pts[i].y += Math.cos(dirs[i])*lspeed;
                } else {
                    pts[i].x -= Math.sin(dirs[i])*speed;
                    pts[i].y -= Math.cos(dirs[i])*speed;
                    if(Math.random() < 0.01) {
                        pts[i].x = Math.random() * siz;
                        pts[i].y = Math.random() * siz;
                    }
                }
                pts[i].x = (pts[i].x + siz) % siz;
                pts[i].y = (pts[i].y + siz) % siz;
            }
            bpanel.repaint();
        }
    }
    @Override
    public void keyReleased(KeyEvent evt) {}
    @Override
    public void keyPressed(KeyEvent evt) {
        if(evt.getKeyCode() == KeyEvent.VK_ENTER) {
            stat++;
            if(stat % 2 == 0) {
                if(rest.size()==0) {
                    stat--;
                    if(!hist.contains(-1)) {
                        hist.add(-1);
                    }
                    current_str = "";
                    renew();
                    return;
                }
                int numi = (int)(Math.random() * rest.size());
                int num = rest.get(numi);
                rest.remove(numi);
                hist.add(num);
                int row = num / 15;
                current_str = rownames[row];
                renew();
            } else {
                int num = hist.get(hist.size()-1);
                current_str = Integer.toString(num + 1);
                renew();
            }
        } else if(evt.getKeyCode() == KeyEvent.VK_ESCAPE) {
            System.exit(0);
        }
    }
    @Override
    public void keyTyped(KeyEvent evt) {}
    private BPanel bpanel = new BPanel();
    private class BPanel extends JPanel {
        @Override
        public void paint(Graphics g) {
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());
            //g.setColor(Color.WHITE);
            for(int i = 0; i < pts.length; i++) {
                Color c = ptcolors[i];
                g.setColor(c);
                int x = (int)pts[i].getX();
                int y = (int)pts[i].getY();
                //g.fillOval(x-5,y-5,10,10);
                g.drawOval(x-5,y-5,10,10);
            }
            g.setColor(Color.WHITE);
            int cx = siz;
            int cy = 0;
            int maxcr = 0;
            for(int i = 0; i < hist.size(); i++) {
                int fsiz = 25;
                if(hist.size()-i<2)fsiz=70;
                if(hist.size()-i<=2 && stat%2==0)fsiz=70;
                g.setFont(new Font(g.getFont().getFamily(), Font.PLAIN, fsiz));
                FontMetrics fm = g.getFontMetrics();
                if(cy+fm.getHeight()>getHeight()) {
                    cy = 0;
                    cx = maxcr+10;
                }
                int cur = hist.get(i);
                String str = "Finished.";
                if(cur != -1) {
                    str = rownames[cur/15];
                    if(i+1==hist.size() && stat%2==0) {
                        str = "_";
                    } else if(i+1<hist.size()) {
                        str += " " + (cur+1);
                    } else {
                        str += " _";
                    }
                }
                g.drawString(str, cx, cy+fm.getAscent());
                maxcr = Math.max(maxcr, cx+fm.stringWidth(str));
                cy += fm.getHeight();
            }
        }
        public BPanel() {
            super(true);
        }
    }
    public static void main(String[] args) {
        new Bingoer();
    }
}