📄 kmahjongg.cpp
字号:
a=Game.shadowHeight(e,y,x-2); b=Game.shadowHeight(e,y-1,x-2); if (a != 0 || b != 0) l = (a>b) ? a : b; a=Game.shadowHeight(e,y-2,x); b=Game.shadowHeight(e,y-2,x-1); if (a != 0 || b != 0) t = (a>b) ? a : b; c = Game.shadowHeight(e, y-2, x-2);}// draw a triangular shadow from the top right to the bottom left.// one such shadow is a right hand edge of a shadow line.// if a second shadow botton left to top right is rendered over it// then the shadow becomes a box (ie in the middle of the run)void BoardWidget::shadowTopLeft(int depth, int sx, int sy, int rx, int ry, QPixmap *src, bool flag) { if (depth) { int shadowPixels= (depth+1) * theTiles.shadowSize(); int xOffset=theTiles.qWidth()-shadowPixels; for (int p=0; p<shadowPixels; p++) { bitBlt( &backBuffer, sx+xOffset, sy+p, src, rx+xOffset, ry+p, shadowPixels-p, 1, CopyROP ); } // Now aafter rendering the triangle, fill in the rest of // the quater width if (flag && ((theTiles.qWidth() - shadowPixels) > 0)) bitBlt( &backBuffer, sx, sy, src, rx, ry, theTiles.qWidth() - shadowPixels, shadowPixels, CopyROP ); }}// Second triangular shadow generator see abovevoid BoardWidget::shadowBotRight(int depth, int sx, int sy, int rx, int ry, QPixmap *src, bool flag) { if (depth) { int shadowPixels= (depth+1) * theTiles.shadowSize(); int xOffset=theTiles.qWidth(); for (int p=0; p<shadowPixels; p++) { bitBlt( &backBuffer, sx+xOffset-p, /* step to shadow right start */ sy+p, /* down for each line */ src, rx+xOffset-p, /* step to shadow right start */ ry+p, p, /* increace width each line down */ 1, CopyROP ); } if (flag && ((theTiles.qHeight() - shadowPixels) >0)) bitBlt( &backBuffer, sx+xOffset-shadowPixels, sy+shadowPixels, src, rx+xOffset-shadowPixels, ry+shadowPixels, shadowPixels, theTiles.qHeight()-shadowPixels, CopyROP ); }}void BoardWidget::shadowArea(int z, int y, int x, int sx, int sy,int rx, int ry, QPixmap *src){ // quick check to see if we are obscured if (z < BoardLayout::depth-1) { if ((x >= 0) && (y<BoardLayout::height)) { if (Game.Mask[z+1][y][x] && Game.Board[z+1][y][x]) { return; } } } // offset to pass tile depth indicator sx+=theTiles.shadowSize(); rx+=theTiles.shadowSize(); // We shadow the top right hand edge of the tile with a // triangular border. If the top shadow covers it all // well and good, otherwise if its smaller, part of the // triangle will show through. shadowTopLeft(Game.shadowHeight(z+1, y-1, x), sx, sy, rx,ry,src, true); shadowBotRight(Game.shadowHeight(z+1, y, x+1), sx, sy, rx, ry, src, true); shadowTopLeft(Game.shadowHeight(z+1, y-1, x+1), sx, sy, rx,ry,src, false); shadowBotRight(Game.shadowHeight(z+1, y-1, x+1), sx, sy, rx, ry, src, false); return;}// ---------------------------------------------------------void BoardWidget::paintEvent( QPaintEvent* pa ){ QPixmap *back; int xx = pa->rect().left(); int xheight = pa->rect().height(); int xwidth = pa->rect().width(); if (gamePaused) { // If the game is paused, then blank out the board. // We tolerate no cheats around here folks.. bitBlt( this, xx, pa->rect().top(), theBackground.getBackground(), xx, pa->rect().top(), xwidth, xheight, CopyROP ); return; } // if the repaint is because of a window redraw after a move // or a menu roll up, then just blit in the last rendered image if (!updateBackBuffer) { bitBlt(this, xx,pa->rect().top(), &backBuffer, xx, pa->rect().top(), xwidth, xheight, CopyROP); return; } // update the complete drawArea back = theBackground.getBackground(); backBuffer.resize(back->width(), back->height()); // erase out with the background bitBlt( &backBuffer, xx, pa->rect().top(), theBackground.getBackground(), xx,pa->rect().top(), xwidth, xheight, CopyROP ); // initial offset on the screen of tile 0,0 int xOffset = theTiles.width()/2; int yOffset = theTiles.height()/2; //short tile = 0; // shadow the background first if (preferences.showShadows()) { for (int by=0; by <BoardLayout::height+1; by++) for (int bx=-1; bx < BoardLayout::width+1; bx++) shadowArea(-1, by, bx, bx*theTiles.qWidth()+xOffset-theTiles.shadowSize(), by*theTiles.qHeight()+yOffset+theTiles.shadowSize(), bx*theTiles.qWidth()+xOffset-theTiles.shadowSize(), by*theTiles.qHeight()+yOffset+theTiles.shadowSize(), theBackground.getShadowBackground()); } // we iterate over the depth stacking order. Each sucessive level is // drawn one indent up and to the right. The indent is the width // of the 3d relief on the tile left (tile shadow width) for (int z=0; z<BoardLayout::depth; z++) { // we draw down the board so the tile below over rights our border for (int y = 0; y < BoardLayout::height; y++) { // drawing right to left to prevent border overwrite for (int x=BoardLayout::width-1; x>=0; x--) { int sx = x*(theTiles.qWidth() )+xOffset; int sy = y*(theTiles.qHeight() )+yOffset; // skip if no tile to display if (!Game.tilePresent(z,y,x)) continue; QPixmap *t; QPixmap *s; if (Game.hilighted[z][y][x]) { t= theTiles.selectedPixmaps( Game.Board[z][y][x]-TILE_OFFSET); s= theTiles.selectedShadowPixmaps( Game.Board[z][y][x]-TILE_OFFSET); } else { t= theTiles.unselectedPixmaps( Game.Board[z][y][x]-TILE_OFFSET); s= theTiles.unselectedShadowPixmaps( Game.Board[z][y][x]-TILE_OFFSET); } // Only one compilcation. Since we render top to bottom , left // to right situations arise where...: // there exists a tile one q height above and to the left // in this situation we would draw our top left border over it // we simply split the tile draw so the top half is drawn // minus border if (x > 1 && y > 0 && Game.tilePresent(z, y-1, x-2)){ bitBlt( &backBuffer, sx+theTiles.shadowSize(), sy, t, theTiles.shadowSize() ,0, t->width()-theTiles.shadowSize(), t->height()/2, CopyROP ); bitBlt( &backBuffer, sx, sy+t->height()/2, t, 0,t->height()/2,t->width(),t->height()/2,CopyROP); } else { bitBlt( &backBuffer, sx, sy, t, 0,0, t->width(), t->height(), CopyROP ); } if (preferences.showShadows() && z<BoardLayout::depth - 1) { for (int xp = 0; xp <= 1; xp++) { for (int yp=0; yp <= 1; yp++) { shadowArea(z, y+yp, x+xp, sx+(xp*theTiles.qWidth()), sy+(yp*theTiles.qHeight()), xp*theTiles.qWidth(), yp*theTiles.qHeight(), s); } } } } } xOffset +=theTiles.shadowSize(); yOffset -=theTiles.shadowSize(); } // Now we add the list of cancelled tiles // we start blitting as usuall right to left, top to bottom, first // we calculate the start pos of the first tile, allowing space for // the upwards at rightwards creep when stacking in 3d unsigned short xPos = backBuffer.width()-(3*theTiles.shadowSize())-theTiles.width(); unsigned short yPos = (3*theTiles.shadowSize()); for (int pos=0; pos < 9; pos++) { int last = 0; int tile=0; // dragon? if (pos >= 0 && pos < 3) { last = removedDragon[pos]; tile = TILE_DRAGON+pos; } else { //Wind? if (pos >= 3 && pos < 7) { last = removedWind[pos-3]; tile = TILE_WIND+pos-3; } else { if (pos == 7) { for (int t=0; t<4;t++) { if (removedFlower[t]) { last++; tile=TILE_FLOWER+t; } } } else { for (int t=0; t<4;t++) { if (removedSeason[t]) { last++; tile=TILE_SEASON+t; } } } } } stackTiles(tile, last, xPos, yPos); stackTiles(TILE_ROD+pos, removedRod[pos], xPos - (1*(theTiles.width() - theTiles.shadowSize())) , yPos); stackTiles(TILE_BAMBOO+pos, removedBamboo[pos], xPos - (2*(theTiles.width() - theTiles.shadowSize())) , yPos); stackTiles(TILE_CHARACTER+pos, removedCharacter[pos], xPos - (3*(theTiles.width() - theTiles.shadowSize())) , yPos); yPos += theTiles.height()-theTiles.shadowSize(); } updateBackBuffer=false; bitBlt(this, xx,pa->rect().top(), &backBuffer, xx, pa->rect().top(), xwidth, xheight, CopyROP);}void BoardWidget::stackTiles(unsigned char t, unsigned short h, unsigned short x,unsigned short y){ int ss = theTiles.shadowSize(); QPainter p(&backBuffer); QPen line; p.setBackgroundMode(OpaqueMode); p.setBackgroundColor(black); line.setWidth(1); line.setColor(white); p.setPen(line); int x2 = x+theTiles.width()-ss-1; int y2 = y+theTiles.height()-1; p.drawLine(x, y+ss, x2, y+ss); p.drawLine(x, y+ss, x, y2); p.drawLine(x2, y+ss, x2, y2); p.drawLine(x+1, y2, x2, y2); // p.fillRect(x+1, y+ss+1, theTiles.width()-ss-2, theTiles.height()-ss-2, QBrush(lightGray)); for (unsigned short pos=0; pos < h; pos++) { QPixmap *p = theTiles.unselectedPixmaps(t-TILE_OFFSET); bitBlt( &backBuffer, x+(pos*ss), y-(pos*ss), p, 0,0, p->width(), p->height(), CopyROP ); }}void BoardWidget::pause() { gamePaused = !gamePaused; drawBoard(true);}// ---------------------------------------------------------int BoardWidget::undoMove(){ cancelUserSelectedTiles(); if( Game.TileNum < Game.MaxTileNum ) { clearRemovedTilePair(Game.MoveList[Game.TileNum], Game.MoveList[Game.TileNum+1]); putTile( Game.MoveList[Game.TileNum], false ); Game.TileNum++; putTile( Game.MoveList[Game.TileNum] ); Game.TileNum++; drawTileNumber(); setStatusText( i18n("Undo operation done successfully.") ); return 1; } else { setStatusText(i18n("What do you want to undo? You have done nothing!")); return 0; }}// ---------------------------------------------------------void BoardWidget::helpMove(){ cancelUserSelectedTiles(); stopMatchAnimation(); if( findMove( TimerPos1, TimerPos2 ) ) { cheatsUsed++; iTimerStep = 1; helpMoveTimeout(); } else setStatusText( i18n("Sorry, you have lost the game.") );}// ---------------------------------------------------------void BoardWidget::helpMoveTimeout(){ if( iTimerStep & 1 ) { hilightTile( TimerPos1, true, false ); hilightTile( TimerPos2, true ); } else { hilightTile( TimerPos1, false, false ); hilightTile( TimerPos2, false ); } // restart timer if( iTimerStep++ < 8 ) QTimer::singleShot( ANIMSPEED, this, SLOT( helpMoveTimeout() ) );}// ---------------------------------------------------------void BoardWidget::startDemoMode(){ cancelUserSelectedTiles(); stopMatchAnimation(); calculateNewGame(); if( TimerState == Stop ) { TimerState = Demo; iTimerStep = 0; emit demoModeChanged( true ); setStatusText( i18n("Demo mode. Click mousebutton to stop.") ); demoMoveTimeout(); }}// ---------------------------------------------------------void BoardWidget::stopDemoMode(){ TimerState = Stop; // stop demo calculateNewGame(); setStatusText( i18n("Now it's you again.") ); emit demoModeChanged( false ); emit gameCalculated();}// ---------------------------------------------------------void BoardWidget::demoMoveTimeout(){ switch( iTimerStep++ % 6 ) { // at firts, find new matching tiles case 0: if( ! findMove( TimerPos1, TimerPos2 ) ) { // if computer has won if( Game.TileNum == 0 ) { animateMoveList(); } // else computer has lost else { setStatusText( i18n("Your computer has lost the game.") ); while( Game.TileNum < Game.MaxTileNum ) { putTile( Game.MoveList[Game.TileNum], false ); Game.TileNum++; putTile( Game.MoveList[Game.TileNum] ); Game.TileNum++; drawTileNumber(); } } TimerState = Stop; startDemoMode(); return; } break; // hilight matching tiles two times case 1: case 3: if( TimerState == Demo ) { hilightTile( TimerPos1, true, false ); hilightTile( TimerPos2, true ); } break; case 2:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -