로그인 바로가기

중앙 내용으로 바로가기

본문내용

하위메뉴

전화문의

053-428-3399

평일 : 09:00~18:30
주말 : 09:00~13:00

링크

본문

일반자료실
+ Home > 커뮤니티 > 일반자료실
자바 테트리스 소스 공유
  • 작성자
    신영민
  • 등록일
    2021-01-26 17:03:22
    조회수
    365

 

자바 테트리스 소스 공유  출처 사이트 
https://m.cafe.daum.net/oopthinking/9HLG/39


import java.applet‎.*;
import java.awt.*;
import java.util.*;

public class Tetris extends Applet‎ implements Runnable {

  /* */
  /* 상태정보,대개 mutex로 보호됨*/
  /* 이들값중일부는 .init이나 .erase 메서드 실행중에 대체된다 */
  /* */

  int edge = 16;		/* 블록의 변의 픽셀 수 */
  int width = 10;		/*  불록 단위의 너비*/
  int height = 20;		/*블록 단위의 높이*/
  int textSquares = 2;		/*점수에 사용되는 추가 네모 높이 */

  int shapes = 8;		/* 빈것을 포함한 도형 수 */
  int empty = 0;		/* 빈 네모의 도혐 번호*/
  Color[] colors = null;	/*각 도형의 색*/

  int[][] occupant = null;	/*각네모의 도형 번호*/
  boolean[][] piece = null;	/* 현재 조각의 도형*/
  int kind = 0;			/* 현재 조각의 도혐 번호 */
  int pieceSize = 4;		/*회전을 위한 현재 조각의 너비와 높이 */
  Point place = null;		/*최근에 조각의 왼쪽 위 좌표*/
  int value = 0;		/* 현재 조각의 현재 점수 값 */
  boolean moved;		/* 최근에 조각을 이동했는가? */

  int score = 0;		/* 현재 게임의 점수 */
  int maxLevel = 10;		/*선택할 수 있는 최고 단계 */
  int[] high = null;		/* 이번회의 최고 점수 */
  int level = 5;		/*현재 단계 */
  int fallCount = 0;		/* 마지막 단계 변경 후위 블록수 */
  int fallEnough = 200;		/* fallCount를 바탕으로 한 단계 증가의 임계값 */
  
  /* 모든시간 계산의 단위는 밀리초임 */
  boolean paused = false;	/*아무것도 변하지 않음  */
  boolean animate = true;	/* 아래로 이동의 부드러운 애니메이션 */
  int sleepTime = 33;		/*daemon 작동간격 */
  int moveTime;			/*이동간격  */
  long movieEnd;		/* "drop"무비가 끝난 실제 시간 */

  Thread daemon = null;		/* 블록 이동 스레드 */
  Image offscreen = null;	/* 화몀 밖 게임판,깜박이지 안게 하기 위해 */
  Image images[] = null;	/* 네모의 화면 밖 이미지 ,빠른 표시를 위해 */
  boolean boardInvalid = true;	/* 화면 밖 이미지가 데이터와 일치하지 않음 */
  Font theFont;			/* 점수위 글꼴 */
  
  
  /* */
  /* Game play */
  /* */
  
