📄 qmainwidget.cpp
字号:
/*********************************************************************** * * * linux版仿联众俄罗斯方块 v1.0 * 该软件在GPL(GNU通用公共许可证)下发布 * * Copyright (C) <codeky@126.com> * * This source code is licensed under the GNU General Public License * ************************************************************************/#include <qapplication.h>#include <qtimer.h>#include <qpainter.h>#include <qpixmap.h>#include <qdrawutil.h>#include "config.h"#include "qmainwidget.h"#include "qgamewidget.h"#include "qgamenext.h"#include "qgamethread.h"#include "qgamebutton.h"#include "qmybuttongroup.h"#include "ruledlg.h"extern char curPath[];QMainWidget::QMainWidget( QWidget *parent, const char *name ) : QWidget( parent, name ){ setMinimumSize( DEF_WIN_WIDTH, DEF_WIN_HEIGHT ); // 最小尺寸 gamer1 = new QGameWidget( this, "gamewidget1"); gamer2 = new QGameWidget( this, "gamewidget2"); if(!gamer1 || !gamer2) exit(-1); // 必须的 gameNext1 = new QGameNext(this); connect( gamer1, SIGNAL( PaintNextSignal(QPixmap*) ), gameNext1, SLOT( drawNextBlock(QPixmap*) ) ); gameNext2 = new QGameNext(this); connect( gamer2, SIGNAL( PaintNextSignal(QPixmap*) ), gameNext2, SLOT( drawNextBlock(QPixmap*) ) ); connect( gamer1, SIGNAL( AddOtherLine(_bS8) ), gamer2, SLOT( gameAddLine(_bS8) ) ); connect( gamer2, SIGNAL( AddOtherLine(_bS8) ), gamer1, SLOT( gameAddLine(_bS8) ) ); connect( gamer1, SIGNAL( NoticeOtherWinGame() ), gamer2, SLOT( iWinTheGame() ) ); connect( gamer2, SIGNAL( NoticeOtherWinGame() ), gamer1, SLOT( iWinTheGame() ) ); connect( this, SIGNAL( game1KeyPressed(int) ), gamer1, SLOT( handleKeyEvent(int) ) ); connect( this, SIGNAL( game2KeyPressed(int) ), gamer2, SLOT( handleKeyEvent(int) ) ); initDefaultKey(); initButtons(); initDefaultWH(); setComponetsRect(); pDriveTimer = new QTimer( this, "move player" ); if(!pDriveTimer) exit(-1);// 必须的 timerSpeed = DEF_TIMER_SPEED; connect( pDriveTimer, SIGNAL( timeout() ), this, SLOT( drvieUsrBlock()) ); pGameThread = new QGameThread(gamer1,1); if(pGameThread) pGameThread->start(); // 线程开始}QMainWidget::~QMainWidget(){ if (pGameThread){ pGameThread->setRunable(0); pGameThread->exit(); // delete pGameThread; }}void QMainWidget::initButtons(){ QWidget *pbutton=NULL; pButtonGroup = new QmyButtonGroup(this,"ButtonGroup"); if(pButtonGroup){ sprintf(tmpName,"%simages/background.bmp",curPath); pButtonGroup->setBackground(tmpName); // 背景 sprintf(tmpName,"%simages/button/begin.bmp",curPath); pbutton=pButtonGroup->addButtons(tmpName,"begin"); connect( pbutton, SIGNAL(click(void)), this, SLOT( beginGame() ) ); sprintf(tmpName,"%simages/button/pause.bmp",curPath); pauseButton=(QGameButton*)pButtonGroup->addButtons(tmpName,"pause"); connect( pauseButton, SIGNAL(click(void)), this, SLOT( pauseGame(void) ) ); sprintf(tmpName,"%simages/button/rule.bmp",curPath); ruleButton=(QGameButton*)pButtonGroup->addButtons(tmpName,"rule"); connect( ruleButton, SIGNAL(click(void)), this, SLOT( setRule(void) ) ); } pAdvanceGroup = new QmyButtonGroup(this,"AdvanceGroup"); if(pAdvanceGroup){ sprintf(tmpName,"%simages/topban_back.bmp",curPath); pAdvanceGroup->setBackground(tmpName); sprintf(tmpName,"%simages/button/set.bmp",curPath); pAdvanceGroup->addButtons(tmpName,"set"); sprintf(tmpName,"%simages/button/help.bmp",curPath); pAdvanceGroup->addButtons(tmpName,"help"); sprintf(tmpName,"%simages/button/quit.bmp",curPath); pAdvanceGroup->addButtons(tmpName,"quit"); pAdvanceGroup->setGroupAttr(QmyButtonGroup::horizontal,0); }}// 设置默认长宽void QMainWidget::initDefaultWH(void){ topBanHeight = DEF_TOPBAN_HEIGHT; barHeight = DEF_BAR_HEIGHT; // 3个相同 nextHeight = DEF_NEXT_HEIGHT; gameFrameHeight = DEF_GAMEFRAME_HEIGHT; gameHeight = DEF_GAME_HEIGHT; scoreHeight = DEF_SCORE_HEIGHT; winHeight = DEF_WIN_HEIGHT; topBanWidth = DEF_TOPBAN_WIDTH; barWidth = DEF_BAR_WIDTH; // 4个相同 nextWidth = DEF_NEXT_WIDTH; gameFrameWidth = DEF_GAMEFRAME_WIDTH; gameWidth = DEF_GAME_WIDTH; scoreWidth = DEF_SCORE_WIDTH; winWidth = DEF_WIN_WIDTH;}void QMainWidget::initDefaultKey(){ P1TurnKey = Qt::Key_K; // k P1LeftKey = Qt::Key_J; // j P1RightKey = Qt::Key_L; // l P1DownKey = Qt::Key_Space; // P1SDownKey = Qt::Key_Comma; // , P2TurnKey = Qt::Key_Up; P2LeftKey = Qt::Key_Left; P2RightKey = Qt::Key_Right; P2DownKey = Qt::Key_Down; P2SDownKey = Qt::Key_End;}void QMainWidget::keyPressEvent ( QKeyEvent * e ){ int k=e->key(); if(k==P2TurnKey){ emit game2KeyPressed(eMoveTurn); }else if(k==P2LeftKey){ emit game2KeyPressed(eMoveLeft); }else if(k==P2RightKey){ emit game2KeyPressed(eMoveRight); }else if(k==P2DownKey){ emit game2KeyPressed(eMoveDown); }else if(k==P2SDownKey){ emit game2KeyPressed(eMoveSDown); }else if(k==Qt::Key_F2){ beginGame(); }else if(k==Qt::Key_F3){ pauseGame(); }else if(k==Qt::Key_F4){ setRule(); }else if(k==P1TurnKey){ // 让游戏自己作怎样的处理,不管是否是电脑 emit game1KeyPressed(eMoveTurn); }else if(k==P1LeftKey){ emit game1KeyPressed(eMoveLeft); }else if(k==P1RightKey){ emit game1KeyPressed(eMoveRight); }else if(k==P1DownKey){ emit game1KeyPressed(eMoveDown); }else if(k==P1SDownKey){ emit game1KeyPressed(eMoveSDown); }}// 按钮事件 -->void QMainWidget::beginGame(){ gamer1->startGame(); gamer2->startGame(); sprintf(tmpName,"%simages/button/pause.bmp",curPath); pauseButton->setBitmap(tmpName); pDriveTimer->start(timerSpeed);}void QMainWidget::pauseGame() // 有一点问题, 图片显示{ switch(gamer1->gameStatus() | gamer2->gameStatus()) { case eGameRun: // 先前状态:正在运行,现在被设置为暂定态 sprintf(tmpName,"%simages/button/continue.bmp",curPath); pDriveTimer->stop (); // 指针必有效 gamer1->setGamePause(true); // 指针必有效 gamer2->setGamePause(true); if(pauseButton) pauseButton->setBitmap(tmpName); break; case eGamePause: sprintf(tmpName,"%simages/button/pause.bmp",curPath); gamer1->setGamePause(false); gamer2->setGamePause(false); pDriveTimer->start(timerSpeed); if(pauseButton) pauseButton->setBitmap(tmpName); break; }}void QMainWidget::setRule(){ static int last_status=-1; QRuleDlg w(this,"ruledlg",true); w.setCurSatus(last_status); bool b = false; if( (gamer1->gameStatus() & gamer2->gameStatus() ) != eGamePause){ b = true; pauseGame(); } ruleButton->directReleaMouse(); // 需要无条件释放鼠标 int r=w.exec(); if(b) pauseGame(); switch(r){ case -1: // 没有做什么就ok了 break; case 0: // 取消了 break; case 1: gamer1->setPlayMode(QGameWidget::ePlaySinle); gamer2->setPlayMode(QGameWidget::ePlaySinle); gamer1->setComputerRun(false); last_status = 1; break; case 2: gamer1->setPlayMode(QGameWidget::ePalyVS); gamer2->setPlayMode(QGameWidget::ePalyVS); gamer1->setComputerRun(false); last_status = 2; break; case 3: gamer1->setPlayMode(QGameWidget::ePalyVS); gamer2->setPlayMode(QGameWidget::ePalyVS); gamer1->setComputerRun(true); last_status = 3; break; }}// <-- 钮事件void QMainWidget::drvieUsrBlock() // timer{ emit game1KeyPressed(eMoveSDown); emit game2KeyPressed(eMoveSDown);}// 和缩放有关的 -->void QMainWidget::setComponetsRect(){ // 重新计算可变分割条的大小 barWidth = (winWidth-gameWidth*2-gameFrameWidth*4-scoreWidth)/4; barHeight = (winHeight-topBanHeight-nextHeight-gameHeight-gameFrameHeight*2)/3; game1Rect.setRect(barWidth+gameFrameWidth, topBanHeight+barHeight+nextHeight+barHeight+gameFrameHeight, gameWidth,gameHeight); game2Rect.setRect(game1Rect.right()+gameFrameWidth*2+barWidth*2+scoreWidth, game1Rect.top(),gameWidth,gameHeight); next1Rect.setRect(game1Rect.left()+(gameWidth-nextWidth)/2, game1Rect.top()-gameFrameHeight-barHeight - nextHeight, nextWidth,nextHeight); next2Rect.setRect(game2Rect.left()+(gameWidth-nextWidth)/2, game2Rect.top()-gameFrameHeight-barHeight - nextHeight, nextWidth,nextHeight); scoreRect.setRect(game1Rect.right()+gameFrameWidth+barWidth, next1Rect.top()+next1Rect.height()/3, scoreWidth,scoreHeight); btGroupRect.setRect(scoreRect.left(),scoreRect.bottom()+5, scoreRect.width(),100); //让它窗体自动调整高度,只是给一个位置 adGroupRect.setRect(topBanWidth,0,winWidth-topBanWidth,topBanHeight);}void QMainWidget::resizeEvent ( QResizeEvent * we){ int cw = we->size().width(); int ch = we->size().height(); int ow = we->oldSize().width(); int oh = we->oldSize().height(); int th=0, tw =0; if( ( (cw!=ow)||(ch!=oh)) ){ // 分别按新高度和欣宽度计算 th = ch - topBanHeight -DEF_BAR_HEIGHT*3 - nextHeight - gameFrameHeight*2; tw = cw - (gameFrameWidth+DEF_BAR_WIDTH)*4 - scoreWidth; // 得到2倍值 if(th > tw){ // 按照宽度计算得到比实际高度小,只能按照宽度计算 th = tw; } // 否则按照宽度计算得到比实际高度大,只能按照高度计算 tw = th/2; } gameWidth = tw; gameHeight = th; winWidth = cw; winHeight = ch; setComponetsRect(); fixComponetsPos();}void QMainWidget::fixComponetsPos(void) // 重新布局{ gamer1->setGeometry(game1Rect); gamer2->setGeometry(game2Rect); // 会进行自动调整 gameWidth = gamer1->rect().width(); // 因此需要重新获得大小 gameHeight= gamer1->rect().height(); pAdvanceGroup->setGeometry(adGroupRect); setComponetsRect(); // 重新得到大小 pButtonGroup->setGeometry(btGroupRect); pAdvanceGroup->adjustButtons(); gameNext1->setGeometry(next1Rect.left()+next1Rect.width()*4/18+10, next1Rect.top()+next1Rect.height()*3/10+1, DEF_BLOCK_SIZE*4,DEF_BLOCK_SIZE*4); gameNext2->setGeometry(next2Rect.left()+next2Rect.width()*4/18+10, next2Rect.top()+next2Rect.height()*3/10+1, DEF_BLOCK_SIZE*4,DEF_BLOCK_SIZE*4);}// 绘图有关的 -->void QMainWidget::paintEvent( QPaintEvent * ){ QPixmap pix( rect().size() ); QPainter p( &pix ); painter_lock(); p.translate( rect().left(), rect().top() ); //设置坐标系 sprintf(tmpName,"%simages/background.bmp",curPath); p.drawTiledPixmap(rect(), QPixmap(tmpName)); drawGameFrame(&p, gamer1); drawGameFrame(&p, gamer2); drawOtherFrame(&p); p.end(); p.begin( this ); p.drawPixmap(0,0, pix ); painter_unlock();}void QMainWidget::drawOtherFrame( QPainter *p ){ sprintf(tmpName,"%simages/topban.bmp",curPath); p->drawPixmap(0,0,QPixmap(tmpName)); // title sprintf(tmpName,"%simages/next.bmp",curPath); p->drawPixmap(next1Rect.left(),next1Rect.top(), QPixmap(tmpName)); // next1 QBrush br(black); qDrawShadeRect(p,next1Rect.left()+next1Rect.width()/6, next1Rect.top()+next1Rect.height()*3/10, next1Rect.width()*5/9, next1Rect.height()*3/5, colorGroup(),true,1,0,&br); // 下一块 外框 p->drawPixmap(next2Rect.left(),next2Rect.top(), QPixmap(tmpName)); // next2 qDrawShadeRect(p,next2Rect.left()+next2Rect.width()/6, next2Rect.top()+next2Rect.height()*3/10, next2Rect.width()*5/9, next2Rect.height()*3/5, colorGroup(),true,1,0,&br); // 下一块 外框 sprintf(tmpName,"%simages/score.bmp",curPath); p->drawPixmap(scoreRect.left(),scoreRect.top(), QPixmap(tmpName)); // score}void QMainWidget::drawGameFrame( QPainter *p, QWidget* w ){ QGameWidget *pw = (QGameWidget*)w; sprintf(tmpName,"%simages/left_top.bmp",curPath); p->drawPixmap(QRect(pw->x()-gameFrameWidth , pw->y()-gameFrameHeight, gameFrameWidth, gameFrameHeight), QPixmap(tmpName)); // left_top sprintf(tmpName,"%simages/top.bmp",curPath); p->drawPixmap(QRect(pw->x(), pw->y()-gameFrameHeight, gameWidth , gameFrameHeight), QPixmap(tmpName)); // top sprintf(tmpName,"%simages/right_top.bmp",curPath); p->drawPixmap(QRect(pw->x()+gameWidth , pw->y()-gameFrameHeight, gameFrameWidth, gameFrameHeight), QPixmap(tmpName)); // right_top sprintf(tmpName,"%simages/bottom.bmp",curPath); p->drawPixmap(QRect(pw->x(), gamer1->y()+gameHeight, gameWidth , gameFrameHeight), QPixmap(tmpName)); // bottom sprintf(tmpName,"%simages/left.bmp",curPath); p->drawPixmap(QRect(pw->x()-gameFrameWidth, pw->y(), gameFrameWidth, gameHeight), QPixmap(tmpName)); // left sprintf(tmpName,"%simages/left_bottom.bmp",curPath); p->drawPixmap(QRect(pw->x()-gameFrameWidth , pw->y()+gameHeight, gameFrameWidth, gameFrameHeight), QPixmap(tmpName)); // left_bottom sprintf(tmpName,"%simages/right.bmp",curPath); p->drawPixmap(QRect(pw->x() +gameWidth, pw->y(), gameFrameWidth, gameHeight), QPixmap(tmpName)); // right sprintf(tmpName,"%simages/right_bottom.bmp",curPath); p->drawPixmap(QRect(pw->x() +gameWidth, pw->y()+gameHeight, gameFrameWidth, gameFrameHeight), QPixmap(tmpName)); // right_bottom}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -