import java.awt.*; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import java.util.*; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.awt.event.WindowAdapter; class Cube { static final int wh=12; static Random rand=new Random(); Component comp; Image image[]= new Image[6]; int color=0; int rot=0; int masks[]= new int[4]; public int mask=0; public Cube(Component comp, int m0, int m1, int m2, int m3){ this.comp=comp; mask=m0; masks[0]=m0; masks[1]=m1; masks[2]=m2; masks[3]=m3; setColor(); } public void setColor(){ int index=rand.nextInt(); if (index<0) index=(-index); color= index%(image.length); } public void rotate(int i){ rot+=i; if (rot<0) rot=3; if (rot>3) rot=0; mask = masks[rot]; } public void draw(Graphics g, Image image, int x, int y){ int index,offset; if (mask!=0) { index = mask; for (int i=0; i<3; i++) { offset=0; if ((index&0x04)!=0) g.drawImage(image,x+offset,y,comp); offset+=wh; if ((index&0x02)!=0) g.drawImage(image,x+offset,y,comp); offset+=wh; if ((index&0x01)!=0) g.drawImage(image,x+offset,y,comp); index>>=4; y+=wh; } }else g.drawImage(image,x,y,comp); } private Image createCube(Color c){ Image temp= comp.createImage(Cube.wh,Cube.wh); Graphics g= temp.getGraphics(); g.setColor(Color.white); g.fillRect(0,0,Cube.wh,Cube.wh); g.setColor(c); g.fillRect(1,1,Cube.wh-1,Cube.wh-1); g.dispose(); return temp; } public void paint(Graphics g, int col, int row){ int x=col*wh; int y=row*wh; if (image[0]==null) { MediaTracker mt= new MediaTracker(comp); try { Class c = Class.forName("ice"); image[0]= Toolkit.getDefaultToolkit().getImage(c.getResource("diamg.gif")); image[1]= Toolkit.getDefaultToolkit().getImage(c.getResource("diamp.gif")); image[2]= Toolkit.getDefaultToolkit().getImage(c.getResource("diamo.gif")); image[3]= Toolkit.getDefaultToolkit().getImage(c.getResource("diamb.gif")); image[4]= Toolkit.getDefaultToolkit().getImage(c.getResource("diamy.gif")); image[5]= Toolkit.getDefaultToolkit().getImage(c.getResource("diamr.gif")); for (int i=0; i<image.length; i++) mt.addImage(image[i], i); try { mt.waitForAll(); }catch (Exception e){ } }catch (Exception e){ } } draw(g,image[color],x,y); } } public class ice extends Panel implements Runnable, KeyListener{ static int TOTALROWS=20; Cube cubes[]= new Cube[4]; Cube current=null; Image tile=null; Image background=null; Image tiling=null; Image copy=null; Random rand=new Random(); Graphics gt,gb,gc; int speedSet=10; //adjust speedSet will adjust after clearing a row the speed int speed=speedSet; //the speed that pieces fall. int row=0,col=0; int lines=0; long grid[]= new long[TOTALROWS+2]; Label label = new Label("by r.redpath "); public ice(String title){ Frame f= new Frame(" ice "); label.setBackground(Color.lightGray); f.setLayout(new BorderLayout() ); f.add("Center", this); f.add("South", label); f.setBounds(10,10,Cube.wh*16+7,Cube.wh*TOTALROWS); setVisible(true); cubes[0] = new Cube((Component)this,0x00000074 ,0x00000446 ,0x00000170 ,0x00000622 ); cubes[1] = new Cube((Component)this,0x00000444 ,0x00000070 ,0x00000444 ,0x00000070 ); cubes[2] = new Cube((Component)this,0x00000066 ,0x00000066 ,0x00000066 ,0x00000066 ); cubes[3] = new Cube((Component)this,0x00000270 ,0x00000262 ,0x00000072 ,0x00000464 ); current= cubes[0]; setBackground(Color.lightGray); addKeyListener(this); // addMouseListener(this); f.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} } ); f.show(); start(); } public void start(){ new Thread(this).start(); } private void set(){ int mask = current.mask; --row; if (row==0) { gb.drawImage(tiling,0,0,this); for (int i=0; i<grid.length; i++) grid[i]=0; newCurrent(); row=0; speed=speedSet; return; } grid[row] |= (mask&0x0F)<<(16-col); mask>>=4; grid[row+1]|= (mask&0x0F)<<(16-col); mask>>=4; grid[row+2]|= (mask&0x0F)<<(16-col); current.paint(gb,col,row); row=0; speed=speedSet; newCurrent(); int j=grid.length-1; gc.drawImage(tiling,0,0,this); for (int i=j; i>=0; i--) if ((grid[i]&0x0007FFF8)==0x0007FFF8) ++lines; else{ gc.drawImage(background, 0,j*Cube.wh, 16*Cube.wh, j*Cube.wh+Cube.wh, 0,i*Cube.wh, 16*Cube.wh, i*Cube.wh+Cube.wh, this); grid[j--]= grid[i]; } if (j>=0) Toolkit.getDefaultToolkit().beep(); for (int i=j; i>=0; i--) grid[i]=0; gb.drawImage(copy,0,0,this); repaint(); } private boolean checkGrid(){ int mask= current.mask; long index; int gridindex=row; if (col>12){ int right=0; index = (mask&0x0F) | ((mask>>4)&0x0F) | ((mask>>8)&0x0F); if ((index&0x004)!=0) right=1; if ((index&0x002)!=0) right=2; if ((index&0x001)!=0) right=3; if (col>(16-right)) col=16-right; } for (int i=0; i<3; i++) { index= mask&0x0F; index<<= (16-col); if ((grid[gridindex]&index)!=0){ return false; } if ( (gridindex>(TOTALROWS-1))&& //at bottom for this cube ((mask&0x0F)!=0) ){ return false; } ++gridindex; mask>>=4; } return true; } public void newCurrent(){ int index=rand.nextInt(); if (index<0) index=(-index); current=cubes[index%cubes.length]; current.setColor(); index=rand.nextInt(); if (index<0) index=(-index); col= index%16; checkGrid(); } public void run(){ Thread.currentThread().setName("ice_thread"); int count=0; try { while (true) { Thread.sleep(25); if (count++<speed) continue; count=0; ++row; if (checkGrid()) paint(getGraphics()); else set(); } }catch (Exception e){ e.printStackTrace(); } } public void keyTyped(KeyEvent e){ } public void keyPressed(KeyEvent e){ switch (e.getKeyCode()){ case KeyEvent.VK_UP: current.rotate(1); break; case KeyEvent.VK_DOWN: current.rotate(-1); break; case KeyEvent.VK_LEFT: if (col!=0) --col; if (checkGrid()) paint(getGraphics()); else --col; break; case KeyEvent.VK_RIGHT: if (col!=15) ++col; if (checkGrid()) paint(getGraphics()); else --col; break; default: speed=0; } } public void keyReleased(KeyEvent e){ } public void update(Graphics g){ paint(g); } public void paint(Graphics g){ g.drawImage(background,0,0,this); current.paint(g,col,row); label.setText("by r.redpath lines "+lines); } private void clearBackground(){ } public void doLayout(){ super.doLayout(); Rectangle rect = getBounds(); TOTALROWS=rect.height/Cube.wh; if (TOTALROWS<2) TOTALROWS=2; grid= new long[TOTALROWS+2]; int h=TOTALROWS*Cube.wh; int w=16*Cube.wh; if (background==null) { MediaTracker mt= new MediaTracker(this); try { Class c = Class.forName("ice"); tile =Toolkit.getDefaultToolkit().getImage(c.getResource("tback.gif")); }catch (Exception e){ } mt.addImage(tile, 1); try { mt.waitForID(1); }catch (Exception e){ } } copy = createImage(w,h); background = createImage(w,h); gb = background.getGraphics(); gc = copy.getGraphics(); tiling = createImage(w,h); gt = tiling.getGraphics(); if (tile==null) { gb.setColor(Color.white); gb.fillRect(0,0,w,h); return; } int ni = w/tile.getWidth(this)+1; int nj = h/tile.getHeight(this)+1; for (int i=0; i<ni; i++) for (int j=0; j<nj; j++) gt.drawImage(tile,i*tile.getWidth(this), j*tile.getHeight(this),this); gb.drawImage(tiling,0,0,this); } public static void main(String args[]){ ice f= new ice(" ice "); } }