  private synchronized void erase(int levelDelta) { /* 새게임 시작,묵시적 초기화 포함 */
    if (colors==null) {
      colors = new Color[shapes];
      colors[empty] = new Color(102,102,102);	/* 어두운 회색 */
      colors[1]     = new Color(153,51,51);	/* 적색 */
      colors[2]     = new Color(204,204,0);	/* 황색 */
      colors[3]     = new Color(51,153,51);	/* 녹색 */
      colors[4]     = new Color(0,204,204);	/* 하늘색 */
      colors[5]     = new Color(51,102,204);	/* 청색 */
      colors[6]     = new Color(153,0,153);	/*선홍색 */
      colors[7]     = new Color(204,102,51);	/*주황색 */
    }
    if (high==null) {
      high = new int[maxLevel+1];
      for (int i=0; i<=maxLevel; i++) high[i] = 0;
    }
    if (occupant==null) occupant = new int[width][height];
    
    /* 이전 게임의 결과를 처리*/
    high[level] = Math.max(high[level], score);
    level = Math.max(0, Math.min(maxLevel, level+levelDelta));
    
    /* 이게 게임판을 지우고 빈 게임판을 다시 표시 */
    for (int x = 0; x= 0) break;
    }
    if (found<0) return false;
    /* 완전한 행이 있음.위의 행을 내림 */
    for (int y=found; y>0; y--) {
      for (int x=0; x=0 && (
                 newX<0 || newX>=width || newY>=height ||
                 occupant[newX][newY] != empty ) ) {
          return false;
        }
      }
    }
    piece = newPiece;
    place = newPlace;
    moved = true;
    repaintPiece();
    return true;
  }
  
  private synchronized boolean newPiece() {
    /* 기존의 조각을 배치된 것으로 변환하고 새 조각을 만든다.새 조각이 타당하면 ture를 반환한다. */
    if (piece != null) {
      for (int x=0; x= 0) occupant[place.x+x][place.y+y] = kind;
        }
      }
      score += value;
    }
    
    while (clearRow()) { }
    
    if (fallCount >= fallEnough) {
      high[level] = Math.max(high[level], score); /* 이동중 ,높은 점수를 기록 */
      level = Math.min(maxLevel, level+1);
      fallCount -= fallEnough;
    }
    moveTime = Math.max(100, 600-level*50);
    
    paintScore();
    repaint();
    boolean[][] newPiece = initPiece();
    kind = (short)(Math.floor(Math.random()*(shapes-1)+1));
    value = 24 + 2*level;
    int initX = 0;
    switch (kind) { /*****블럭의 형태 구현. ^^****/
    case 1:                    
      newPiece[0][1] = true;	/* . . . . */
      newPiece[1][1] = true;	/* X X X X */
      newPiece[2][1] = true;	/* . . . . */
      newPiece[3][1] = true;	/* . . . . */
      initX = -1;
      pieceSize = 4;
      break;
    case 2:
      newPiece[0][1] = true;	/* . . . . */
      newPiece[1][1] = true;	/* X X X . */
      newPiece[1][2] = true;	/* . X . . */
      newPiece[2][1] = true;	/* . . . . */
      initX = -1;
      pieceSize = 3;
      break;
    case 3:
      newPiece[0][2] = true;	/* . . . . */
      newPiece[1][1] = true;	/* . X X . */
      newPiece[1][2] = true;	/* X X . . */
      newPiece[2][1] = true;	/* . . . . */
      initX = -2;
      pieceSize = 3;
      break;
    case 4:
      newPiece[0][1] = true;	/* . . . . */
      newPiece[1][1] = true;	/* X X . . */
      newPiece[1][2] = true;	/* . X X . */
      newPiece[2][2] = true;	/* . . . . */
      initX = -2;
      pieceSize = 3;
      break;
    case 5:
      newPiece[0][1] = true;	/* . . . . */
      newPiece[0][2] = true;	/* X X X . */
      newPiece[1][1] = true;	/* X . . . */
      newPiece[2][1] = true;	/* . . . . */
      initX = -1;
      pieceSize = 3;
      break;
    case 6:
      newPiece[0][1] = true;	/* . . . . */
      newPiece[1][1] = true;	/* X X X . */
      newPiece[2][1] = true;	/* . . X . */
      newPiece[2][2] = true;	/* . . . . */
      initX = -1;
      pieceSize = 3;
      break;
    case 7:
      newPiece[0][0] = true;	/* X X . . */
      newPiece[0][1] = true;	/* X X . . */
      newPiece[1][0] = true;	/* . . . . */
      newPiece[1][1] = true;	/* . . . . */
      initX = -1;
      pieceSize = 2;
      break;
    default:
      System.err.println("unexpected shape kind "+kind);
      return false;
    }
    return putPiece(newPiece, new Point((width-pieceSize)/2, initX));
  }

  private boolean movePiece(int dx, int dy) {
    /* 타당하면 조각을 어떤 방향으로든 네모 하나 너비만큼 이동 */
    if (piece==null) return false;
    return putPiece(piece, new Point(place.x+dx, place.y+dy));
  }
  
  private boolean rotatePiece() {
    /* 타탕하면 조각을 반시계 방향으로 회전 */
    if (piece==null) return false;
    boolean[][] newPiece = initPiece();
    for (int x=0; x= nextMove && !paused) {
          nextMove = Math.max(now, nextMove+moveTime);
          long newMovieEnd = animate ? nextMove : now;
          if (moved) {
            /* 아직 자동으로 또는 사용자가 조각을 움직여 진행 중.한번 더 아래로 이동해 볼것*/
            moved = false;
            movieEnd = newMovieEnd;
            if (movePiece(0,1)) {
              value = Math.max(0, value-1);
              fallCount+=1;
            } else {
              /* 아직 이전 조각을 표시 중.무비를 종료하고 조각을 마지막 장소에 표시*/
              movieEnd = now;
              repaintPiece();
            };
          } else {
            /* 마지막 자동 이동으로 아무 일도 일어나지 않았는데 사용자가 아무 행동도 하지 않음.
            다른 조각을 생성하고 실패하면 게임을 종료*/
            movieEnd = now;
            repaintPiece();
            movieEnd = newMovieEnd;
            if (!newPiece()) erase(0);
          }
        } else {
          repaintPiece();
        }
      }
      try { Thread.sleep(sleepTime);
      } catch (InterruptedException e) { };
    };
  }


  /* */
  /* 그리기 */
  /* */
  
  /* 일반적인 "offscreen"에 표시하여 깜박임을 방지한 다음 그것의 적절한 부분집합을 화면 에
     표시하는 것이다.대부분의 표시 작동은 "repaintPiece"호출을 통해 동기화되는데,그 이유는
     그것이 화면에 복사하는 네모 수를 줄이는 방법이기 때문이다.대안으로느 "repaintPiece"의
     "repaint"가 있지만 그것은 속도가 느리고 실행 시간 시스템이 "update"를 호출할 경우 
     타이밍이 달라질 수 있다.또한 가 네모 새긩 픽셀을 저장하는 "images"라는 화면 밖 이미지가
     있는데,이것은 필요할때 네모를 생성하는 것보다 좀더 빠르며 네모의 이미지에 GIF와 같은 
     형식을 사용할 경우 적합한 방법이기도 하다*/
     
  private void paintSquare(Graphics g, int x, int y, int delta, int shape) {
    /* "images"에서 한 픽셀을 사실상 화면 밖 이미지에 표시 */
    g.drawImage(images[shape], x*edge, (y+textSquares)*edge+delta, this);
  }

  private void paintScore() {
    /* score나 pause상태가 바뀌었으므로 화면 밖 이미지를 새로 고침 */
    if (offscreen == null) return;
    Graphics g = offscreen.getGraphics();
    int margin = 1+edge/8;
    g.setColor(colors[empty]);
    g.fill3DRect(0, 0, width*edge, textSquares*edge, true);
    g.setFont(theFont);
    FontMetrics fm = this.getFontMetrics(theFont);
    int fontHeight = fm.getHeight();
    int fontAscent = fm.getAscent();
    int leading = (textSquares*edge-2*fontHeight)/3;
    String left = "Best: "+high[level];
    String right = paused ? "Paused" : "";
    String left2 = "Current: "+score;
    String right2 = "Level: "+level;
    int baseline = leading + fontAscent;
    g.setColor(Color.white);
    g.drawString(left, margin, baseline);
    g.setColor(Color.red);
    g.drawString(right, width*edge-margin-fm.stringWidth(right), baseline);
    g.setColor(Color.white);
    baseline += fontHeight+leading;
    g.drawString(left2, margin, baseline);
    g.drawString(right2, width*edge-margin-fm.stringWidth(right2), baseline);
  }

  private void paintPiece(boolean doRepaint) {
    /* 조각이 바뀌거나 이동했으므로 화면 밖 이미지를 새로 고친다.조각을 표시하고 최근의
	  네모 하나 이동과 이전의 진행 중 이동을 처리한다."doRepaint"인 경우네는 대상 네모들을 
  	동기화하여 화면에 표시한다 */
    long now = System.currentTimeMillis();
    int moviePos = -(int)((Math.max(movieEnd-now,0)*edge+moveTime/2)/moveTime);
    if (piece == null || offscreen == null ) return;
    int minX = Math.max(place.x-1, 0);
    int limX = Math.min(place.x+pieceSize+1, width);
    int minY = Math.max(place.y-2, 0);
    int limY = Math.min(place.y+pieceSize, height); /*조각이 이동하지 않았음! */
    {
      Graphics g = offscreen.getGraphics();
      g.clipRect(0, textSquares*edge, width*edge, height*edge);
      for (int x = minX; x= place.x && x < place.x+pieceSize &&
               y >= place.y && y < place.y+pieceSize &&
               piece[x-place.x][y-place.y] )  {
            paintSquare(g, x, y, moviePos, kind);
          }
        }
      }
    }
    if (doRepaint) {
      Graphics g = getGraphics();
      g.clipRect(minX*edge, (minY+textSquares)*edge,
                 (limX-minX)*edge, (limY-minY)*edge);
      g.drawImage(offscreen, 0, 0, this);
    }
  }
  
  private void repaintPiece() {
    /* 화면 밖 이미지를 현재 사애의 조각으로 갱신하고 픽셀이 화면에 제대로 표시되는지 확인. */
    paintPiece(!boardInvalid);
  }
  
  private void paintBoard() {
    /* 화면 밖 이미지를 백지 상태에서 생성 */
    Graphics g = offscreen.getGraphics();
    g.clipRect(0, textSquares*edge, width*edge, height*edge);
    for (int x = 0; x 0) erase(-1);
      return true;
    case 'j':
    case Event.LEFT:
      movePiece(-1,0);
      return true;
    case 'k':
    case Event.UP:
      rotatePiece();
      return true;
    case 'l':
    case Event.RIGHT:
      movePiece(1,0);
      return true;
    case 'p':
      paused = !paused;
      paintScore();
      repaint();
      return true;
    case 's':
      erase(0);
      return true;
    case 'u':
      if (level < maxLevel) erase(+1);
      return true;
    case ' ':
    case Event.DOWN:
      movieEnd = System.currentTimeMillis();
      while (movePiece(0,1)) {}
      return true;
   }
    return false;
  }

}                 

 

