伊莉討論區

標題: 坦克大戰 [打印本頁]

作者: daviddr    時間: 2009-7-24 12:51 AM     標題: 坦克大戰

本帖最後由 daviddr 於 2009-7-24 11:35 PM 編輯

20 關,每回 25 隻敵人,不含音效資料,不含雪地地形,
吃越多星星能力越高,最後能在河面行走。
可雙人操作,按 Esc 退出遊戲。
P1 按 S、W、D、A 控制方向,H 發射子彈,
P2 按方向鍵控制方向,Num0 發射子彈。

若發現 bug 可在此帖 post,
但.. 可能沒時間 debug 吆 :-)

程式碼僅供私人學習參考。
  1. //坦克大戰雛形,daviddr, 2009, 7 天寫完。
  2. #pragma comment (lib,"WINMM.LIB")
  3. #undef UNICODE
  4. #include <windows.h>
  5. #include <mmsystem.h>
  6. #include <stdio.h>
  7. #include <time.h>
  8. #define TankWar(o) m##o##n(){int daviddr(907);}\
  9.         using namespace ImageSet;struct
  10. extern"C" WINBASEAPI HWND WINAPI GetConsoleWindow();
  11. enum {UP=0, RIGHT, DOWN, LEFT};
  12. namespace Bonus {enum{LIFE, CLOCK, SHOVEL, BOMB, STAR, HELMET};};
  13.    
  14. struct Image                                        //影像物件
  15. {
  16.     int  w, h, *data;
  17.     int& operator[] (int i)    {return data[i];}
  18.     void create (int W, int H) {w=W; h=H; data = new int[w*h];}
  19.     void free ()               {delete[] data; data=0;}
  20.     void draw (const Image& in, int sx, int sy, int dir=UP)
  21.     {        
  22.         #define DRAW if (0x8F8F8E^in.data[j]) data[i] = in.data[j];
  23.         int i, j=0, x, y, W=in.w, H=in.h;
  24.         int beg = sy*w+sx, sz = W*H, dw=w-W;
  25.         if (0==dir) for (i=beg; j<sz; i+=dw)
  26.             for (x=0; x<W; ++x, ++i, ++j) {DRAW} else
  27.         if (1==dir) for (i=beg, x=0; x<W; i+=dw, ++x)
  28.             for (y=H-1; y>=0; --y, ++i) {j=y*W+x; DRAW} else
  29.         if (2==dir) for (i=beg, y=H-1; y>=0; i+=dw, --y)
  30.             for (x=0; x<W; ++x, ++i) {j=y*W+x; DRAW}
  31.         else for (i=beg, x=0; x<W; i+=dw, ++x)
  32.             for (y=0; y<H; ++y, ++i) {j=y*W+x; DRAW}
  33.     }
  34.     void draw16 (const Image& in, int sx, int sy, int c)
  35.     {
  36.         int i=sy*w+sx, j=0, x, sz = in.h*in.w, dw=w-in.w;
  37.         for (short* p=(short*)in.data; j<sz; i+=dw)
  38.             for (x=0; x<in.w; ++x, ++i)
  39.                 if (p[j++]^0x6318) data[i] = c;
  40.     }
  41.     void draw32 (const Image& in, int sx, int sy, int c)
  42.     {
  43.         int i, j=0, x, sz = in.h*in.w, dw=w-in.w;
  44.         for (i=sy*w+sx; j<sz; i+=dw)
  45.             for (x=0; x<in.w; ++x, ++i)
  46.                 if (in.data[j++]^0xC0C0C0) data[i] = c;
  47.     }
  48. };

  49. namespace ImageSet
  50. {
  51.     enum {NUL=-1, BRICK, CONCRETE, TREE, RIVER, ROAD, HAWK, STONE, //6
  52.           STAR, SHIELD=STAR+4, SHIELD2, PLAYER, ENEMY=PLAYER+8,
  53.           EXPLODE=ENEMY+6, EXPLODE2, BONUS, BULLET=BONUS+6, PLAYER2,
  54.           RENEMY=PLAYER2+8, YENEMY=RENEMY+6, GENEMY=YENEMY+2, HOLE=54};
  55.     const int N_OBJ = 36+8+6+4+1;                       //物件數目
  56.     int   palette[N_OBJ];
  57.     Image obj[N_OBJ];
  58.       
  59.     char obj_pal[][4] = {                               //物件色盤索引
  60.         {1,2,3},{3,4,5},{6,7,8,9},{10,11},{10,11},{1,0,3},   //5
  61.         {2,0,3},{9,12},{9,12},{9,12},{9,12},{9,12},{9,12},   //12
  62.         {9,13,14,15},{0},{0},{0},{0},{0},{0},{0},{9,16,4,17},//21
  63.         {0},{0},{0},{0},{0},{9,18,19,20},{21,9,22,12},{9,16,4,12},
  64.         {0},{0},{0},{0},{0},{9,4},{9,6,23,24},{9,25,21,17}
  65.     };
  66.     char* hex_pal[] = { "202020",                       //色盤總表
  67.         "990000","CC6600","868686","C0C0C0","E3E3E3","006600",  //6
  68.         "008000","CCFF00","8F8F8E","0066FF","00FFFF","F1F1F1",  //12
  69.         "A06000","FFA040","FFC080","003366","DDDDDD","800000",  //18
  70.         "FF0000","FFFFFF","FF3300","800080","00AB47","B8F8D8","990099"
  71.     };
  72.     char* hex_img[] = {
  73.     "3P2CP0ACP0AWP6P0EP0EW","GF0AS1AS1AS1AS1A5@6","`2@0P`1@P0P0P4R@1Q@0P1"
  74.     "P@R@0@0TT@Q`Q@R`","4@17@60@1@22@0@170@51@2@0","6@0@51@42@1@06@2@31@0"
  75.     "@2@6","OQKQ@QBRCQ@SBP0PAS@RBQBR@U@Q@UAP0W0PA@R0U0R@AS0Q0SAA[ABR@Q@RB"
  76.     "FQFESECWCCQ@Q@QCO","OOC0JB1@PHB0@RGA0@TF@1@XB@0@ZA1@ZA0AWAQ@0@UAPAQ@"
  77.     "0BREPA0DPEPA0N0N0N","***6@76@76@75B62H35B66@76@76@7****","*6@76@76@7"
  78.     "6@75C54E40L14E45C56@76@76@76@7**","*6@76@76@75B65B63F40L13F45B65B66@"
  79.     "76@76@7**","6@76@76@75B65B64D52I2O2I24D55B65B66@76@76@76@7","5C54@3@"
  80.     "43@5@33@5@31A7A10@;@0@=@@=@@=@0@;@01A7A13@5@33@5@34@3@44@3@45C5","1A"
  81.     "7A10@1@5@1@0@3A1A3@@5A5@0@;@01@9@11@9@12@7@22@7@21@9@11@9@10@;@0@5A5"
  82.     "@@3A1A3@0@1@5@1@01A7A1","5`65`6`A2`3`A`P`2`3@QA`0`P`A1B`PbSBQAaPaSB`"
  83.     "PaP`P@R@QAaP`P@RB`PbPAR@QA`@aRD`P`0D1@QPA7BPA7B","5`65`6`Q2`3`QA`2`3"
  84.     "B`P`0`P`A1@QAbSD`PaPaS@QAaP`P@RB`PaP`P@R@QAbPARB`P`@aRBQA`0D1B`Q7@Q`"
  85.     "Q7@Q","5`65`65`6`Q1@`@2`QAb@`F`QaP`PCQAPaREAP`P`P@PD`Q`P`P@PBQAP`P`P"
  86.     "@PD`Q`QAPBQAPaRE`P`HQB7B","5`65`65`6AP1@`@2`A`Qa@`DQAPaP`PE`QaRCQ`Q`"
  87.     "P`P@PBQAP`P`P@PD`Q`P`P@PBQAP`QAPD`QaRCQA`J`P@7@Q","4`Q55`6PA0`@`A1`A"
  88.     "`Q@`@`EP@PaTD`P`QaSAP@P`Q`P@RB`P`Q`P@RAP@P`Q`P@RB`P`Q`P@RAP@PaQAPD`Q"
  89.     "aRDP@QJ`Q7AP","4`Q55`6`A0`@`A1`@PR@`@`F`PaTCPQ`QaSB`P`Q`P@RAPQ`Q`P@R"
  90.     "B`P`Q`P@RAPQ`Q`P@RB`PaQAPCPRaRE`QIPR7B","PA2`P2`A`PbP`P@R@P@QaP`P@Q@"
  91.     "P@`QaP`P@Q@Q@QcRAP@`Q`UAQ@Q`PbQAP@`Q`P`Q@PAQ@Q`P`Q@PAP@`Q`QBPAQ@Q`UA"
  92.     "P@`QFP@Q@PHPA`Q7@Q","PA2`P2`@P@PbP`P@RA`QaP`P@Q@Q@QaP`P@Q@P@`QcRAQ@Q"
  93.     "`UAP@`Q`PbQAQ@Q`P`Q@PAP@`Q`P`Q@PAQ@Q`QBPAP@`Q`UAQ@QFP@P@`PHP@P@Q7@P@"
  94.     ,"5`65`6`Q1P`@2`QAP0`P`A1PA`QaP`CRAPaRBPA`Q`Q@QARAP`PA`PAPA`Q`P@aPARA"
  95.     "P`TAPA`QaRBRAP0`QA1PA`Q1B2R=","5`65`6AP1P`@2`A`Q0`P`A1RAPaP`CPA`QaRB"
  96.     "RAP`Q@QAPA`Q`PA`PARAP`P@aPAPA`Q`TARAPaRBPA`Q0`QA1RAP1B2PA=","6`50A0a"
  97.     "@`@Q0@00P@b@`@S00APa@`BP@02Q`P`PAP12P`T@P10AP`Q@Q@P@00P@P`PA`P@Q00AP"
  98.     "`P@aP@P@02P`T@P10ARbAP@00P@PFQ00A0BPB0@00A0BPB0@0","6`50P@0a@`@Q0P00"
  99.     "Ab@`@R@00APa@`BP@02Q`P`PAP12P`T@P10P@P`Q@Q@Q00AP`PA`P@P@00AP`P@aP@P@"
  100.     "02P`T@P10P@RbAQ00APFP@00A0BPB0@00A0BPB0@0","AQ@aP@QA0`T`@T0AP`Q`@QB0"
  101.     "`Q`Q`@`P@Q0APaP`@`C0`QeAQ0AP`Q@QC0`Q`PA`PAQ0AP`P@aPC0`Q`TAQ0AP`TC0`R"
  102.     "DP@Q0APFPA0`Q2P2@Q0","`R@aP@S0AS`@RA0`Q`Q`@Q@Q0AP`Q`@`PB0`QaP`@`AQ0A"
  103.     "PeC0`Q`Q@QAQ0AP`PA`PC0`Q`P@aPAQ0AP`TC0`Q`TAQ0AQDPB0`QFR0AP2P2B0","1@"
  104.     "1@2`30`0@0`@0`@2`A`@0@`0`@0a@1@`Ab@`A02`Pb@Pa0@0@0@`P0PaA1@0@bR0@baA"
  105.     "`0Q0aA01@a@R`A0@2`P`@0@`P`1C`PbP@a02`@`Aa0A`2A`@0@`2@1`1`0@0A2","`ON"
  106.     "P`B`LQaF`@@P`BPD`R@PcQC`PAAQCa@bP@PbA`QA`PBBQA`Pb0b@a@`P@`QAPBBPAaQ0"
  107.     "PiP@`PEE`PcPeQa@`P@aBCQhQcPbQaPACPc@`QcPeQaR@DaAd0c0cPa@`Q@Bb@b0b1a1"
  108.     "`0`Pc@`P@APf2`0`2`0cPa@`P`A`Pa@b0@1`P1`0dP`@`RBP`@Pc0a0@0`0b0`P`@`Q`"
  109.     "@BQ@Pc3`P2`0ePB@`@b@P`4b@`0eQaA@i1P@a3cPbQ@b0Pc0`0a0Pa0@`2eP@cPb0a3@"
  110.     "1`0f@aP`PaP`0c1`1`3dPa@aPSaQ`1Q`2a1aQc@`@@Q@i0e0bPa@`P`DfPePh@`PCa@a"
  111.     "@f@Q@fP`P`CbAQbPbAbP@aAPaCeQb@cPaQA`Q`@CPcP@c@bRaT`AA`AP`QARa@R@`0aQ"
  112.     "`CB`AQEbBbQC`AAP@PD`PBfQ`AP@PA@`APF`BaQ`RCP@`@`I`DR@PHP","0lP`<``0K`"
  113.     "`0D`Q0B``0@cR@0A``0@3R@0A``0B`QAP@0@``0A`TA0@``0@QcR@0``0@P`P5P0``0@"
  114.     "0`0`0`0`@P0``0A0V0@``0B6A`PlP","0lP`<``0C`P`P0B``0CP2`P0@``0BS3@``0A"
  115.     "PcP0B``0@Pa@bP0A``0@Pa@bP0A``0@Pb@aP0A``0@0PcP0B``0A0S0C``0B3D``0K`P"
  116.     "lP","0lP`<``0G`B``0G`PA``0GR@``0F`2@``0B`A`0C``0AaP`0D``0@aP@P0D``0@"
  117.     "`P@R0C``0@T0D``0@S0E``0@3F`PlP","0lP`<``0BbQ0B``0B`P@1P0A``0A`R@1P0@"
  118.     "``0@`P@`P@P0P0@``0@R1P1P0@``0@`P@`P@P0P0@``0@R1P1P0@``0@`P@`P@P1A``0"
  119.     "AP@1P0C``0B`Q0D``0B2E`PlP","0lP`<``0D`0D``0CaP0C``0CaP0C``0dQc0``0@R"
  120.     "`P`R1``0APcQ1@``0AaQaP0A``0@P`Q0Q`P0@``0@`Q2Q`0@``0@P2A1P0@``0@1E1@`"
  121.     "PlP","0lP`<``0K``0K``0BbQ0B``0AaT0A``0A`U0A``0AV0A``0@W0A``0@4S0@``0"
  122.     "E4@``0K``0K`PlP","0@1B0B0B0"
  123.     };
  124.     char* lev_data[] = {
  125.     "uuuk'g'g'g'g'g'i'g'g'g'g'g'i'g'g'g'g'g'i'g'g'g'g'g'i'g'g'7'g'g'i'g'g"
  126.     "'7'g'g'i'g'g'g'g'g'i'g'o'g'i'g'o'g'q'g'ui'g'o'g)o)g'7g)o)g7o'g'ui+q'"
  127.     "g'g+g'g'i'g'g'g'g'g'i'g'g'g'g'g'i'g'g'g'g'g'i'g'o'g'i'g'o'g'i'g'i'i'"
  128.     "g'r&g&uk&g&p","k7k7u7k7q'g7k'g'g'i'g7k'g'g'i'm)g'7'i'm)g'7'm'o7q'o7k"
  129.     "Gi'i7i'G'7Gi'i7i'G'7Ik'i7gGiIk'i7gGk+K7iG'i+K7iG'm7G'g'g'g'm7G'g'g'g"
  130.     "'g7'g7g'g'k'g7'g7g'g'k'i'g'g+g'7'i'g'g+g'7'i'g'g+q'g'g+q's'g'i's'g'i"
  131.     "'g'iwi+i'g'iwi+g","m'k'u'k'oK'ugK'o;'Kug'KuiKk'g,hKk'g,fM-g'h&gM+i'h"
  132.     "&gMi'n&gMi'n&iGm;iGiGm;iGuiMg'g'oM(g)g,M(g)g&kMo'kMo'g)M'i6l)Kg'i6pK"
  133.     "g)g6pKg)g6pKg7)kwi'k7)kwi'k","gIuGiIuGgIk'qKi/kIj2i7Gj4i7i5&n5&m(k+g"
  134.     "&m&o)g&m&g6h6h(q&g6h6h(lWg'o(h[g'g)i(hYi5o5n5'm5'l5)o1o)g-g)gGg+g)g+"
  135.     "gIg)m)gKuiI7GmwkI9GmwkI7","m)uk)uk'k;i7g'g'o7i7g'k'q7g'k'q'g+g)gYgW'"
  136.     "g+g)gYgW'k'mWumWsYg[o'gYg[k)iW'g(j-iW'g(j)mWo7qWo7i[gWg7g'g6j[gWg7g'"
  137.     "g6un6f)k)o6f)m/u'k)k+q)i)u'i'owumwq","p&g&fIuf&g&fIm&g6g&m&G&g&Gg&g6"
  138.     "g&m&G&g&Gg&g6g&h'h&G&g&Gg&g6g&h'h&G&g&Gg'i'g7g'Gg'Gg'i'g7g'Gg'Gg'h&7"
  139.     "g'g'6hIg'h&i'i6hIg'kG'Gi)i'kG'Gi)p&K&ug&K&n7k'K'f*9mKh*=kGk;m'gGg'o'"
  140.     "i'k'o'i'k'o(j'g'j(Gg(u(Gi'sKuiKqwmIi'kwk'I","s9uuk=m7m7s7m7kGg;m7kGi"
  141.     "9k7kG7k7k7kG7k7qG9k9oG9m7i7gG;g7o7gG;g7p6g9k9n6g9k9k6l7g;j6g6l7g;j6j"
  142.     "8k9Gi7j8k9Gi7i7m7Gi9i7m7Gi9i;iGi7q7iGi7um7i7uk9qwq9mwq","i'i'k'o'i'g"
  143.     "'g'kG+g'k(jG+g'g7g(jKi'g'g'h'fKm'l'fGeYgWGeYgWg'um'm)s'j07k'j*g'm'g'"
  144.     "h*G'i'g'g'h*G'9'k7kMo7g7gMiYg_gag_g]Ih&ugIh&i)oI'g&k&k'gI'g&k&g7)gGg"
  145.     "'g&n'g'gG7'g&r'swm'swi'k","k'qGo'o7Gi'qGf9h)o7Gf9h'mGf9h7Go7Gf9jGn9h"
  146.     "7Gt9jGu7GumGukGgGgGgGqG7GgG7Gk7'h9i9h'9'h9i9h'7kG7GgG7GqGgGgGgGuum7k"
  147.     "7m'j9i9j)j9i9j)iG7GgG7Gi)iGgGgGgGi'us's'm)iwi)m)iwi)i","uuul*q*i&g'q"
  148.     "'g&g(i'gIg'j&f&k'gIg'j(k'M'j(k'M'j(k'G9G(h)k'G9G(h'ma)i+a)i+9'9+i+9'"
  149.     "9+k)7g'g7*l)7g'g7*l5(l5(h'G+9-G)Gk9mG)UK)UK'iKkMkKkMm&jwk&p&jwk&j",
  150.     "o7g'g)s7g'g)l.g'r.g'u&h'g)gKk&h'g)gKh&o7gMh&o7gMh&g+7)I'7h&g+7)Ig7g+"
  151.     "7i'gIq7i'gIj,g7Oj,g7Oo7iO'm7iO'g7'gM7K'g7'gM7K'h(Om(g(Om(h'Im7+i'Io+"
  152.     "kIo'h&kIo'h&kIiws'Iiwq","s+ui+m+o'm-g'i's'g'm)m'q)g_g(j'7g_g(j'qWg'g"
  153.     "8f'k;Wg'g8f'i-[gW)i-[gW)o7WkW7q7WkWk[gY)gWk[gY)gWu'9g[q'k[g+ui+um'g9"
  154.     "k)h&i'q)h(u'i)u'i'qwumwq","uug'k'o-k-i-k-i'm'm7i'm'm7i7g)k)g)g7g'o'g"
  155.     ")g'g&fGg7gGf&g7'g'g&fG;Gf&g7'g'iOi7oOm'kOm'7iOi'g'7g&fG;Gf&g'g'7g&fG"
  156.     "g7gGf&g'g)g'o'g7g)g)k)g7g'7m'm'g'7m'm'g/k+9/k+9)i'k'i'g)ug'g)mwq)mwq"
  157.     ,"uuuiIk+kMi/iKj1jIj1jGk)G'G)q)G'G)q'I'I'q'I'I'kGi3iIi3iKi'G'G'iMi'G'"
  158.     "G'iI[g/gag/g[n&f&f&f&f&uf&f&f&f&f&u&f&f&f&f&uf&f&f&f&f&o6f6f6s6f6f6g"
  159.     "6f6f6s6f6f6f&f&f&u&f&f'f&f&u&f&f&6f6f6g6iwi6g6f6f7f6f6g6iwi6g6f6f6",
  160.     "m)i'u)i'oI)k'oI)k'mU)kU)kG7'G+M'7Gg'G+M'7I'K7I'6f'gI'KgI'6f'iI'gM'g'"
  161.     "iI'7M'g'i+iI*fIg+iI*fIf8)k)kGf6g)k'mGg'g'k'I(fGg'g'g7'gI(fGg'j*I'iGg"
  162.     "'j(gI'iGg*g(IgG'Ig*g&gI'G'Ii'o'G'Gk'o'G'Gk'kwiKswiKg","uuum7G7ui7G7u"
  163.     "kGgGuiGgG7sGmGsGmG'qIiGgGqIiGgG7oGgGgGiGoGgGgGiG'mGiGkImGiGkI7mGmMmG"
  164.     "mM'mGiGgMmGiGgMg'oGiK7'oGiK7)oGgM)oGgM7)oGgK7)oGgK9)iwgGiI9)iwgGiI",
  165.     "uug'o'k'g)iK)i'g)iK)i'i'g7Oi'i'g7OgK6f'i'MgK6f'i'MgQ)f'lQ)f'q6M'f'h7"
  166.     "l6M'f'l-S1S)k)M6r)M6n+gK)g'i+gK)g'gK'Gm'g'gK'Gm'g'gO7g7k'gOo)g'Mm'k'"
  167.     "Mm'k)6lwi'g'g)6lwi'g'g","u;Gug;Gi'q7i7i'q7i7g'G'k-g7g'G'k-g7i'G'i'gG"
  168.     "'9i'G'i'gG'9k'gG7'Gg'o'gG7'Gg's7g'7)s7g'7)o)7'g7s)7'g7s'gG'7Gs'gG'7G"
  169.     "o;Gg'i)k;Gg'i)k7g-i'9i7g-i'9i7i7o7)g7i7o7)gG;q'9G;q'9qwm9qwm9","g'g'"
  170.     "g'g'g'g'i'g'g'g'g'g'i'g'g'g'g'g'i'g'g'g'g'g'i7g7g7g7g7g7uui'k'm'g'g'"
  171.     "k'g'g)g+g'g+g)g'g'g'g'g'g'i7g7g7g7g7q7k7mIi'gGg'iMi'gGg'iQ)G)U'gGg'U"
  172.     "UUQm'K'm'g'g'K'g'g'g'g'iGi'g'i'g'iGi'g'i'g'o'g'i'g'o'g'swumwq","kWg'"
  173.     "i'g'oWg'i'g'ui'g7ui'g7oWi7g'g'oWg'7g'g'i7g'Wg7i'g'm'Wg7g'i'm'Wk's'Wk"
  174.     "'q)Yg]g'i)Yg]g'uGgWg9k'kGgWk)f(g7KWk)f(g7KWg+h&i'KWg'l&i'KWg'q'gGgWg"
  175.     "Gi7k'gGgWgGi'k+iKg'g7qKg'g'oWKg'g'oWKqwiWgGswiWgGg"
  176.     };
  177.     void set_image (char pal[4], char* code, Image& img, int w, int h)
  178.     {
  179.         img.create (w,h);
  180.         int i,j,n; char c, *end = code + strlen (code);
  181.         for (i=0; i<w*h && code < end; ++code) {
  182.             c = *code; c = (c=='*'?'?':c=='+'?'\\':c)-'0';
  183.             j = pal [c>>4];                     //顏色索引值 (0~3)
  184.             n = (c&15) + 1;                     //重複次數 (1~16)
  185.             while (n--) img[i++] = palette [j];
  186.         }
  187.     }
  188.     void init_obj ()
  189.     {
  190.         int i, n = sizeof hex_pal/ sizeof*hex_pal;
  191.         for (i=0; i<n; ++i)                     //設定調色盤
  192.             sscanf (hex_pal[i], "%x", palette+i); i=0;
  193.         #define SET_IMG(p,i,o,w,h) \
  194.             set_image (obj_pal[p], hex_img[i], obj[o], w, h);
  195.         for (;i <= ROAD;    ++i) SET_IMG (i,i,i,  8,  8);
  196.         for (;i <= SHIELD2; ++i) SET_IMG (i,i,i, 16, 16);
  197.         for (;i <= EXPLODE-1;++i)SET_IMG (i<21?PLAYER:ENEMY,i,i, 14,14);
  198.         for (;i <= EXPLODE; ++i) SET_IMG (i,i,i, 14, 14);
  199.         for (;i <= EXPLODE2;++i) SET_IMG (i,i,i, 32, 32);
  200.         for (;i <= BULLET-1;++i) SET_IMG (BONUS,i,i, 15, 14);
  201.         SET_IMG (i,i,i, 4, 4);
  202.         for (i=0; i<8; ++i) SET_IMG (36, i+PLAYER,i+PLAYER2,14, 14);
  203.         for (i=0; i<6; ++i) SET_IMG (37, i+ENEMY, i+RENEMY, 14, 14);
  204.         for (i=0; i<2; ++i) SET_IMG (13, i+ENEMY+4, i+YENEMY, 14, 14);
  205.         for (i=0; i<2; ++i) SET_IMG (36, i+ENEMY+4, i+GENEMY, 14, 14);  
  206.         obj[HOLE].create (4, 4);
  207.         memset (obj[HOLE].data, 0x22, 4*4*4);
  208.     }
  209.     void release_obj () {for (int i=N_OBJ; i--;) obj[i].free();}
  210. };

  211. int TankWar(ai) Sprite                          //單元物件
  212. {
  213.     int   id;                                   //影像類型,可索引物件邊界
  214.     int   x, y, dir, step;                      //位置, 移動方向, 步距
  215.     int   type, life;                           //元素類型, 生命值
  216.     int   maxMoveDelay, nMoveDelay;             //移動延遲, 移動計數
  217.     bool  bActive;                              //是否在活動中

  218.     bool move (int dir_)                        //傳回「是否移動了」
  219.     {                                           //時間到才移動
  220.         if (nMoveDelay-- > 0) return false;        
  221.         nMoveDelay = maxMoveDelay;        
  222.         dir = dir_;
  223.         if (dir == UP   ) y -= step; else
  224.         if (dir == DOWN ) y += step; else
  225.         if (dir == LEFT ) x -= step; else
  226.         if (dir == RIGHT) x += step;
  227.         return true;
  228.     }
  229.     bool bCollide (const Sprite& o)             //碰撞判定
  230.     {
  231.         int x2 = x + obj[id].w;
  232.         int y2 = y + obj[id].h;
  233.         int X2 = o.x + obj[o.id].w;
  234.         int Y2 = o.y + obj[o.id].h;
  235.         return !(x2 < o.x || x > X2 || y2 < o.y || y > Y2);
  236.     }
  237.     void set (int ID, int X, int Y, int DIR, int STP,
  238.               int LF, int MD=0, int TYPE=0, bool ACT=true) {
  239.         id=ID; x=X; y=Y; dir=DIR; step=STP; life=LF; type=TYPE;
  240.         nMoveDelay = maxMoveDelay = MD; bActive = ACT;
  241.     }
  242.     Sprite() :bActive (false) {}
  243. };


  244. struct Map
  245. {
  246.     enum   {W=13, H=13, W4=W*4, H4=H*4};
  247.     enum   {MAX_EXPLODE = 64};
  248.     Sprite explode [MAX_EXPLODE];               //爆破物件
  249.     int    nMaxExplode;
  250.     int    cid;                                 //撞到什麼東西   
  251.     char   space[W4][H4];                       //記錄子區塊的元素類型
  252.     int    mapX, mapY;                          //地圖在canvas中的起始座標
  253.     Image  canvas;                              //back buffer
  254.     Image  bg;                                  //背景畫面
  255.     bool   bStone;                              //堡壘是否被破壞
  256.     bool   bRiver1;                             //河流動畫
  257.     bool   bProtected;                          //基地是否被水泥保護  
  258.     int    riverChangeTime;
  259.     int    nRiverChangeTime;
  260.     int    protectTime;                         //基地被水泥保護的剩餘秒數
  261.    
  262.     Map(): riverChangeTime(10), protectTime(0),
  263.            nRiverChangeTime(0), nMaxExplode(0)
  264.     {mapX = 16; mapY = 18;}

  265.     void set_space_2x2 (int x, int y, int o)
  266.     {
  267.         space [y][x  ] = space [y+1][x  ] =
  268.         space [y][x+1] = space [y+1][x+1] = o;
  269.     }
  270.     void draw_hawk (bool bStone_=false)
  271.     {
  272.         bStone = bStone_;
  273.         set_space_2x2 (7*4-2, 13*4-2, HAWK);    //建主堡
  274.         bg.draw (obj[bStone?STONE:HAWK], 6*16, 12*16);        
  275.     }
  276.     void setProtect (bool bProtect)             //設定基地是否被水泥保護
  277.     {
  278.         static struct {int x,y;}
  279.         p[] = {11,23,12,23,13,23,14,23,11,24,11,25,14,24,14,25};
  280.         for (int o = bProtect? CONCRETE: BRICK, i=0; i<8; i++) {
  281.             bg.draw (obj[o], p[i].x*8, p[i].y*8);
  282.             set_space_2x2 (p[i].x*2, p[i].y*2, o);
  283.         }
  284.         if (bProtected = bProtect) protectTime = 360;        
  285.     }

  286.     bool bPass (Sprite& o)                      //測試物件是否發生碰撞
  287.     {
  288.         cid = ROAD;
  289.         int x = o.x, W = obj[o.id].w;
  290.         int y = o.y, H = obj[o.id].h;
  291.         if (x<0 || y<0 || x>=bg.w-W || y>=bg.h-H) {
  292.             cid = HOLE; return false;
  293.         }
  294.         int i,j,c, w = x+W-1, h = y+H-1;
  295.         x/=4; y/=4; w/=4; h/=4;                 
  296.         for (i=y; i<=h; ++i)
  297.             for (j=x; j<=w; ++j) {
  298.                 c = space[i][j];
  299.                 if (c!= TREE && c!= ROAD) {
  300.                     if (o.type > 15 && c==RIVER) continue;
  301.                     cid = c;
  302.                     return false;
  303.                 }
  304.             }
  305.         return true;
  306.     }

  307.     void draw_canvas (const Sprite& s)
  308.     {
  309.         canvas.draw (obj[s.id], mapX+s.x, mapY+s.y, s.dir);
  310.     }
  311.     void draw_river()
  312.     {
  313.         for (int o,x,y=0; y<H4; y+=2)
  314.             for (x=0; x<W4; x+=2)
  315.                 if((o = space[y][x])==RIVER)
  316.                     canvas.draw (obj[o+bRiver1], mapX+x*4, mapY+y*4);
  317.     }
  318.     void update()
  319.     {
  320.         if (protectTime > 0) {
  321.             if (protectTime-- == 1) setProtect (false);
  322.         }
  323.         if (nRiverChangeTime++ > riverChangeTime) {
  324.             nRiverChangeTime = 0;               //更新河流狀態
  325.             bRiver1 = !bRiver1;
  326.         }
  327.         for (int o,x,y=0; y<H4; y+=2)
  328.             for (x=0; x<W4; x+=2)               //重繪樹
  329.                 if ((o = space[y][x]) == TREE)
  330.                     canvas.draw (obj[o], mapX+x*4, mapY+y*4);
  331.         draw_explodes();                        //畫出爆破物
  332.     }

  333.     void addExplode (int id, int x, int y)
  334.     {
  335.         int i, j;
  336.         for (i=0; i<MAX_EXPLODE; ++i)
  337.             if (!explode[i].bActive) {          //根據爆炸模式設定時間
  338.                 explode[i].set (id, x, y,0,0, id==EXPLODE? 4:12);   
  339.                 if (i > nMaxExplode) nMaxExplode = i;
  340.                 break;
  341.             }
  342.         for (j=nMaxExplode; !explode[j].bActive && j>i; --j);
  343.         nMaxExplode = j;                        //調整欲顯示的最大編號
  344.     }
  345.     void draw_explodes ()
  346.     {
  347.         Sprite *e;
  348.         for (int i=0; i<= nMaxExplode; ++i)
  349.             if (explode[i].bActive) {
  350.                 e = explode + i;                //是否播放完畢
  351.                 if (--e->life == 0)
  352.                     e->bActive = false;                     
  353.                 else if (EXPLODE == e->id ||    //延遲大爆炸的播放
  354.                     (EXPLODE2 == e->id && e->life < 8))
  355.                     draw_canvas (explode[i]);
  356.             }
  357.     }
  358. };
  359. const int MAX_LEVEL = 20;                       //內定關卡數
  360. const int MAX_TANK = 27;                        //坦克集合的大小
  361. struct Tank; Tank *tanks = 0;                   //指向坦克集合
  362. Map*   map = 0;                                 //指向遊戲地圖

  363. struct Depot                                    //彈藥庫
  364. {
  365.     int MAX_BULLET;                             //最大彈藥數
  366.     int nLimit;                                 //限制可存取的總彈藥量
  367.     Sprite *b, *bullet;                         //庫藏彈藥
  368.    
  369.     int getBullet ()                            //從庫中取出 1 顆子彈
  370.     {                                           //若失敗, 傳回 -1
  371.         for (int i=0; i<MAX_BULLET; ++i)        //若成功, 傳回子彈id
  372.             if (bullet[i].bActive == false)
  373.                 {bullet[i].bActive = true; return i;}
  374.         return -1;
  375.     }
  376.     void processBullets ()                      //顯示所有作用中的子彈
  377.     {
  378.         for (int i=0; i<nLimit; i++)
  379.             if ((b=bullet+i)->bActive) {   
  380.                 map->draw_canvas (*b);          //畫出子彈
  381.                 hitObject (*b);                 //是否撞到其他物件
  382.             }
  383.     }   
  384.     bool hitObject (Sprite& b)
  385.     {
  386.         bool hit = false;
  387.         int x,y, dx,dy, c, sx,sy, ex,ey;
  388.         int bx= b.x-6, by= b.y-6;               //(bx,by) = 邊界盒左上角
  389.         int bW = map->bg.w, bH = map->bg.h;

  390.         b.move (b.dir);
  391.         switch (b.dir) {
  392.             case UP:  case DOWN:  sx=0, ex=16, sy=4, ey=12; break;
  393.             case LEFT:case RIGHT: sx=4, ex=12, sy=0, ey=16; break;
  394.         }
  395.         for (dy=sy; dy<ey; dy+=4)               //檢測子彈邊界盒 4 邊角
  396.             for (dx=sx; dx<ex; dx+=4) {
  397.                 x = bx + dx;                    
  398.                 y = by + dy;                    //是否出界?
  399.                 if (x<0 || y<0 || x>=bW-2 || y>=bH-2) {  
  400.                     hit = true;
  401.                     b.life = 1;
  402.                     continue;
  403.                 }               
  404.                 x/=4; y/=4;                     //對應到 space 單位去索引
  405.                 c = map->space[y][x];            
  406.                
  407.                 if (b.type==c || c==BRICK && b.type==CONCRETE) {
  408.                     map->space[y][x] = ROAD;                    
  409.                     map->bg.draw (obj[HOLE], x*4, y*4);
  410.                 }
  411.                 if (c==BRICK || c==CONCRETE) hit = true;
  412.                 else if (c==HAWK) {             //若打到堡壘
  413.                     map->draw_hawk (true);      //便將它化成廢墟
  414.                     map->addExplode (EXPLODE2, 11*8, 23*8);
  415.                     hit = true;
  416.                 }               
  417.             }                                   //若打中東西
  418.         if (hit) checkExplode (b);              //便損耗子彈壽命
  419.         return hit;
  420.     }
  421.     void checkExplode (Sprite& b)
  422.     {
  423.         if (--b.life <= 0) {                    
  424.             b.bActive = false;   
  425.             map->addExplode (EXPLODE, b.x-6, b.y-6);
  426.         }
  427.     }   
  428.     void setup (int nBullet, int nLimit_)
  429.     {
  430.         nLimit = nLimit_;
  431.         bullet = new Sprite [MAX_BULLET = nBullet];
  432.         for (int i=0; i<MAX_BULLET; ++i)
  433.             bullet[i].bActive = false;
  434.     }
  435.    ~Depot () {delete[] bullet;}
  436. };


  437. struct Tank: Sprite
  438. {
  439.     bool  bMov2;                                //捲輪子
  440.     int   cid;                                  //撞到什麼東西
  441.     int   frame;
  442.     int   bonus;                                //攜帶道具
  443.     int   nAtkDelay, maxAtkDelay;               //攻擊時間間隔
  444.     float nBegin, nFlick, nShield;              //各種特效的剩餘播放時間
  445.     Depot *depot;                               //彈藥庫指標
  446.    
  447.     void setBonus()
  448.     {
  449.         int i = rand()%100; flick();
  450.         bonus = BONUS + (i<10?0: i<30?1: i<50?2: i<62?3: i<85?4: 5);
  451.     }
  452.     void fire()
  453.     {
  454.         if (nAtkDelay>0 || nBegin>0) return;    //時間到才做運算
  455.         nAtkDelay = maxAtkDelay;                //重新啟動射擊延遲
  456.         int i = depot->getBullet();             //申請子彈
  457.         if (i == -1) return;                    //彈藥已無庫存
  458.          
  459.         int cw = obj[id].w, bX = x, bW = 4;     //子彈圖像的寬度
  460.         int ch = obj[id].h, bY = y, bH = 4;     //子彈圖像的高度
  461.         switch (dir) {                          //將子彈放在砲口方向
  462.             case UP:    bX += (cw-bW)/2; bY -= bH; break;
  463.             case LEFT:  bX -= bW; bY += (ch-bH)/2; break;
  464.             case DOWN:  bX += (cw-bW)/2; bY += ch; break;
  465.             case RIGHT: bX += cw; bY += (ch-bH)/2; break;
  466.         }            
  467.         int speed = 1, b_life = 1;
  468.         int b_type = type>2? CONCRETE: BRICK;
  469.         switch (type) {                         //在坦克物件中的
  470.             case 0: speed = 3; break;           //type 意指子彈類型
  471.             case 1: speed = 4; break;
  472.             case 2: speed = 5; break;
  473.             case 3: speed = 5; break;
  474.             case 4: speed = 5; b_life = 2; break;
  475.             case 5: case 6: speed = 5; b_life = 3; break;
  476.             case 7: case 8: speed = 5; b_life = 4; break;
  477.             case 9: case 10:speed = 6; b_life = 5; break;
  478.             case 11:case 12:speed = 7; b_life = 5; break;
  479.             case 13:case 14:speed = 7; b_life = 6; break;
  480.             case 15:case 16:speed = 7; b_life = 7; break;
  481.             case 17:case 18:speed = 7; b_life = 8; break;
  482.         }                                       
  483.         depot->bullet[i].set                    //設定子彈資訊
  484.             (BULLET, bX, bY, dir, speed, b_life, 0, b_type, true);
  485.     }

  486.     void move (int dir_)
  487.     {
  488.         cid = ROAD;
  489.         if (nBegin > 0) return;
  490.         int ox=x, oy=y, odir = dir;             //保存移動前的位置
  491.         ++frame %= 4;
  492.         if (0 == frame) bMov2 = !bMov2;
  493.         Sprite::move (dir_);                       
  494.         
  495.         if (!map->bPass (*this)) {              //若和地圖元素發生碰撞
  496.             if (dir != odir) {                  //若方向有變
  497.                 int dx = x%16, dy = y%16;       //調整位置使之與元素相貼
  498.                 x = (x/16)*16+ (dx<6? 1: dx<13? 9: 17);
  499.                 y = (y/16)*16+ (dy<6? 1: dy<13? 9: 17);
  500.                 if (!map->bPass (*this))
  501.                     x = ox, y = oy, cid = map->cid;
  502.             }else x = ox, y = oy, cid = map->cid;
  503.         }           
  504.         Sprite s; s.id=ENEMY;                   //重疊移動用的暫時物件
  505.         for (int i=0; i<MAX_TANK; ++i)          //是否和其他坦克發生碰撞
  506.             if (this != &tanks[i] &&
  507.                 tanks[i].bActive  &&
  508.                 tanks[i].nBegin <=0 &&
  509.                 bCollide (tanks[i])) {
  510.                     s.x = ox; s.y = oy;         //檢驗移動前是否已碰撞
  511.                     if (!tanks[i].bCollide(s))  //若非一開始便位置重疊
  512.                         x = ox, y = oy,         //便進行碰撞處理
  513.                         cid = i>1? ENEMY: PLAYER;      
  514.                 }
  515.     }
  516.     void autoMove()
  517.     {
  518.         move (rand()%180==0? rand()%4: dir);
  519.         if (cid != ROAD) {
  520.             if ((cid == BRICK || cid == PLAYER) &&
  521.                  rand()%3 > 0) fire();
  522.             else dir = rand()%4;
  523.         }
  524.         else if (rand()%15 == 0) fire();
  525.     }
  526.     void draw ()                                //根據狀態描繪外貌
  527.     {
  528.         if (nAtkDelay > 0) nAtkDelay--;
  529.         int mx = x + map->mapX;
  530.         int my = y + map->mapY;
  531.         Image* c = &map->canvas;  
  532.         if (nBegin > 0)
  533.             c->draw (obj[STAR + int(nBegin-=.7f) %4], mx, my);
  534.         else {
  535.             if (nFlick > 0 && bMov2) {          //閃紅光
  536.                 nFlick--;
  537.                 int i = id>ENEMY+6? 4: id-ENEMY;
  538.                 c->draw (obj[RENEMY + i + bMov2], mx, my, dir);
  539.             }
  540.             else c->draw (obj[id + bMov2], mx, my, dir);
  541.             if (nShield > 0)
  542.                 c->draw (obj[SHIELD+(int(--nShield)%4<2)],mx,my);
  543.         }
  544.     }   
  545.     void setup (Depot& depot_, int atkDelay_)
  546.     {
  547.         depot = &depot_;
  548.         maxAtkDelay = atkDelay_;
  549.         begin();
  550.     }
  551.     void checkExplode()
  552.     {
  553.         life--;
  554.         if (id == GENEMY) id = YENEMY; else
  555.         if (id == YENEMY) id = ENEMY+4;
  556.         if (life <= 0) {
  557.             bActive = false;
  558.             map->addExplode (EXPLODE2, x-8, y-8);
  559.         }
  560.     }
  561.     void levelup()
  562.     {
  563.         if (type < 18) type++;
  564.         if (type == 2) {
  565.             int i = depot->nLimit++;
  566.             depot->bullet[i].bActive = false;
  567.         }
  568.         int a = id-PLAYER, b = id-PLAYER2;
  569.         if (0<=a && a<6 || 0<=b && b<6) id += 2;    //改變外型
  570.     }                                   
  571.     void begin()  {nBegin  = 28;}
  572.     void flick()  {nFlick  = 360;}
  573.     void shield() {nShield = 320;}
  574. };

  575. struct Game: Map
  576. {   
  577.     enum   {txtW=80, txtH=14};
  578.     HBITMAP hBmp;
  579.     HDC     hdc, hdcMem;  
  580.     HFONT   font;
  581.     Image   text;
  582.     bool    bOver;                              //是否結束遊戲
  583.     int     level;                              //目前關卡
  584.     int     life[2];                            //玩家生命
  585.     int     nEnemy, nActEnemy;                  //剩餘& 活動中 的坦克數
  586.     int     enemyHoldTime;
  587.     int     enemyCreateTime;  
  588.     int     maxEnemyCreateTime;
  589.     Tank    tank [MAX_TANK];                    //坦克集合: [0,1] 為我方
  590.     Depot   depot[3];                           //我方2人與敵方彈藥庫
  591.     Sprite  bonus;
  592.    
  593.     void setup_player (int i, bool bReset)
  594.     {
  595.         int type = bReset? 0: tank[i].type;
  596.         int id   = bReset? (i? PLAYER2: PLAYER): tank[i].id;
  597.         if (bReset) depot[i].nLimit = 1;
  598.         tank[i].set (id, (i?7:4)*16+8+1, 12*16+1, UP, 2, 1, 0, type);
  599.         tank[i].setup (depot[i], 5); tank[i].shield();
  600.     }
  601.     void create_enemy()
  602.     {
  603.         static struct {int x, y;}
  604.         p[] = {0,0, 16*6,0, 16*12,0, 16*12,16*5, 0,16*5};
  605.         if (--enemyCreateTime > 0  ||
  606.              nEnemy < 1 || nActEnemy >= level/4+4) return;
  607.         enemyCreateTime = maxEnemyCreateTime;
  608.         nActEnemy++;
  609.         int i = --nEnemy + 2;                           //t決定坦克類型
  610.         int t = rand()%(MAX_LEVEL+7)<=level?2: rand()%2;      
  611.         int d = t==0? 2: t==1? 3+(level>13): 1+level/6; //移動速度
  612.         int l = nEnemy% (level<15? 3: 5);               //出現位置
  613.         int id = t<2? ENEMY+ t*2: GENEMY;
  614.         tank[i].set (id, p[l].x+1, p[l].y+1, rand()%4, d, (t==2?3:1), 1);
  615.         d = (6-t) * (level>15? 4: level>10? 5: 6);      //攻擊時間間隔
  616.         tank[i].setup (depot[2], d);              
  617.         if (rand()%100 > 61) tank[i].setBonus();        //39%機率攜帶道具
  618.     }
  619.     void init (int w=W*4, int h=H*2)
  620.     {
  621.         srand ((UINT)time(0));
  622.         hdc    = GetDC (GetConsoleWindow());
  623.         hdcMem = CreateCompatibleDC (hdc);
  624.         hBmp   = CreateCompatibleBitmap (hdc, txtW, txtH);
  625.         font = CreateFont (10,0,0,0,FW_BOLD,0,0,0,0,0,0,0,0,"Courier");
  626.         SelectObject (hdcMem, GetStockObject (LTGRAY_BRUSH));
  627.         SetBkColor   (hdcMem, RGB(0xC0,0xC0,0xC0));
  628.         SetTextColor (hdcMem, RGB(0,0,64));
  629.         SelectObject (hdcMem, font);                //取入字型
  630.         SelectObject (hdcMem, hBmp);
  631.         SetBkMode (hdc, TRANSPARENT);
  632.         SMALL_RECT size = {0, 0, 79, 40};        
  633.         HANDLE     hOut = GetStdHandle (STD_OUTPUT_HANDLE);
  634.         CONSOLE_CURSOR_INFO cur = {100, 0};
  635.         SetConsoleCursorInfo (hOut, &cur);          //關閉字標
  636.         SetConsoleWindowInfo (hOut, TRUE, &size);   //變更視窗大小
  637.         bg.create (w*4, h*8);                       //背景佔視窗的 1/4
  638.         canvas.create (w*4+mapX*2, h*8+mapY*2+12);  //畫布要比背景大
  639.         memset (bg.data, 0x22, 4*bg.w*bg.h);        //用以容納邊界爆破
  640.         init_obj();                                 //配置影像元素
  641.         text.create (txtW, txtH);                   //配置文字面版
  642.         map = this;                                 //設定全域性代理者
  643.         tanks = tank;                               //指涉地圖與坦克集合
  644.         depot[0].setup (16, 1);                     //配置我方彈藥庫
  645.         depot[1].setup (16, 1);                     //配置我方彈藥庫
  646.         depot[2].setup (64,64);                     //配置敵方彈藥庫
  647.         life[0] = life[1] = 3;                      //初始生命值
  648.         setup_player (0, true);                     //初始屬性        
  649.         setup_player (1, true);  
  650.         level = 0;
  651.         new_level();                                //建立地圖
  652.     }
  653.     void release ()                                 //釋放資源
  654.     {
  655.         release_obj();
  656.         DeleteObject (hBmp);
  657.         DeleteDC (hdcMem);  
  658.         DeleteDC (hdc);
  659.         text.free();
  660.         bg.free();
  661.         canvas.free();
  662.     }
  663.     void new_level ()
  664.     {
  665.         char c, *code = lev_data [level];         //元素索引值 j=(0~4)
  666.         for (int x,y,n,j,k=0, len = strlen (code), i=0; i<len; ++i) {
  667.             c = ((c=code[i])== ' ? '?' : c=='%'?'\\':c)-'&';
  668.             for (j = c>>4, n = (c&15)+1 ;n--; ++k) {
  669.                 set_space_2x2 (x= k%(W*2)*2, y= k/(H*2)*2, j);
  670.                 if (j<2) bg.draw (obj[j], x*4, y*4);               
  671.             }
  672.         }
  673.         draw_hawk ();
  674.         setProtect (false);
  675.         level++;
  676.         nActEnemy = 0;
  677.         maxEnemyCreateTime = 132;
  678.         nEnemy = MAX_TANK - 2;
  679.         if (life[0]) setup_player (0, false);
  680.         if (life[1]) setup_player (1, false);      
  681.     }
  682.     void check_over ()
  683.     {
  684.         if (bStone || life[0]==0 && life[1]==0)
  685.             drawText (5*16, 7*16, "Game Over", 9);
  686.         else if (nActEnemy + nEnemy == 0 && level == MAX_LEVEL)
  687.             drawText (5*16, 7*16, "You  Win!", 9);
  688.     }
  689.     void check_levelup()
  690.     {
  691.         static int c = 0; if(++c>255) c=0;
  692.         if (nActEnemy + nEnemy == 0 && level < MAX_LEVEL) {     
  693.             SetTextColor (hdc,  RGB(255,(c+55)%256,c));
  694.             TextOut (hdc, 5*16*3+6, 7*16*3,
  695.                  "請按空白鍵進入下一關", 20);
  696.             if (GetAsyncKeyState (VK_SPACE) >= 0) return;
  697.             memset (bg.data, 0x22, 4*bg.w*bg.h);
  698.             new_level();
  699.         }
  700.     }
  701.     void create_bonus (int id)
  702.     {
  703.         bonus.id   = id;
  704.         bonus.x    = rand()%(W-1) *16;
  705.         bonus.y    = rand()%(H-1) *16;
  706.         bonus.life = 280;
  707.     }
  708.     void draw_bonus()
  709.     {
  710.         if (bonus.life > 0) {bonus.life--; draw_canvas (bonus);}
  711.     }
  712.     void colisionTest()
  713.     {
  714.         Depot *d, *d2; Tank* t;
  715.         int i,j,k,l;
  716.         if (enemyHoldTime > 0)
  717.             enemyHoldTime--;
  718.         for (i=0; i<MAX_TANK; ++i)                  //畫出坦克
  719.             if ((t = tank+i)->bActive) {
  720.                 if (i>1 && t->nBegin<=0 && enemyHoldTime <= 0)
  721.                     t->autoMove();                  //移動敵方坦克
  722.                 t->draw();
  723.                 if (t->nBegin > 0) continue;        //閃爍時不做碰撞測試
  724.                 for (j=0; j<3; ++j) {               //處理子彈和坦克的碰撞
  725.                     if (t->depot == (d = &depot[j])) continue;
  726.                     for (k=0; k<d->nLimit; ++k)
  727.                         if (d->bullet[k].bActive &&
  728.                             t->bCollide (d->bullet[k])) {
  729.                             if (t->nShield > 0){    //護盾狀態時吸收子彈
  730.                                 if (--d->bullet[k].life <= 0)
  731.                                     d->bullet[k].bActive= false;
  732.                                 continue;
  733.                             }
  734.                             d->checkExplode (d->bullet[k]);
  735.                             t->checkExplode ();
  736.                             if (t->life == 0 && i>1) {
  737.                                 nActEnemy--;
  738.                                 if (t->nFlick > 0)
  739.                                     create_bonus(t->bonus);
  740.                             }
  741.                         }
  742.                 }
  743.             }
  744.         Sprite *b, *b2;
  745.         for (j=0; j<3; ++j) {                       //子彈碰撞處理
  746.             d = depot + j;
  747.             d->processBullets ();                   //和景物的碰撞
  748.             for (i=0; i<d->nLimit; ++i)             //和其他子彈的碰撞
  749.                 for (b= d->bullet+i, k=0; k<3; ++k)
  750.                     if (k != j && b->bActive)
  751.                         for (d2= depot+k, l=0; l<d2->nLimit; ++l) {
  752.                             b2 = d2->bullet + l;
  753.                             if (b2->bActive && b->bCollide (*b2)) {
  754.                                 if (--b->life <= 0) b->bActive = false;
  755.                                 if (--b2->life<= 0) b2->bActive= false;
  756.                             }
  757.                         }
  758.         }
  759.     }
  760.     void check_player()
  761.     {
  762.         for (int j,i=0; i<2; ++i)
  763.             if (life[i] == 0) continue;
  764.             else if (!tank[i].bActive) {            //還有命嗎?
  765.                 if (--life[i] > 0) setup_player (i, true);
  766.             }
  767.             else if (bonus.life > 0 &&
  768.                      tank[i].nBegin <= 0 &&
  769.                      tank[i].bCollide (bonus)) {
  770.                 bonus.life = 0;
  771.                 switch (bonus.id - BONUS) {         //若吃到特殊道具
  772.                 case Bonus::LIFE:   life[i]++;           break;
  773.                 case Bonus::CLOCK:  enemyHoldTime = 240; break;
  774.                 case Bonus::SHOVEL: setProtect (true);   break;
  775.                 case Bonus::HELMET: tank[i].shield();    break;
  776.                 case Bonus::STAR:   tank[i].levelup();   break;
  777.                 case Bonus::BOMB:
  778.                      for (j=2; j<MAX_TANK; ++j)
  779.                         if (tank[j].bActive && tank[i].nBegin < 1)
  780.                             tank[j].life = 1,
  781.                             tank[j].checkExplode(),
  782.                             nActEnemy--;
  783.                 }
  784.             }
  785.     }
  786.     void _cdecl drawText (int x, int y, char* fmt...)
  787.     {
  788.         static char s[64];
  789.         static int bits = GetDeviceCaps (hdc, BITSPIXEL) *
  790.                           GetDeviceCaps (hdc, PLANES);
  791.         static BITMAPINFO f = {{40,txtW,-txtH,1,bits,0,0,0,0,0,0},{{0}}};
  792.         Rectangle (hdcMem, -1, -1, txtW+1, txtH+1);
  793.         vsprintf_s (s, fmt, (char*)(&fmt+1));
  794.         TextOut (hdcMem, 0, 0, s, strlen(s));
  795.         GetDIBits (hdcMem, hBmp, 0,txtH, text.data, &f, DIB_RGB_COLORS);
  796.         if (bits == 16)
  797.              canvas.draw16 (text, x, y, RGB(180,80,80));
  798.         else canvas.draw32 (text, x, y, RGB(180,80,80));
  799.     }
  800.     void update ()                       
  801.     {      
  802.         memset (canvas.data, 0xC0, 4*canvas.w*canvas.h);
  803.         drawText (16*6-8,   2,   "LEVEL%2d", level);
  804.         drawText (16*11,    2,   "  [%2d] ", nEnemy);
  805.         drawText (16*1, 16*14+2, "P1:%2d  ", life[0]);
  806.         drawText (16*9, 16*14+2, "  P2:%2d", life[1]);
  807.         canvas.draw (bg, mapX, mapY);               //繪出背景
  808.         draw_river();                               //畫出河流
  809.         create_enemy();
  810.         colisionTest();                             //移動物件並處理碰撞
  811.         check_player();                             //吃東西與重生
  812.         Map::update();                              //繪出前景
  813.         draw_bonus();                               //繪出道具
  814.         check_over();
  815.         show (canvas, 0,0);
  816.         check_levelup();                            //是否進到下一關
  817.     }
  818.     void show (Image& in, int x, int y)  
  819.     {
  820.         BITMAPINFO info = {{40, in.w, -in.h, 1,32,0,0,0,0,0,0},{{0}}};
  821.         StretchDIBits (hdc, x, y, int(in.w*2.7), int(in.h*2.7),
  822.             0, 0, in.w, in.h, in.data, &info, DIB_RGB_COLORS, SRCCOPY);
  823.     }
  824.     void key_control()                              //按鍵控制
  825.     {                     
  826.         #define PRESS(key) if (GetAsyncKeyState(key)& 0x8000)
  827.         PRESS (VK_ESCAPE) bOver = true;
  828.         if (bStone) return;
  829.         if (tank[0].bActive) {                      //操控玩家1
  830.             PRESS ('S') tank[0].move (DOWN); else
  831.             PRESS ('A') tank[0].move (LEFT); else
  832.             PRESS ('D') tank[0].move (RIGHT);else
  833.             PRESS ('W') tank[0].move (UP);   
  834.             PRESS ('H') tank[0].fire ();
  835.         }
  836.         if (tank[1].bActive) {                      //操控玩家2
  837.             PRESS (VK_DOWN  ) tank[1].move (DOWN); else
  838.             PRESS (VK_LEFT  ) tank[1].move (LEFT); else
  839.             PRESS (VK_RIGHT ) tank[1].move (RIGHT);else
  840.             PRESS (VK_UP    ) tank[1].move (UP);   
  841.             PRESS (VK_NUMPAD0)tank[1].fire ();
  842.         }
  843.     }
  844.     Game()
  845.     {
  846.         init();
  847.         for (DWORD curr = timeGetTime(); !bOver;)   
  848.             if (timeGetTime() - curr > 20) {
  849.                 update();
  850.                 key_control();
  851.                 curr = timeGetTime();
  852.             }
  853.         release ();
  854.     }
  855. }_;
複製代碼

作者: daviddr    時間: 2009-7-24 12:59 AM

本帖最後由 daviddr 於 2009-7-24 11:40 PM 編輯

code 用 VC++ 或 Dev C++,以 console mode 編譯。

編譯問題:
論壇會吸收掉 $ 字元....
編譯時要自行修正此行,成為: c = ((c=code[ i ])=='$' ? '?' : c=='%'?'\\':c)-'&';

Dev C++ 要在 [專案選項>參數>連結器]
內設定 -lwinmm、-lGDI32,
並將 vsprintf_s 改成 vsprintf。

執行畫面: (右上是剩餘坦克數)

[attach]22779095[/attach]
作者: 284ru04g4    時間: 2009-7-25 09:51 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: huadi73    時間: 2009-7-26 02:31 AM

真是懷念呀~現在還差選1P 2P 還有自定地圖
這程式碼我都看不太懂呀~
有哪些中文書會有嗎??
作者: kkutar    時間: 2009-7-26 08:45 PM

本帖最後由 kkutar 於 2009-7-26 08:47 PM 編輯

太強了吧,我從來不知道C++可以做到這樣
1樓版主,請問一下
就是寫這種程式一開始的構築要怎樣規劃呢?
作者: daviddr    時間: 2009-7-26 10:21 PM

> 一開始的構築要怎樣規劃呢?

首先要讓遊戲以穩定的速度進行,
也就是讓 FPS 盡量維持在一定範圍,
在這段時間內,進行畫面更新和玩家輸入處理。
最簡單的計時器架構是:


     bool  bGameOver;                     //是否結束遊戲
     DWORD curr;                          //目前的時間點
     int   frequence = 50;                //更新率
  
     curr = timeGetTime();
     while (!bGameOver)   
         if (timeGetTime() - curr > 1000/frequence)
         {
             update();                    //畫面更新
             key_control();               //玩家輸入處理
             curr = timeGetTime();
         }


接著是秀圖,由於各平台的繪圖 API 不盡相同,
我們會把秀圖功能統一包裝在一個函式中,
然後在其中呼叫系統相關的繪圖函式,如 2D 方面有:
xlib、Glib、libXt、BGI、OpenGL、DirectX、GDI、
GDI+、Motif、LessTif、Qt/KDE、GTK+/Gnome.. 等。

圖會先畫在一塊 buffer 上,再根據玩家螢幕解析度進行縮放。
程式中使用 StretchDIBits 達成此目的。

處理輸入有許多方法,皆為 platform dependent,
如 Win32 上有 kbhit + getch,GetAsyncKeyState、或 DirectInput。
因為 Battle City 一次要分析的按鍵不多,
這裡便使用 GetAsyncKeyState 來讀取按鍵狀態。
作者: tommy790506    時間: 2009-7-27 11:26 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: neilchen_nc    時間: 2009-7-31 05:41 PM

厲害耶~~~
800多行就能搞出這樣......
我也要來好好研究研究一下了....
作者: rock1223    時間: 2009-8-2 02:00 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: daviddr    時間: 2009-8-2 11:43 AM

在右邊框框內打:-lwinmm、-lGDI32,
詳情請 google Dev C++ 使用方法。

code 有兩處要修正:加入 $、拿掉 _s。
作者: tadzio    時間: 2009-8-7 12:25 AM

推推~
厲害厲害
感謝分享!!

話說按了複製代碼  再貼到VC++後空白處都會變成0x0a
貼到DevC++後空白處則會變成"?"
應該是論壇的問題(還是我的問題@@?)...有辦法解決嗎..?
作者: BOMM    時間: 2009-8-7 01:44 AM

還沒看程式碼 我就被你的圖片吸引近來
好懷念以前紅白機阿....

畫面一樣的坦克大戰
作者: yynnyyee    時間: 2009-8-9 12:08 AM

推~~
很想玩, 但
在main中
{int daviddr(907);}
找不到 daviddr?
請問何解?
感謝
作者: daviddr    時間: 2009-8-9 11:16 AM

本帖最後由 daviddr 於 2009-8-9 11:32 AM 編輯

13# yynnyyee
別在意,那只是個「mark」:標示製造者和製造日期 XD
主程式在 main() 開始之前便已執行。
作者: haegyo    時間: 2009-8-9 12:17 PM

高手阿
連這麼複雜的東西
都弄得出來,真是佩服!!
作者: kuanhsiun    時間: 2009-8-12 11:58 AM

太強了~~配服配服~~~~
作者: c_h_wu    時間: 2009-8-12 10:58 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: mtv320320    時間: 2009-8-16 07:36 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: first350    時間: 2009-8-19 04:45 PM

太誇張了..0.0

版主真威..謝謝分享
作者: gslab    時間: 2009-8-19 09:47 PM

哇靠~~這也太屌了吧!!真是高手~~
但是這樣願意分享給大家~~真的很難得的說!!嗯嗯!!
推推推!!!
作者: cool7845520    時間: 2009-8-26 01:53 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: patrick456654    時間: 2009-8-27 02:01 PM

cannot find -lwinmm、-lGDI32
                 ld returned 1 exit status
C:\Documents and Settings\****\桌面\Makefile.win [Build Error]  [坦克大戰.exe] Error 1
編譯完之後,下方出現上面三行,想了幾分鐘....原來將連結器裡的-lwinmm、-lGDI32
改為:
-lwinmm
-lGDI32
就可以了......感謝分享.....為了成為像大大一樣厲害我要努力...
作者: a246513a51    時間: 2009-8-27 06:00 PM

太厲害了 小弟初學 沒想到c++可以做到這樣程度.
作者: warren8890    時間: 2009-8-29 08:19 PM

好棒阿  
來研究看看
我很早就對這種小遊戲有很大的興趣
作者: andy78328    時間: 2009-9-2 08:53 PM

想問一下hex_img究竟是做什麼功用的array呢,關於繪圖方面的知識我還完全是外行人,這一部分的code完全看不懂orz,有沒有什麼參考資料可以看呢
作者: flylikeann9    時間: 2009-9-3 10:02 PM

好利害唷~~

編譯出來就可以玩了耶
而且還蠻好玩的
作者: bbq66666    時間: 2009-9-11 12:49 PM

厲害耶!!!!!!!!!!!!
感謝大大的分享!!!!!!!!!!!!!!
作者: jimgjack    時間: 2009-9-15 01:20 PM

大大你真是太厲害了~~
不愧是高手高手高高手~~
作者: ttcto520    時間: 2009-9-17 07:26 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: 3136631    時間: 2009-9-20 01:24 AM

太神了  ...

看了這篇神乎其技的文章  ...

我都想學了
作者: o04o04    時間: 2009-9-23 12:41 PM

謝謝分享!感激不盡喔!
作者: f8659    時間: 2009-9-23 02:01 PM

這個不是一天二天就可以學會的可見大大用了很多心去寫的真希望可以象大大一樣利害這樣就不怕找不到工作了謝謝大大分享
作者: h0919318199    時間: 2009-9-24 10:32 AM

原來我學的程式連這個都可以做到
看來我還有很多東西要學
作者: gaptx    時間: 2009-9-24 07:18 PM

大哥你太猛了吧
這個寫起來很累人勒
雖然當初的仙見奇俠傳那年代的遊戲都是採用類是的方式編寫
但是你也太強了吧800多行達到這個經典的遊戲
作者: rabbit6030    時間: 2009-9-25 05:37 PM

800多行就能搞出這樣......來研究研究CODE
作者: se20080    時間: 2009-10-6 11:46 AM

好厲害唷!!改天我也要自己寫出一款小遊戲
先拿去分析摟順便玩玩看
作者: yyyyman    時間: 2009-10-6 10:23 PM

真的好好玩喔,我玩得不亦樂乎
有點重返任天堂的時代
讚!!
作者: linkaoyen    時間: 2009-11-8 03:13 PM

@@"真的是太利害了
多謝大大的分享!!
看都看不太懂
只能說程式語言太利害了
我要加油了而且是要加很多的油!!!
作者: 皮皮崽    時間: 2009-11-8 03:43 PM

大大實在是太猛了!!
目前可以動
之後有時間再拿出來玩玩!

(不知道大家目前改的怎樣?!)
作者: 玉鹿    時間: 2009-11-8 07:27 PM

失敗了...><b
1>------ Build started: Project: Just In Case, Configuration: Debug Win32 ------
1>Compiling...
1>vector.cpp
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(193) : warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>        c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(324) : see declaration of 'sscanf'
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(682) : error C2015: too many characters in constant
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(682) : error C2017: illegal escape sequence
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(682) : error C2017: illegal escape sequence
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(682) : error C2001: newline in constant
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(686) : error C2958: the left parenthesis '(' found at 'c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(682)' was not matched correctly
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(682) : error C2143: syntax error : missing ',' before 'constant'
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(683) : error C2143: syntax error : missing ',' before 'for'
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(683) : error C2143: syntax error : missing ')' before ';'
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(683) : error C2143: syntax error : missing ';' before ')'
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(683) : error C2143: syntax error : missing ';' before ')'
1>c:\users\andy chung\documents\visual studio 2008\projects\just in case\just in case\vector.cpp(683) : error C2143: syntax error : missing ';' before '{'
1>Build log was saved at "file://c:\Users\ANDY CHUNG\Documents\Visual Studio 2008\Projects\Just In Case\Just In Case\Debug\BuildLog.htm"
1>Just In Case - 11 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
作者: daviddr    時間: 2009-11-8 08:48 PM

話說按了複製代碼  再貼到VC++後空白處都會變成0x0a
貼到DevC++後空白處則會變成"?"
應該是論壇的問題(還是我的問題@@?)...有辦法解決嗎..?
  
FireFox 會有此問題:
例如貼到 VC++ 9.0 上,行首會有 # 字號,
這時可押著 Alt,再移動滑鼠,框選「多行」,按 [Delete] 將之消去。
或是貼到 UltraEdit 上,按 [Alt]+[C] 切換成選行模式,
刪去 #,再貼到 Dev C++。
或是暫時開啟 IE,用它複製 code,再換回 FireFox。

失敗了...>------ Build started: Project: Just In Case, Configuration: Debug Win32 ------
1>Compilin ...
玉鹿 發表於 2009-11-8 07:27 PM

論壇貼文時,會將某些字元視為功能字元而吸收掉,
將它補回才能正確編譯。前頭有寫處理方式了。
作者: b5905268    時間: 2009-11-9 12:56 AM

天阿

好神喔!!!!!!!
作者: Mario_Go    時間: 2009-11-12 07:57 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: xyakoqfb    時間: 2009-11-12 10:40 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: fzzlfzzl    時間: 2009-11-14 01:04 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: ea19943    時間: 2009-11-16 10:20 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: 0933753987    時間: 2009-12-1 11:43 PM

我出現這些問題a

c:\documents and settings\123\桌面\資料\c++\text\text\tank.cpp(835) : error C2065: 'b' : 未宣告的識別項
c:\documents and settings\123\桌面\資料\c++\text\text\tank.cpp(835) : error C2228: '.type' 的左邊必須有類別/結構/等位
c:\documents and settings\123\桌面\資料\c++\text\text\tank.cpp(835) : fatal error C1003: 錯誤計數超過 100; 停止編譯

大大可以幫忙解答一下嗎
作者: fire6409    時間: 2010-4-8 07:26 PM

這個....也太厲害了吧,小弟我真的是要多加練習才行
作者: idtgg20208    時間: 2010-4-8 08:27 PM

我是超級初新者= =+
複製後按F9又要除錯
看不懂= =''
作者: ericinca    時間: 2010-4-23 11:43 PM

可以教一下 圖怎麼 印出來的嗎?
稍微看了一下 還是看不懂

還有 存圖的那個 陣列   是怎麼用的?

很想學 但是 好難看懂
可以 大概解釋一下 整個程式的邏輯嗎?
感謝 (鞠躬
作者: daviddr    時間: 2010-4-24 01:24 AM

這是將圖像「納入」程式碼的簡易寫法之一,
且很多地方以較隱晦的形式表達,
正規的遊戲設計並不會如此撰寫。

set_image 為圖像解碼程式:
圖像陣列 hex_img 是用另外一個程式壓縮出的 ASCII code,
ASCII 的 8 bits 中只約有 6 bits 為正常可見符號,
將 6 bits 分成 2 + 4 bits 前後 2 部分,
前 2bits 表示此圖像之調色盤 obj_pal 的 1~4 種顏色索引,
obj_pal 中的索引值再對應到 hex_pal 列表中的實際顏色。
實際顏色以 00~FF 表示 RGB 3 個分量。
後 4bits 表示此顏色的重複次數 (1~16 次)。

為了避開 ANSI C 的 trigraph 與 escape sequence,
在編碼時將 ? 轉成 *,將 \ 轉成 +,解碼時再反轉回來。
(沒記錯的話,C99 的 digraph 倒是自然規避了)

其他運行上的邏輯在註解中已寫的很明白。
作者: runeray2000    時間: 2010-4-24 11:32 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: gn01134053    時間: 2010-4-24 01:29 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: daviddr    時間: 2010-4-24 01:39 PM

回復 53# gn01134053

VC++ 以 Win32 主控台應用程式 建專案,
再依第一頁所述稍微修正,按 F5 即可執行。
作者: skywine    時間: 2010-4-25 12:14 AM

真神人阿,太佩服了~
作者: 高義嫩    時間: 2010-4-25 12:22 AM

大大好強喔,可是我完全看不懂。
作者: qweqweqwe7410    時間: 2010-5-3 10:05 AM

大大好厲害呀  佩服佩服
不開始努力不行了
作者: steven78916    時間: 2010-5-4 04:35 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: joe01032002    時間: 2010-5-16 12:11 AM

好強…
抓來看看到底是怎麼寫出來的
冏…
作者: FERR    時間: 2010-5-16 02:15 AM

真的好好玩喔,我玩得不亦樂乎
有點重返任天堂的時代
讚!!
作者: fire6400    時間: 2010-5-16 02:15 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: ufoknow    時間: 2010-5-17 08:05 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: sai20145    時間: 2010-5-17 08:53 PM

好強= =
自嘆不如阿
小弟c++慘遭被當邊緣阿!!
作者: polikujm    時間: 2010-5-18 06:45 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: mushas    時間: 2010-6-12 05:43 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: 沒有明天    時間: 2010-6-13 08:12 PM

本帖最後由 沒有明天 於 2010-6-13 08:27 PM 編輯

太厲害了
連這個也都能做出來
下次我也來秀一下我所做的遊戲吧
不過也只適用GDI做出來的超小品遊戲而已
作者: 606simps    時間: 2010-7-25 03:07 PM

抄屌的!!!!太強的程式了!!!!!!!!!!!!!!!!!!!!!
作者: 606simps    時間: 2010-7-25 03:07 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:08 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:08 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:09 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:09 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:10 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:11 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:14 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:17 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:18 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:52 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:55 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:56 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 03:57 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 04:05 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 606simps    時間: 2010-7-25 04:20 PM

我也好想學喔!!!!
可惜程式功力不到家
作者: 人生無大志    時間: 2010-7-25 04:52 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: fcffg    時間: 2010-7-29 11:52 AM

太厲害了 = =

這不研究一下 真的對不起自己
作者: roystyle    時間: 2010-7-31 08:53 PM

wow. that's cool! I think that should be difficult.
作者: davidjack750    時間: 2010-8-1 12:02 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: cool1949    時間: 2010-8-11 08:59 PM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: leila80324    時間: 2010-8-13 04:09 PM

太強了吧!!!
八百多行就能弄出一個小遊戲
我要學多久才能到這種境界
話說中怎麼有一段很像亂碼的東西...是本來就這樣ㄇ
作者: amd21456    時間: 2010-8-13 08:07 PM

好強阿
能做到這樣,真是不簡單
不過現在改行了,比較沒在碰程式類了
現在看到程式碼就開始頭暈了
作者: foxyman9    時間: 2010-8-17 08:55 PM

太利害了
我就先拿走 回家玩玩看摟
作者: 86637550    時間: 2010-8-30 03:08 AM

感謝大大的原程式碼
沒想到一個小遊戲的程式碼如此大量
這樣的話現在遊戲的程式碼真的不是一般人可以理解的
辛苦大大了
作者: robin0338    時間: 2010-9-1 08:39 PM

回復 1# daviddr


太厲害了   研究一下!!!!!!!!!!!!!
作者: shingetter    時間: 2010-9-14 02:47 PM

可以用了,真是太強了
作者: 版主    時間: 2010-9-14 06:27 PM

回復 1# daviddr


    請問一下樓主,有載點可以提供下載嗎?
作者: goodboy1234    時間: 2010-9-15 01:30 PM

高手高手高高手
我什麼時候才能達到這樣的境界
作者: jimmyspa    時間: 2010-9-16 03:46 PM

真的是太強了,我都不知道我要花上多久的時間才能有這樣的功力...
作者: thelord2009    時間: 2010-9-17 08:52 AM

照上面修正程式碼後
... 上面還有很多 LINK的問題
[Linker error] undefined reference to `operator new[](unsigned int)'
  ld returned 1 exit status
[Build Error]  [專案1.exe] Error 1
作者: xseul4315    時間: 2010-9-17 10:04 AM

提示: 作者被禁止或刪除 內容自動屏蔽
作者: chenhewen1    時間: 2010-9-17 10:32 AM

提示: 作者被禁止或刪除 內容自動屏蔽




歡迎光臨 伊莉討論區 (http://www1357.eyny.com/) Powered by Discuz!