태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

기존에 Java로 만든 Tetris를 2인용으로 바꾸려고 하니, 구조에 문제가 있다는 걸 깨닫고,

키입력과 UI를 담당할 Player 클래스를 추가했다.

Key입력에 따른 동작과 화면을 그려 주는 부분을 변경 할 수 있도록, Strategy pattern을 적용하였다.

UI 클래스는 단지 키보드 입력을 받아 Player 객체로 전달하고,

Player 객체가 그린 화면을 뿌려주는 역할만 하도록 하였다.



ChoboTetris_20180504.zip

Source : https://github.com/chobocho/JavaTetris

'Coding > Java 삽질기' 카테고리의 다른 글

Java Tetris (자바 테트리스 만들기 2)  (0) 2018.05.03
Java Tetris (자바 테트리스 만들기 1)  (0) 2018.04.28
UML of Alarm clock  (0) 2018.04.06
Android 화면 녹화 방법  (0) 2018.01.04
Posted by chobocho


Source : https://github.com/chobocho/JavaTetris

구조설명 : http://chobocho.tistory.com/2461355

ChoboTetris_20180429.zip


Java GUI Refer : http://zetcode.com/tutorials/javagamestutorial/tetris/

'Coding > Java 삽질기' 카테고리의 다른 글

Java Tetris (자바 테트리스 만들기 2)  (0) 2018.05.03
Java Tetris (자바 테트리스 만들기 1)  (0) 2018.04.28
UML of Alarm clock  (0) 2018.04.06
Android 화면 녹화 방법  (0) 2018.01.04
Posted by chobocho
TAG Java, Tetris

2018년 Toy project로 기능 추가가 쉬운(?) 테트리스를 만들어 보기로 했다.


1. 결과물

먼저 기본 기능만 동작하는 테트리스(?)의 동작 화면은 아래와 같다.


[ 다운로드 링크 ]

https://play.google.com/store/apps/details?id=com.chobocho.tetris





2. 설계

먼저 구현을 위하여 아래와 같이 UML을 그렸다.




3. 상세설명

3.1 Block

Tetris는 아래 7가지 Block를 사용한다

그래서 Tetrominos 라는 추상 클래스를 만들고, 모든 블럭은 이 클래스를 상속받아서 만든다

이렇게 하면 추후 다른 모양의 블럭을 추가 하기가 쉽다.

[ Tetroinos.java ]

package com.chobocho.tetris;
import java.util.*;

public abstract class Tetrominos {
protected int x;
protected int y;
protected int r;
protected int w;
protected int h;
protected int type;
protected int numOfBlockType;
protected int[][][] block;


public Tetrominos() {
}

public void rotate() {
r = (r+1) % numOfBlockType;
}

public void preRotate() {
r = (r-1+numOfBlockType) % numOfBlockType;
}

public void moveLeft() {
x--;
}

public void moveRight() {
x++;
}


public void moveDown() {
y++;
}

public void moveUp() {
y--;
}

public int[][] getBlock() {
return null;
}

public int getWidth() {
return w;
}

public int getHeight() {
return h;
}

public int getX() {
return x;
}

public int getY() {
return y;
}

public int getType() { return type; }
}

각각의 블록은 위 클래스를 상속받아서 구현 한다.

x, y : 블럭이 보드에 표시되는 시작 좌표

w, h : 블럭을 나타내는 배열의 크기 (블럭마다 다르다. I의 경우 4x4 지만, ㅁ의 경우 2x2 면 된다)

r : 회전한 값을 나타내기 위해 필요하다

type : 블럭의 색상을 나타내기 위해 사용한다

numOfBlock : 블럭 회전시 나타날 수 있는 모양의 수 이다.

실제 이를 상속받은 I형 블럭의 구현 클래스의 소스를 확인하면 아래와 같다

[ ITetrominos.java ]

package com.chobocho.tetris;
import java.util.*;

public class ITetrominos extends Tetrominos {

public ITetrominos() {
this.block = new int[][][]{
{
{1, 0, 0, 0},
{1, 0, 0, 0},
{1, 0, 0, 0},
{1, 0, 0, 0},
},
{
{1, 1, 1, 1},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
}
};
numOfBlockType = 2;
x = 3;
y = 0;
r = 0;
w = 4;
h = 4;
type = 1;
}

public int[][] getBlock() {
return block[r];
}
}


3.2 Tetrominos Factory

Tetris 에서 사용하는 블럭을 만들어 주는 Factory class 이다

게임에 사용되는 모든 블럭은 이 클래스를 통하여 생성한다