import java.applet‎.*;
import java.awt.*;
import java.util.*;

public class Tetris extends Applet‎ implements Runnable {

  /* */
  /* 상태정보,대개 mutex로 보호됨*/
  /* 이들값중일부는 .init이나 .erase 메서드 실행중에 대체된다 */
  /* */

  int edge = 16;		/* 블록의 변의 픽셀 수 */
  int width = 10;		/*  불록 단위의 너비*/
  int height = 20;		/*블록 단위의 높이*/
  int textSquares = 2;		/*점수에 사용되는 추가 네모 높이 */

  int shapes = 8;		/* 빈것을 포함한 도형 수 */
  int empty = 0;		/* 빈 네모의 도혐 번호*/
  Color[] colors = null;	/*각 도형의 색*/

  int[][] occupant = null;	/*각네모의 도형 번호*/
  boolean[][] piece = null;	/* 현재 조각의 도형*/
  int kind = 0;			/* 현재 조각의 도혐 번호 */
  int pieceSize = 4;		/*회전을 위한 현재 조각의 너비와 높이 */
  Point place = null;		/*최근에 조각의 왼쪽 위 좌표*/
  int value = 0;		/* 현재 조각의 현재 점수 값 */
  boolean moved;		/* 최근에 조각을 이동했는가? */

