Ir ao conteúdo

Posts recomendados

Postado

olá galera, estou com um problema o qual não consigo resolver de forma alguma no meu código!
as colisões o grid tudo está funcionando, más tem um problema na hora de retirar a linha completa do tetris! os métodos criados não estão respondendo corretamente, já pedi auxilio até para a porquera do ChatGPT  e nem ele conseguiu ajudar só piorou kkkkk
eu não sei em qual aula eu faltei de java, mas o problema é o seguinte. Quando a ultima peça que o jogador coloca no grid fecha uma linha ou mais, a peça em si que fechou a linha não tem tem a parte correspondente a linha fechada removida, a peça continua e as peças próximas também não são removidas! este projeto de recriar o jogo tetris é para uma implementação de uma IA, que eu também irei bater a cabeça para fazer kkk, mas primeiro preciso ter o jogo completo jogavel.

se alguém puder me ajudar com esse problema eu agradeceria muito. irei compactar o projeto inteiro com todas as classes e assets para que possam analisar onde eu errei!

caso queiram analisar a classe que manipula os tetrominos irei mostrar aqui!

 

package com.mygdx.iadojogo;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


public class TetrominoManager {
    private int score;
    private Tetromino currentTetromino;
    private Tetromino nextTetromino;
    private static final int GRID_WIDTH = 10;
    private static final int GRID_HEIGHT = 20;
    private int[][] grid;

    private Texture spriteSheet;
    private int blockSize;
    private int xOffset;
    private int gridFirstScreenX = 60;
    private int gridFirstScreenY = 50;
    private float moveDelay = 1f; // Ajuste o valor conforme desejado (maior valor -> movimento mais lento)
    private float moveTimer = 0f;
    private boolean isPieceFalling = true;
    private boolean isMovingHorizontally = false; // Verifica se a peça está se movendo lateralmente
    private float horizontalMoveTimer = 0f;
    private float horizontalMoveDelay = 2f;
    private boolean gameOver = false;
    private int[][] gridSprites;


    public TetrominoManager(final Texture spriteSheet, final int blockSize, final int xOffset) {
        this.spriteSheet = spriteSheet;
        this.blockSize = blockSize;
        this.xOffset = xOffset;
        this.score = 0;
        currentTetromino = new Tetromino(getRandomShape());
        nextTetromino = new Tetromino(getRandomShape());
        gridSprites = new int[GRID_HEIGHT][GRID_WIDTH]; // Inicialize a matriz gridSprites
        grid = new int[GRID_HEIGHT][GRID_WIDTH];
        currentTetromino.setPosX(GRID_WIDTH / 2 - currentTetromino.getShape()[0].length / 2);
        currentTetromino.setPosY(GRID_HEIGHT - currentTetromino.getShape().length);
        int spriteWidth = 32;
        int spriteHeight = 32;

    }

