दिलचस्प पोस्ट
Install.packages का उपयोग करके आर-फोर्ज पैकेज इंस्टॉल नहीं कर सकते XCode 6 iPhone सिम्युलेटर के लिए iOS 8 UITableView पर सेपरेटर इनसेट निकालें एंड्रॉइड: ऐप लेबल प्रोग्रामैटिक रूप से बदलें क्या एंड्रॉइड व्यू के ऊपर और नीचे सीमा को जोड़ने का एक आसान तरीका है? क्या पीएनजी में एक्सपी डाटा जैसे JPG होते हैं? नजदीकी वर्चुअल को परिणाम वस्तु का हिस्सा बनाने के लिए नहीं मिल सकता है एक स्ट्रिंग में पैटर्न की पहली घटना बदलें एंटिटी फ़्रेमवर्क धाराप्रवाह एपीआई का उपयोग करके कई रिश्तों को कैसे विन्यस्त करें जावा जनरिक्स और एन्यूम, टेम्पलेट पैरामीटर का नुकसान इकाई फ़्रेमवर्क 6 का उपयोग करते हुए एसक्यूएल सर्वर से छवि (बाइनरी) को सुरक्षित और पुनः प्राप्त करें मोबाइल ब्राउज़र से ऐप (फेसबुक / ट्विटर / आदि) कैसे लॉन्च करें, लेकिन ऐप इंस्टॉल नहीं होने पर हाइपरलिंक पर वापस आ जाए Firebase डेटाबेस में स्ट्रिंग में एक साधारण खोज कैसे करें? Chrome पर एक कुंजीपटल ईवेंट को फ़ायरिंग कैसे एक छवि पर एक रेखा खींचने के लिए? यदि == का उपयोग करते हुए बयान अप्रत्याशित परिणाम देता है

चौंका देने वाले स्तंभ आइसोमैट्रिक ग्रिड पर क्लिक का पता लगाने के प्रदर्शन में सुधार

मैं एक isometric खेल इंजन पर काम कर रहा हूं और पिक्सेल सही क्लिक पहचान के लिए पहले से ही एक एल्गोरिदम बनाया है। प्रोजेक्ट पर जाएं और नोटिस करें कि क्लिक करें पता लगाने में सक्षम है कि टाइल के किन किन किन किन क्लिक किए गए थे। यह सबसे अग्रिम टाइल को क्लिक करने के लिए y- अनुक्रमणिका को भी जांचता है।

मेरे वर्तमान एल्गोरिदम का स्पष्टीकरण:

आइसोमेट्रिक ग्रिड टाइल छवियों से बना है जो 100 * 65 पीएक्स हैं। TileW=100, TileL=50, tileH=15

टाइल का आकार बदलना

नक्शा एक त्रि-आयामी सरणी map[z][y][x] द्वारा दर्शाया गया है map[z][y][x]

टाइल केंद्र बिंदु (x,y) की गणना इस प्रकार की जाती है:

 //x, y, z are the position of the tile if(y%2===0) { x-=-0.5; } //To accommodate the offset found in even rows this.centerX = (x*tileW) + (tileW/2); this.centerY = (y*tileL) - y*((tileL)/2) + ((tileL)/2) + (tileH/2) - (z*tileH); 

Isometric ग्रिड