  int score = 0;		/* 현재 게임의 점수 */
  int maxLevel = 10;		/*선택할 수 있는 최고 단계 */
  int[] high = null;		/* 이번회의 최고 점수 */
  int level = 5;		/*현재 단계 */
  int fallCount = 0;		/* 마지막 단계 변경 후위 블록수 */
  int fallEnough = 200;		/* fallCount를 바탕으로 한 단계 증가의 임계값 */
  
  /* 모든시간 계산의 단위는 밀리초임 */
  boolean paused = false;	/*아무것도 변하지 않음  */
  boolean animate = true;	/* 아래로 이동의 부드러운 애니메이션 */
  int sleepTime = 33;		/*daemon 작동간격 */
  int moveTime;			/*이동간격  */
  long movieEnd;		/* "drop"무비가 끝난 실제 시간 */

  Thread daemon = null;		/* 블록 이동 스레드 */
  Image offscreen = null;	/* 화몀 밖 게임판,깜박이지 안게 하기 위해 */
  Image images[] = null;	/* 네모의 화면 밖 이미지 ,빠른 표시를 위해 */
  boolean boardInvalid = true;	/* 화면 밖 이미지가 데이터와 일치하지 않음 */
  Font theFont;			/* 점수위 글꼴 */
  
  
  /* */
  /* Game play */
  /* */
  
