00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <TVirtualX.h>
00019 #include <TGClient.h>
00020 #include <KeySymbols.h>
00021 #include <TRootCanvas.h>
00022 #include <TApplication.h>
00023 #include <TList.h>
00024 #include "Tetris.h"
00025
00026 static Tetris *gTetris;
00027
00028 static const UInt_t gBoxPixelSize = 20;
00029
00030
00031 ClassImp(Tetris)
00032
00033
00034
00035
00036 TetrisBox::TetrisBox(Int_t x, Int_t y, UInt_t type, TPad* pad) :
00037 TWbox(0,0,1,1,33,2,1)
00038 {
00039
00040
00041 fType = type;
00042 fPad = pad;
00043
00044
00045 SetBit(kMustCleanup);
00046 SetBit(kCanDelete);
00047 pad->GetListOfPrimitives()->Add(this);
00048 SetXY(x,y);
00049 }
00050
00051 void TetrisBox::SetX(Int_t x)
00052 {
00053
00054
00055
00056 Float_t width = (Float_t)fPad->XtoPixel(fPad->GetX2());
00057
00058 Coord_t x1 = ((Float_t)x)*gBoxPixelSize/width;
00059 Coord_t x2 = ((Float_t)x+1)*gBoxPixelSize/width;
00060
00061 SetX1(x1);
00062 SetX2(x2);
00063 fX = x;
00064 }
00065
00066 void TetrisBox::SetY(Int_t y)
00067 {
00068
00069
00070
00071 Float_t height = (Float_t)fPad->YtoPixel(fPad->GetY1());
00072
00073 Coord_t y1 = ((Float_t)y)*gBoxPixelSize/height;
00074 Coord_t y2 = ((Float_t)y+1)*gBoxPixelSize/height;
00075
00076 SetY1(y1);
00077 SetY2(y2);
00078 fY = y;
00079 }
00080
00081 void TetrisBox::Paint(Option_t *option)
00082 {
00083
00084
00085 if (!IsHidden() && fPad) TWbox::Paint(option);
00086 }
00087
00088 void TetrisBox::Erase()
00089 {
00090
00091
00092 Double_t fX1sav = fX1;
00093 Double_t fY1sav = fY1;
00094 Double_t fX2sav = fX2;
00095 Double_t fY2sav = fY2;
00096
00097
00098 fX1 = fX1-fPad->PixeltoX(2);
00099 fY1 = fY1+fPad->PixeltoY(2);
00100 fX2 = fX2+fPad->PixeltoX(2);
00101 fY2 = fY2-fPad->PixeltoY(2);
00102
00103 SetFillColor(fPad->GetFillColor());
00104 SetBorderMode(0);
00105 Paint();
00106
00107 fX1 = fX1sav;
00108 fY1 = fY1sav;
00109 fX2 = fX2sav;
00110 fY2 = fY2sav;
00111 }
00112
00113
00114
00115
00116
00117 static Int_t gPieceTypes[10][4][2] = {
00118 {{-1,1},
00119 {-1,0},
00120 { 0,0},
00121 { 0,-1}},
00122
00123 {{ 1, 1},
00124 { 1, 0},
00125 { 0, 0},
00126 { 0,-1}},
00127
00128 {{ 0, 1},
00129 { 0, 0},
00130 { 0,-1},
00131 { 0,-2}},
00132
00133 {{ 0, 1},
00134 { 1, 0},
00135 { 0, 0},
00136 { -1,0}},
00137
00138 {{ 1, 1},
00139 { 0, 1},
00140 { 1, 0},
00141 { 0, 0}},
00142
00143 {{ 0, 1},
00144 { 0, 0},
00145 { 0,-1},
00146 { -1,-1}},
00147
00148 {{ 0, 1},
00149 { 0, 0},
00150 { 0,-1},
00151 { 1,-1}},
00152
00153 {{ 0, 1},
00154 { 0, 1},
00155 { 0, 1},
00156 { 0, 1}},
00157
00158 {{ 0, 1},
00159 { 0, 0},
00160 { 0, 1},
00161 { 0, 0}},
00162
00163 {{ 0, 1},
00164 { 0, 0},
00165 { 0,-1},
00166 { 0, 0}}};
00167
00168 static Color_t gPieceColors[10] = { 2,3,4,5,6,7,13,9,28,41 };
00169
00170
00171 TetrisPiece::~TetrisPiece()
00172 {
00173
00174
00175 for (int i = 0; i < 4; i++) delete fBoxes[i];
00176 }
00177
00178 void TetrisPiece::Initialize(UInt_t type, TPad* pad)
00179 {
00180 for (int i = 0; i < 4; i++) fBoxes[i] = new TetrisBox(0,0,0,pad);
00181 fX = 0;
00182 fY = 0;
00183 SetType(type);
00184 }
00185
00186 void TetrisPiece::SetType(UInt_t type)
00187 {
00188
00189
00190 if (type < 1 || type > 10)
00191 type = 9;
00192
00193 for (int i = 0 ; i < 4 ; i++) {
00194 fBoxes[i]->SetType(type);
00195 fBoxes[i]->SetFillColor(gPieceColors[type-1]);
00196 fBoxes[i]->SetX(gPieceTypes[type-1][i][0]+fX);
00197 fBoxes[i]->SetY(gPieceTypes[type-1][i][1]+fY);
00198 }
00199 HideSomeBoxes(type);
00200 fType = type;
00201 }
00202
00203 void TetrisPiece::HideSomeBoxes(UInt_t type)
00204 {
00205
00206
00207 switch(type) {
00208 case 8: fBoxes[1]->Hide();
00209 case 9: fBoxes[2]->Hide();
00210 case 10: fBoxes[3]->Hide();
00211 default: return;
00212 }
00213 }
00214
00215 Bool_t TetrisPiece::RotateRight()
00216 {
00217
00218
00219
00220 if (GetType() == 5 || GetType() == 8) return kFALSE;
00221
00222 Int_t tmp;
00223
00224 for (int i = 0 ; i < 4 ; i++) {
00225 tmp = GetXx(i);
00226 SetXx(i,-GetYy(i));
00227 SetYy(i,tmp);
00228 }
00229 return kTRUE;
00230 }
00231
00232 Bool_t TetrisPiece::RotateLeft()
00233 {
00234
00235
00236
00237 if (GetType() == 5 || GetType() == 8) return kFALSE;
00238
00239 Int_t tmp;
00240
00241 for (int i = 0 ; i < 4 ; i++) {
00242 tmp = GetXx(i);
00243 SetXx(i,GetYy(i));
00244 SetYy(i,-tmp);
00245 }
00246 return kTRUE;
00247 }
00248
00249 void TetrisPiece::Hide()
00250 {
00251
00252
00253 for (int i = 0 ; i < 4 ; i++) {
00254 fBoxes[i]->Hide();
00255 }
00256 }
00257
00258 void TetrisPiece::Show()
00259 {
00260
00261
00262 for (int i = 0 ; i < 4 ; i++) {
00263 fBoxes[i]->SetType(fType);
00264 }
00265 HideSomeBoxes(fType);
00266 }
00267
00268 void TetrisPiece::SetX(Int_t x)
00269 {
00270
00271
00272 for (int i = 0 ; i < 4 ; i++) SetX(i,x+GetXx(i));
00273 fX = x;
00274 }
00275
00276 void TetrisPiece::SetY(Int_t y)
00277 {
00278
00279
00280 for (int i = 0 ; i < 4 ; i++) SetY(i,y+GetYy(i));
00281 fY = y;
00282 }
00283
00284 void TetrisPiece::SetXY(Int_t x,Int_t y)
00285 {
00286
00287
00288 for (int i = 0 ; i < 4 ; i++) {
00289 SetX(i,x+GetXx(i));
00290 SetY(i,y+GetYy(i));
00291 }
00292 fX = x;
00293 fY = y;
00294 }
00295
00296
00297
00298
00299
00300 CurrentPiece::CurrentPiece(UInt_t type,TetrisBoard* board) :
00301 TetrisPiece(type,board), TTimer(1000,kTRUE)
00302 {
00303
00304
00305 fBoard = board;
00306
00307 Int_t line = fBoard->GetHeight()-2;
00308 Int_t xPosition = fBoard->GetWidth()/2;
00309
00310 SetXY(xPosition,line);
00311
00312 if (!CanMoveTo(xPosition,line)) { gTetris->StopGame(); return; }
00313
00314 fBoard->Modified();
00315 fBoard->Update();
00316 fBoard->SetDropped(kFALSE);
00317 SetSpeed();
00318 Start();
00319 }
00320
00321 void CurrentPiece::MoveTo(int x, int y)
00322 {
00323
00324
00325 Erase();
00326 SetXY(x,y);
00327 fBoard->Modified();
00328 fBoard->Update();
00329 }
00330
00331 Bool_t CurrentPiece::CanMoveTo(int x, int y)
00332 {
00333
00334
00335 Bool_t return_value;
00336
00337 int savX = fX;
00338 int savY = fY;
00339
00340 SetXY(x,y);
00341 return_value = CanPosition();
00342 SetXY(savX,savY);
00343
00344 return return_value;
00345 }
00346
00347 Bool_t CurrentPiece::CanPosition()
00348 {
00349
00350
00351 int x, y;
00352
00353 for (int i = 0 ; i < 4 ; i++) {
00354 GetXY(i,x,y);
00355 if (x < 0 || x >= fBoard->GetWidth() ||
00356 y < 0 || y >= fBoard->GetHeight() ||
00357 !fBoard->IsEmpty(x,y)) return kFALSE;
00358 }
00359 return kTRUE;
00360 }
00361
00362 Bool_t CurrentPiece::RotateRight()
00363 {
00364
00365
00366 Bool_t return_value;
00367
00368 Erase();
00369 TetrisPiece::RotateRight();
00370 return_value = CanPosition();
00371 if (!return_value) TetrisPiece::RotateLeft();
00372
00373 fBoard->Modified();
00374 fBoard->Update();
00375 return return_value;
00376 }
00377
00378 Bool_t CurrentPiece::RotateLeft()
00379 {
00380
00381
00382 Bool_t return_value;
00383
00384 Erase();
00385 TetrisPiece::RotateLeft();
00386 return_value = CanPosition();
00387 if (!return_value) TetrisPiece::RotateRight();
00388
00389 fBoard->Modified();
00390 fBoard->Update();
00391 return return_value;
00392 }
00393
00394 Bool_t CurrentPiece::OneLineDown()
00395 {
00396
00397
00398 int y = GetY();
00399 int x = GetX();
00400
00401 y--;
00402 if (!CanMoveTo(x,y)) return kFALSE;
00403
00404 MoveTo(x,y);
00405 return kTRUE;
00406 }
00407
00408 Bool_t CurrentPiece::DropDown()
00409 {
00410
00411
00412 int y = GetY();
00413 int x = GetX();
00414 int dropHeight = 0;
00415
00416 while (CanMoveTo(x,--y)) dropHeight++;
00417
00418 y++;
00419 MoveTo(x,y);
00420 Stop();
00421 fBoard->PieceDropped(this, dropHeight);
00422 return kTRUE;
00423 }
00424
00425 Bool_t CurrentPiece::MoveLeft(int steps)
00426 {
00427
00428
00429 int y = GetY();
00430 int x = GetX();
00431
00432 while(steps) {
00433 if (!CanMoveTo(--x ,y)) return kFALSE;
00434 MoveTo(x,y);
00435 steps--;
00436 }
00437 return kTRUE;
00438 }
00439
00440 Bool_t CurrentPiece::MoveRight(int steps)
00441 {
00442
00443
00444 int y = GetY();
00445 int x = GetX();
00446
00447 while(steps) {
00448 if (!CanMoveTo(++x,y)) return kFALSE;
00449 MoveTo(x,y);
00450 steps--;
00451 }
00452 return kTRUE;
00453 }
00454
00455 Bool_t CurrentPiece::Notify()
00456 {
00457
00458
00459 if (OneLineDown()) {
00460 TTimer::Reset();
00461 return kFALSE;
00462 } else {
00463 Stop();
00464 fBoard->PieceDropped(this,0);
00465 return kTRUE;
00466 }
00467 }
00468
00469 void CurrentPiece::SetSpeed()
00470 {
00471
00472
00473 const Int_t factor = 2;
00474 SetTime(1000/(1 + gTetris->GetLevel()*factor));
00475 }
00476
00477 void CurrentPiece::Paint(Option_t*)
00478 {
00479
00480
00481 TPad* padsav = (TPad*)TVirtualPad::Pad();
00482 fBoard->cd();
00483
00484 for (int i = 0 ; i < 4 ; i++) {
00485 fBoxes[i]->SetBorderMode(1);
00486 fBoxes[i]->SetFillColor(gPieceColors[fType-1]);
00487 fBoxes[i]->Paint();
00488 }
00489 padsav->cd();
00490 }
00491
00492 void CurrentPiece::Erase()
00493 {
00494
00495
00496 TPad* padsav = (TPad*)TVirtualPad::Pad();
00497 fBoard->cd();
00498
00499 for (int i = 0 ; i < 4 ; i++) {
00500 fBoxes[i]->Erase();
00501 }
00502 padsav->cd();
00503 }
00504
00505
00506
00507
00508
00509 TetrisBoard::TetrisBoard(Float_t xlow, Float_t ylow,Float_t xup,Float_t yup) :
00510 TPad("tetris_board","Tetris Board",xlow,ylow,xup,yup,17,4,-1)
00511 {
00512
00513
00514 fWidth = (int)(fMother->XtoAbsPixel(GetX2())*(xup-xlow))/gBoxPixelSize;
00515 fHeight = (int)(fMother->YtoAbsPixel(GetY1())*(yup-ylow))/gBoxPixelSize;
00516 Double_t box = fMother->PixeltoX(gBoxPixelSize);
00517 Double_t xx = xlow + box*fWidth;
00518
00519 if (xx<xup) {
00520 xx += fMother->PixeltoX(1);
00521 SetPad(xlow, ylow, xx, yup);
00522 }
00523
00524 fBoard = new TetrisBoxPtr[fWidth*fHeight];
00525 fFilledLines = 0;
00526 Clear();
00527 }
00528
00529 void TetrisBoard::Clear(Option_t *)
00530 {
00531
00532
00533 GetListOfPrimitives()->Delete();
00534
00535 for (int i = 0; i < fWidth; i++)
00536 for (int j = 0; j < fHeight; j++)
00537 Board(i,j) = 0;
00538
00539 fIsDropped = kTRUE;
00540 }
00541
00542 void TetrisBoard::Hide()
00543 {
00544
00545
00546 TetrisBox *box;
00547 TIter nextin(GetListOfPrimitives());
00548
00549 while ((box = (TetrisBox*)nextin())) box->Hide();
00550 Modified();
00551 Update();
00552 }
00553
00554 void TetrisBoard::Show()
00555 {
00556
00557
00558 TetrisBox *box;
00559 TIter nextin(GetListOfPrimitives());
00560
00561 while ((box = (TetrisBox*)nextin())) box->Show();
00562 Modified();
00563 Update();
00564 }
00565
00566 Bool_t TetrisBoard::IsFullLine(Int_t line)
00567 {
00568
00569
00570 Bool_t return_value = kTRUE;
00571
00572 for (int i = 0; i < fWidth; i++)
00573 return_value = return_value && !IsEmpty(i,line);
00574
00575 return return_value;
00576 }
00577
00578 Bool_t TetrisBoard::IsEmptyLine(Int_t line)
00579 {
00580
00581
00582 Bool_t return_value = kTRUE;
00583
00584 for (int i = 0; i < fWidth; i++)
00585 return_value = return_value && IsEmpty(i,line);
00586
00587 return return_value;
00588 }
00589
00590 void TetrisBoard::RemoveLine(Int_t line)
00591 {
00592
00593
00594 for (int i=0; i<fWidth; i++) {
00595 if (Board(i,line))
00596 delete Board(i,line);
00597
00598 Board(i,line) = 0;
00599 }
00600 }
00601
00602 void TetrisBoard::MoveOneLineDown(Int_t line)
00603 {
00604
00605
00606 if (!line) return;
00607
00608 for (int i = 0; i < fWidth; i++) {
00609 if (!IsEmpty(i,line)) {
00610 Board(i,line)->MoveOneLineDown();
00611 Board(i,line-1) = Board(i,line);
00612 }
00613 Board(i,line)=0;
00614 }
00615 Modified();
00616 Update();
00617 }
00618
00619 void TetrisBoard::RemoveFullLines()
00620 {
00621
00622
00623 for (int i = 0; i < fFilledLines; i++) {
00624 while (IsFullLine(i)) {
00625 RemoveLine(i);
00626 gTetris->UpdateLinesRemoved();
00627 AllAboveLinesDown(i);
00628 fFilledLines--;
00629 }
00630 }
00631 }
00632
00633 void TetrisBoard::GluePiece(TetrisPiece* piece)
00634 {
00635
00636
00637 int x,y;
00638 TetrisBox *box;
00639
00640 for (int i = 0 ; i < 4 ; i++) {
00641 piece->GetXY(i,x,y);
00642 box = piece->GetTetrisBox(i);
00643 if (box->IsHidden()) { delete box; continue;}
00644 Board(x,y) = piece->GetTetrisBox(i);
00645 if (y>fFilledLines) fFilledLines = y+1;
00646 }
00647 }
00648
00649 void TetrisBoard::PieceDropped(TetrisPiece* piece, int height)
00650 {
00651
00652
00653 Int_t add2score = height*gTetris->GetLevel() + 10;
00654
00655 fIsDropped = kTRUE;
00656 GluePiece(piece);
00657 RemoveFullLines();
00658
00659
00660 gTetris->UpdatePiecesDropped();
00661 gTetris->UpdateScore(add2score);
00662 gTetris->CreateNewPiece();
00663 fIsDropped = kFALSE;
00664 }
00665
00666 void TetrisBoard::Print(const char *) const
00667 {
00668
00669
00670 printf("\n");
00671
00672 for (int j = fHeight-1; j > -1; j--) {
00673 for (int i = 0; i < fWidth; i++)
00674 ((TetrisBoard*)this)->IsEmpty(i,j) ? printf("| ") : printf("| * ") ;
00675 printf("|\n");
00676 }
00677 }
00678
00679 void TetrisBoard::PaintModified()
00680 {
00681
00682
00683
00684 if (!fIsDropped && gTetris->IsGameOn() && !gTetris->IsPaused())
00685 gTetris->fCurrentPiece->Paint();
00686 else
00687 TPad::PaintModified();
00688 }
00689
00690
00691
00692
00693
00694 NextPiecePad::NextPiecePad(Float_t xlow, Float_t ylow, Float_t xup, Float_t yup)
00695 : TPad("next_piece","Next Piece Pad",xlow,ylow,xup,yup,17,4,-1)
00696 {
00697
00698
00699 fPiece = new TetrisPiece(this);
00700 fPiece->Hide();
00701
00702
00703 Int_t x = (int)(fMother->XtoAbsPixel(GetX2())*(xup-xlow))/gBoxPixelSize/2;
00704 Int_t y = (int)(fMother->YtoAbsPixel(GetY1())*(yup-ylow))/gBoxPixelSize/2;
00705
00706 fPiece->SetXY(x,y);
00707 Modified(kTRUE);
00708 Update();
00709 }
00710
00711
00712
00713
00714
00715
00716 PauseButton::PauseButton(Float_t xlow, Float_t ylow, Float_t xup, Float_t yup) :
00717 TButton("Pause"," ",xlow,ylow,xup,yup)
00718 {
00719
00720
00721 SetBorderSize(5);
00722 SetTextSize(0.45);
00723 SetFillColor(42);
00724 }
00725
00726 void PauseButton::ExecuteEvent(Int_t event, Int_t, Int_t)
00727 {
00728
00729
00730 if (event == kButton1Up) {
00731 IsPressed() ? gTetris->Continue() : gTetris->Pause();
00732 Modified(kTRUE);
00733 }
00734 }
00735
00736
00737
00738
00739
00740
00741 QuitButton::QuitButton(Float_t xlow, Float_t ylow, Float_t xup, Float_t yup) :
00742 TButton("Quit"," ",xlow,ylow,xup,yup)
00743 {
00744
00745
00746 SetBorderSize(5);
00747 SetTextSize(0.45);
00748 SetFillColor(42);
00749 }
00750
00751 void QuitButton::ExecuteEvent(Int_t event, Int_t, Int_t)
00752 {
00753
00754
00755 if (event == kButton1Up) gTetris->Quit();
00756 }
00757
00758
00759
00760
00761
00762
00763 NewGameButton::NewGameButton(Float_t xlow, Float_t ylow, Float_t xup, Float_t yup)
00764 : TButton("New Game"," ",xlow,ylow,xup,yup)
00765 {
00766
00767
00768 SetBorderSize(5);
00769 SetTextSize(0.45);
00770 SetFillColor(42);
00771 }
00772
00773 void NewGameButton::ExecuteEvent(Int_t event, Int_t, Int_t)
00774 {
00775
00776
00777 if (event == kButton1Up) {
00778 gTetris->NewGame();
00779 Modified(kTRUE);
00780 }
00781 }
00782
00783
00784
00785
00786
00787 InfoPad::InfoPad(const char* title, Float_t xlow, Float_t ylow, Float_t xup, Float_t yup)
00788 : TPad("info_pad",title,xlow,ylow,xup,yup,17,4,-1), TAttText(22,0,2,71,0.65)
00789 {
00790
00791
00792 SetBit(kCanDelete);
00793
00794 TText *text = new TText(xlow,yup,title);
00795 text->SetTextSize(0.45*(yup-ylow));
00796 text->SetY(yup+0.2*text->GetTextSize());
00797 fMother->GetListOfPrimitives()->Add(text);
00798
00799 text = new TText(0.5,0.5,"0");
00800 GetListOfPrimitives()->Add(text);
00801
00802 fValue = 0;
00803 Modified(kTRUE);
00804 Update();
00805 }
00806
00807 void InfoPad::PaintModified()
00808 {
00809
00810
00811 char str[40];
00812
00813 sprintf(str,"%d",fValue);
00814
00815 TObject *obj = GetListOfPrimitives()->First();
00816
00817 if (obj && obj->InheritsFrom("TText")) {
00818 TText *text = (TText*)obj;
00819 text->SetTitle(str);
00820
00821 text->SetTextSize(GetTextSize());
00822 text->SetTextFont(GetTextFont());
00823 text->SetTextAlign(GetTextAlign());
00824 text->SetTextColor(GetTextColor());
00825 text->SetTextAngle(GetTextAngle());
00826 text->TAttText::Modify();
00827
00828 text->SetX(0.5);
00829 text->SetY(0.5);
00830 }
00831 TPad::PaintModified();
00832 }
00833
00834
00835
00836
00837
00838 KeyHandler::KeyHandler() : TGFrame(gClient->GetRoot(),0,0)
00839 {
00840
00841
00842
00843 TRootCanvas *main_frame = (TRootCanvas*)(gTetris->GetCanvasImp());
00844
00845
00846 main_frame->BindKey((const TGWindow*)this, gVirtualX->KeysymToKeycode(kKey_Up), 0);
00847 main_frame->BindKey((const TGWindow*)this, gVirtualX->KeysymToKeycode(kKey_Left), 0);
00848 main_frame->BindKey((const TGWindow*)this, gVirtualX->KeysymToKeycode(kKey_Right), 0);
00849 main_frame->BindKey((const TGWindow*)this, gVirtualX->KeysymToKeycode(kKey_Down), 0);
00850 main_frame->BindKey((const TGWindow*)this, gVirtualX->KeysymToKeycode(kKey_Space), 0);
00851 }
00852
00853 KeyHandler::~KeyHandler()
00854 {
00855
00856
00857
00858 TRootCanvas *main_frame = (TRootCanvas*)(gTetris->GetCanvasImp());
00859
00860
00861 main_frame->RemoveBind(this, gVirtualX->KeysymToKeycode(kKey_Up), 0);
00862 main_frame->RemoveBind(this, gVirtualX->KeysymToKeycode(kKey_Left), 0);
00863 main_frame->RemoveBind(this, gVirtualX->KeysymToKeycode(kKey_Right), 0);
00864 main_frame->RemoveBind(this, gVirtualX->KeysymToKeycode(kKey_Down), 0);
00865 main_frame->RemoveBind(this, gVirtualX->KeysymToKeycode(kKey_Space), 0);
00866
00867 gVirtualX->SetKeyAutoRepeat(kTRUE);
00868 }
00869
00870
00871 Bool_t KeyHandler::HandleKey(Event_t *event)
00872 {
00873
00874
00875 char tmp[2];
00876 UInt_t keysym;
00877
00878 gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
00879
00880 if (event->fType == kGKeyPress) {
00881 switch ((EKeySym)keysym) {
00882 case kKey_Left:
00883 gTetris->MoveLeft();
00884 break;
00885 case kKey_Right:
00886 gTetris->MoveRight();
00887 break;
00888 case kKey_Down:
00889 gTetris->RotateRight();
00890 break;
00891 case kKey_Up:
00892 gTetris->RotateLeft();
00893 break;
00894 case kKey_Space:
00895 gTetris->DropDown();
00896 break;
00897 default:
00898 return kTRUE;
00899 }
00900 }
00901 return kTRUE;
00902 }
00903
00904
00905
00906
00907 UpdateLevelTimer::UpdateLevelTimer(ULong_t time) : TTimer(time,kTRUE)
00908 {
00909
00910
00911 SetBit(kCanDelete);
00912 gTetris->GetListOfPrimitives()->Add(this);
00913 }
00914
00915 Bool_t UpdateLevelTimer::Notify()
00916 {
00917
00918
00919 if (!gTetris->IsGameOn()) {
00920 Remove();
00921 return kTRUE;
00922 }
00923 gTetris->UpdateLevel();
00924 TTimer::Reset();
00925 return kFALSE;
00926 }
00927
00928
00929
00930
00931
00932 Tetris::Tetris() :
00933 TCanvas("Tetris","Have a little fun with ROOT!",200,200,700,500)
00934 {
00935
00936
00937 gTetris = this;
00938
00939 fCurrentPiece = 0;
00940
00941
00942 fBoard = new TetrisBoard(0.35,0.05,0.7,0.95);
00943 fBoard->Draw();
00944
00945
00946 fNextPiece = new NextPiecePad(0.05,0.65,0.25,0.95);
00947 fNextPiece->Draw();
00948
00949 fLinesRemoved = new InfoPad("Lines Removed",0.75,0.8,0.95,0.9);
00950 fLinesRemoved->Draw();
00951
00952 fLevel = new InfoPad("Level",0.75,0.6,0.95,0.7);
00953 fLevel->Draw();
00954
00955 fScore = new InfoPad("Score",0.75,0.4,0.95,0.5);
00956 fScore->Draw();
00957
00958
00959 fNewGame = new NewGameButton(0.05,0.05,0.25,0.15);
00960 fNewGame->Draw();
00961
00962 fQuit = new QuitButton(0.05,0.2,0.25,0.3);
00963 fQuit->Draw();
00964
00965 fPause = new PauseButton(0.05,0.35,0.25,0.45);
00966 fPause->Draw();
00967
00968 fPiecesDropped = 0;
00969 SetFillColor(21);
00970
00971 fKeyHandler = new KeyHandler();
00972 fUpdateLevelTimer = new UpdateLevelTimer(60000);
00973 SetFixedSize();
00974 Update();
00975 PrintHelpInfo();
00976 fEditable = kFALSE;
00977 }
00978
00979 void Tetris::PrintHelpInfo()
00980 {
00981
00982
00983 printf("\n\n\n");
00984 printf(" Move Piece Left --------- left-arrow\n");
00985 printf(" Move Piece Right --------- right-arrow\n");
00986 printf(" Rotate Piece --------- up/down-arrow \n");
00987 printf(" Drop Piece Down --------- space-bar\n");
00988 printf("\n\n\n");
00989 }
00990
00991 void Tetris::CreateNewPiece()
00992 {
00993
00994
00995 UInt_t type = fNextPiece->GetPiece()->GetType();
00996 fNextPiece->NewPiece();
00997 fCurrentPiece = new CurrentPiece(type,fBoard);
00998 }
00999
01000 void Tetris::SetFixedSize()
01001 {
01002
01003
01004 ((TRootCanvas*)fCanvasImp)->SetWMSizeHints(fCw,fCh+20,fCw,fCh,0,0);
01005 }
01006
01007 void Tetris::Quit()
01008 {
01009
01010
01011 delete fKeyHandler; fKeyHandler = 0;
01012 StopGame();
01013 ((TRootCanvas*)fCanvasImp)->CloseWindow();
01014 }
01015
01016 void Tetris::NewGame()
01017 {
01018
01019
01020 gVirtualX->SetInputFocus(((TRootCanvas*)fCanvasImp)->GetId());
01021
01022 if (IsGameOn()) StopGame();
01023 fScore->Reset();
01024 fLinesRemoved->Reset();
01025 fPiecesDropped = 0;
01026 SetLevel(1);
01027 fUpdateLevelTimer->Start();
01028 fBoard->Clear();
01029 fNewGame->SetPressed(kTRUE);
01030 CreateNewPiece();
01031 }
01032
01033 void Tetris::StopGame()
01034 {
01035
01036
01037 fUpdateLevelTimer->Stop();
01038 if (fCurrentPiece) fCurrentPiece->Stop();
01039 fNewGame->SetPressed(kFALSE);
01040 fPause->SetPressed(kFALSE);
01041 }
01042
01043 void Tetris::Pause()
01044 {
01045
01046
01047 if (!IsGameOn()) return;
01048 if (fCurrentPiece) fCurrentPiece->Stop();
01049 fPause->SetPressed(kTRUE);
01050 fBoard->Hide();
01051 }
01052
01053 void Tetris::Continue()
01054 {
01055
01056
01057 if (!IsGameOn()) return;
01058 fBoard->Show();
01059 fPause->SetPressed(kFALSE);
01060 if (fCurrentPiece) fCurrentPiece->Start();
01061 }
01062
01063 void Tetris::MoveLeft()
01064 {
01065
01066
01067 if (!IsGameOn() || IsPaused() || IsWaiting()) return;
01068 fCurrentPiece->MoveLeft();
01069 }
01070
01071 void Tetris::MoveRight()
01072 {
01073
01074
01075 if (!IsGameOn() || IsPaused() || IsWaiting()) return;
01076 fCurrentPiece->MoveRight();
01077 }
01078
01079 void Tetris::DropDown()
01080 {
01081
01082
01083 if (!IsGameOn() || IsPaused() || IsWaiting()) return;
01084 fCurrentPiece->DropDown();
01085 }
01086
01087 void Tetris::RotateRight()
01088 {
01089
01090
01091 if (!IsGameOn() || IsPaused() || IsWaiting()) return;
01092 fCurrentPiece->RotateRight();
01093 }
01094
01095 void Tetris::RotateLeft()
01096 {
01097
01098
01099 if (!IsGameOn() || IsPaused() || IsWaiting()) return;
01100 fCurrentPiece->RotateLeft();
01101 }
01102
01103 void Tetris::SetLevel(int level)
01104 {
01105
01106
01107 fLevel->SetValue(level);
01108 if (fCurrentPiece) fCurrentPiece->SetSpeed();
01109 }