tetris 2*2

来源:互联网 发布:starbound mac 编辑:程序博客网 时间:2024/06/04 18:04

game.cpp

#include "Game.h"
#include "BaseItem.h"
#include "ItemFactroy.h"
#include "ScoreCalculater.h"
CGame::CGame(void)
{
m_IsRunning = true;
m_CurrentState = BEGIN;
memset(m_Items,0,sizeof(m_Items));
m_lastTime = 0;
m_CurrentFallItem = 0;
m_Calculater = new CScoreCalculater(this);
}




CGame::~CGame(void)
{
delete m_Calculater;
m_Calculater = 0;
}


void CGame::DrawAll(irr::video::IVideoDriver* driver)
{
for(irr::u32 i = 0; i < s_ItemColunm ; i ++)
{
for(irr::u32 j = 0; j < s_ItemRowCount ; j ++)
{
switch(m_Items[i][j])
{
case NOTHING:
break;
case WHITE:
{
irr::video::ITexture* images = driver->getTexture("white.png");
driver->draw2DImage(images, irr::core::position2d<irr::s32>(i*s_ImageWidth,j*s_ImageHeight),
irr::core::rect<irr::s32>(0,0,s_ImageWidth,s_ImageHeight));
}
break;
case BLACK:
{
irr::video::ITexture* images = driver->getTexture("black.png");
driver->draw2DImage(images, irr::core::position2d<irr::s32>(i*s_ImageWidth,j*s_ImageHeight),
irr::core::rect<irr::s32>(0,0,s_ImageWidth,s_ImageHeight));
}
break;
case RED:
{
irr::video::ITexture* images = driver->getTexture("red.png");
driver->draw2DImage(images, irr::core::position2d<irr::s32>(i*s_ImageWidth,j*s_ImageHeight),
irr::core::rect<irr::s32>(0,0,s_ImageWidth,s_ImageHeight));
}
break;
case YELLOW:
{
irr::video::ITexture* images = driver->getTexture("yellow.png");
driver->draw2DImage(images, irr::core::position2d<irr::s32>(i*s_ImageWidth,j*s_ImageHeight),
irr::core::rect<irr::s32>(0,0,s_ImageWidth,s_ImageHeight));
}
break;
case GREEN:
{
irr::video::ITexture* images = driver->getTexture("green.png");
driver->draw2DImage(images, irr::core::position2d<irr::s32>(i*s_ImageWidth,j*s_ImageHeight),
irr::core::rect<irr::s32>(0,0,s_ImageWidth,s_ImageHeight));
}
break;
default:
break;
}
}
}
}


void CGame::Update(irr::u32 time)
{
DealKeyEvent();
switch(m_CurrentState)
{
case BEGIN:
m_CurrentState = CONSTRUCT;
m_lastTime = time;
break;
case CONSTRUCT:
if(!ConstructNewItem())
m_CurrentState = END;
else
m_CurrentState = FALLING;
break;
case FALLING:
if(time - m_lastTime > 1000)
{
if(!m_CurrentFallItem->Fall())
m_CurrentState = FALLED;
m_lastTime = time;
}
break;
case SIGLEFALLING:
if(time - m_lastTime > 100)
{
if(!SigleFall())
{
irr::u32 score = m_Calculater->Calculate();
if(-1 == score)
m_CurrentState = CONSTRUCT;
}
m_lastTime = time;
}
break;
case FALLED:
m_CurrentState = SIGLEFALLING;
break;
case END:
m_IsRunning = false;
break;
default:
break;
}
}


bool CGame::OnEvent(const irr::SEvent& event)
{
if(event.EventType == irr::EET_KEY_INPUT_EVENT)
{
this->m_EventQuque.push(event);
return true;
}
return false;
}


void CGame::DealKeyEvent()
{
while(!m_EventQuque.empty())
{
const irr::SEvent& event = m_EventQuque.front();
if(event.KeyInput.PressedDown && FALLING == m_CurrentState)
{
switch(event.KeyInput.Key)
{
case irr::KEY_DOWN:
m_CurrentFallItem->Fall();
break;
case irr::KEY_UP:
m_CurrentFallItem->Change();
break;
case irr::KEY_LEFT:
m_CurrentFallItem->Left();
break;
case irr::KEY_RIGHT:
m_CurrentFallItem->Right();
break;
default:
break;
}
}
m_EventQuque.pop();
}
}


