PC SOFT

FOROS PROFESIONALES
WINDEVWEBDEV y WINDEV Mobile

Inicio → WINDEV 25 → Jogo Tetris em WLanguage
Jogo Tetris em WLanguage
Iniciado por Boller, 17,mar. 2025 13:38 - No hay respuesta
Miembro registrado
3.855 mensajes
Publicado el 17,marzo 2025 - 13:38
Bom dia, pessoal!

Tudo ótimo com vcs?

Vamos criar um exemplo incrível do jogo Tetris usando WLanguage com programação orientada a objetos e criação dinâmica de objetos em runtime.

Vou desenvolver um código divertido e eficiente!

Qualquer dúvida me chamem para discutirmos esse código:

//##############################
```
// Classe para representar uma peça do Tetris
Classe Peca
PROTECTED
forma is array of int // Matriz que representa a forma da peça
cor is int // Código de cor da peça
posX is int // Posição X no tabuleiro
posY is int // Posição Y no tabuleiro
rotacao is int // Estado de rotação atual (0-3)
END

PROCEDURE Construtor(nForma is int)
// Inicializa a peça com base no tipo (0-6)
posX = 4 // Posição inicial no centro
posY = 0 // Topo do tabuleiro
rotacao = 0 // Sem rotação inicial

// Define a forma e cor da peça
SWITCH nForma
CASE 0: // Peça I
forma = [
[0,0,0,0],
[1,1,1,1],
[0,0,0,0],
[0,0,0,0]
]
cor = RGB(0,240,240) // Ciano
CASE 1: // Peça J
forma = [
[1,0,0],
[1,1,1],
[0,0,0]
]
cor = RGB(0,0,240) // Azul
CASE 2: // Peça L
forma = [
[0,0,1],
[1,1,1],
[0,0,0]
]
cor = RGB(240,160,0) // Laranja
CASE 3: // Peça O
forma = [
[1,1],
[1,1]
]
cor = RGB(240,240,0) // Amarelo
CASE 4: // Peça S
forma = [
[0,1,1],
[1,1,0],
[0,0,0]
]
cor = RGB(0,240,0) // Verde
CASE 5: // Peça T
forma = [
[0,1,0],
[1,1,1],
[0,0,0]
]
cor = RGB(160,0,240) // Roxo
CASE 6: // Peça Z
forma = [
[1,1,0],
[0,1,1],
[0,0,0]
]
cor = RGB(240,0,0) // Vermelho
END
END

// Método para rotacionar a peça
PROCEDURE Rotacionar()
IF PoderRotacionar() THEN
tamForma is int = ArrayCount(forma)
novaForma is array of int

// Inicializa nova forma com mesmas dimensões
ArrayDim(novaForma, tamForma, tamForma)

// Aplica a rotação
FOR i = 0 TO tamForma - 1
FOR j = 0 TO tamForma - 1
novaForma[j][tamForma - 1 - i] = forma[i][j]
END
END

forma = novaForma
rotacao = (rotacao + 1) % 4 // Incrementa rotação (0-3)
END
END

// Método para verificar se a peça pode rotacionar
PROCEDURE PoderRotacionar() : boolean
// Verificação simplificada - em uma implementação completa,
// verificaria colisões com o tabuleiro
Result True
END

// Método para mover a peça para baixo
PROCEDURE MoverBaixo() : boolean
posY++
IF !PosicaoValida() THEN
posY--
Result False // Não pode mover mais
END
Result True // Movimento realizado
END

// Método para mover a peça para esquerda
PROCEDURE MoverEsquerda()
posX--
IF !PosicaoValida() THEN
posX++
END
END

// Método para mover a peça para direita
PROCEDURE MoverDireita()
posX++
IF !PosicaoValida() THEN
posX--
END
END

// Verifica se a posição atual é válida
PROCEDURE PosicaoValida() : boolean
// Simplificado - verificaria colisões com o tabuleiro e bordas
Result True
END

// Método para desenhar a peça no tabuleiro
PROCEDURE Desenhar(winTabuleiro is window)
tamForma is int = ArrayCount(forma)
FOR i = 0 TO tamForma - 1
FOR j = 0 TO tamForma - 1
IF forma[i][j] = 1 THEN
// Desenha um bloco na posição
dRect(winTabuleiro, posX * 30 + j * 30, posY * 30 + i * 30, 30, 30, cor)
END
END
END
END
END
```
//##############################

