자바로 만든 테트리스 질문
간단하게 만들어서
.블럭 생성
.블럭 이동
.블럭 회전
.꽉찬 라인 제거
.라인 제거 마다 점수증가
이정도...?
간단한 설명을 하면
블럭을 [4][4] array로, 게임 패널을 [30][20] array로 나타 냈습니다.
그리고 블럭 부분을 1로 하고 나머지는 0으로 초기화 해서 블럭을 표현했고,
이 것을 토대로 [30][20]개의 Label을 만든 후 1인 부분(블럭)을 BackgroundColor로 블럭 색을 만들었습니다.
움직이는 것은 백그라운드 제거, 배열 값 변경, 변경 값으로 백그라운드 설정 으로 나타냈습니다.
Thread로 3초마다 1칸씩 내리고, KeyListener로 좌, 우, 회전을 할 수 있게 했습니다.
게임패널 pre_array를 하나 더만들어서 블럭이 맨 아래로 가거나 1을 만나면 정지 후 pre_array에 array를 대입.
다음 블럭을 만들 때 array에 pre_array 대입해서 내려간 이전 블럭을 유지.
겹치는 블럭 확인은 내리다가 array[y][x] 값이 1이면 정지.
꽉찬 라인 없애는 건 array에서 x축 값이 모두 1이면 그 라인부터 처음 라인까지 덮었습니다.
질문
자바로 처음 만들어 보는거라 많이 조잡 합니다만..
근데 속도가 너무 느립니다. 너무 심하게 느려요.. 블럭이 부셔져서 보입니다.
속도가 느린 이유를 알 수 있을까요?
그리고 다른 방법으로 다시 만들어 보는 중인데
KeyListener를 mainclass에 만 설정 가능한가요? MouseListener하고 KeyListener를 같이 넣어봤는데
MouseListener만 반응하고 KeyListener는 반응하지 않아서 mainclass에 다시 달고 있네요.. requestFocus는 했습니다.
MainFrame
package Tetris; import java.awt.Color; import java.awt.GridLayout; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.Iterator; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class MainFrame extends JFrame { Block block = new Block(); Score ScorePanel = new Score(); int gameX = 20;//Game X-length int gameY = 30;//Game Y-length JPanel GamePanel = new JPanel(); JLabel[][] GL = new JLabel[gameY][gameX]; int[][] GameArray = new int[gameY][gameX]; int[][] StandardArray = new int[gameY][gameX]; Down down = new Down(); ArrayList<Integer> line = new ArrayList<Integer>(); ArrayList<Integer> LineCheck()//full line check { ArrayList<Integer> Item = new ArrayList<Integer>(); int count; for(int i = 0; i < gameY; i++) { count = 0; for(int j = 0; j < gameX; j++) if(GameArray[i][j] == 1) count++; if(count == gameX) Item.add(i); } return Item; } void LineRemove()//full line remove { line = LineCheck(); Iterator<Integer> iter = line.iterator(); int index = 0; int size = line.size(); ScorePanel.Scoring(size); while(iter.hasNext()) { index = iter.next(); for(int i = index; i > 1; i--) for(int j = 0; j < gameX; j++) GameArray[i][j] = GameArray[i-1][j]; } index = 0; } boolean Overlap()//overlap { try { for(int i = 0; i < block.array_size; i++) for(int j = 0; j < block.array_size; j++) if(block.array[i][j] == 1 && StandardArray[i+block.y][j+block.x] == 1)//block overlap throw new Exception(); return false; } catch(Exception e) { return true; } } void Next()//next block { for(int i = 0; i < gameY; i++)//Game repaint for(int j = 0; j < gameX; j++) StandardArray[i][j] = GameArray[i][j]; block = ScorePanel.Pre_block;//next block ScorePanel.Pre_block = new Block(); } void View()//view { for(int i = 0; i < gameY; i++) for(int j = 0; j < gameX; j++)//Game repaint { GameArray[i][j] = StandardArray[i][j]; if(GameArray[i][j] == 0) GL[i][j].setBackground(null); } for(int i = 0; i < block.array_size; i++) for(int j = 0; j < block.array_size; j++)//Block repaint if(block.array[i][j] == 1) { GameArray[i+block.y][j+block.x] = 1; GL[i+block.y][j+block.x].setBackground(block.color); GL[i+block.y][j+block.x].setOpaque(true); } } class Down extends Thread//down { @Override public void run() { // TODO Auto-generated method stub super.run(); try { while(true) { block.y++; if(block.y > 26 || Overlap())//bottom throw new Exception(); View(); sleep(3000); } } catch (InterruptedException e) { // TODO Auto-generated catch block System.out.println("End"); e.printStackTrace(); } catch (Exception e)//bottom { LineRemove(); Next(); run(); return; } } } class Keyboard implements KeyListener//keyboard { @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub try { switch(e.getKeyCode()) { case 37://← if(Overlap()) break; block.x--; View(); break; case 38://↑ block.Rotate(); View(); break; case 39://→ if(Overlap()) break; block.x++; View(); break; case 40://↓ if(Overlap()) break; block.y++; View(); } } catch(ArrayIndexOutOfBoundsException a) { switch(e.getKeyCode()) { case 37://← block.x++; View(); break; case 39://→ block.x--; View(); break; case 40://↓ block.y--; View(); } } } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } } MainFrame() //main { // TODO Auto-generated constructor stub setTitle("TETRIS"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(null); ScorePanel.setBounds(240, 20, 90, 300); GamePanel.setBounds(20, 20, 200, 300); GamePanel.setLayout(new GridLayout(30, 20, 1, 1)); GamePanel.setBackground(Color.lightGray); GamePanel.setOpaque(true); for(int i = 0; i < gameY; i++) for(int j = 0; j < gameX; j++)//Game initialize { GL[i][j] = new JLabel(); GamePanel.add(GL[i][j]); } //////test(Bottom OBlock)////// // for(int i = gameY-2; i < gameY; i++) // for(int j = 2; j < gameX; j++) // { // StandardArray[i][j] = 1; // GL[i][j].setBackground(block.color); // GL[i][j].setOpaque(true); // } // View(); /////////////////////////////// down.start(); add(GamePanel); add(ScorePanel); setSize(350, 400); setVisible(true); addKeyListener(new Keyboard()); requestFocus(); } public static void main(String[] args) { // TODO Auto-generated method stub new MainFrame(); } }
Block
package Tetris; import java.awt.Color; import java.awt.Graphics; import java.util.ArrayList; import java.util.Random; import java.util.Iterator; import javax.swing.JLabel; public class Block extends JLabel { int[][][] block_array = { {//OBlock[0] {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 1, 1, 0}, {0, 1, 1, 0} }, {//LBlock[1] {0, 0, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 1, 0} }, {//JBlock[2] {0, 0, 0, 0}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 1, 1} }, {//TBlock[3] {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 1, 1, 1}, {0, 0, 1, 0} }, {//IBlock[4] {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0} }, {//ZBlock[5] {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 1} }, {//SBlock[6] {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 1, 1}, {0, 1, 1, 0} } }; int array_size = 4;//array size int array_index = 0;// select index int[][] array = new int[array_size][array_size];//selected array Random ran = new Random(); int x = 9;//block X-coordinate int y = 0;//block Y-coordinate Color color = null;//block color boolean flag = true;//rotate flag void Rotate()//rotate { int[][] temp = new int[array_size][array_size]; switch(array_index) { case 0://OBlock No rotate break; case 1://L, J, TBlock 90ºrotate 4times case 2: case 3: for(int i = 0; i < array_size; i++) for(int j = 0; j < array_size; j++) { temp[j][i] = array[i][j]; array[i][j] = 0; } for(int i = 0; i < array_size; i++) for(int j = 0; j < array_size; j++) if(temp[i][j] == 1 && i < 2) array[2+Math.abs(i-2)][j] = temp[i][j]; else if(temp[i][j] == 1) array[2-Math.abs(i-2)][j] = temp[i][j]; break; case 4://I, Z, SBlock 90ºrotate 2times case 5: case 6: if(flag)//rotate check { for(int i = 0; i < array_size; i++) for(int j = 0; j < array_size; j++) { temp[j][i] = array[i][j]; array[i][j] = 0; } for(int i = 0; i < array_size; i++) for(int j = 0; j < array_size; j++) if(temp[i][j] == 1 && i < 2) array[2+Math.abs(i-2)][j] = temp[i][j]; else if(temp[i][j] == 1) array[2-Math.abs(i-2)][j] = temp[i][j]; flag = false; } else { for(int i = 0; i < array_size; i++) for(int j = 0; j < array_size; j++) array[i][j] = block_array[array_index][i][j]; flag = true; } } } public Block() { // TODO Auto-generated constructor stub array_index = ran.nextInt(7); // array_index = *;//test(All *Block) for(int i = 0; i < array_size; i++) for(int j = 0; j < array_size; j++)//choice block array[i][j] = block_array[array_index][i][j]; switch(array_index) { case 0://OBlock[0] color = Color.blue; break; case 1://LBlock[1] color = Color.magenta; break; case 2://JBlock[2] color = Color.yellow; break; case 3://TBlock[3] color = Color.green; break; case 4://IBlock[4] color = Color.red; break; case 5://ZBlock[5] color = Color.orange; break; case 6://SBlock[6] color = Color.cyan; break; } } }
Score
package Tetris; import java.awt.Color; import java.awt.GridLayout; import javax.swing.BorderFactory; import javax.swing.JLabel; import javax.swing.JPanel; public class Score extends JPanel { Block Pre_block = new Block(); int number = 0; JPanel PrePanel = new JPanel();//block view JLabel PreLabel = new JLabel("Pre Block");//block name JLabel ScoreTitle = new JLabel("Score"); JLabel ScoreNumber = new JLabel(Integer.toString(number));//score view JLabel[][] PL = new JLabel[Pre_block.array_size][Pre_block.array_size];//block void Scoring(int size) { for(int i = 0; i < size; i++)//10 + bonus(line * 5); number += 10; number += size * 5; ScoreNumber.setText(Integer.toString(number)); } public Score() { // TODO Auto-generated constructor stub setBackground(Color.lightGray); setOpaque(true); setLayout(null); setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); PreLabel.setBounds(15, 20, 80, 10); ScoreTitle.setBounds(30, 150, 60, 10); ScoreNumber.setBounds(40, 180, 60, 10); PrePanel.setBounds(35, 40, 40, 40); PrePanel.setBackground(Color.lightGray); PrePanel.setOpaque(true); PrePanel.setLayout(new GridLayout(4, 4, 1, 1)); for(int i = 0; i < Pre_block.array_size; i++) for(int j = 0; j < Pre_block.array_size; j++)//block initialize { PL[i][j] = new JLabel(); if(Pre_block.array[i][j] == 1) { PL[i][j].setBackground(Pre_block.color); PL[i][j].setOpaque(true); } PrePanel.add(PL[i][j]); } add(PreLabel); add(PrePanel); add(ScoreTitle); add(ScoreNumber); } }
첨부 | 파일 크기 |
---|---|
Tetris.zip | 16.13 KB |
스레드와 화면출력은 이런 방식으로 사용 할 수 있는거 같습니다.
synchronized(this) 와 for() 문 2가지를 적용해야 오류가 나지 않았습니다.
스레드 오류를 수정하였습니다.
http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040201&docId=221054316&qb=ZXh0ZW5kcyBKRnJhbWUsIGV4dGVuZHMgVGhyZWFk&enc=utf8§ion=kin&rank=1&search_sort=0&spq=0
AWT-EventQueue-0
http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040201&docId=241836507&qb=SmF2YSByYW5k&enc=utf8§ion=kin&rank=1&search_sort=0&spq=0&pid=So2DcwoRR18ssvgjdQ0sssssss8-086974&sid=3ZSiXSWGS0A%2BSu/da7hOuA%3D%3D
http://blog.naver.com/robinnw/80211544638
http://blog.naver.com/kdw9242/70139152463
https://opentutorials.org/module/1335/8711
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
댓글 달기