प्रोटोटाइप फ़ंक्शन जो निर्धारित करते हैं कि माउस टाइल पर किसी दिए गए क्षेत्र में है:

 Tile.prototype.allContainsMouse = function() { var dx = Math.abs(mouse.mapX-this.centerX), dy = Math.abs(mouse.mapY-this.centerY); if(dx>(tileW/2)) {return false;} //Refer to image return (dx/(tileW*0.5) + (dy/(tileL*0.5)) < (1+tileHLRatio)); } 

Tile.prototype.allContainsMouse() रिटर्न सही करता है अगर माउस हरे रंग के भीतर है लाल क्षेत्र का पता लगाया जाता है कि क्या डीएक्स> आधा टाइल की चौड़ाई है

आकृति 1


 Tile.prototype.topContainsMouse = function() { var topFaceCenterY = this.centerY - (tileH/2); var dx = Math.abs(mouse.mapX-this.centerX), dy = Math.abs(mouse.mapY-topFaceCenterY); return ((dx/(tileW*0.5) + dy/(tileL*0.5) <= 1)); }; 

सच है कि यदि माउस शीर्ष चेहरे पर है तो रिटर्न देता है


 Tile.prototype.leftContainsMouse = function() { var dx = mouse.mapX-this.centerX; if(dx<0) { return true; } else { return false; } }; 

(यदि माउस को केंद्र बिंदु से छोड़ दिया गया है)


 Tile.prototype.rightContainsMouse = function() { var dx = mouse.mapX-this.centerX; if(dx>0) { return true; } else { return false; } }; 

(यदि माउस केंद्र बिंदु का सही है)

एक साथ काम करने के लिए सभी तरीकों को एक साथ लाना:

  • लूप पूरे 3 डी मानचित्र के माध्यम से [z] [y] [x] सरणी
  • अगर सभी allContainsMouse() रिटर्न सही, नक्शा [z] [y] [x] टाइल हमारे माउस पर है।
  • इस टाइल को सरणी टाइल tilesUnderneathMouse सरणी में जोड़ें।
  • टाइल tilesUnderneathMouse सरणी के माध्यम से लूप, और उच्चतम y साथ टाइल चुनें। यह सबसे अग्रिम टाइल है

     if(allContainsMouse && !topContainsMouse) 

निचला मैच

  •  if(allContainsMouse && !topContainsMouse && leftContainsMouse) 

बाएं मैच

(समान अवधारणा सही के लिए लागू होती है)

अंत में, मेरे प्रश्न:

# 1 आप इसे कैसे पूरा करेंगे, जैसे कि यह अधिक कुशल है (सभी टाइल्स के माध्यम से पाशन नहीं) (पेसोडो कोड स्वीकार किया गया है)

# 2 अगर आप # 1 का उत्तर देने में असमर्थ हैं, तो मेरे क्लिक का पता लगाने की क्षमता में सुधार करने के लिए आपके पास क्या सुझाव हैं (चंक लोडिंग पहले से ही माना जा चुका है)

मैंने क्या सोचा है:

मैं मूल रूप से टाइल केंद्र बिंदुओं का उपयोग न करके इस समस्या को हल करने की कोशिश की थी, बल्कि माउस (एक्स, वाई) की स्थिति को सीधे टाइल एक्स, वाई में परिवर्तित कर रहा था। मेरे मन में यह कोड के लिए सबसे मुश्किल है, फिर भी सबसे कुशल समाधान एक वर्ग ग्रिड पर ग्रिड पर एक वर्ग (x, y) की स्थिति को बदलने में बहुत आसान है हालांकि एक कंपित स्तंभ ग्रिड में, आप ऑफ़सेट के साथ काम करते हैं। मैंने ऑफसेट को एक फ़ंक्शन का उपयोग करने की कोशिश की जो एक एक्स या वाई मान लेता है, और परिणामी ऑफ़सेट y, या x देता है आर्कोको (कॉक्स) के ज़िग-ज़ैग ग्राफ़ ने इसका समाधान किया

यह जांचते हुए कि माउस टाइल के भीतर था, इस पद्धति का उपयोग करना कठिन था और मैं इसे समझ नहीं सका। मैं देख रहा था कि माउस (x, y) y=mx+b रेखा के नीचे था जो कि टाइल एक्स, टाइलवाई सन्निकटन (लगभग एक वर्ग ग्रिड) पर निर्भर था।

यदि आप यहां आए तो धन्यवाद!

Solutions Collecting From Web of "चौंका देने वाले स्तंभ आइसोमैट्रिक ग्रिड पर क्लिक का पता लगाने के प्रदर्शन में सुधार"

यह उत्तर निम्न आधार पर है:

  • 2 डी ग्रिड छवि मान 2 डी सरणी के लिए

तो यहाँ यह जाता है:

  1. ग्रिड और स्क्रीन के बीच रूपांतरण

    जैसा कि मैंने टिप्पणी में उल्लेख किया है आपको स्क्रीन और सेल ग्रिड स्थिति के बीच कन्वर्ट करने वाले कार्यों को बनाना चाहिए। कुछ ऐसा ( सी ++ में ):

     //--------------------------------------------------------------------------- // tile sizes const int cxs=100; const int cys= 50; const int czs= 15; const int cxs2=cxs>>1; const int cys2=cys>>1; // view pan (no zoom) int pan_x=0,pan_y=0; //--------------------------------------------------------------------------- void isometric::cell2scr(int &sx,int &sy,int cx,int cy,int cz) // grid -> screen { sx=pan_x+(cxs*cx)+((cy&1)*cxs2); sy=pan_y+(cys*cy/2)-(czs*cz); } //--------------------------------------------------------------------------- void isometric::scr2cell(int &cx,int &cy,int &cz,int sx,int sy) // screen -> grid { // rough cell ground estimation (no z value yet) cy=(2*(sy-pan_y))/cys; cx= (sx-pan_x-((cy&1)*cxs2))/cxs; cz=0; // isometric tile shape crossing correction int xx,yy; cell2scr(xx,yy,cx,cy,cz); xx=sx-xx; mx0=cx; yy=sy-yy; my0=cy; if (xx<=cxs2) { if (yy> xx *cys/cxs) { cy++; if (int(cy&1)!=0) cx--; } } else { if (yy>(cxs-xx)*cys/cxs) { cy++; if (int(cy&1)==0) cx++; } } } //--------------------------------------------------------------------------- 

    मैंने आपके लेआउट का इस्तेमाल किया था (मुझे लगता है कि इस तरह से कुछ गलत गलती नहीं की उम्मीद है कि मेरा कन्वर्ट करने के लिए मील लिया):

    ख़ाका

    • लाल क्रॉस cell2scr(x,y,0,0,0) द्वारा लौटा निर्देशांक cell2scr(x,y,0,0,0)
    • हरी पार माउस समन्वय प्रस्तुत करता है
    • एक्वा हाइलाइट प्रस्तुत सेल स्थिति दर्शाता है

    अगर आप पूर्णांक अंकगणित का उपयोग कर रहे हैं तो सावधान रहें, यदि आप आधा आकारों से विभाजित / गुणा करते हैं तो आप सटीकता खो सकते हैं। पूर्ण आकार का उपयोग करें और इस तरह के मामलों के लिए 2 से परिणाम विभाजित करें (बहुत समय व्यतीत करें जो कि पहले से एक है)।

    cell2scr 2 cell2scr बहुत आसान है। स्क्रीन की स्थिति पेंस ऑफ़सेट + सेल की स्थिति है जो उसके आकार (चरण) से गुणा करती है। x अक्ष को भी / अजीब पंक्तियों के लिए सुधार की आवश्यकता होती है (जो कि ((cy&1)*cxs2) के लिए है और y अक्ष को z अक्ष ( ((cy&1)*cxs2) द्वारा स्थानांतरित किया गया है। मेरी स्क्रीन में ऊपरी बाएं कोने में बिंदु (0,0) है, +x अक्ष सही इंगित कर रहा है और +y इंगित कर रहा है।

    scr2cell 2 scr2cell के समीकरणों से बीजीय रूप से हल स्क्रीन स्थिति से किया जाता है जबकि z=0 मानते हुए केवल ग्रिड मैदान का चयन किया जाता है। उस के शीर्ष पर, यहां तक ​​कि बस / अजीब सुधार जोड़ा गया है यदि माउस की स्थिति सेल क्षेत्र से बाहर है

  2. स्कैन पड़ोसियों

    scr2cell(x,y,z,mouse_x,mouse_y) सिर्फ वह सेल देता है जहां आपका माउस जमीन पर है इसलिए यदि आप अपनी मौजूदा चयन कार्यक्षमता जोड़ना चाहते हैं तो आपको उस स्थिति और कुछ पड़ोसी कोशिकाओं पर शीर्ष सेल को स्कैन करने और कम से कम दूरी वाला एक का चयन करना होगा

    पूरे ग्रिड / नक्शा को वापस लौटाने की स्थिति के आसपास कुछ कोशिकाओं को स्कैन करने की आवश्यकता नहीं है। उस चीज़ को काफी तेज करना चाहिए

    मैं इसे इस तरह करता हूं:

    स्कैन पैटर्न

    लाइनों की संख्या सेल z अक्ष का आकार ( czs ), अधिकतम z परतों ( gzs ) और सेल आकार ( cys ) पर cys । स्कैन के साथ मेरा मेरा C ++ कोड ऐसा दिखता है:

     // grid size const int gxs=15; const int gys=30; const int gzs=8; // my map (all the cells) int map[gzs][gys][gxs]; void isometric::scr2cell(int &cx,int &cy,int &cz,int sx,int sy) { // rough cell ground estimation (no z value yet) cy=(2*(sy-pan_y))/cys; cx= (sx-pan_x-((cy&1)*cxs2))/cxs; cz=0; // isometric tile shape crossing correction int xx,yy; cell2scr(xx,yy,cx,cy,cz); xx=sx-xx; yy=sy-yy; if (xx<=cxs2) { if (yy> xx *cys/cxs) { cy++; if (int(cy&1)!=0) cx--; } } else { if (yy>(cxs-xx)*cys/cxs) { cy++; if (int(cy&1)==0) cx++; } } // scan closest neighbors int x0=-1,y0=-1,z0=-1,a,b,i; #define _scann \ if ((cx>=0)&&(cx<gxs)) \ if ((cy>=0)&&(cy<gys)) \ { \ for (cz=0;(map[cz+1][cy][cx]!=_cell_type_empty)&&(cz<czs-1);cz++); \ cell2scr(xx,yy,cx,cy,cz); \ if (map[cz][cy][cx]==_cell_type_full) yy-=czs; \ xx=(sx-xx); yy=((sy-yy)*cxs)/cys; \ a=(xx+yy); b=(xx-yy); \ if ((a>=0)&&(a<=cxs)&&(b>=0)&&(b<=cxs)) \ if (cz>=z0) { x0=cx; y0=cy; z0=cz; } \ } _scann; // scan actual cell for (i=gzs*czs;i>=0;i-=cys) // scan as many lines bellow actual cell as needed { cy++; if (int(cy&1)!=0) cx--; _scann; cx++; _scann; cy++; if (int(cy&1)!=0) cx--; _scann; } cx=x0; cy=y0; cz=z0; // return remembered cell coordinate #undef _scann } 

    यह हमेशा शीर्ष सेल (सभी संभव से अधिक से अधिक) का चयन करता है जब माउस के साथ खेलते समय इसे सही तरीके से महसूस होता है (कम से कम मेरे लिए):

    स्कैन परिणाम

यहां मेरे आईओमेट्रिक इंजन के लिए पूर्ण वीसीएल / सी ++ स्रोत है जो आज मैं इसके लिए पर्दाफाश किया है:

  //--------------------------------------------------------------------------- //--- Isometric ver: 1.01 --------------------------------------------------- //--------------------------------------------------------------------------- #ifndef _isometric_h #define _isometric_h //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // colors 0x00BBGGRR DWORD col_back =0x00000000; DWORD col_grid =0x00202020; DWORD col_xside=0x00606060; DWORD col_yside=0x00808080; DWORD col_zside=0x00A0A0A0; DWORD col_sel =0x00FFFF00; //--------------------------------------------------------------------------- //--- configuration defines ------------------------------------------------- //--------------------------------------------------------------------------- // #define isometric_layout_1 // x axis: righ+down, y axis: left+down // #define isometric_layout_2 // x axis: righ , y axis: left+down //--------------------------------------------------------------------------- #define isometric_layout_2 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- /* // grid size const int gxs=4; const int gys=16; const int gzs=8; // cell size const int cxs=100; const int cys= 50; const int czs= 15; */ // grid size const int gxs=15; const int gys=30; const int gzs=8; // cell size const int cxs=40; const int cys=20; const int czs=10; const int cxs2=cxs>>1; const int cys2=cys>>1; // cell types enum _cell_type_enum { _cell_type_empty=0, _cell_type_ground, _cell_type_full, _cell_types }; //--------------------------------------------------------------------------- class isometric { public: // screen buffer Graphics::TBitmap *bmp; DWORD **pyx; int xs,ys; // isometric map int map[gzs][gys][gxs]; // mouse int mx,my,mx0,my0; // [pixel] TShiftState sh,sh0; int sel_x,sel_y,sel_z; // [grid] // view int pan_x,pan_y; // constructors for compiler safety isometric(); isometric(isometric& a) { *this=a; } ~isometric(); isometric* operator = (const isometric *a) { *this=*a; return this; } isometric* operator = (const isometric &a); // Window API void resize(int _xs,int _ys); // [pixels] void mouse(int x,int y,TShiftState sh); // [mouse] void draw(); // auxiliary API void cell2scr(int &sx,int &sy,int cx,int cy,int cz); void scr2cell(int &cx,int &cy,int &cz,int sx,int sy); void cell_draw(int x,int y,int tp,bool _sel=false); // [screen] void map_random(); }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- isometric::isometric() { // init screen buffers bmp=new Graphics::TBitmap; bmp->HandleType=bmDIB; bmp->PixelFormat=pf32bit; pyx=NULL; xs=0; ys=0; resize(1,1); // init map int x,y,z,t; t=_cell_type_empty; // t=_cell_type_ground; // t=_cell_type_full; for (z=0;z<gzs;z++,t=_cell_type_empty) for (y=0;y<gys;y++) for (x=0;x<gxs;x++) map[z][y][x]=t; // init mouse mx =0; my =0; sh =TShiftState(); mx0=0; my0=0; sh0=TShiftState(); sel_x=-1; sel_y=-1; sel_z=-1; // init view pan_x=0; pan_y=0; } //--------------------------------------------------------------------------- isometric::~isometric() { if (pyx) delete[] pyx; pyx=NULL; if (bmp) delete bmp; bmp=NULL; } //--------------------------------------------------------------------------- isometric* isometric::operator = (const isometric &a) { resize(a.xs,a.ys); bmp->Canvas->Draw(0,0,a.bmp); int x,y,z; for (z=0;z<gzs;z++) for (y=0;y<gys;y++) for (x=0;x<gxs;x++) map[z][y][x]=a.map[z][y][x]; mx=a.mx; mx0=a.mx0; sel_x=a.sel_x; my=a.my; my0=a.my0; sel_y=a.sel_y; sh=a.sh; sh0=a.sh0; sel_z=a.sel_z; pan_x=a.pan_x; pan_y=a.pan_y; return this; } //--------------------------------------------------------------------------- void isometric::resize(int _xs,int _ys) { if (_xs<1) _xs=1; if (_ys<1) _ys=1; if ((xs==_xs)&&(ys==_ys)) return; bmp->SetSize(_xs,_ys); xs=bmp->Width; ys=bmp->Height; if (pyx) delete pyx; pyx=new DWORD*[ys]; for (int y=0;y<ys;y++) pyx[y]=(DWORD*) bmp->ScanLine[y]; // center view cell2scr(pan_x,pan_y,gxs>>1,gys>>1,0); pan_x=(xs>>1)-pan_x; pan_y=(ys>>1)-pan_y; } //--------------------------------------------------------------------------- void isometric::mouse(int x,int y,TShiftState shift) { mx0=mx; mx=x; my0=my; my=y; sh0=sh; sh=shift; scr2cell(sel_x,sel_y,sel_z,mx,my); if ((sel_x<0)||(sel_y<0)||(sel_z<0)||(sel_x>=gxs)||(sel_y>=gys)||(sel_z>=gzs)) { sel_x=-1; sel_y=-1; sel_z=-1; } } //--------------------------------------------------------------------------- void isometric::draw() { int x,y,z,xx,yy; // clear space bmp->Canvas->Brush->Color=col_back; bmp->Canvas->FillRect(TRect(0,0,xs,ys)); // grid DWORD c0=col_zside; col_zside=col_back; for (y=0;y<gys;y++) for (x=0;x<gxs;x++) { cell2scr(xx,yy,x,y,0); cell_draw(xx,yy,_cell_type_ground,false); } col_zside=c0; // cells for (z=0;z<gzs;z++) for (y=0;y<gys;y++) for (x=0;x<gxs;x++) { cell2scr(xx,yy,x,y,z); cell_draw(xx,yy,map[z][y][x],(x==sel_x)&&(y==sel_y)&&(z==sel_z)); } // mouse0 cross bmp->Canvas->Pen->Color=clBlue; bmp->Canvas->MoveTo(mx0-10,my0); bmp->Canvas->LineTo(mx0+10,my0); bmp->Canvas->MoveTo(mx0,my0-10); bmp->Canvas->LineTo(mx0,my0+10); // mouse cross bmp->Canvas->Pen->Color=clGreen; bmp->Canvas->MoveTo(mx-10,my); bmp->Canvas->LineTo(mx+10,my); bmp->Canvas->MoveTo(mx,my-10); bmp->Canvas->LineTo(mx,my+10); // grid origin cross bmp->Canvas->Pen->Color=clRed; bmp->Canvas->MoveTo(pan_x-10,pan_y); bmp->Canvas->LineTo(pan_x+10,pan_y); bmp->Canvas->MoveTo(pan_x,pan_y-10); bmp->Canvas->LineTo(pan_x,pan_y+10); bmp->Canvas->Font->Charset=OEM_CHARSET; bmp->Canvas->Font->Name="System"; bmp->Canvas->Font->Pitch=fpFixed; bmp->Canvas->Font->Color=clAqua; bmp->Canvas->Brush->Style=bsClear; bmp->Canvas->TextOutA(5, 5,AnsiString().sprintf("Mouse: %ix %i",mx,my)); bmp->Canvas->TextOutA(5,20,AnsiString().sprintf("Select: %ix %ix %i",sel_x,sel_y,sel_z)); bmp->Canvas->Brush->Style=bsSolid; } //--------------------------------------------------------------------------- void isometric::cell2scr(int &sx,int &sy,int cx,int cy,int cz) { #ifdef isometric_layout_1 sx=pan_x+((cxs*(cx-cy))/2); sy=pan_y+((cys*(cx+cy))/2)-(czs*cz); #endif #ifdef isometric_layout_2 sx=pan_x+(cxs*cx)+((cy&1)*cxs2); sy=pan_y+(cys*cy/2)-(czs*cz); #endif } //--------------------------------------------------------------------------- void isometric::scr2cell(int &cx,int &cy,int &cz,int sx,int sy) { int x0=-1,y0=-1,z0=-1,a,b,i,xx,yy; #ifdef isometric_layout_1 // rough cell ground estimation (no z value yet) // translate to (0,0,0) top left corner of the grid xx=sx-pan_x-cxs2; yy=sy-pan_y+cys2; // change aspect to square cells cxs x cxs yy=(yy*cxs)/cys; // use the dot product with axis vectors to compute grid cell coordinates cx=(+xx+yy)/cxs; cy=(-xx+yy)/cxs; cz=0; // scan closest neighbors #define _scann \ if ((cx>=0)&&(cx<gxs)) \ if ((cy>=0)&&(cy<gys)) \ { \ for (cz=0;(map[cz+1][cy][cx]!=_cell_type_empty)&&(cz<czs-1);cz++); \ cell2scr(xx,yy,cx,cy,cz); \ if (map[cz][cy][cx]==_cell_type_full) yy-=czs; \ xx=(sx-xx); yy=((sy-yy)*cxs)/cys; \ a=(xx+yy); b=(xx-yy); \ if ((a>=0)&&(a<=cxs)&&(b>=0)&&(b<=cxs)) \ if (cz>=z0) { x0=cx; y0=cy; z0=cz; } \ } _scann; // scan actual cell for (i=gzs*czs;i>=0;i-=cys) // scan as many lines bellow actual cell as needed { cy++; _scann; cx++; cy--; _scann; cy++; _scann; } cx=x0; cy=y0; cz=z0; // return remembered cell coordinate #undef _scann #endif #ifdef isometric_layout_2 // rough cell ground estimation (no z value yet) cy=(2*(sy-pan_y))/cys; cx= (sx-pan_x-((cy&1)*cxs2))/cxs; cz=0; // isometric tile shape crossing correction cell2scr(xx,yy,cx,cy,cz); xx=sx-xx; yy=sy-yy; if (xx<=cxs2) { if (yy> xx *cys/cxs) { cy++; if (int(cy&1)!=0) cx--; } } else { if (yy>(cxs-xx)*cys/cxs) { cy++; if (int(cy&1)==0) cx++; } } // scan closest neighbors #define _scann \ if ((cx>=0)&&(cx<gxs)) \ if ((cy>=0)&&(cy<gys)) \ { \ for (cz=0;(map[cz+1][cy][cx]!=_cell_type_empty)&&(cz<czs-1);cz++); \ cell2scr(xx,yy,cx,cy,cz); \ if (map[cz][cy][cx]==_cell_type_full) yy-=czs; \ xx=(sx-xx); yy=((sy-yy)*cxs)/cys; \ a=(xx+yy); b=(xx-yy); \ if ((a>=0)&&(a<=cxs)&&(b>=0)&&(b<=cxs)) \ if (cz>=z0) { x0=cx; y0=cy; z0=cz; } \ } _scann; // scan actual cell for (i=gzs*czs;i>=0;i-=cys) // scan as many lines bellow actual cell as needed { cy++; if (int(cy&1)!=0) cx--; _scann; cx++; _scann; cy++; if (int(cy&1)!=0) cx--; _scann; } cx=x0; cy=y0; cz=z0; // return remembered cell coordinate #undef _scann #endif } //--------------------------------------------------------------------------- void isometric::cell_draw(int x,int y,int tp,bool _sel) { TPoint pnt[5]; bmp->Canvas->Pen->Color=col_grid; if (tp==_cell_type_empty) { if (!_sel) return; bmp->Canvas->Pen->Color=col_sel; pnt[0].x=x; pnt[0].y=y ; pnt[1].x=x+cxs2; pnt[1].y=y+cys2; pnt[2].x=x+cxs; pnt[2].y=y ; pnt[3].x=x+cxs2; pnt[3].y=y-cys2; pnt[4].x=x; pnt[4].y=y ; bmp->Canvas->Polyline(pnt,4); } else if (tp==_cell_type_ground) { if (_sel) bmp->Canvas->Brush->Color=col_sel; else bmp->Canvas->Brush->Color=col_zside; pnt[0].x=x; pnt[0].y=y ; pnt[1].x=x+cxs2; pnt[1].y=y+cys2; pnt[2].x=x+cxs; pnt[2].y=y ; pnt[3].x=x+cxs2; pnt[3].y=y-cys2; bmp->Canvas->Polygon(pnt,3); } else if (tp==_cell_type_full) { if (_sel) bmp->Canvas->Brush->Color=col_sel; else bmp->Canvas->Brush->Color=col_xside; pnt[0].x=x+cxs2; pnt[0].y=y+cys2; pnt[1].x=x+cxs; pnt[1].y=y; pnt[2].x=x+cxs; pnt[2].y=y -czs; pnt[3].x=x+cxs2; pnt[3].y=y+cys2-czs; bmp->Canvas->Polygon(pnt,3); if (_sel) bmp->Canvas->Brush->Color=col_sel; else bmp->Canvas->Brush->Color=col_yside; pnt[0].x=x; pnt[0].y=y; pnt[1].x=x+cxs2; pnt[1].y=y+cys2; pnt[2].x=x+cxs2; pnt[2].y=y+cys2-czs; pnt[3].x=x; pnt[3].y=y -czs; bmp->Canvas->Polygon(pnt,3); if (_sel) bmp->Canvas->Brush->Color=col_sel; else bmp->Canvas->Brush->Color=col_zside; pnt[0].x=x; pnt[0].y=y -czs; pnt[1].x=x+cxs2; pnt[1].y=y+cys2-czs; pnt[2].x=x+cxs; pnt[2].y=y -czs; pnt[3].x=x+cxs2; pnt[3].y=y-cys2-czs; bmp->Canvas->Polygon(pnt,3); } } //--------------------------------------------------------------------------- void isometric::map_random() { int i,x,y,z,x0,y0,r,h; // clear for (z=0;z<gzs;z++) for (y=0;y<gys;y++) for (x=0;x<gxs;x++) map[z][y][x]=_cell_type_empty; // add pseudo-random bumps Randomize(); for (i=0;i<10;i++) { x0=Random(gxs); y0=Random(gys); r=Random((gxs+gys)>>3)+1; h=Random(gzs); for (z=0;(z<gzs)&&(r);z++,r--) for (y=y0-r;y<y0+r;y++) if ((y>=0)&&(y<gys)) for (x=x0-r;x<x0+r;x++) if ((x>=0)&&(x<gxs)) map[z][y][x]=_cell_type_full; } } //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- 

लेआउट सिर्फ निर्देशांक प्रणाली अक्ष निर्देशों को परिभाषित करता है (आपके लिए #define isometric_layout_2 उपयोग करें)। यह बोरेल्स वीसीएल Graphics::TBitmap का उपयोग करता है ताकि यदि आप बोर्लैंड का उपयोग किसी भी जीडीआई बिटमैप में नहीं बदलते या अपने Graphics::TBitmap भाग को ओवरराइट करते हैं (यह केवल draw() लिए प्रासंगिक है और इसका resize() बदलता है)। TShiftState भी TShiftState का हिस्सा है, यह सिर्फ माउस बटन और shift,alt,ctrl जैसी विशेष कुंजियों की shift,alt,ctrl ताकि आप इसके बजाय bool उपयोग कर सकें (वर्तमान में इसका उपयोग नहीं किया जाता क्योंकि मेरे पास कोई क्लिक कार्यक्षमता नहीं है)।

यहां मेरा बोर्लैंड खिड़की कोड (उस पर एक टाइमर के साथ एकल फॉर्म ऐप) ताकि आप इसका उपयोग कैसे करें देखें:

 //$$---- Form CPP ---- //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "win_main.h" #include "isometric.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TMain *Main; isometric iso; //--------------------------------------------------------------------------- void TMain::draw() { iso.draw(); Canvas->Draw(0,0,iso.bmp); } //--------------------------------------------------------------------------- __fastcall TMain::TMain(TComponent* Owner) : TForm(Owner) { Cursor=crNone; iso.map_random(); } //--------------------------------------------------------------------------- void __fastcall TMain::FormResize(TObject *Sender) { iso.resize(ClientWidth,ClientHeight); draw(); } //--------------------------------------------------------------------------- void __fastcall TMain::FormPaint(TObject *Sender) { draw(); } //--------------------------------------------------------------------------- void __fastcall TMain::tim_redrawTimer(TObject *Sender) { draw(); } //--------------------------------------------------------------------------- void __fastcall TMain::FormMouseMove(TObject *Sender, TShiftState Shift, int X,int Y) { iso.mouse(X,Y,Shift); draw(); } void __fastcall TMain::FormMouseDown(TObject *Sender, TMouseButton Button,TShiftState Shift, int X, int Y) { iso.mouse(X,Y,Shift); draw(); } void __fastcall TMain::FormMouseUp(TObject *Sender, TMouseButton Button,TShiftState Shift, int X, int Y) { iso.mouse(X,Y,Shift); draw(); } //--------------------------------------------------------------------------- void __fastcall TMain::FormDblClick(TObject *Sender) { iso.map_random(); } //--------------------------------------------------------------------------- 

[संपादन 1] ग्राफिक्स दृष्टिकोण

सरल ओपनजीएल जीयूआई फ्रेमवर्क उपयोगकर्ता इंटरैक्शन सलाह पर एक नज़र डालें ? ।

मुख्य विचार छाया स्क्रीन बफर बनाना है जहां गाया सेल का आईडी संग्रहीत है। यह कोड में कुछ लाइनों के साथ O(1) में पिक्सेल परिपूर्ण प्रेत / सेल चयन प्रदान करता है।

  1. छाया स्क्रीन बफर idx[ys][xs] बनाएं

    इसमें आपके मानचित्र के दृश्य के रूप में एक ही संकल्प होना चाहिए और एकल पिक्सेल (नक्शा ग्रिड सेल इकाइयों में) के अंदर रेंडर सेल का (x,y,z) मान को संचय करने में सक्षम होना चाहिए। मैं 32 बिट पिक्सेल प्रारूप का उपयोग करता हूं इसलिए मैं x,y और z लिए 8 बिट्स के लिए 12 बिट्स का चयन करता हूं

     DWORD color = (x) | (y<<12) | (z<<24) 
  2. नक्शा बदलने से पहले इस बफर को साफ़ करें

    मैं खाली रंग के रूप में 0xFFFFFFFF उपयोग करता हूं, इसलिए यह सेल (0,0,0) साथ टकराने नहीं है।

  3. नक्शा सेल प्रेत रेंडरिंग पर

    जब भी आप स्क्रीन बफर pyx[y][x]=color लिए पिक्सेल प्रदान करते हैं, तो आप छाया स्क्रीन बफर idx[y][x]=c पिक्सेल भी रेंडर करते हैं जहां c ग्रिड इकाइयों में सेल स्थिति को एन्कोड किया जाता है (देखें # 1 )।

  4. माउस क्लिक पर (या जो कुछ भी)

    आपको माउस mx,my की स्क्रीन स्थिति मिली है mx,my ऐसा इसलिए है अगर यह सीमा में है तो छाया बैफर को पढ़ें और चयनित सेल की स्थिति प्राप्त करें।

     c=idx[my][mx] if (c!=0xFFFFFFFF) { x= c &0x00000FFF; y=(c>>12)&0x00000FFF; z=(c>>24)&0x000000FF; } else { // here use the grid floor cell position formula from above approach if needed // or have empty cell rendered for z=0 with some special sprite to avoid this case. } 

    इस मैप (स्क्रीन) को एन्कोडिंग के साथ:

    स्क्रीन

    इस तरह छाया स्क्रीन करने के लिए भी गाया जाता है:

    साया

    चयन पिक्सेल परिपूर्ण है यदि आप शीर्ष पर क्लिक करते हैं, तो कोई फर्क नहीं पड़ता …

    ये टाइलें हैं:

     Title: Isometric 64x64 Outside Tileset Author: Yar URL: http://opengameart.org/content/isometric-64x64-outside-tileset License(s): * CC-BY 3.0 http://creativecommons.org/licenses/by/3.0/legalcode 

    और यहां Win32 डेमो:

    • डेमो