/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz 07/2002 ! ! Copyright: MAGIC Software Development, 2000-2002 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MagicSnake // ---------- // // Camera Display Games: Snake // // Start the game by: // MagicSnake snake; // // Controll the worm using right/left. Make sure, that the mouse pointer // is inside the canvas. // // Move the mouse pointer outside the canvas to pause the game. // // The pixel colors have the following meaning: // -------------------------------------------- // Green: Food, collect all packages. // Red: Bombs, don't touch it! // Yellow: Transport, try it. // Magenta: Home, touch it to win the game. // // To restart the game use the context menu. It can only be accessed if // the game has been stopped (either because you win the game or because // you hit a bomb) With the context menu you can also toggle between // different camera layouts. // //////////////////////////////////////////////////////////////////////////// #include "MagicSnake.h" #include #include #include #include #include #include #include #include "MHexagon.h" #include "MGeomPix.h" #include "MGeomCamCT1.h" #include "MGeomCamMagic.h" ClassImp(MagicSnake); using namespace std; void MagicSnake::Free() { if (!fGeomCam) return; fPixels->Delete(); delete fPixels; delete fGeomCam; delete fArray; } // ------------------------------------------------------------------------ // // Draw all pixels of the camera // (means apend all pixelobjects to the current pad) // void MagicSnake::DrawHexagons() { for (UInt_t i=0; iGetNumPixels(); fRange = fGeomCam->GetMaxRadius(); // // Construct all hexagons. Use new-operator with placement // fPixels = new TClonesArray("MHexagon", fNumPixels); for (UInt_t i=0; i ROOT_VERSION(3,01,06) h.SetBit(kNoContextMenu|kCannotPick); #endif } } void MagicSnake::Init() { // // Make sure, that the object is destroyed when the canvas/pad is // destroyed. Make also sure, that the interpreter doesn't try to // delete it a second time. // SetBit(kCanDelete); gInterpreter->DeleteGlobal(this); Draw(); Pause(); fTimer.TurnOn(); } // ------------------------------------------------------------------------ // // default constructor // MagicSnake::MagicSnake() : fTimer(this, 500, kTRUE), fGeomCam(NULL), fDone(NULL), fPaused(NULL), fW(0), fH(0) { SetNewCamera(new MGeomCamMagic); Init(); } // ------------------------------------------------------------------------ // // default constructor // MagicSnake::MagicSnake(const MGeomCam &geom) : fTimer(this, 500, kTRUE), fGeomCam(NULL), fDone(NULL), fPaused(NULL), fW(0), fH(0) { SetNewCamera(static_cast(geom.Clone())); Init(); } void MagicSnake::Pause(Bool_t yes) { if (yes && !fPaused) { fPaused = new TText(0, 0, "Paused!"); fPaused->SetTextColor(kWhite); fPaused->SetTextAlign(22); fPaused->SetTextSize(0.05); // white fPaused->Draw(); #if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06) fPaused->SetBit(kNoContextMenu|kCannotPick); fDrawingPad->ResetBit(kNoContextMenu); ResetBit(kNoContextMenu); #endif fDrawingPad->Update(); } if (yes) return; if (!fDone) { #if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06) fDrawingPad->SetBit(kNoContextMenu); SetBit(kNoContextMenu); #endif } if (!fPaused) return; Remove(fPaused); fDrawingPad->Update(); delete fPaused; fPaused=NULL; } // ------------------------------------------------------------------------ // // Destructor. Deletes TClonesArrays for hexagons and legend elements. // MagicSnake::~MagicSnake() { Free(); Pause(kFALSE); if (fDone) delete fDone; if (fDrawingPad->GetListOfPrimitives()->FindObject(this)==this) { fDrawingPad->RecursiveRemove(this); delete fDrawingPad; } } // ------------------------------------------------------------------------ // // This is called at any time the canvas should get repainted. // Here we maintain an aspect ratio of 5/4=1.15. This makes sure, // that the camera image doesn't get distorted by resizing the canvas. // void MagicSnake::Paint(Option_t *opt) { const UInt_t w = (UInt_t)(gPad->GetWw()*gPad->GetAbsWNDC()); const UInt_t h = (UInt_t)(gPad->GetWh()*gPad->GetAbsHNDC()); // // Check for a change in width or height, and make sure, that the // first call also sets the range // if (w*fH == h*fW && fW && fH) return; // // Calculate aspect ratio (5/4=1.25 recommended) // const Double_t ratio = (Double_t)w/h; Float_t x; Float_t y; if (ratio>1.0) { x = fRange*(ratio*2-1); y = fRange; } else { x = fRange; y = fRange/ratio; } fH = h; fW = w; // // Set new range // fDrawingPad->Range(-fRange, -y, x, y); } // ------------------------------------------------------------------------ // // Call this function to draw the camera layout into your canvas. // Setup a drawing canvas. Add this object and all child objects // (hexagons, etc) to the current pad. If no pad exists a new one is // created. // void MagicSnake::Draw(Option_t *option) { // // if no canvas is yet existing to draw into, create a new one // /*TCanvas *c =*/ new TCanvas("MagicSnake", "Magic Snake", 0, 0, 800, 800); //c->ToggleEventStatus(); fDrawingPad = gPad; fDrawingPad->SetBorderMode(0); // // Append this object, so that the aspect ratio is maintained // (Paint-function is called) // AppendPad(option); // // Reset the game pad // Reset(); DrawHexagons(); fShow.SetTextAlign(23); // centered/bottom #if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06) fShow.SetBit(kNoContextMenu|kCannotPick); #endif fShow.Draw(); } void MagicSnake::Update() { TString txt = "Pixels: "; txt += fNumPixels; txt += " Bombs: "; txt += fNumBombs; txt += " Food: "; txt += fNumFood; fShow.SetText(0, fRange, txt); } // ------------------------------------------------------------------------ // // reset the all pixel colors to a default value // void MagicSnake::Reset() { fDirection = fGeomCam->InheritsFrom("MGeomCamCT1") ? kLeft : kRight; fLength = 2; for (UInt_t i=0; iGetColor(51+i)->SetRGB(f, f, f); } for (int i=0; iSetFillColor(22); #if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06) fDrawingPad->SetBit(kNoContextMenu); SetBit(kNoContextMenu); #endif if (!fDone) return; delete fDone; fDone = NULL; } void MagicSnake::Done(TString txt, Int_t col) { //(*this)[fArray[fLength-1]].SetFillColor(kBlue); fDone = new TText(0, 0, txt); fDone->SetTextColor(kWhite); // white fDone->SetTextAlign(22); // centered/centered fDone->SetTextSize(0.05); // white fDone->Draw(); fDrawingPad->SetFillColor(col); #if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06) fDone->SetBit(kNoContextMenu|kCannotPick); fDrawingPad->ResetBit(kNoContextMenu); ResetBit(kNoContextMenu); #endif } void MagicSnake::Remove(TObject *obj) { fDrawingPad->RecursiveRemove(obj); } // ------------------------------------------------------------------------ // // Execute a mouse event on the camera // void MagicSnake::ExecuteEvent(Int_t event, Int_t keycode, Int_t keysym) { if (event==kMouseEnter || event==kMouseMotion) { Pause(kFALSE); return; } if (fDone) return; if (event==kMouseLeave) { Pause(); return; } if (event!=kKeyPress) return; switch (keysym) { case kKey_Left: fDirection --; break; case kKey_Right: fDirection ++; break; case kKey_Escape: Done("Reset...", 22); Reset(); return; default: cout << "Keysym=0x" << hex << keysym << endl; } if (fDirection < kRightTop) fDirection = kLeftTop; if (fDirection > kLeftTop) fDirection = kRightTop; } void MagicSnake::Step(Int_t newpix) { if ((*fGeomCam)[newpix].TestBit(kHasTransport)) { (*this)[fArray[0]].SetFillColor(kBackground); (*fGeomCam)[fArray[0]].ResetBit(kHasWorm); for (int i=1; i=dx && y>dy) { newpix=idx; dy=y; } continue; case kRight: if (x>dx) { newpix=idx; dx=x; } continue; case kRightBottom: if (x>=dx && ydy) { newpix=idx; dy=y; } continue; case kLeft: if (xModified(); fDrawingPad->Update(); //cout << "Done." << endl; return kTRUE; }