[ TetrominosFactory.java ]

Factory pattern을 사용하여, Tetrominos 블럭을 생성한다.

package com.chobocho.tetris;
import java.util.*;

public class TetrominosFactory {

public static Tetrominos create() {
switch( (int) (Math.random() * 7)) {
case 0:
return new OTetrominos();
case 1:
return new ITetrominos();
case 2:
return new LTetrominos();
case 3:
return new JTetrominos();
case 4:
return new TTetrominos();
case 5:
return new STetrominos();
case 6:
return new ZTetrominos();
default:
return new ITetrominos();
}
}

private TetrominosFactory() {}
}

3.3 State

본 테트리스 게임은 4가지의 State를 가진다

1) IDLE

2) PLAY

3) PAUSE

4) GAMEOVER


[ Tetris game state chart ]


그래서 State pattern을 적용하였다.

각각의 State는 TetrisGameState를 상속받는 구조로 되어 있고, 실제 게임 동작은 TetrisPlayState에서 이루어 진다.

[ TetrisGameState.java ]

package com.chobocho.tetris;

public abstract class TetrisGameState {
protected ITetris tetris;

public TetrisGameState() {}

public void init() {}

public void rotate() {}

public void moveLeft() {}

public void moveRight() {}

public void moveDown() {}

public void fixCurrentBlock() {}

public void moveBottom() {}

public void updateBlock() {}

public boolean gameOver() {
return false;
}

public void updateBoard() {}

public Tetrominos getCurrentTetrominos() {
return null;
}

public Tetrominos getNextTetrominos() { return null; }

public void update() {
TetrisLog.d("TetrisGameState.update()");
}
}


TetrisPlayState는 TetrisGameState를 상속받으며, 현재 블럭과 다음 블럭의 정보를 가지고 있다.

사용자가 화면을 터치하여 블럭을 움직이거나 회전을 하게 되면 블럭의 정보를 업데이트 하고

보드에 블럭정보를 업데이트 하는 동작을 한다.

블럭을 이동하고 나면 Observer pattern을 이용하여 UI 화면을 갱신한다


[ TetrisPlayState.java ]

package com.chobocho.tetris;

public class TetrisPlayState extends TetrisGameState {
private Tetrominos currentTetrominos;
private Tetrominos nextTetrominos;
private TetrisBoard tetrisBoard;
private int additionalPoint = 1;

public TetrisPlayState(Tetris tetris, TetrisBoard board) {
this.tetris = tetris;
this.tetrisBoard = board;
currentTetrominos = TetrominosFactory.create();
nextTetrominos = TetrominosFactory.create();
}

public void init() {
this.tetrisBoard.init();
currentTetrominos = TetrominosFactory.create();
nextTetrominos = TetrominosFactory.create();
additionalPoint = 1;
}

public void update() {
TetrisLog.d("TetrisPlayState.update()");
tetris.getObserver().updatePlay();
}

public void moveLeft() {
TetrisLog.d("TetrisPlayState.moveLeft()");
currentTetrominos.moveLeft();
if (tetrisBoard.isAcceptable(currentTetrominos) == false) {
currentTetrominos.moveRight();
TetrisLog.d("Not Accept");
} else {
TetrisLog.d("Accept");
}
}

public void moveRight() {
TetrisLog.d("TetrisPlayState.moveRight()");
currentTetrominos.moveRight();
if (tetrisBoard.isAcceptable(currentTetrominos) == false) {
currentTetrominos.moveLeft();
TetrisLog.d("Not Accept");
} else {
TetrisLog.d("Accept");
}
}

public void rotate() {
TetrisLog.d("TetrisPlayState.rotate()");
currentTetrominos.rotate();
if (tetrisBoard.isAcceptable(currentTetrominos) == false) {
currentTetrominos.preRotate();
TetrisLog.d("Not Accept");
} else {
TetrisLog.d("Accept");
}
}

public void moveDown() {
TetrisLog.d("TetrisPlayState.moveDown()");
currentTetrominos.moveDown();
if (tetrisBoard.isAcceptable(currentTetrominos) == false) {
currentTetrominos.moveUp();
TetrisLog.d("Can not move down");
fixCurrentBlock();
updateBoard();
updateBlock() ;
} else {
TetrisLog.d("Accept");
}
}

public void moveBottom() {
TetrisLog.d("TetrisPlayState.moveBottom()");
while(tetrisBoard.isAcceptable(currentTetrominos)) {
currentTetrominos.moveDown();
}
if (tetrisBoard.isAcceptable(currentTetrominos) == false) {
currentTetrominos.moveUp();
}
}

public void fixCurrentBlock() {
tetrisBoard.addTetrominos(currentTetrominos);
}

public void updateBlock() {
currentTetrominos = nextTetrominos;
nextTetrominos = TetrominosFactory.create();
}

public boolean gameOver() {
TetrisLog.d("Game over!");
return (tetrisBoard.isAcceptable(currentTetrominos) == false);
}

public void updateBoard() {
int removedLine = tetrisBoard.arrange();
int point = calculatorScore(removedLine);
tetris.addSore(point);
}

private int calculatorScore(int removedLineCount) {
if (removedLineCount == 0) {
additionalPoint = 1;
return 0;
}
if (removedLineCount >= 4) {
removedLineCount = 4;
}
if (additionalPoint > 10000) {
additionalPoint = 10000;
}
additionalPoint <<= removedLineCount;
TetrisLog.d("calculatorScore : " + additionalPoint + " : " + removedLineCount);
return (removedLineCount * 10 * additionalPoint);
}

public Tetrominos getCurrentTetrominos() {
return currentTetrominos;
}

public Tetrominos getNextTetrominos() {
return nextTetrominos;
}
}