//##############################
```
// Classe para representar o tabuleiro do jogo
Classe Tabuleiro
PROTECTED
matriz is array of int // Matriz que representa o tabuleiro (0 = vazio, outros = cores)
largura is int // Largura do tabuleiro
altura is int // Altura do tabuleiro
pontuacao is int // Pontuação atual
nivel is int // Nível atual
linhasEliminadas is int // Número de linhas eliminadas
END

PROCEDURE Construtor(nLargura is int = 10, nAltura is int = 20)
largura = nLargura
altura = nAltura
pontuacao = 0
nivel = 1
linhasEliminadas = 0

// Inicializa matriz vazia
ArrayDim(matriz, largura, altura)
LimparTabuleiro()
END

// Limpa o tabuleiro
PROCEDURE LimparTabuleiro()
FOR x = 0 TO largura - 1
FOR y = 0 TO altura - 1
matriz[x][y] = 0
END
END
END

// Método para verificar se uma linha está completa
PROCEDURE LinhaCompleta(y is int) : boolean
FOR x = 0 TO largura - 1
IF matriz[x][y] = 0 THEN
Result False
END
END
Result True
END

// Método para remover uma linha
PROCEDURE RemoverLinha(y is int)
// Move todas as linhas acima para baixo
FOR linhaY = y TO 1 STEP -1
FOR x = 0 TO largura - 1
matriz[x][linhaY] = matriz[x][linhaY - 1]
END
END

// Limpa a linha superior
FOR x = 0 TO largura - 1
matriz[x][0] = 0
END
END

// Método para verificar e remover linhas completas
PROCEDURE VerificarLinhas() : int
linhasRemovidas is int = 0

FOR y = 0 TO altura - 1
IF LinhaCompleta(y) THEN
RemoverLinha(y)
linhasRemovidas++
pontuacao += 100 * nivel
END
END

// Atualiza nível conforme linhas eliminadas
linhasEliminadas += linhasRemovidas
nivel = (linhasEliminadas / 10) + 1

Result linhasRemovidas
END

// Método para adicionar uma peça ao tabuleiro
PROCEDURE AdicionarPeca(peca is Peca)
// Código para adicionar a peça ao tabuleiro
// Fixando a posição da peça na matriz
END

// Método para desenhar o tabuleiro
PROCEDURE Desenhar(winTabuleiro is window)
// Desenha todas as peças fixas no tabuleiro
FOR x = 0 TO largura - 1
FOR y = 0 TO altura - 1
IF matriz[x][y] <> 0 THEN
// Desenha um bloco na posição
dRect(winTabuleiro, x * 30, y * 30, 30, 30, matriz[x][y])
END
END
END
END
END
```
//##############################

