Jump to content

Missing childeren elements at an element of group after move


Evgeniy
 Share

Recommended Posts

Hi all,

I build simple word match game:

Скриншот 2016-05-18 06.47.01.png


http://woa.troinof.ru/

 

If you play game you can see that elements not always disappear, for some reason after selected element removed and other moved down his children element disappear:

Скриншот 2016-05-18 07.00.25.png

and must be:

Скриншот 2016-05-18 07.06.57.png

 

It happends after letter moves.

 

Bug step by step:

 

Step 1:

step_1.png

 

Step 2 (all good):

step_2.png

 

Step 3 ( repeat step 2):

step_3.png

 

Result step 3 ( FAIL ):

Скриншот 2016-05-18 06.47.01.png

 

I dont't understand where i made mistake.

 

Fanks for attention:

 

Source code: http://woa.troinof.ru/bc.tar

Source code ( board.ts ):

///<reference path="../def/require.d.ts"/>
///<reference path="../def/lodash.d.ts"/>

///<reference path="../game.ts"/>
///<reference path="../boot.ts"/>

define(['phaser', 'lodash'],function(Phaser, _) {

    class Board {
        game: any;
        letters: any;
        tileWidth: number;
        tileHeight: number;
        userSelect: any = [];
        word: string = '';

        btnExit: any;
        btnHelp: any;
        btnSound: any;
        btnMusic: any;
        btnCoin: any;

        movesCounter: any;
        userCoin: number = 250;
        userScore: any;

        coinCountLabel: any;

        levelTheme: any;
        hoverSound: any;
        tileMoveSound: any;

        letterGrid: any = [
            [null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null],
            [null, null, null, null, null, null, null, null],
        ];

        constructor(game: any) {
            this.game = game;
            this.tileWidth       = this.game.cache.getImage('field').width;
            this.tileHeight      = this.game.cache.getImage('field').height;
            this.tileMoveSound   = this.game.add.audio('tile_move');
            this.hoverSound      = this.game.add.audio('tile_select');

            // Саундтрек игровой комнаты
            this.levelTheme = this.game.add.audio('level_theme', 1, true).play();

            // Создаем кнопку выхода и назначаем обработчик
            this.btnExit = this.game.add.button(5, this.game.height - 80, 'btn_exit', this.exit, this, 1, 0, 2, 0);
            this.btnExit.input.useHandCursor = true;
            this.btnExit.onOverSound = this.hoverSound;

            // Создаем кнопку подсказки и назначаем обработчик
            this.btnHelp = this.game.add.button(this.game.width - 81, this.game.height - 80, 'btn_help', this.help, this, 1, 0, 2, 0);
            this.btnHelp.input.useHandCursor = true;
            this.btnHelp.onOverSound = this.hoverSound;

            // Создаем кнопку вкл/вкл звуков и назначаем обработчик
            this.btnSound = this.game.add.button(100, this.game.height - 45, 'btn_sound', this.toggleSound, this, 1, 0, 2, 0);
            this.btnSound.input.useHandCursor = true;
            this.btnSound.onOverSound = this.hoverSound;

            // Создаем кнопку вкл/вкл музыки и назначаем обработчик
            this.btnMusic = this.game.add.button(150, this.game.height - 45, 'btn_music', this.toggleMusic, this, 1, 0, 2, 0);
            this.btnMusic.input.useHandCursor = true;
            this.btnMusic.onOverSound = this.hoverSound;

            // Индикатор монет
            this.btnCoin = this.game.add.button(this.game.width - 164, -5, 'btn_coin', this.buyCoin, this, 1, 0, 2, 0);
            this.btnCoin.input.useHandCursor = true;
            this.btnCoin.onOverSound = this.hoverSound;

            this.coinCountLabel = this.game.add.text(70, 23, this.userCoin, {font: "bold 32px Arial", fill: "#EEFF9C"});
            this.btnCoin.addChild(this.coinCountLabel);
        }

        toggleSound() {
            this.hoverSound.mute    = this.hoverSound.mute ? false : true;
            this.tileMoveSound.mute = this.tileMoveSound.mute ? false : true;
        }

        toggleMusic() {
            this.levelTheme.mute = this.levelTheme.mute ? false : true;
        }

        buyCoin() {
            alert('покупка монет');
        }

        /** Заполняем доску буквами - на данный момент не испльзуется */
        initTiles() {
            let self = this;

            for (let i = 0; i < self.letterGrid.length; i++) {

                for (let j = 0; j < self.letterGrid.length; j++) {
                    let tile = self.addLetterTile(i, j);

                    self.letterGrid[i][j] = tile;
                }
            }
        }

        addLetterTile(x: number, y: number) {}

        resetTile() {
            // Проходим циклом по каждой колонке начиная слева
            for(let i = 0; i < this.letterGrid.length; i++) {
                // Проходим циклом по каждой букве снизу вверх
                for(let j = this.letterGrid[i].length - 1; j > 0; j--) {

                    // Если область пустая, но область выше нет, смещаем на одну вниз
                    if(this.letterGrid[i][j] === null && this.letterGrid[i][j-1] !== null) {
                        let tempTile = this.letterGrid[i][j-1];

                        // Меняем буквы местами
                        this.letterGrid[i][j]   = tempTile;
                        this.letterGrid[i][j-1] = null;

                        // Добавим анимацию перемещения
                        this.moveDown(tempTile, j);

                        // Перемещаем указатель снова вверх для повторного прохода массива
                        // Примечание: мы не указываем this.letterGrid[i].length - 1 так как данное значение уже будет изменено
                        // В данный момент мы в конце цикла
                        // Данная процедура будет повторятся до тех пор пока в данном массиве все null значения
                        // небудут перемещенны вверх
                        j = this.letterGrid[i].length;
                    }
                }
            }

            // Звук падения камней
            this.tileMoveSound.play();
        }

        exit() {
            alert('You leave the room');
        }

        help() {
            alert('Подсказка');
        }


        moveDown(letter: any, position: number) {
            let tw = this.game.add.tween(letter);

            tw.to({y: (LETTER_SIZE_SPACED * position) + (LETTER_SIZE_SPACED / 2) + 150}, 600, Phaser.Easing.Bounce.Out, true);
        }

        fillTile() {}

        // Deprecated
        fill() {
            let letterIndex: number = 0,
                letterContainer: any,
                letter: any,
                ground: any,
                time: any = new Date();

            // Создаем группу которая будет содержать буквы
            this.letters = this.game.add.group();
            this.letters.enableBody = true;

            for(let i = 0; i < BOARD_COLS; i++) {

                // Заполняем массив буквами
                for (let j = 0; j < BOARD_ROWS; j++) {
                    letterIndex     = Math.floor(Math.random() * (31 - 0));

                    letterContainer = this.letters.create(
                        i * LETTER_SIZE_SPACED + (LETTER_SIZE_SPACED / 2) + 200,
                        j * LETTER_SIZE_SPACED + (LETTER_SIZE_SPACED / 2) + 150,
                        'field'
                    );

                    // Устанавливаем точку объекту по центру
                    // для выравнивания текста и анимации
                    letterContainer.anchor.setTo(0.5, 0.5);

                    // Устанавливаем стартовый размер в 0
                    letterContainer.scale = {
                        type: 25,
                        x: 0.4,
                        y: 0.4
                    };

                    letter = this.game.add.text(
                              0,
                              0,
                              ALPHABET[letterIndex], {
                                  font: "bold 38px Arial",
                                  fill: "#5E1400",

                                  // Выравние текста по центру
                                  boundsAlignH: "center",
                                  boundsAlignV: "middle"
                              });

                    // Генерируем уникальный id для каждой буквы
                    letter.uid = (Math.random() * time.getTime()).toFixed();

                    // Обработка событий мышки на буквах
                    letter.inputEnabled = true;

                    letter.events.onInputDown.add(this.selectLetter, this);
                    letter.events.onInputOver.add(this.hoverLetter, this);

                    // Запоминаем позицию буквы на карте
                    letterContainer.gridPosition = {
                        y: i,
                        x: j
                    };

                    // Устанавливаем границы контейнера буквы
                    letter.setTextBounds(0, 0, 0, 0);

                    // Помещаем букву в контейнер с фоном
                    letterContainer.addChild(letter);

                    // fill board letterGrid
                    this.letterGrid[i][j] = letterContainer;

                    // Анимация появления буквы
                    this.game.add.tween(letterContainer.scale).to({x: 1, y: 1}, 700, Phaser.Easing.Bounce.Out, true);
                }
            }
        }

        /**
         * Change letter state
         *
         * @param {obect} letter - obect contain leter
         * @param {letter} state - letter state ( normal, selected, active)
         */
        changeLetterState(letter: any, state: string) {
            let tw: any;

            switch(state) {
                case 'select':
                    // Меняем цвет и фон буквы
                    letter.parent.loadTexture('field_active');
                    letter.fill = '#ffffff';

                    // Заносим букву в список выделенных и запускаем анимацию нажатия
                    // tw = this.game.add.tween(letter.parent.scale).from({x: 0.2, y: 0.2}, 400, Phaser.Easing.Bounce.Out, true);

                    this.word += letter.text;
                    break;

                    default:
                        break;
            }

        }

        /**
         * Устанавливаем флаг нажатия когда пользователь кликнул по тайлу
         *
         * @public
         * @param {obect} - contain letter obect
         */
        selectLetter(letter: any) {
            this.hoverSound.play();

            // Заносим букву в выбранные
            this.userSelect.push(letter.parent);

            // Меняем состояние буквы
            this.changeLetterState(letter, 'select');
        }

        /** Проверяем значение тайла когда курсор над ним */
        hoverLetter(letter: any) {
            this.hoverSound.play();

            // Проверяем нажата ли кнопка мышки и есть ли ходы у игрока
            this.game.input.activePointer.isDown && this.game.userMoves > 0 && (() => {
                // Заносим букву в выбранные
                this.userSelect.push(letter.parent);

                // Меняем состояние буквы
                this.changeLetterState(letter, 'select');
            })();
        }

        /** Снимаем флаг нажатия когда пользователь отпустил клавишу */
        removeSelectedLetter(letter:any) {
            let el: any,
                tw: any,
                tile: any;


            if(this.userSelect.length > 1) {
                this.debugDrawletterGrid();

                while (!!this.userSelect.length) {
                    tile = this.userSelect.shift();

                    ((sprite: any) => {
                        let position = sprite.gridPosition;

                        this.letterGrid[position.y][position.x] = null;

/*
                        tw = this.game.add.tween(sprite.scale);
                        tw.to({x: 0, y: 0}, 500, Phaser.Easing.Bounce.Out);
                        tw.start();

                        tw.onComplete.add(() => {*/
                            sprite.destroy();
                        /*});*/
                    })(tile);

                    this.game.userScore = this.game.userScore + 20;
                }

                this.userScore.text    = this.game.userScore;
                this.movesCounter.text = --this.game.userMoves;

                this.resetTile();
                this.debugDrawletterGrid();
            }

        }

        debugDrawletterGrid() {
            var str: string = '',
                letterObj: any = '';

            for (var i = 0; i < BOARD_COLS ; i++) {
                str = '';
                for (var j = 0; j < BOARD_ROWS; j++) {
                    letterObj = this.letterGrid[j][i];
                    if(!_.isNull(letterObj)) {
                        if(letterObj.children.length && ('_text' in letterObj.children[0])) {
                            str += '| ' + letterObj.children[0]._text + ' ';
                            console.info(letterObj);
                        } else {
                            str += '| letter not exist';
                            console.info(letterObj);
                        }
                    } else {
                        str += '| ' + letterObj + ' ';
                    }
                }
                console.info(str);
            }
            console.info('-----------------------------');
        }
    }

    return Board;
});

