Ajuda para terminar o projeto tetris

Pessoal pode me dar uma ajuda, estou desenvolvendo um game tetris.
Oque está faltando?

TelaTetris

package Tetris;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Canvas;
import java.awt.Color;

public class TelaTetris extends JFrame {

	private JPanel contentPane;
	private static TelaTetris singleton;
	private static Canvas canvas;

	/**
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					TelaTetris frame = new TelaTetris();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	**/
	
	/**
	 * Create the frame.
	 */
	public TelaTetris() {
				
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 266, 462);
		contentPane = new JPanel();
		contentPane.setBackground(Color.GRAY);
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		getCanvas().setBackground(Color.WHITE);
		getCanvas().setForeground(Color.WHITE);
		getCanvas().setBounds(0, 0, 258, 366);
		contentPane.add(getCanvas());		
	}
	
	public static TelaTetris getSingleton(){
		
		if(singleton == null) {
			
			singleton = new TelaTetris();
		}		
		return singleton;
	}
	
	public static Canvas getCanvas() {
		
		if(canvas == null) {
			
			canvas = new Canvas();
		}
		return canvas;
	}
}

Principal

package Tetris;

public class Principal {

	public static void main(String[] args){
		TelaTetris.getSingleton().setVisible(true);
		try {
			Thread.sleep(200);			
			MoverPeca.getSingleton().mover();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
			
	}
	
}

MoverPeca

package Tetris;

public class MoverPeca {

	public static MoverPeca singleton;
	
	public void mover() {
			TetrisPeca peca = TetrisPeca.getSingleton();	
			while(true) {
				
				try {
					Thread.sleep(1500);
					if(peca.getY() <= 266) {
						
						peca.setY(peca.getY() + 38);
						peca.limpaTela();
						peca.desenharPeca();
						peca.desenharGrade();					
					}
					else{
											
						peca.sortear();					
						peca.setY(0);
						this.mover();
					}
					} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}					
			}				
	}	
	
	public static MoverPeca getSingleton() {
		
		if(singleton == null) {
			
			singleton = new MoverPeca();
		}
		return singleton;
	}
}

TelaTetris

package Tetris;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Canvas;
import java.awt.Color;

public class TelaTetris extends JFrame {

	private JPanel contentPane;
	private static TelaTetris singleton;
	private static Canvas canvas;

	/**
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					TelaTetris frame = new TelaTetris();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	**/
	
	/**
	 * Create the frame.
	 */
	public TelaTetris() {
				
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 266, 462);
		contentPane = new JPanel();
		contentPane.setBackground(Color.GRAY);
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		getCanvas().setBackground(Color.WHITE);
		getCanvas().setForeground(Color.WHITE);
		getCanvas().setBounds(0, 0, 258, 366);
		contentPane.add(getCanvas());		
	}
	
	public static TelaTetris getSingleton(){
		
		if(singleton == null) {
			
			singleton = new TelaTetris();
		}		
		return singleton;
	}
	
	public static Canvas getCanvas() {
		
		if(canvas == null) {
			
			canvas = new Canvas();
		}
		return canvas;
	}
}

TetrisPeca

package Tetris;

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;

public class TetrisPeca{

	private static TetrisPeca singleton;	
	private Color[] cor = {Color.BLACK,Color.BLUE,Color.CYAN,Color.DARK_GRAY,
	Color.GRAY,Color.GREEN,Color.LIGHT_GRAY,Color.MAGENTA,Color.ORANGE,Color.PINK,
	Color.RED,Color.YELLOW};	
	private int x = 0;
	private int y = 0;
	private int sortearPeca = 0;	
	private Graphics g = TelaTetris.getCanvas().getGraphics();
	
	public void limpaTela() {
				
		g.setColor(Color.WHITE);
		g.clearRect(0, 0, 500, 500);
	}
	
	public Color getCor() { 
		
		Random r = new Random();
		return cor[r.nextInt(11)];
	}
	
	public void desenharGrade() {		
		
		g.setColor(Color.BLACK);
		int i;			
		for(i = 0; i < 500;i = i + 38) {		
						
			g.drawLine(0,0 + i,256, 0 + i);			
			g.drawLine(0 + i, 0,0 + i,362);			
		}		
	}
	
	public void sortear() {
		
		Random r = new Random();
		sortearPeca = (r.nextInt(4) + 1);		
	}
			
	public void desenharPeca() {
		
			switch(1) {
		
			case 1:				
				int j = 0;
				g.setColor(getCor());
				g.fillRect(76 + x, 0 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(114 + x, 0 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(152 + x, 0 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(76 + x, j = j + (38 + y), 38, 38);							
			break;
			case 2:
				g.setColor(getCor());
				g.fillRect(38 + x, 0 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(76 + x, 0 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(114 + x, 0 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(152 + x, 0 + y, 38, 38);
			break;
			case 3:
				g.setColor(getCor());
				g.fillRect(114 + x, 0 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(152 + x, 0 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(114 + x, 38 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(76 + x, 38 + y, 38, 38);				
			break;	
			case 4:
				g.setColor(getCor());
				g.fillRect(76 + x, 0 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(114 + x, 0 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(76 + x, 38 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(114 + x, 38 + y, 38, 38);				
			break;	
			case 5:
				g.setColor(getCor());
				g.fillRect(114 + x, 0 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(76 + x, 38 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(114 + x, 38 + y, 38, 38);
				g.setColor(getCor());
				g.fillRect(152 + x, 38 + y, 38, 38);				
			break;	
		}
	}
	
	public static TetrisPeca getSingleton() {
		
		if(singleton == null) {
			
			singleton = new TetrisPeca();		
		}		
		return singleton;
	}
	
	public int getX() {
		
		return this.x;	
	}
	
	public int getY() {
		
		return this.y;
	}
	
	public void setX(int x) {
		
		this.x = x;
	}
	
	public void setY(int y) {
		
		this.y = y;
	}
	
	public int getSortearPeca() {
		
		return this.getSortearPeca();
	}
		
	public void setSortearPeca(int sortearPeca) {
		
		this.sortearPeca = sortearPeca;
	}	
}

É meio ruim pegar esse código todo, executar e te dizer o que está faltando. Mais fácil você dizer o que já está pronto e o que você acha que está faltando e por que (com screenshots, de preferência).

Faça um checklist das características de gameplay de tetris e vá marcando o que já está implementado e o que precisa mudar. Por exemplo:

  • representar um tabuleiro de jogo (com uma matriz, por exemplo);
  • desenhar cada peça na tela;
  • mover cada peça para baixo a uma velocidade constante;
  • mover a peça lateralmente com o input do usuário;
  • girar a peça com input do usuário;
  • detectar colisão com os lados;
  • detectar colisão com a parte de baixo;
  • verificar se uma linha foi preenchida;
  • eliminar uma linha preenchida;
  • randomizar a próxima peça;
  • critério de game over (tela sem espaço para a peça atual);
  • contador de pontuação;
  • pausar o jogo;
  • reiniciar o jogo;

Sobre seu código: se entendi (olhando por cima), ele usa threads para ser dinâmico. Isso geralmente não é uma boa ideia. Tente criar um gameloop na thread principal. Veja este artigo do Ponto V sobre isto.

Abraço.

Na classe MoverPeca tem as linhas this.mover() e while(true), isso causa um processo recursivo infinito que pode causar problemas de memória. Como o trecho será repetido de qualquer forma por causa do while(true), acredito que o this.mover() possa ser removido.