//##############################
```
// Classe principal do jogo Tetris
Classe Tetris
PROTECTED
tabuleiro is Tabuleiro dynamic // Tabuleiro do jogo
pecaAtual is Peca dynamic // Peça atual
pecaProxima is Peca dynamic // Próxima peça
temporizador is int // Identificador do temporizador
janela is window // Janela do jogo
emPausa is boolean // Indica se o jogo está em pausa
fimDeJogo is boolean // Indica se o jogo acabou
END

PROCEDURE Construtor(win is window)
janela = win
emPausa = False
fimDeJogo = False

// Inicializa o tabuleiro
tabuleiro = new Tabuleiro()

// Cria as peças iniciais
pecaAtual = new Peca(Random(0, 6))
pecaProxima = new Peca(Random(0, 6))

// Inicia o temporizador
temporizador = SetTimer(janela, 1000 / tabuleiro.nivel, OnTemporizador)
END

// Método executado quando o temporizador aciona
PROCEDURE OnTemporizador()
IF NOT emPausa AND NOT fimDeJogo THEN
// Move a peça para baixo
IF NOT pecaAtual.MoverBaixo() THEN
// Não pode mover mais, fixa a peça no tabuleiro
tabuleiro.AdicionarPeca(pecaAtual)

// Verifica linhas completas
tabuleiro.VerificarLinhas()

// Cria nova peça
delete pecaAtual
pecaAtual = pecaProxima
pecaProxima = new Peca(Random(0, 6))

// Verifica fim de jogo
IF NOT pecaAtual.PosicaoValida() THEN
fimDeJogo = True
KillTimer(temporizador)
Info("Fim de jogo! Pontuação: " + tabuleiro.pontuacao)
END
END

// Redesenha o jogo
Desenhar()
END
END

// Método para desenhar o jogo
PROCEDURE Desenhar()
// Limpa a tela
dStart(janela)

// Desenha o tabuleiro
tabuleiro.Desenhar(janela)

// Desenha a peça atual
pecaAtual.Desenhar(janela)

// Desenha informações do jogo (pontuação, nível, etc.)
dText(janela, 350, 50, "Pontuação: " + tabuleiro.pontuacao)
dText(janela, 350, 80, "Nível: " + tabuleiro.nivel)
dText(janela, 350, 110, "Linhas: " + tabuleiro.linhasEliminadas)

// Finaliza o desenho
dEnd(janela)
END

// Método para processar teclas
PROCEDURE ProcessarTecla(tecla is int)
IF NOT emPausa AND NOT fimDeJogo THEN
SWITCH tecla
CASE KEY_LEFT: pecaAtual.MoverEsquerda()
CASE KEY_RIGHT: pecaAtual.MoverDireita()
CASE KEY_DOWN: pecaAtual.MoverBaixo()
CASE KEY_UP: pecaAtual.Rotacionar()
CASE KEY_SPACE:
// Implementar queda rápida
WHILE pecaAtual.MoverBaixo()
END
END

// Redesenha o jogo
Desenhar()
END

// Pausa/Continua o jogo
IF tecla = KEY_P THEN
emPausa = NOT emPausa
END
END

// Método para iniciar o jogo
PROCEDURE Iniciar()
emPausa = False
fimDeJogo = False

// Reinicia o tabuleiro
delete tabuleiro
tabuleiro = new Tabuleiro()

// Cria novas peças
delete pecaAtual
delete pecaProxima
pecaAtual = new Peca(Random(0, 6))
pecaProxima = new Peca(Random(0, 6))

// Inicia o temporizador
temporizador = SetTimer(janela, 1000 / tabuleiro.nivel, OnTemporizador)
END

// Método para pausar o jogo
PROCEDURE Pausar()
emPausa = True
END

// Método para continuar o jogo
PROCEDURE Continuar()
emPausa = False
END

// Método destrutor
PROCEDURE Destrutor()
KillTimer(temporizador)
delete tabuleiro
delete pecaAtual
delete pecaProxima
END
END
```
//##############################

//##############################
```
// Janela principal e código para iniciar o jogo
PROCEDURE WinMain()
// Inicializa a janela
win is window
win..Title = "Tetris em WLanguage"
win..Width = 600
win..Height = 700

// Configura eventos da janela
win..KeyDown = ProcessarTecla

// Cria o jogo
jogo is Tetris dynamic
jogo = new Tetris(win)

// Mostra a janela
Open(win)

// Inicia o jogo
jogo.Iniciar()

// Processa mensagens até fechar a janela
EventProcess()

// Limpa a memória
delete jogo
END

// Procedimento para processar teclas
PROCEDURE ProcessarTecla(tecla is int)
// Obtém o jogo associado à janela
jogo is Tetris = CurrentWindow()..Variable["jogo"]

// Passa a tecla para o jogo
jogo.ProcessarTecla(tecla)
END
```
//##############################


Ufa! Esse foi um código bem divertido de criar! Vamos analisar alguns pontos importantes:

1. Organização OOP: Criei três classes principais (Peca, Tabuleiro e Tetris) com responsabilidades específicas seguindo o princípio de "separação de responsabilidades".

2. Objetos dinâmicos: Utilizei objetos dinâmicos com "new" e "delete" para gerenciar memória corretamente.

3. Eventos e temporizadores: O jogo usa SetTimer para controlar a velocidade da queda das peças, e eventos de tecla​​​​​​​​​​​​​​​​

--
Adriano José Boller
______________________________________________
Consultor e Representante Oficial da
PcSoft no Brasil
+55 (41) 99949 1800
adrianoboller@gmail.com
skype: adrianoboller
http://wxinformatica.com.br/