3.4 Board

3.5 Observer pattern

3.6 Tetris


3.7 Source 코드로 부터 생성한 UML







4. Source code

https://github.com/chobocho/ClassBlockGame


5. Reference

* Head first design pattern


* 질문은 언제나 환영 합니다.

Posted by chobocho

Tetris

Coding/Java 삽질기 2016.03.17 02:44



심심해서 다시 만들어 보는 테트리스


'Coding > Java 삽질기' 카테고리의 다른 글

Android studio 디바이스 연결  (0) 2016.08.20
Tetris  (0) 2016.03.17
1. 온라인 테트리스 만들기 ( 이클립스 설치 )  (0) 2014.01.03
초간단 보이스 레코더  (0) 2013.03.08
Posted by chobocho
TAG Java, Tetris

1. Groovy download

    http://groovy.codehaus.org/Download



2. 환경설정

    .bash_profile 을 아래와 같이 설정한다.



3. groovysh 실행 결과





4. GroovyConsole 실행결과



'Coding > JVM 삽질기' 카테고리의 다른 글

Mac에서 Kotlin 설치하기  (0) 2017.10.14
[groovy] 50!  (0) 2016.09.24
Groovy 설치( Mac )  (0) 2014.11.11
Pocket PC를 위한 JVM  (0) 2005.09.28
Posted by chobocho
TAG Groovy, Java

자바는 Static block -> Instance block -> 생성자 순으로 초기화가 된다.

먼저 아래와 같은 코드를 실행해 보자.

public class TestClass {
    public static void main (String[] args) {
       System.out.println("---------------------------");
       
       Parent father = new Parent("father");
       
       System.out.println("---------------------------");
    }
}

class Parent {
    public String myName = "Parent";

    static {
        System.out.println ("This is first message of Parent class!");
    }

    public Parent() {
       System.out.println (myName + ": This is third message! I'm a default constructor of Parent class!");
    }

    public Parent(String name) {
        myName = name;
        System.out.println (myName + ": This is third message! I'm a constructor of Parent class!");
    }
    
    {
      System.out.println (myName + ": This is second message!");
    }
}


그럼 하기와 같은 결과를 얻을 수 있다.

---------------------------
This is first message of Parent class!
Parent: This is second message!
father: This is third message! I'm a constructor of Parent class!
---------------------------



 public class TestClass {

    public static void main (String[] args) {
       System.out.println("---------------------------");
       
       Parent father = new Parent("father");
       Parent mother = new Parent("mother");
       
       System.out.println("---------------------------");
    }
}

class Parent {
    public String myName = "Parent";

    static {
        System.out.println ("This is first message of Parent class!");
    }

    public Parent() {
       System.out.println (myName + ": This is third message! I'm a default constructor of Parent class!");
    }

    public Parent(String name) {
        myName = name;
        System.out.println (myName + ": This is third message! I'm a constructor of Parent class!");
    }
    
    {
      System.out.println (myName + ": This is second message!");
    }
}


 위 와 같이 한 줄을 추가하여 실행하면 아래와 같은 결과를 얻을 수 있다.

---------------------------
This is first message of Parent class!
Parent: This is second message!
father: This is third message! I'm a constructor of Parent class!
Parent: This is second message!
mother: This is third message! I'm a constructor of Parent class!
---------------------------