Game.ts:

/// <reference path="def/p2.d.ts" />
/// <reference path="def/pixi.d.ts" />
/// <reference path="def/phaser.d.ts" />
/// <reference path="def/require.d.ts" />

/// <reference path="class/board.ts"/>


define(['phaser', 'class/board'], function(Phaser, Board) {

    /** Start dictionary */
    var dictionary = [
            "нож",
            "стул",
            "стол",
            "карандаш",
            "паж"
        ],
        guessing = false;

    /**
     * Class representing game Wisdom of Atlantis
     */
    class WisdomOfAtlantis {
        game: Phaser.Game;
        self: any;
        guessing: boolean = false;
        board: any;

        constructor() {
            this.game = new Phaser.Game(GAME_ROOM_WIDTH, GAME_ROOM_HEIGHT, Phaser.AUTO, 'game-container', { preload: this.preload, create: this.create, update: this.update });
            this.game.userScore = 0;
            this.game.userMoves = 15;
        }

        /** Load game assets */
        preload() {

            // Фон для игровой комнаты
            this.game.load.image('game_room', '../img/bg/game_room.jpg');

            // Фон игровых плиток (normal, hover, active)
            this.game.load.image('field', '../img/bg/field_normal.png');
            this.game.load.image('field_active', '../img/bg/field_active.png');

            // Кнопка выхода
            this.game.load.spritesheet('btn_exit', '../img/controls/buttons/exit.png', 76, 72, 3, 0, 10);

            // Кнопка подсказки
            this.game.load.spritesheet('btn_help', '../img/controls/buttons/help.png', 76, 72, 3, 0, 10);

            // Кнопка вкл/вкл звук
            this.game.load.spritesheet('btn_sound', '../img/controls/buttons/sound.png', 46, 42, 3, 0, 10);

            // Кнопка вкл/вкл музыку
            this.game.load.spritesheet('btn_music', '../img/controls/buttons/music.png', 46, 42, 3, 0, 10);

            // Индикатор монет
            this.game.load.spritesheet('btn_coin', '../img/controls/buttons/coin.png', 166, 84, 3);

            // Загружаем звуки и музыку
            this.game.load.audio('level_theme', '../audio/theme/level_v1.mp3');
            this.game.load.audio('tile_select', '../audio/effect/click.ogg');
            this.game.load.audio('tile_move', '../audio/effect/move.ogg');
            this.game.load.audio('add_score', '../audio/effect/addscore.ogg');
        }

        /** Set game settings */
        create() {
            // Фон игровой комнаты
            this.game.add.image(0, 0, 'game_room');

            // Обрабатываем нажатие мыши
            this.game.input.onDown.add(() => {
                this.guessing = true;
            });

            this.game.input.onUp.add(() => {
                this.guessing = false;
            });

            // Создаем доску
            this.board = new Board(this.game);

            // Счетчик ходов
            this.board.movesCounter = this.game.add.text(55, 45, this.game.userMoves, {font: "bold 68px Arial", fill: "#EEFF9C", boundsAlignH: "center", boundsAlignV: "middle"});
            this.board.userScore = this.game.add.text((this.game.width / 2) + 50, this.game.height - 40, this.game.userScore, {font: "bold 38px Arial", fill: "#EEFF9C", boundsAlignH: "center", boundsAlignV: "middle"});

            this.game.add.text(63, 30, 'Xоды', {
                font: "bold 24px Arial",
                fill: "#EEFF9C",
                boundsAlignH: "center",
                boundsAlignV: "middle"
            });

            // Заполняем доску буквами
            this.board.fill();
        }

        /** Check game state and processing of a condition of game objects */
        update() {
            if (!this.guessing) {
                this.board.removeSelectedLetter();
            }
        }
    }


    return WisdomOfAtlantis;
});

 

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...