строим двухмерное счастье ПАЛАГИН АНТОН Спецвыпуск: Хакер, номер #064, стр. 064-076-4 if(!m_isNewGame && !(m_gameState & GAME_OVER) ) return; m_gameView.SetGraphics( g ); //Если есть падающая фигура if( m_current ) { //Если наступил момент изменения кадра и игра не на паузе if( elapsed > m_gameLogic.GetSpeed() && !m_isPaused ) { //Необходимо или оставить блок на поле или опустить его на ячейку вниз if( m_playfield.CheckBlock(*m_current, m_currentX, m_currentY+1) ) { //Опускаем блок на ячейку вниз m_playfield.InsertBlock(*m_current, m_currentX, m_currentY); //Проверяем, не заполнился ли наш стакан if( IsGameOver() ) { GameOver(); secStart = secEnd; return; } m_current = 0; //Проверяем, заполнена ли полностью линия(и) стакана m_playfield.GetFullRows(bottom, count); if(!count) { //Если нет ни одной заполненной линии стакана, то //Опускаем в стакан новую фигуру ThrowNextBlock(); //Проигрываем специфический звук gSexyAppBase->PlaySample(SOUND_BLOCK_DOWN); } else { //Устанавливаем состояние для последующей анимации процесса //удаления заполненной линии стакана m_animState = CLEAN_ROWS; //Проигрываем специфический звук gSexyAppBase->PlaySample(SOUND_FULL_LINE); } } else { ++m_currentY; } secStart = secEnd; elapsed = 0; } } //Если надо анимировать только падение фигуры if(m_animState == NORMAL) { //То анимируем падающую фигуру DrawNormal(elapsed / m_gameLogic.GetSpeed()); } //Надо показывать «спец»Эффекты else { //Если игра не на паузе и надо удалить заполненные линии стакана if( elapsed > LINE_ANIM_SPEED && !m_isPaused ) { //Обновляем стакан m_playfield.Update(); secStart = secEnd; elapsed = 0; m_animState = NORMAL; //Выбрасываем новую фигуру ThrowNextBlock(); //Обновляем набранные игроком очки m_gameLogic.UpdateScore(count); bottom=count=0; return; } //Рисуем спецэффекты (удаление линии) DrawSfx(elapsed/LINE_ANIM_SPEED, bottom, count); } Вначале нужно опустить фигуру тетриса на ячейку вниз, затем — проверить, не закончилась ли на этом игра. Если игра не закончилась, то стоит проверить, есть ли заполненные линии. Если после того, как фигура опустилась, появились заполненные линии, то проигрывается звук удаления линии и отображается анимация удаления этих линий. Если заполненных линий нет, то проигрывается глухой звук, который соответствует простому опусканию фигуры. Далее проверяем, есть ли место в стакане (еще ниже), куда бы могла опуститься фигура. Если некуда — генерируется новая фигура. Теперь должно быть обновлено игровое поле (должны быть удалены линии в стакане) и очки, набранные игроком. Процесс обновления поля см. на листинге «Обновление стакана». Листинг «Обновление стакана» void Playfield::Update() { SquareCoord bottom, count; //Узнаем, есть ли заполненные линии в стакане GetFullRows(bottom, count); if(count) { //Удаляем заполненные линии RemoveRows(bottom, count); } } void Playfield::GetFullRows(SquareCoord & bottom, SquareCoord & count) const { count = 0; bottom = -1; //Итерируемся по всем линиям в указанном диапазоне for(int i = m_rows.size()-1; i != 0 && !m_rows[i].IsEmpty(); --i) { //Если линия заполнена if(m_rows[i].IsFull()) { //То устанавливаем флаг наличия заполненных линий if(count == 0) |