bool CGame::SigleFall()
{
bool re = false;
for(irr::s32 i = 0 ; i < s_ItemColunm ; i ++)
{
for(irr::s32 j = s_ItemRowCount - 1; j > 0 ; j --)
{
if(NOTHING == m_Items[i][j] && NOTHING!=m_Items[i][j-1])
{
re = true;
m_Items[i][j] = m_Items[i][j-1];
m_Items[i][j-1] = NOTHING;
}
}
}
return re;
}


irr::u32 Goal()
{
return 0;
}
bool CGame::ConstructNewItem()
{
m_CurrentFallItem = CItemFactroy::Instance().CreateItem(this);
return m_CurrentFallItem !=0;
}




#include "Item_2X1.h"
#include "Game.h"


CItem_2X1::CItem_2X1(CGame* game):CBaseItem(game)
{
m_position.X = 3;
m_position.Y = 0;
m_Self[0][0] = Int2ITEM((game->m_lastTime % 5) + 1);
m_Self[1][0] = Int2ITEM(((game->m_lastTime+1) % 5) + 1);
m_Self[0][1] = NOTHING;
m_Self[1][1] = NOTHING;
m_CurrentState = 0;
}




CItem_2X1::~CItem_2X1(void)
{
}


bool CItem_2X1::Fall()
{
return SetPosition(irr::core::position2d<irr::s32>(m_position.X,m_position.Y + 1));
}
void CItem_2X1::Change()
{
ClearSelf();
irr::u32 old = m_CurrentState;
ITEM oldItem[2][2];
memcpy(oldItem,m_Self,sizeof(oldItem));
switch(m_CurrentState)
{
case 0:
m_CurrentState = 1;
m_Self[0][1] = m_Self[0][0];
m_Self[0][0] = m_Self[1][0];
m_Self[1][0] = NOTHING;
break;
case 1:
m_CurrentState = 2;
m_Self[1][1] = m_Self[0][1];
m_Self[0][1] = m_Self[0][0];
m_Self[0][0] = NOTHING;
break;
case 2:
m_CurrentState = 3;
m_Self[1][0] = m_Self[1][1];
m_Self[1][1] = m_Self[0][1];
m_Self[0][1] = NOTHING;
break;
case 3:
m_CurrentState = 0;
m_Self[0][0] = m_Self[1][0];
m_Self[1][0] = m_Self[1][1];
m_Self[1][1] = NOTHING;
break;
default:
break;
}
if(!Initialize())
{
m_CurrentState = old;
memcpy(m_Self,oldItem,sizeof(oldItem));
Initialize();
}
}
void CItem_2X1::Left()
{
SetPosition(irr::core::position2d<irr::s32>(m_position.X - 1,m_position.Y));
}
void CItem_2X1::Right()
{
SetPosition(irr::core::position2d<irr::s32>(m_position.X + 1,m_position.Y));
}
bool CItem_2X1::Initialize()
{
for(irr::u32 i = 0; i < 2 ;i ++)
{
for(irr::u32 j = 0; j < 2 ;j ++)
{
if(m_Self[i][j] != NOTHING)
{
if(i + m_position.X < 0 || i + m_position.X  > m_Game->s_ItemColunm -1 || j + m_position.Y < 0 || j + m_position.Y > m_Game->s_ItemRowCount - 1)
return false;
if(m_Game->m_Items[i + m_position.X][j + m_position.Y] != NOTHING)
return false;
}
}
}
for(irr::u32 i = 0; i < 2 ;i ++)
{
for(irr::u32 j = 0; j < 2 ;j ++)
{
if(i + m_position.X < 0 || i + m_position.X  > m_Game->s_ItemColunm -1 || j + m_position.Y < 0 || j + m_position.Y > m_Game->s_ItemRowCount - 1)
continue;
if(m_Self[i][j] != NOTHING)
m_Game->m_Items[i + m_position.X][j + m_position.Y] = m_Self[i][j];
}
}
return true;
}


void CItem_2X1::ClearSelf()
{
for(irr::u32 i = 0; i < 2 ;i ++)
{
for(irr::u32 j = 0; j < 2 ;j ++)
{
if(m_Self[i][j] != NOTHING)
m_Game->m_Items[i + m_position.X][j + m_position.Y] = NOTHING;
}
}
}