여기서 보면 static { }  으로 둘러 싸인 구문은 객체 생성시 최초 1회만 수행이 되고, 그 뒤에는 수행이 되지 않는 걸 알 수 있다. 그러나 { } 로 둘러싸인 instance block은 객체가 생성 될 때마다 실행 되며 생성자 보다 먼저 생성되는 걸 알 수 있다.

class Child extends Parent {
    public String myName = "Child";

    static {
        System.out.println ("This is first message of Child class!");
    }

    public Child(String name) {
        myName = name;
        System.out.println (myName + ": This is third message! I'm a constructor of Child class!");
    }
    
    {
      System.out.println (this.myName + ": This is second message of Child class!");
    }
  
}



위 와 같이 Parent class를 상속받는 Child 클래스를 만들고, 아래와 같이 객체를 생성해 보자

public class TestClass {
    public static void main (String[] args) {
       System.out.println("---------------------------");
       
         Child son     = new Child("son");
       
       System.out.println("---------------------------");
    }



그럼 하기와 같은 결과가 나온다.

---------------------------
This is first message of Parent class!
This is first message of Child class!
Parent: This is second message!
Parent: This is third message! I'm a default constructor of Parent class!
Child: This is second message of Child class!
son: This is third message! I'm a constructor of Child class!
---------------------------


위 결과를 보면 알 수 있듯이,
부모 클래스의 static block -> 자식 클래스의 static block -> 부모 클래스의 instance block
-> 부모 클래스의 생성자 -> 자식 클래스의 instance block -> 자식클래스의 생성자 순으로 실행 되는 것을 알 수 있다.

마지막으로 아래와 같이 실행을 하면,

public class TestClass {
    public static void main (String[] args) {
       System.out.println("---------------------------");
       
       Parent father = new Parent("father");
      Parent mother = new Parent("mother");
       Child son     = new Child("son");
       
       System.out.println("---------------------------");
    }
}



하기와 같이 실행 된다. 천천히 살펴보면 앞에서 설명한 내용에서 벗어나지 않는다.

---------------------------
This is first message of Parent class!
Parent: This is second message!
father: This is third message! I'm a constructor of Parent class!
Parent: This is second message!
mother: This is third message! I'm a constructor of Parent class!
This is first message of Child class!
Parent: This is second message!
Parent: This is third message! I'm a default constructor of Parent class!
Child: This is second message of Child class!
son: This is third message! I'm a constructor of Child class!
---------------------------





 

'Coding > Java 삽질기' 카테고리의 다른 글

Java 실행 시간 측정 하기  (0) 2011.09.01
Java에서 객체의 초기화 순서  (0) 2011.08.24
[Android] Image match game  (0) 2011.06.04
Android Tetris  (0) 2011.02.02
Posted by chobocho
TAG Java, 객체

'Coding > Java 삽질기' 카테고리의 다른 글

Android Tetris  (0) 2011.02.02
Bubble sort  (0) 2010.07.11
Selection sort  (0) 2010.07.11
Text2Memo  (0) 2010.05.09
Posted by chobocho

http://chobocho.com/game/sort/selection_sort/select_sort.html

'Coding > Java 삽질기' 카테고리의 다른 글

Bubble sort  (0) 2010.07.11
Selection sort  (0) 2010.07.11
Text2Memo  (0) 2010.05.09
Tetris  (2) 2010.03.10
Posted by chobocho

Tetris

Coding/Java 삽질기 2010.03.10 00:13


자바로 만든 테트리스

* 소스가 필요하신 분은 댓글을 남겨 주세요 ^^

'Coding > Java 삽질기' 카테고리의 다른 글

Text2Memo  (0) 2010.05.09
Tetris  (2) 2010.03.10
Fruit Game  (4) 2010.03.06
[Java] 숫자 세기 게임  (0) 2009.10.22
Posted by chobocho



자바로 만든 짝퉁 비주얼드 게임.

규칙 : 비쥬얼드와 동일.

시작방법 : 우측 상단 점수판을 클릭하면 된다.

게임하기 : http://chobocho.com/game/fruit/fruit.html

소스코드 : 곧 업데이트 할께요... 필요하시면 댓글을 남겨주세요.

'Coding > Java 삽질기' 카테고리의 다른 글

Tetris  (2) 2010.03.10
Fruit Game  (4) 2010.03.06
[Java] 숫자 세기 게임  (0) 2009.10.22
[Android] Speed Game  (0) 2009.10.13
Posted by chobocho