Android видеоигры с использованием 2D массив-найти соединительные спички

Хорошо, я строю игру в свободное время для удовольствия. Это не для работы или школы. Я закончил. То, что я не сделал, это выпускник в области программирования игр, поэтому я изучаю его по ходу. Я разработал несколько игр, но эта, вероятно, моя самая продвинутая.

У меня около 5 2d массивов. Один для удержания растровых изображений, один для удержания X местоположений, один для удержания y местоположений, один для удержания состояния элемента (они являются птицами, статус для состояния полета и состояния попадания), а один определяет, что такое элемент. Каждый массив работает вместе, чтобы дать мне игровую доску с птицами, хлопая крыльями. Я могу коснуться игрового поля, я получаю расположение обратно. Эта часть все работает.

То, что я пытаюсь сделать, это создать способ определения, являются ли элементы поблизости тем же самым элементом, что и помеченный элемент (тронутый элемент). Когда это происходит, я в основном хочу отметить все эти элементы как «Хит». Это не просто получение 8 блоков вокруг элемента, это получение каждого элемента, касаясь отмеченного элемента и идентифицируя их как «Хит». Возможно,Вы играли в такие игры. Они головоломки, как игры (шахты кулер, потому что птицы какают на вас, и это убивает вашего персонажа 🙂 ). Я создал еще один 2D массив, чтобы закрепить состояние попадания (в этой последней итерации моей попытки решить проблему, поэтому я не считаю дважды попадание, и теперь я использую его, чтобы отметить элементы, которые я не считаю с -1.

Мои массивы все[8] [8] массивы. Они не меняются, они всегда будут такими. Это должно облегчить задачу. Так в качестве примера:

пример из игры

Обведенные кружком красные птицы на изображении также должны были быть помечены.

К коду:

 public void calculateGunDestruction(){
    int currentRow = targetBirdRow;
    int currentCol = targetBirdCol;
    int hitbird = whichBird[targetBirdRow][targetBirdCol];
    boolean[] pathState = new boolean[5];
    countedArray = new int[8][8];
    for(int j = 0; j < countedArray.length;j++){
        for(int jj = 0; jj< countedArray[j].length;jj++){
            countedArray[j][jj] = 0;
        }
    }
    for(int i = currentRow;i < whichBird.length; i++) {
        for (int ii = currentCol; ii < whichBird[i].length; ii++) {
            pathState = pathMatch(i,ii,hitbird);
            if(!pathState[0] && !pathState[1] && !pathState[2] && !pathState[3]){
                break;
            }
        }
        if(!pathState[0] && !pathState[1] && !pathState[2] && !pathState[3]){
            break;
        }
    }
    for(int i = currentRow;i > -1; i--) {
        for (int ii = currentCol; ii < whichBird[i].length; ii++) {
            pathState = pathMatch(i,ii,hitbird);
            if(!pathState[0] && !pathState[1] && !pathState[2] && !pathState[3]){
                break;
            }
        }
        if(!pathState[0] && !pathState[1] && !pathState[2] && !pathState[3]){
            break;
        }
    }
    for(int i = currentRow;i < whichBird.length; i++) {
        for (int ii = currentCol; ii > - 1; ii--) {
            pathState = pathMatch(i,ii,hitbird);
            if(!pathState[0] && !pathState[1] && !pathState[2] && !pathState[3]){
                break;
            }
        }
        if(!pathState[0] && !pathState[1] && !pathState[2] && !pathState[3]){
            break;
        }
    }
    for(int i = currentRow;i > -1; i--) {
        for (int ii = currentCol; ii > - 1; ii--) {
            pathState = pathMatch(i,ii,hitbird);
            if(!pathState[0] && !pathState[1] && !pathState[2] && !pathState[3]){
                break;
            }
        }
        if(!pathState[0] && !pathState[1] && !pathState[2] && !pathState[3]){
            break;
        }
    }
}


 public boolean[] pathMatch(int i, int ii, int hitbird){

    boolean pathTop = false;
    boolean pathBottom = false;
    boolean pathLeft = false;
    boolean pathRight = false;

    if(findMatch(i,ii,hitbird)) {
        if(countedArray[i][ii] == 0) {
            countedArray[i][ii] = 1;
            destroyedBirds(i, ii);
        }
        if((i - 1) > -1) {
            if (countedArray[i - 1][ii] == 0) {
                if (findMatch(i - 1, ii, hitbird)) {
                    countedArray[i - 1][ii] = 1;
                    destroyedBirds(i - 1, ii);
                    pathLeft = true;
                } else {countedArray[i - 1][ii] = -1;pathLeft = false;}
            } else {pathLeft = false;}
        } else {pathLeft = false;}
        if((i + 1) < 8) {
            if (countedArray[i + 1][ii] == 0) {
                if (findMatch(i + 1, ii, hitbird)) {
                    countedArray[i + 1][ii] = 1;
                    destroyedBirds(i + 1, ii);
                    pathRight = true;
                } else {countedArray[i + 1][ii] = -1;pathRight = false;}
            } else {pathRight = false;}
        }else {pathRight = false;}
        if((ii - 1) > -1) {
            if (countedArray[i][ii - 1] == 0) {
                if (findMatch(i, ii - 1, hitbird)) {
                    countedArray[i][ii - 1] = 1;
                    destroyedBirds(i, ii - 1);
                    pathTop = true;
                } else {countedArray[i][ii - 1] = -1;pathTop = false;}
            } else {pathTop = false;}
        } else {pathTop = false;}
        if((ii + 1) < 8) {
            if (countedArray[i][ii + 1] == 0) {
                if (findMatch(i, ii + 1, hitbird)) {
                    countedArray[i][ii + 1] = 1;
                    destroyedBirds(i, ii + 1);
                    pathBottom = true;
                } else {countedArray[i][ii + 1] = -1;pathBottom = false;}
            } else {pathBottom = false;}
        }else {pathBottom = false;}
    }else{
        countedArray[i][ii] = -1;
    }

    return new boolean[]{pathTop,pathBottom,pathLeft,pathRight};
}

public boolean findMatch(int row,int col,int hitbird){
    if(hitbird == whichBird[row][col]){
        return true;
    }
    return false;
}
public void destroyedBirds(int row,int col){
    destroyedBirdsRow.add(0, row);
    destroyedBirdsCol.add(0, col);
}

Я пробовал несколько разных способов, это просто последний на момент написания этой книги. Некоторые из них были ближе, чем другие, но никто не понимал этого. Кажется, что это должно быть очень просто, но я не программист игры профессионально, Программирование игры-это то, чему я пытаюсь научиться.

Код выше в основном разбивает 2D массив на квадранты от точки, в которой вы касаетесь. Я добавил элемент управления «countedArray» с этой попытки, потому что я знал, что не было никакого реального способа остановить двойной подсчет с этим методом без какого-то способа отслеживать его. Он идет влево / вниз, влево, вверх, вправо/вниз, вправо/вверх от точки касания.
точки касания возле верхней части:

int currentRow = targetBirdRow;
int currentCol = targetBirdCol;
int hitbird = whichBird[targetBirdRow][targetBirdCol];

hit bird содержит идентификатор затронутой птицы или элемента. Это не очень элегантное решение, но оно также не работает. В этот момент элегантность выбрасывается в окно, я собираюсь написать длинный неприятный кусок кода, который никто не может прочитать, проверяя каждый элемент индивидуально без петли и надежды на то, что работает. Так что булыжные решения в порядке.

Для справки — область, из которой вызывается приведенный выше код, выглядит следующим образом:

if(playerObj.getWeaponSelected() == wGun) {
    calculateGunDestruction();//CALLING FUNCTION

    for (int i = 0; i < destroyedBirdsRow.size(); i++) {
        state[destroyedBirdsRow.get(i)][destroyedBirdsCol.get(i)] = hit;
    }
    destroyedBirdsRow.clear();
    destroyedBirdsCol.clear();

Полное Изображение Игры
Я отредактировал, чтобы добавить полное изображение игры. Вопросы о том, почему это слишком сложно, побудили меня немного объяснить. (И да, возможно, есть лучшие способы сделать это — я, конечно, не эксперт в этом). Идея заключается в том, как птицы попадают, чтобы отобразить краткое изображение удара, сделать хит птица исчезает, а затем переместить птиц слева, добавив новую птицу(ы), чтобы заменить хит птиц. Что структура все работает-если не возможно над сложным в дизайне. Одиночные хиты работают, бомбы хиты работают (когда вы снимаете бомбу, которая случайным образом появляется на доске в качестве новой птицы). Я использую массивы позиций, чтобы направлять анимацию птиц, которые должны двигаться, чтобы заполнить пробел, оставленный ударившими птицами. Я бы не удивился, узнав о лучшем способе, и я здесь и делаю это, чтобы узнать, поэтому не стесняйтесь комментировать вне первоначального объема вопроса. Это может помочь другим, пытающимся учиться, и мне; и я думаю, что это действительно самая важная точка такого сайта.

Что касается части, мне трудно добраться до работы. Когда я стреляю из пистолета, идея заключалась в том, чтобы он привязал всех птиц одного цвета/вида, которые прикасаются к ударной птице, пометить их как удар и заставить их исчезнуть. И да, код, который я в настоящее время имею для этого раздела, вероятно, самая сложная версия, которую я написал. Я начинал по крайней мере дюжину раз. Самый простой вариант включал две группы петель и менее внешние методы (он был вдвое меньше) — он работал примерно так же, как и этот, но имел тенденцию отмечать дополнительных птиц. Этот, кажется, не отмечает дополнительных птиц, но не получает их все.

Я построил несколько небольших игр в прошлом — но это, безусловно, самый сложный, который я пытался, и он выглядит довольно хорошо до сих пор — за исключением всего сгруппированного убийства.

1 ответ

  1. Возможно, ваше падение с этим связано с усложнением дизайна. Я изо всех сил, чтобы понять, почему вам нужно 5 8×8 массивов для хранения 2D игрового поля.

    Ваше решение для маркировки хит плитки и тех, кто вокруг него должно быть что-то вроде этого для простоты:

    public static final int NOTHING=0,BIRD_FLYING=1,BIRD_HIT=2,
                            TILE_LAND=0,TILE_WATER=1;
    
    private int[][] gameBoard=new int[8][8]; // Store terrain etc.
    private int[][] birds=new int[8][8]; // Store entities on the map
    private int tileSize=32; // Store the size of the tile in pixels
    private Image landImg,seaImg,flyingImg,hitImg; // Store the tile images (or use 1 tilesheet and segment it in the draw method)
    
    private void hitTile(int x,int y)
    {
        for(int i=-1;i<=1;i++)
        {
            for(int j=-1;j<=1;j++)
            {
                birds[hitX+i,hitY+j]=BIRD_HIT;
            }
        }
    }
    
    private void drawTheTiles()
    {
        for(int i=0;i<8;i++)
        {
            for(int j=0;j<8;j++)
            {
                // Draw background tiles first
                switch(gameBoard[i][j])
                {
                    default:
                    case TILE_LAND:
                        g.drawImage(landImg,i*tileSize,j*tileSize,this);
                        break;
                    case TILE_SEA:
                        g.drawImage(seaImg,i*tileSize,j*tileSize,this);
                        break;
                }
                // Draw entities on tiles last
                switch(gameBoard[i][j])
                {
                    default:
                    case NOTHING:
                        // Don't draw anything
                        break;
                    case BIRD_FLYING:
                        g.drawImage(flyingImg,i*tileSize,j*tileSize,this);
                        break;
                    case BIRD_HIT:
                        g.drawImage(hitImg,i*tileSize,j*tileSize,this);
                        break;
                }
            }
        }
    }
    

    Конечно, вам нужно будет добавить в свою собственную обработку, загрузку изображений, рендеринг и записи массива, но не должно быть необходимости хранить позиции в массиве для 2D игровой доски, как это, так как позиции могут подразумеваться индексом плитки.

    Я надеюсь, что это даст вам что-то, чтобы продолжить. Но, боюсь, я не совсем понимаю вашу оригинальную программу/посылку.