Evgeniy

Members
  • Content Count

    2
  • Joined

  • Last visited

  1. Hi all, I build simple word match game: 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: and must be: It happends after letter moves. Bug step by step: Step 1: Step 2 (all good): Step 3 ( repeat step 2): Result step 3 ( FAIL ): 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; });
  2. Hi, all I try to write game similar on: During development I have faced a problem how to place text above sprite for each element in group. At the moment I see only one solution, create for each letter personal group, but i think that it not the best decision. I have checked all documentation but haven't found anything similar. Thanks for any help.