bool CItem_2X1::SetPosition(const irr::core::position2d<irr::s32>& position)
{
ClearSelf();
irr::core::position2d<irr::s32> old = m_position;
m_position = position;
if(Initialize())
return true;
else
{
m_position = old;
Initialize();
}
return false;
}


#include "ScoreCalculater.h"
#include "Game.h"


CScoreCalculater::CScoreCalculater(CGame* game):
m_Game(game)
{
m_Comboed = new bool[game->s_ItemColunm * game->s_ItemRowCount];
memset(m_Comboed,0,game->s_ItemColunm * game->s_ItemRowCount);
}




CScoreCalculater::~CScoreCalculater(void)
{
delete[] m_Comboed;
m_Comboed = 0;
}


irr::u32 CScoreCalculater::Calculate()
{
irr::u32 Score = 0;
memset(m_Comboed,0,m_Game->s_ItemColunm * m_Game->s_ItemRowCount);
for(irr::u32 i = 0 ; i < m_Game->s_ItemColunm ; i ++)
{
for(irr::u32 j = 0 ; j < m_Game->s_ItemRowCount ; j ++)
{
if(m_Game->m_Items[i][j] != NOTHING &&!m_Comboed[i * m_Game->s_ItemRowCount + j])
Score += Calculate(i ,j );
}
}


for(irr::u32 i = 0 ; i < m_Game->s_ItemColunm ; i ++)
{
for(irr::u32 j = 0 ; j < m_Game->s_ItemRowCount ; j ++)
{
if(m_Comboed[i * m_Game->s_ItemRowCount + j])
m_Game->m_Items[i][j] = NOTHING;
}
}
return Score > 0 ? Score : -1;
}


irr::u32 CScoreCalculater::Calculate(irr::u32 colunm ,irr::u32 row)
{
irr::u32 ComboNum= 1;
irr::u32 Score = 0;
for( irr::s32 i = colunm - 1 ; i >= 0;i --)  //horizontal top
{
if(m_Game->m_Items[colunm][row] != m_Game->m_Items[i][row])
break;
else
ComboNum++;
}
for( irr::s32 i = colunm + 1 ; i < m_Game->s_ItemColunm ; i ++) //horizontal down
{
if(m_Game->m_Items[colunm][row] != m_Game->m_Items[i][row])
break;
else
ComboNum++;
}
if(ComboNum >= s_ComboLeast)
{
Score += ComboNum * s_ComboLeast;
for( irr::s32 i = colunm - 1 ; i >= 0;i --)
{
if(m_Game->m_Items[colunm][row] != m_Game->m_Items[i][row])
break;
else
this->m_Comboed[i * m_Game->s_ItemRowCount + row] = true;
}
for( irr::s32 i = colunm ; i < m_Game->s_ItemColunm ; i ++)
{
if(m_Game->m_Items[colunm][row] != m_Game->m_Items[i][row])
break;
else
this->m_Comboed[i * m_Game->s_ItemRowCount + row] = true;
}
}


ComboNum = 1;
for( irr::s32 i = row - 1 ; i >= 0;i --)
{
if(m_Game->m_Items[colunm][row] != m_Game->m_Items[colunm][i])
break;
else
ComboNum++;
}
for( irr::s32 i = row + 1 ; i < m_Game->s_ItemRowCount ; i ++)
{
if(m_Game->m_Items[colunm][row] != m_Game->m_Items[colunm][i])
break;
else
ComboNum++;
}
if(ComboNum >= s_ComboLeast)
{
Score += ComboNum * s_ComboLeast;
for( irr::s32 i = row - 1 ; i >= 0;i --)
{
if(m_Game->m_Items[colunm][row] != m_Game->m_Items[colunm][i])
break;
else
this->m_Comboed[colunm * m_Game->s_ItemRowCount + i] = true;
}
for( irr::s32 i = row ; i < m_Game->s_ItemRowCount ; i ++)
{
if(m_Game->m_Items[colunm][row] != m_Game->m_Items[colunm][i])
break;
else
this->m_Comboed[colunm * m_Game->s_ItemRowCount + i] = true;
}
}
return Score;
}