  private synchronized void erase(int levelDelta) { /* 새게임 시작,묵시적 초기화 포함 */
    if (colors==null) {
      colors = new Color[shapes];
      colors[empty] = new Color(102,102,102);	/* 어두운 회색 */
      colors[1]     = new Color(153,51,51);	/* 적색 */
      colors[2]     = new Color(204,204,0);	/* 황색 */
      colors[3]     = new Color(51,153,51);	/* 녹색 */
      colors[4]     = new Color(0,204,204);	/* 하늘색 */
      colors[5]     = new Color(51,102,204);	/* 청색 */
      colors[6]     = new Color(153,0,153);	/*선홍색 */
      colors[7]     = new Color(204,102,51);	/*주황색 */
    }
    if (high==null) {
      high = new int[maxLevel+1];
      for (int i=0; i<=maxLevel; i++) high[i] = 0;
    }
    if (occupant==null) occupant = new int[width][height];
    
    /* 이전 게임의 결과를 처리*/
    high[level] = Math.max(high[level], score);
    level = Math.max(0, Math.min(maxLevel, level+levelDelta));
    
    /* 이게 게임판을 지우고 빈 게임판을 다시 표시 */
    for (int x = 0; x= 0) break;
    }
    if (found<0) return false;
    /* 완전한 행이 있음.위의 행을 내림 */
    for (int y=found; y>0; y--) {
      for (int x=0; x=0 && (
                 newX<0 || newX>=width || newY>=height ||
                 occupant[newX][newY] != empty ) ) {
          return false;
        }
      }
    }
    piece = newPiece;
    place = newPlace;
    moved = true;
    repaintPiece();
    return true;
  }
  
  private synchronized boolean newPiece() {
    /* 기존의 조각을 배치된 것으로 변환하고 새 조각을 만든다.새 조각이 타당하면 ture를 반환한다. */
    if (piece != null) {
      for (int x=0; x= 0) occupant[place.x+x][place.y+y] = kind;
        }
      }
      score += value;
    }
    
    while (clearRow()) { }
    
    if (fallCount >= fallEnough) {
      high[level] = Math.max(high[level], score); /* 이동중 ,높은 점수를 기록 */
      level = Math.min(maxLevel, level+1);
      fallCount -= fallEnough;
    }
    moveTime = Math.max(100, 600-level*50);
    
    paintScore();
    repaint();
    boolean[][] newPiece = initPiece();
    kind = (short)(Math.floor(Math.random()*(shapes-1)+1));
    value = 24 + 2*level;
    int initX = 0;
    switch (kind) { /*****블럭의 형태 구현. ^^****/
    case 1:                    
      newPiece[0][1] = true;	/* . . . . */
      newPiece[1][1] = true;	/* X X X X */
      newPiece[2][1] = true;	/* . . . . */
      newPiece[3][1] = true;	/* . . . . */
      initX = -1;
      pieceSize = 4;
      break;
    case 2:
      newPiece[0][1] = true;	/* . . . . */
      newPiece[1][1] = true;	/* X X X . */
      newPiece[1][2] = true;	/* . X . . */
      newPiece[2][1] = true;	/* . . . . */
      initX = -1;
      pieceSize = 3;
      break;
    case 3:
      newPiece[0][2] = true;	/* . . . . */
      newPiece[1][1] = true;	/* . X X . */
      newPiece[1][2] = true;	/* X X . . */
      newPiece[2][1] = true;	/* . . . . */
      initX = -2;
      pieceSize = 3;
      break;
    case 4:
      newPiece[0][1] = true;	/* . . . . */
      newPiece[1][1] = true;	/* X X . . */
      newPiece[1][2] = true;	/* . X X . */
      newPiece[2][2] = true;	/* . . . . */
      initX = -2;
      pieceSize = 3;
      break;
    case 5:
      newPiece[0][1] = true;	/* . . . . */
      newPiece[0][2] = true;	/* X X X . */
      newPiece[1][1] = true;	/* X . . . */
      newPiece[2][1] = true;	/* . . . . */
      initX = -1;
      pieceSize = 3;
      break;
    case 6:
      newPiece[0][1] = true;	/* . . . . */
      newPiece[1][1] = true;	/* X X X . */
      newPiece[2][1] = true;	/* . . X . */
      newPiece[2][2] = true;	/* . . . . */
      initX = -1;
      pieceSize = 3;
      break;
    case 7:
      newPiece[0][0] = true;	/* X X . . */
      newPiece[0][1] = true;	/* X X . . */
      newPiece[1][0] = true;	/* . . . . */
      newPiece[1][1] = true;	/* . . . . */
      initX = -1;
      pieceSize = 2;
      break;
    default:
      System.err.println("unexpected shape kind "+kind);
      return false;
    }
    return putPiece(newPiece, new Point((width-pieceSize)/2, initX));
  }

  private boolean movePiece(int dx, int dy) {
    /* 타당하면 조각을 어떤 방향으로든 네모 하나 너비만큼 이동 */
    if (piece==null) return false;
    return putPiece(piece, new Point(place.x+dx, place.y+dy));
  }
  
  private boolean rotatePiece() {
    /* 타탕하면 조각을 반시계 방향으로 회전 */
    if (piece==null) return false;
    boolean[][] newPiece = initPiece();
    for (int x=0; x= nextMove && !paused) {
          nextMove = Math.max(now, nextMove+moveTime);
          long newMovieEnd = animate ? nextMove : now;
          if (moved) {
            /* 아직 자동으로 또는 사용자가 조각을 움직여 진행 중.한번 더 아래로 이동해 볼것*/
            moved = false;
            movieEnd = newMovieEnd;
            if (movePiece(0,1)) {
              value = Math.max(0, value-1);
              fallCount+=1;
            } else {
              /* 아직 이전 조각을 표시 중.무비를 종료하고 조각을 마지막 장소에 표시*/
              movieEnd = now;
              repaintPiece();
            };
          } else {
            /* 마지막 자동 이동으로 아무 일도 일어나지 않았는데 사용자가 아무 행동도 하지 않음.
            다른 조각을 생성하고 실패하면 게임을 종료*/
            movieEnd = now;
            repaintPiece();
            movieEnd = newMovieEnd;
            if (!newPiece()) erase(0);
          }
        } else {
          repaintPiece();
        }
      }
      try { Thread.sleep(sleepTime);
      } catch (InterruptedException e) { };
    };
  }


  /* */
  /* 그리기 */
  /* */
  
  /* 일반적인 "offscreen"에 표시하여 깜박임을 방지한 다음 그것의 적절한 부분집합을 화면 에
     표시하는 것이다.대부분의 표시 작동은 "repaintPiece"호출을 통해 동기화되는데,그 이유는
     그것이 화면에 복사하는 네모 수를 줄이는 방법이기 때문이다.대안으로느 "repaintPiece"의
     "repaint"가 있지만 그것은 속도가 느리고 실행 시간 시스템이 "update"를 호출할 경우 
     타이밍이 달라질 수 있다.또한 가 네모 새긩 픽셀을 저장하는 "images"라는 화면 밖 이미지가
     있는데,이것은 필요할때 네모를 생성하는 것보다 좀더 빠르며 네모의 이미지에 GIF와 같은 
     형식을 사용할 경우 적합한 방법이기도 하다*/
     
  private void paintSquare(Graphics g, int x, int y, int delta, int shape) {
    /* "images"에서 한 픽셀을 사실상 화면 밖 이미지에 표시 */
    g.drawImage(images[shape], x*edge, (y+textSquares)*edge+delta, this);
  }

  private void paintScore() {
    /* score나 pause상태가 바뀌었으므로 화면 밖 이미지를 새로 고침 */
    if (offscreen == null) return;
    Graphics g = offscreen.getGraphics();
    int margin = 1+edge/8;
    g.setColor(colors[empty]);
    g.fill3DRect(0, 0, width*edge, textSquares*edge, true);
    g.setFont(theFont);
    FontMetrics fm = this.getFontMetrics(theFont);
    int fontHeight = fm.getHeight();
    int fontAscent = fm.getAscent();
    int leading = (textSquares*edge-2*fontHeight)/3;
    String left = "Best: "+high[level];
    String right = paused ? "Paused" : "";
    String left2 = "Current: "+score;
    String right2 = "Level: "+level;
    int baseline = leading + fontAscent;
    g.setColor(Color.white);
    g.drawString(left, margin, baseline);
    g.setColor(Color.red);
    g.drawString(right, width*edge-margin-fm.stringWidth(right), baseline);
    g.setColor(Color.white);
    baseline += fontHeight+leading;
    g.drawString(left2, margin, baseline);
    g.drawString(right2, width*edge-margin-fm.stringWidth(right2), baseline);
  }

  private void paintPiece(boolean doRepaint) {
    /* 조각이 바뀌거나 이동했으므로 화면 밖 이미지를 새로 고친다.조각을 표시하고 최근의
	  네모 하나 이동과 이전의 진행 중 이동을 처리한다."doRepaint"인 경우네는 대상 네모들을 
  	동기화하여 화면에 표시한다 */
    long now = System.currentTimeMillis();
    int moviePos = -(int)((Math.max(movieEnd-now,0)*edge+moveTime/2)/moveTime);
    if (piece == null || offscreen == null ) return;
    int minX = Math.max(place.x-1, 0);
    int limX = Math.min(place.x+pieceSize+1, width);
    int minY = Math.max(place.y-2, 0);
    int limY = Math.min(place.y+pieceSize, height); /*조각이 이동하지 않았음! */
    {
      Graphics g = offscreen.getGraphics();
      g.clipRect(0, textSquares*edge, width*edge, height*edge);
      for (int x = minX; x= place.x && x < place.x+pieceSize &&
               y >= place.y && y < place.y+pieceSize &&
               piece[x-place.x][y-place.y] )  {
            paintSquare(g, x, y, moviePos, kind);
          }
        }
      }
    }
    if (doRepaint) {
      Graphics g = getGraphics();
      g.clipRect(minX*edge, (minY+textSquares)*edge,
                 (limX-minX)*edge, (limY-minY)*edge);
      g.drawImage(offscreen, 0, 0, this);
    }
  }
  
  private void repaintPiece() {
    /* 화면 밖 이미지를 현재 사애의 조각으로 갱신하고 픽셀이 화면에 제대로 표시되는지 확인. */
    paintPiece(!boardInvalid);
  }
  
  private void paintBoard() {
    /* 화면 밖 이미지를 백지 상태에서 생성 */
    Graphics g = offscreen.getGraphics();
    g.clipRect(0, textSquares*edge, width*edge, height*edge);
    for (int x = 0; x 0) erase(-1);
      return true;
    case 'j':
    case Event.LEFT:
      movePiece(-1,0);
      return true;
    case 'k':
    case Event.UP:
      rotatePiece();
      return true;
    case 'l':
    case Event.RIGHT:
      movePiece(1,0);
      return true;
    case 'p':
      paused = !paused;
      paintScore();
      repaint();
      return true;
    case 's':
      erase(0);
      return true;
    case 'u':
      if (level < maxLevel) erase(+1);
      return true;
    case ' ':
    case Event.DOWN:
      movieEnd = System.currentTimeMillis();
      while (movePiece(0,1)) {}
      return true;
   }
    return false;
  }

}                 

 


 

목록보기
수정하기
삭제하기