    public void update(float delta) {

        if (gameOver) {
            return; // Se o jogo acabou, não atualize mais nada
        }
        // Verificar o movimento lateral esquerdo
        if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
            horizontalMoveTimer += delta;
            if (horizontalMoveTimer >= horizontalMoveDelay) {
                moveLeft();
                horizontalMoveTimer = 0f;
            }
        }
        // Verificar o movimento lateral direito
        if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
            horizontalMoveTimer += delta;
            if (horizontalMoveTimer >= horizontalMoveDelay) {
                moveRight();
                horizontalMoveTimer = 0f;
            }
        }
        // Atualização da queda da peça
        if (isPieceFalling) {
            moveTimer += delta;
            if (moveTimer >= moveDelay) {
                moveTimer = 0f;
                if (!moveDown()) {
                    placeTetromino();
                    isPieceFalling = false;
                    if (currentTetromino.getPosY() >= GRID_HEIGHT - currentTetromino.getShape().length) {
                        gameOver = true; // Peça chegou ao topo do grid, indicação de Game Over
                    }
                }
            }
        } else {
            currentTetromino = new Tetromino(getRandomShape());
            currentTetromino.setPosX(GRID_WIDTH / 2 - currentTetromino.getShape()[0].length / 2);
            currentTetromino.setPosY(GRID_HEIGHT - currentTetromino.getShape().length);
            isPieceFalling = true;
        }
        if (!isPieceFalling) {
            currentTetromino = nextTetromino;
            generateNextTetromino();
            currentTetromino.setPosX(GRID_WIDTH / 2 - currentTetromino.getShape()[0].length / 2);
            currentTetromino.setPosY(GRID_HEIGHT - currentTetromino.getShape().length);
            isPieceFalling = true;
        }
    }

    public void draw(SpriteBatch batch) {
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //primeira parte
        // Desenhar o contorno branco de cada bloco do grid
        for (int y = 0; y < GRID_HEIGHT; y++) {
            for (int x = 0; x < GRID_WIDTH; x++) {
                int xDraw = x * blockSize + gridFirstScreenX;
                int yDraw = y * blockSize + gridFirstScreenY;

                // Desenhar o contorno branco em volta do bloco
                batch.setColor(Color.WHITE);
                batch.draw(spriteSheet, xDraw - 1, yDraw - 1, blockSize + 2, 1);
                batch.draw(spriteSheet, xDraw - 1, yDraw + blockSize - 1, blockSize + 2, 1);
                batch.draw(spriteSheet, xDraw - 1, yDraw, 1, blockSize);
                batch.draw(spriteSheet, xDraw + blockSize - 1, yDraw, 1, blockSize);
            }
        }
        //fim primeira parte
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //segunda parte
        // Desenhar as peças que estão caindo
        int[][] shape = currentTetromino.getShape();
        int pieceIndex = currentTetromino.getSpriteIndex() ; // Índice 0 representa o primeiro sprite da folha de sprite (32x32)


        for (int i = 0; i < shape.length; i++) {
            for (int j = 0; j < shape[i].length; j++) {
                int index = shape[i][j];
                if (index == 1) {
                    // Calcule a posição na folha de sprite com base no pieceIndex
                    int xSheet = (pieceIndex % 4) * blockSize; // O módulo 4 garante que fique dentro da primeira linha (0 a 3)
                    int ySheet = (pieceIndex / 4) * blockSize; // A divisão inteira por 4 obtém a posição da linha correta (0 a 9)

                    // Calcule a posição de desenho no grid
                    int xDraw = (currentTetromino.getPosX() + j) * blockSize + gridFirstScreenX;
                    int yDraw = (currentTetromino.getPosY() + i) * blockSize + gridFirstScreenY;

                    // Desenhe o sprite de 32x32 na posição do Tetromino
                    batch.draw(spriteSheet, xDraw, yDraw, blockSize, blockSize,
                            xSheet, ySheet, blockSize, blockSize, false, false);
                }
            }
        }
        //fim segunda parte
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //terceira parte
        // Desenhar as peças que já estão no grid
        for (int y = 0; y < GRID_HEIGHT; y++) {
            for (int x = 0; x < GRID_WIDTH; x++) {
                if (grid[y][x] != 0) { // Verificar se a posição do grid está ocupada
                    int pieceIndex1 = grid[y][x] - 1; // Obtém o índice do sprite da peça (subtrai 1 pois os índices são incrementados na matriz grid)
                    int xDraw = x * blockSize + gridFirstScreenX;
                    int yDraw = y * blockSize + gridFirstScreenY;

                    // Desenhe o sprite de 32x32 na posição do grid
                    batch.draw(spriteSheet, xDraw, yDraw, blockSize, blockSize,
                            pieceIndex1 * blockSize, 0, blockSize, blockSize, false, false);
                }
            }
        }
        //fim terceira parte
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //quarta parte
        // Desenha a próxima peça
        int[][] nextShape = nextTetromino.getShape();
        int nextBlockSize = blockSize / 2; // Tamanho reduzido para a próxima peça
        int nextGridFirstScreenX = gridFirstScreenX + GRID_WIDTH * blockSize + 50; // Posição x da próxima peça
        int nextGridFirstScreenY = gridFirstScreenY + GRID_HEIGHT * blockSize - nextShape.length * nextBlockSize; // Posição y da próxima peça

        for (int i = 0; i < nextShape.length; i++) {
            for (int j = 0; j < nextShape[i].length; j++) {
                int index = nextShape[i][j];
                if (index == 1) {
                    int nextPieceIndex = nextTetromino.getSpriteIndex() + 2; // Índice na folha de sprites para a próxima peça
                    int xSheet = (nextPieceIndex % 4 ) * blockSize; // O módulo 4 garante que fique dentro da primeira linha (0 a 3)
                    int ySheet = (nextPieceIndex / 4 ) * blockSize; // A divisão inteira por 4 obtém a posição da linha correta (0 a 9)

                    int xDraw = (j + nextGridFirstScreenX / nextBlockSize) * nextBlockSize;
                    int yDraw = (i + nextGridFirstScreenY / nextBlockSize) * nextBlockSize;

                    batch.draw(spriteSheet , xDraw, yDraw, nextBlockSize, nextBlockSize,
                            xSheet, ySheet, blockSize, blockSize, false, false);
                }
            }
        }
        //fim quarta parte
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    }

    public void setTetrominoShape(int[][] shape) {
        currentTetromino.setShape(shape);
    }
    private void generateNextTetromino() {
        nextTetromino = new Tetromino(getRandomShape());
    }

    private void startHorizontalMovement() {
        isMovingHorizontally = true;
    }


    public boolean moveLeft() {
        if (canMoveTo(currentTetromino.getPosX() - 1, currentTetromino.getPosY())) {
            currentTetromino.moveLeft();
            startHorizontalMovement();
            return true;
        }
        return false;
    }

    public boolean moveRight() {
        if (canMoveTo(currentTetromino.getPosX() + 1, currentTetromino.getPosY())) {
            currentTetromino.moveRight();
            startHorizontalMovement();
            return true;
        }
        return false;
    }

    public boolean moveDown() {
        if (canMoveTo(currentTetromino.getPosX(), currentTetromino.getPosY() - 1)) {
            currentTetromino.moveDown();
            return true;
        } else {
            // Se a peça não puder se mover para baixo, ela atinge a parte inferior do grid.
            // Neste ponto, podemos definir a peça no grid e definir a variável isPieceFalling como false.
            placeTetromino();
            isPieceFalling = false;
            return false;
        }
    }

    private boolean canMoveTo(int newX, int newY) {
        return canMoveTo(newX, newY, currentTetromino.getShape());
    }

    private boolean canMoveTo(int newX, int newY, int[][] newShape) {
        for (int i = 0; i < newShape.length; i++) {
            for (int j = 0; j < newShape[i].length; j++) {
                if (newShape[i][j] == 1) {
                    int x = newX + j;
                    int y = newY + i;
                    // Verifique se a posição (x, y) está dentro dos limites do grid
                    if (x < 0 || x >= GRID_WIDTH || y < 0 || y >= GRID_HEIGHT ) {
                        return false;
                    }
                    // Verifique se a posição (x, y) está vazia no grid
                    if (y >= 0 && grid[y][x] != 0) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
    private boolean isLineComplete(int line) {
        for (int x = 0; x < GRID_WIDTH; x++) {
            if (grid[line][x] == 0) {
                return false; // Encontrou um bloco vazio na linha, não está completa
            }
        }
        return true;
    }

    private void removeLine(int line) {
        for (int y = line + 1; y < GRID_HEIGHT; y++) {
            for (int x = 0; x < GRID_WIDTH; x++) {
                grid[y - 1][x] = grid[y][x]; // Move cada linha acima para baixo em um passo
                gridSprites[y - 1][x] = gridSprites[y][x];
            }
        }

        for (int x = 0; x < GRID_WIDTH; x++) {
            grid[GRID_HEIGHT - 1][x] = 0; // Define a linha superior como vazia
            gridSprites[GRID_HEIGHT - 1][x] = 0;
        }
    }


    private void placeTetromino() {
        // Colocar o tetromino no grid
        int[][] shape = currentTetromino.getShape();
        int pieceIndex = currentTetromino.getSpriteIndex();

        int posX = currentTetromino.getPosX();
        int posY = currentTetromino.getPosY();

        for (int i = 0; i < shape.length; i++) {
            for (int j = 0; j < shape[i].length; j++) {
                if (shape[i][j] == 1) {
                    int x = posX + j;
                    int y = posY + i;

                    // Verificar se a posição (x, y) está dentro dos limites do grid
                    if (x >= 0 && x < GRID_WIDTH && y >= 0 && y < GRID_HEIGHT) {
                        // Verificar se a posição (x, y) está vazia no grid
                        if (grid[y][x] != 0) {
                            // Parte da peça está na linha completa, limpar essa célula do gridSprites e grid
                            gridSprites[y][x] = 0;
                            grid[y][x] = 0;
                        }

                        // Marque a posição no grid como ocupada pela peça
                        grid[y][x] = 1;
                        gridSprites[y][x] = pieceIndex + 1;
                    }
                }
            }
        }

        // Verificar se há linhas completas e removê-las, inclusive as peças adjacentes
        int linesCleared = 0;
        for (int y = 0; y < GRID_HEIGHT; y++) {
            if (isLineComplete(y)) {
                removeLine(y);
                linesCleared++;
                y--; // Após remover uma linha, precisamos verificar a linha atual novamente, pois a próxima linha desceu uma posição.
            }
        }


        if (linesCleared > 0) {
            score += calculateScore(linesCleared);
        }

        // Verifique se houve um Tetris (4 linhas eliminadas) e adicione pontos adicionais
        if (linesCleared == 4) {
            score += 800; // Valor padrão para Tetris
        }

    }


    private int calculateScore(int linesCleared) {
        // Implemente a lógica de pontuação aqui, você pode ajustar os valores conforme desejado
        switch (linesCleared) {
            case 1:
                return 100; // Pontuação para uma linha eliminada
            case 2:
                return 300; // Pontuação para duas linhas eliminadas simultaneamente
            case 3:
                return 500; // Pontuação para três linhas eliminadas simultaneamente
            default:
                return 0; // Por padrão, não há pontuação extra para eliminar mais de 3 linhas
        }
    }
    public void rotate() {
        currentTetromino.rotate();
    }

    private int[][] getRandomShape() {
        // Array que contém todas as formas possíveis de tetromino
        int[][][] allShapes = {
                Shape.getShapeI(),
                Shape.getShapeJ(),
                Shape.getShapeL(),
                Shape.getShapeO(),
                Shape.getShapeS(),
                Shape.getShapeT(),
                Shape.getShapeZ()
        };

        // Gerar um número aleatório para selecionar uma forma aleatória
        int randomIndex = (int) (Math.random() * allShapes.length);

        // Retornar a forma selecionada aleatoriamente
        return allShapes[randomIndex];
    }

    public Tetromino getCurrentTetromino() {
        return currentTetromino;
    }

    public void setCurrentTetromino(Tetromino currentTetromino) {
        this.currentTetromino = currentTetromino;
    }

    public int[][] getGrid() {
        return grid;
    }

    public void setGrid(int[][] grid) {
        this.grid = grid;
    }

    public Texture getSpriteSheet() {
        return spriteSheet;
    }

    public void setSpriteSheet(Texture spriteSheet) {
        this.spriteSheet = spriteSheet;
    }

    public int getBlockSize() {
        return blockSize;
    }

    public void setBlockSize(int blockSize) {
        this.blockSize = blockSize;
    }

    public int getxOffset() {
        return xOffset;
    }

    public void setxOffset(int xOffset) {
        this.xOffset = xOffset;
    }

    public int getGridFirstScreenX() {
        return gridFirstScreenX;
    }

    public void setGridFirstScreenX(int gridFirstScreenX) {
        this.gridFirstScreenX = gridFirstScreenX;
    }

    public int getGridFirstScreenY() {
        return gridFirstScreenY;
    }

    public void setGridFirstScreenY(int gridFirstScreenY) {
        this.gridFirstScreenY = gridFirstScreenY;
    }

    public float getMoveDelay() {
        return moveDelay;
    }

    public void setMoveDelay(float moveDelay) {
        this.moveDelay = moveDelay;
    }

    public float getMoveTimer() {
        return moveTimer;
    }

    public void setMoveTimer(float moveTimer) {
        this.moveTimer = moveTimer;
    }

    public boolean isPieceFalling() {
        return isPieceFalling;
    }

    public void setPieceFalling(boolean pieceFalling) {
        isPieceFalling = pieceFalling;
    }

    public boolean isMovingHorizontally() {
        return isMovingHorizontally;
    }

    public void setMovingHorizontally(boolean movingHorizontally) {
        isMovingHorizontally = movingHorizontally;
    }

    public float getHorizontalMoveTimer() {
        return horizontalMoveTimer;
    }

    public void setHorizontalMoveTimer(float horizontalMoveTimer) {
        this.horizontalMoveTimer = horizontalMoveTimer;
    }

    public float getHorizontalMoveDelay() {
        return horizontalMoveDelay;
    }

    public void setHorizontalMoveDelay(float horizontalMoveDelay) {
        this.horizontalMoveDelay = horizontalMoveDelay;
    }

    public boolean isGameOver() {
        return gameOver;
    }

    public void setGameOver(boolean gameOver) {
        this.gameOver = gameOver;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

 

 

 

 

desde já agradeço a todos!

 

TetrisIA.zip

  • Amei 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!