import java.awt.*; import java.applet.Applet; import java.awt.event.*; import java.io.*; import java.awt.image.*; import java.util.*; public class BozuMekuri extends Applet implements MouseListener,WindowListener,Runnable { Yama ba=new Yama(252,181),sute=new Yama(192,181); Yama[] te=new Yama[4]; Image cats,arrow; Point source=new Point(); Polygon shadow=new Polygon(new int[4],new int[4],4); Rectangle expanded=new Rectangle(); int current=(int)(Math.random()*4); Karuta drawn; boolean zooming=false; Image offscreen; public void init() { try { cats=Toolkit.getDefaultToolkit().getImage(getClass().getResource("cats.gif")); arrow=Toolkit.getDefaultToolkit().getImage(getClass().getResource("arrow.gif")); StreamTokenizer st=new StreamTokenizer( new BufferedReader(new InputStreamReader( getClass().getResourceAsStream("data.txt")))); for (int i=0;i<100;i++) { while (st.ttype!=StreamTokenizer.TT_NUMBER) st.nextToken(); Karuta karuta=new Karuta(); karuta.number=(int)st.nval; for (int j=0;j<5;j++) { st.nextToken(); karuta.uta[j]=st.sval; } st.nextToken(); karuta.yomibito=st.sval; st.nextToken(); if (st.sval.equals("男")) karuta.type=Karuta.OTOKO; else if (st.sval.equals("女")) karuta.type=Karuta.ONNA; else karuta.type=Karuta.BOZU; ba.put(karuta); } } catch (Exception e) { } ba.shuffle(); te[0]=new Yama(185,261); te[1]=new Yama(445,173); te[2]=new Yama(276,113); te[3]=new Yama(25,172); setSize(512,342); addMouseListener(this); } public void mouseClicked(MouseEvent e) { if (!zooming && !(ba.isEmpty() && drawn==null)) new Thread(this).start(); } public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} synchronized public void run() { zooming=true; if (drawn==null) { Karuta drawing=ba.get(); source.setLocation(ba.point.x+30,ba.point.y+30); expanded.setBounds((int)(Math.random()*(512-200)),(int)(Math.random()*(342-320)),200,320); for (int step=0;step<=20;step++) { setShadow(step,20); repaint(); try { Thread.sleep(30); } catch (InterruptedException e) { } } drawn=drawing; repaint(); } else { Karuta restoring=drawn; source.setLocation(te[current].point.x+30,te[current].point.y+30); drawn=null; for (int step=20;step>=0;step--) { setShadow(step,20); repaint(); try { Thread.sleep(30); } catch (InterruptedException e) { } } te[current].put(restoring); if (restoring.type==Karuta.ONNA && !te[current].isEmpty()) { Stack moving=new Stack(); while (!te[current].isEmpty()) moving.push(te[current].get()); for (int step=0;step<=10;step++) { setShadow(step,10,te[current].point.x+30,te[current].point.y+30,sute.point.x+30,sute.point.y+30); repaint(); try { Thread.sleep(30); } catch (InterruptedException e) { } } while (!moving.isEmpty()) sute.put((Karuta)moving.pop()); } if (restoring.type==Karuta.BOZU && !sute.isEmpty()) { Stack moving=new Stack(); while (!sute.isEmpty()) moving.push(sute.get()); for (int step=20;step>=0;step--) { setShadow(step,20,te[current].point.x+30,te[current].point.y+30,sute.point.x+30,sute.point.y+30); repaint(); try { Thread.sleep(30); } catch (InterruptedException e) { } } while (!moving.isEmpty()) te[current].put((Karuta)moving.pop()); } current=(current+3)%4; repaint(); } zooming=false; } void setShadow(int step,int nsteps,int sx,int sy,int ex,int ey) { int x=(step*ex+(nsteps-step)*sx)/nsteps; int y=(step*ey+(nsteps-step)*sy)/nsteps; double theta=2*Math.PI*step/nsteps-Math.PI/6; double cos=Math.cos(theta); double sin=Math.sin(theta); shadow.xpoints[0]=x+(int)(16*cos-10*sin); shadow.ypoints[0]=y+(int)(16*sin+10*cos); shadow.xpoints[1]=x+(int)(-16*cos-10*sin); shadow.ypoints[1]=y+(int)(-16*sin+10*cos); shadow.xpoints[2]=x+(int)(-16*cos+10*sin); shadow.ypoints[2]=y+(int)(-16*sin-10*cos); shadow.xpoints[3]=x+(int)(16*cos+10*sin); shadow.ypoints[3]=y+(int)(16*sin-10*cos); } void setShadow(int step,int nsteps) { int x=(step*(expanded.x+expanded.width/2)+(nsteps-step)*source.x)/nsteps; int y=(step*(expanded.y+expanded.height/2)+(nsteps-step)*source.y)/nsteps; int width=expanded.width*step/nsteps/2; int height=expanded.height*step/nsteps/2; double theta=-2*Math.PI*step/nsteps; double cos=Math.cos(theta); double sin=Math.sin(theta); shadow.xpoints[0]=x+(int)(width*cos-height*sin); shadow.ypoints[0]=y+(int)(width*sin+height*cos); shadow.xpoints[1]=x+(int)(-width*cos-height*sin); shadow.ypoints[1]=y+(int)(-width*sin+height*cos); shadow.xpoints[2]=x+(int)(-width*cos+height*sin); shadow.ypoints[2]=y+(int)(-width*sin-height*cos); shadow.xpoints[3]=x+(int)(width*cos+height*sin); shadow.ypoints[3]=y+(int)(width*sin-height*cos); } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { if (offscreen==null) offscreen=createImage(512,342); Graphics og=offscreen.getGraphics(); try { og.drawImage(cats,0,0,this); ba.paint(og,this); sute.paint(og,this); for (int i=0;i<4;i++) te[i].paint(og,this); if (ba.isEmpty() && drawn==null && !zooming) { Font font=new Font(og.getFont().getName(),Font.PLAIN,24); FontMetrics fm=Toolkit.getDefaultToolkit().getFontMetrics(font); og.setFont(font); og.drawString(te[0].size(),295,267); og.drawString(te[1].size(),367-fm.stringWidth(te[1].size()),175); og.drawString(te[2].size(),219-fm.stringWidth(te[2].size()),123); og.drawString(te[3].size(),153,198); } else switch (current) { case 0: og.drawImage(arrow,268-arrow.getWidth(this)/2,244-arrow.getHeight(this),this); break; case 1: og.drawImage(arrow,392-arrow.getWidth(this)/2,147-arrow.getHeight(this),this); break; case 2: og.drawImage(arrow,243-arrow.getWidth(this)/2,101-arrow.getHeight(this),this); break; case 3: og.drawImage(arrow,124-arrow.getWidth(this)/2,168-arrow.getHeight(this),this); break; } if (drawn!=null){ og.setClip(expanded); drawn.paint(og,this); } else if (zooming) og.drawPolygon(shadow); } catch (NullPointerException e) { } g.drawImage(offscreen,0,0,this); } static public void main(String[] args) { BozuMekuri main=new BozuMekuri(); main.init(); Frame frame=new Frame("ぼうずめくり"); frame.add(main); frame.setSize(512,384); frame.addWindowListener(main); frame.show(); } public void windowOpened(WindowEvent e) {} public void windowActivated(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowClosing(WindowEvent e) { System.exit(0); } public void windowClosed(WindowEvent e) {} } class Karuta { final static int OTOKO=0,ONNA=1,BOZU=2; static Image[] image=new Image[3]; int number; String[] uta=new String[5]; String yomibito; int type; void paint(Graphics g,ImageObserver io) { Rectangle rect=g.getClipBounds(); int grid=Math.min(rect.width/10,rect.height/15); g.setColor(new Color(0x336600)); g.fillRect(rect.x,rect.y,rect.width,rect.height); g.setColor(Color.white); g.fillRect(rect.x+grid/2,rect.y+grid/2,rect.width-grid,rect.height-grid); try { if (image[type]==null) switch (type) { case OTOKO: image[type]=Toolkit.getDefaultToolkit().getImage(getClass().getResource("otoko.gif")); break; case ONNA: image[type]=Toolkit.getDefaultToolkit().getImage(getClass().getResource("onna.gif")); break; case BOZU: image[type]=Toolkit.getDefaultToolkit().getImage(getClass().getResource("bozu.gif")); break; } g.drawImage(image[type],rect.x+grid/2,rect.y+rect.height-grid/2-(rect.width-grid)*image[type].getHeight(io)/image[type].getWidth(io), rect.width-grid,(rect.width-grid)*image[type].getHeight(io)/image[type].getWidth(io),io); } catch (Exception e) { } Font font=new Font(g.getFont().getName(),Font.PLAIN,grid); FontMetrics fm=Toolkit.getDefaultToolkit().getFontMetrics(font); g.setFont(font); g.setColor(Color.black); for (int i=0;i0) g.drawImage(image,point.x,point.y,point.x+60,point.y+60,(index-1)/10*60,0,((index-1)/10+1)*60,60,io); } catch (Exception e) { } } }