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: adrianobollerhttp://wxinformatica.com.br/