免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3236 | 回复: 1
打印 上一主题 下一主题

[C++] 贴个俄罗斯方块 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-29 22:38 |只看该作者 |倒序浏览
图形资源文件 tetris.h

  1. const unsigned char data_logo[] =
  2. {
  3.   45, 45, 46, 47, 48, 49, 50, 49, 48, 48, 49, 50, 52, 53, 55, 56,
  4.   59, 62, 64, 65, 64, 64, 66, 66, 65, 66, 72, 76, 78, 80, 77, 74,
  5.   83, 84, 79, 78, 82, 85, 91, 97, 85, 92, 90, 95, 97, 97, 93, 88,
  6.   95, 87, 85, 88, 88, 85, 82, 81, 83, 77, 74, 81, 81, 78, 73, 69,
  7.   67, 65, 63, 65, 66, 65, 65, 65, 64, 61, 59, 56, 54, 53, 52, 52,
  8.   52, 51, 51, 49, 48, 47, 46, 45, 44, 43, 43, 43, 42, 41, 41, 41, 
  9.   //太长,以下略去
  10. };
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2013-12-29 22:39 |只看该作者
源文件:
  1. /*
  2. #
  3. #  File        : tetris.cpp
  4. #                ( C++ source file )
  5. #
  6. #  Description : A CImg version of the famous Tetris game.
  7. #                This file is a part of the CImg Library project.
  8. #                ( http://cimg.sourceforge.net )
  9. #
  10. #  Copyright   : David Tschumperle
  11. #                ( http://tschumperle.users.greyc.fr/ )
  12. #
  13. #  License     : CeCILL v2.0
  14. #                ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html )
  15. #
  16. #  This software is governed by the CeCILL  license under French law and
  17. #  abiding by the rules of distribution of free software.  You can  use,
  18. #  modify and/ or redistribute the software under the terms of the CeCILL
  19. #  license as circulated by CEA, CNRS and INRIA at the following URL
  20. #  "http://www.cecill.info".
  21. #
  22. #  As a counterpart to the access to the source code and  rights to copy,
  23. #  modify and redistribute granted by the license, users are provided only
  24. #  with a limited warranty  and the software's author,  the holder of the
  25. #  economic rights,  and the successive licensors  have only  limited
  26. #  liability.
  27. #
  28. #  In this respect, the user's attention is drawn to the risks associated
  29. #  with loading,  using,  modifying and/or developing or reproducing the
  30. #  software by the user in light of its specific status of free software,
  31. #  that may mean  that it is complicated to manipulate,  and  that  also
  32. #  therefore means  that it is reserved for developers  and  experienced
  33. #  professionals having in-depth computer knowledge. Users are therefore
  34. #  encouraged to load and test the software's suitability as regards their
  35. #  requirements in conditions enabling the security of their systems and/or
  36. #  data to be ensured and,  more generally, to use and operate it in the
  37. #  same conditions as regards security.
  38. #
  39. #  The fact that you are presently reading this means that you have had
  40. #  knowledge of the CeCILL license and that you accept its terms.
  41. #
  42. */

  43. #include "tetris.h"
  44. #include <CImg.h>
  45. using namespace cimg_library;

  46. // Main procedure
  47. //----------------
  48. int main( int argc, char** argv )
  49. {
  50.     // Read command line argument (if any)
  51.     cimg_usage( "An implementation of the well known 'Tetris' game with CImg." );
  52.     unsigned int
  53.     blocdim = cimg_option( "-blocdim", 18, "Sprite bloc size" ),
  54.     speed   = cimg_option( "-speed", 20, "Initial speed" ),
  55.     level   = cimg_option( "-level", 0, "Level" );
  56.     const char* geometry = cimg_option( "-g", "12x20", "Size of the board" );
  57.     unsigned int bwidth = 12, bheight = 20;
  58.     std::sscanf( geometry, "%u%*c%u", &bwidth, &bheight );
  59.     const CImg<unsigned char> dlogo = CImg<unsigned char>( data_logo, 128, 96, 1, 3, true );
  60.     if ( cimg::dialog( "CImg Tetris",
  61.                        "Welcome to the CImg version of Tetris.\n"
  62.                        "( by David Tschumperle )\n\n"
  63.                        "Press 'Start' when you are ready to play !", "Start", "Quit", 0, 0, 0, 0, dlogo, true ) ) std::exit( 0 );
  64.     // Create sprite, background graphics and initial board data
  65.     const CImgList<unsigned char> pieces = CImgList<unsigned char>().
  66.                                            insert( CImg<unsigned char>( 3, 2 ).fill( 1, 1, 1, 0, 0, 1 ) ).
  67.                                            insert( CImg<unsigned char>( 3, 2 ).fill( 2, 2, 2, 2, 0, 0 ) ).
  68.                                            insert( CImg<unsigned char>( 2, 2 ).fill( 3, 3, 3, 3 ) ).
  69.                                            insert( CImg<unsigned char>( 4, 1 ).fill( 4, 4, 4, 4 ) ).
  70.                                            insert( CImg<unsigned char>( 3, 2 ).fill( 5, 5, 0, 0, 5, 5 ) ).
  71.                                            insert( CImg<unsigned char>( 3, 2 ).fill( 0, 6, 6, 6, 6, 0 ) ).
  72.                                            insert( CImg<unsigned char>( 3, 3 ).fill( 0, 7, 0, 7, 7, 7, 0, 7, 0 ) ).
  73.                                            insert( CImg<unsigned char>( 2, 1 ).fill( 8, 8 ) ).
  74.                                            insert( CImg<unsigned char>( 3, 2 ).fill( 9, 9, 9, 0, 9, 0 ) ).
  75.                                            insert( CImg<unsigned char>( 2, 2 ).fill( 10, 10, 0, 10 ) ).
  76.                                            insert( CImg<unsigned char>( 3, 1 ).fill( 11, 11, 11 ) );
  77.     CImg<unsigned char> board( bwidth, bheight, 1, 1, 0 ), background( board.width()*blocdim, board.height()*blocdim, 1, 3, 0 );
  78.     ( background.noise( 30 ).draw_plasma().noise( 30 ).deriche( 5, 0, 'y' ).shift( 0, -background.height() / 2, 0, 0, 2 ).deriche( 5, 0, 'y' ) ) /= 1.5f;
  79.     if ( level ) ( board.get_shared_rows( board.height() - level, board.height() - 1, 0, 0 ).noise( 100 ) ) %= pieces.size() + 1;
  80.     // Create a set of small gradient-colored blocs used to draw the pieces.
  81.     CImgList<unsigned char> blocs( pieces.size(), blocdim, blocdim, 1, 3 );
  82.     cimglist_for( blocs, l )
  83.     {
  84.         CImg<unsigned char> color = CImg<unsigned char>( 3, 1, 1, 1, 128 ).noise( 127, 1 ).cut( 120, 255 );
  85.         float val;
  86.         cimg_forXYC( blocs[l], x, y, k ) blocs[l]( x, y, k ) = ( unsigned char )( ( val = ( color[k] * 0.7f * ( x + y + 5 ) / blocdim ) ) > 255 ? 255 : val );
  87.         blocs[l].draw_line( 0, 0, 0, blocdim - 1, ( color >> 1 ).data() ).draw_line( 0, blocdim - 1, blocdim - 1, blocdim - 1, ( color >> 1 ).data() );
  88.         color = ( CImg<unsigned int>( color ) *= 2 ).cut( 0, 255 );
  89.         blocs[l].draw_line( 0, 0, ( int )blocdim - 1, 0, color.data() ).draw_line( blocdim - 1, 0, blocdim - 1, blocdim - 1, color.data() );
  90.     }
  91.     // Initialize window display and enter the main event loop
  92.     CImgDisplay disp( background, "CImg Tetris", 0, false, true );
  93.     disp.move( ( CImgDisplay::screen_width() - disp.width() ) / 2,
  94.                ( CImgDisplay::screen_height() - disp.height() ) / 2 ).hide_mouse();
  95.     const unsigned char white[3] = { 255, 255, 255 };
  96.     CImg<unsigned char> visu, nboard, piece, next, next_mask;
  97.     int cx = -1, cy = -1, cn = -1, nn = rand() % pieces.size(), time = 0, score = 0;
  98.     bool gameover = false, pause = false;
  99.     while ( !gameover && !disp.is_closed() && !disp.is_keyESC() && !disp.is_keyQ() )
  100.     {
  101.         if ( !pause )
  102.         {
  103.             // Draw the board on the display window.
  104.             nboard = board; visu = background;
  105.             if ( cx >= 0 && cy >= 0 ) cimg_forXY( piece, x, y ) if ( piece( x, y ) ) nboard( cx - piece.width() / 2 + x, cy - piece.height() / 2 + y ) = piece( x, y );
  106.             cimg_forXY( board, xx, yy ) if ( nboard( xx, yy ) ) visu.draw_image( xx * blocdim, yy * blocdim, blocs[nboard( xx, yy ) - 1] );
  107.             visu.draw_text( 5, 5, "Lines : %d", white, 0, 1, 13, score, nn ).draw_text( visu.width() - 65, 5, "Next :", white, 0, 1, 13 );
  108.             if ( next ) visu.draw_image( visu.width() - next.width() - 2, 10 - next.height() / 2, next, next_mask ).display( disp.wait( 20 ) );
  109.             if ( cn < 0 )
  110.             {
  111.                 // Introduce a new piece on the board (if necessary) and create representation of the next piece
  112.                 board = nboard;
  113.                 piece = pieces[cn = nn];
  114.                 nn = rand() % pieces.size();
  115.                 cx = board.width() / 2;
  116.                 cy = piece.height() / 2;
  117.                 next = CImg<unsigned char>( pieces[nn].width() * blocdim, pieces[nn].height() * blocdim, 1, 3, 0 );
  118.                 cimg_forXY( pieces[nn], xi, yi ) if ( pieces[nn]( xi, yi ) ) next.draw_image( xi * blocdim, yi * blocdim, blocs[pieces[nn]( xi, yi ) - 1] );
  119.                 next_mask = next.resize( -50, -50 ).get_norm().threshold( 0 );
  120.                 // Detect tetris lines and do line removal animation if found.
  121.                 cimg_forY( board, yyy )
  122.                 {
  123.                     int Y = yyy * blocdim, line = 1;
  124.                     cimg_forX( board, xxx ) if ( !board( xxx, yyy ) ) line = 0;
  125.                     if ( line )
  126.                     {
  127.                         board.draw_image( 0, 1, board.get_crop( 0, 0, board.width() - 1, yyy - 1 ) );
  128.                         if ( !( ( ++score ) % 1 ) && speed > 1 ) --speed;
  129.                         for ( float alpha = 0; alpha <= 1; alpha += 0.07f )
  130.                             CImg<unsigned char>( visu ).draw_image( 0, Y, background.get_crop( 0, Y, visu.width() - 1, Y + blocdim - 1 ), alpha ).display( disp.wait( 20 ) );
  131.                         visu.draw_image( 0, Y, background.get_crop( 0, Y, visu.width() - 1, Y + blocdim - 1 ) );
  132.                     }
  133.                 }
  134.             }
  135.             // Handle motion & collisions
  136.             const int ox = cx, oy = cy;
  137.             bool rotated = false, collision;
  138.             switch ( disp.key() )
  139.             {
  140.                 case cimg::keyP: pause = true; break;
  141.                 case cimg::keyARROWUP: piece.rotate( 90 ); rotated = true; disp.set_key(); break;
  142.                 case cimg::keyARROWLEFT: --cx;  disp.set_key(); break;
  143.                 case cimg::keyARROWRIGHT: ++cx;  disp.set_key(); break;
  144.             }
  145.             if ( cx - piece.width() / 2 < 0 ) cx = piece.width() / 2;
  146.             if ( cy - piece.height() / 2 < 0 ) cy = piece.height() / 2;
  147.             if ( cx + ( piece.width() - 1 ) / 2 >= board.width() ) cx = board.width() - 1 - ( piece.width() - 1 ) / 2;
  148.             // Detect collision along the X axis
  149.             collision = false; cimg_forXY( piece, i, j ) if ( piece( i, j ) && board( cx - piece.width() / 2 + i, cy - piece.height() / 2 + j ) ) collision = true;
  150.             if ( collision ) { cx = ox; if ( rotated ) piece.rotate( -90 ); }
  151.             if ( disp.key() == cimg::keyARROWDOWN || !( ( ++time ) % speed ) ) { ++cy; disp.set_key(); }
  152.             // Detect collisiong along the Y axis
  153.             collision = false; cimg_forXY( piece, ii, jj ) if ( piece( ii, jj ) && board( cx - piece.width() / 2 + ii, cy - piece.height() / 2 + jj ) ) collision = true;
  154.             if ( collision || cy + ( piece.height() - 1 ) / 2 >= board.height() ) { cy = oy; cn = -1; }
  155.             if ( collision && cy == piece.height() / 2 ) gameover = true;
  156.         }
  157.         else
  158.         {
  159.             // If game is paused (key 'P'), do a little text animation
  160.             float A = 0, B = 0;
  161.             CImg<float> pauselogo = CImg<unsigned char>().draw_text( 0, 0, "Game Paused\nPress a key", white );
  162.             disp.set_key(); while ( !disp.is_closed() && !disp.key() )
  163.             {
  164.                 const CImg<float> pauserotated = pauselogo.get_rotate( ( float )( 30 * std::sin( A ) ), 1, 0 ).
  165.                                                  resize( ( int )( -150 - 80 * std::sin( B ) ), ( int )( -150 - 80 * std::sin( B ) ) );
  166.                 A += 0.08f; B += 0.043f;
  167.                 CImg<unsigned char>( background ).
  168.                 draw_image( ( background.width() - pauserotated.width() ) / 2,
  169.                             ( background.height() - pauserotated.height() ) / 2,
  170.                             pauserotated.get_resize( -100, -100, 1, 3, 2 ), pauserotated, 1, 255 ).display( disp.wait( 20 ) );
  171.                 if ( disp.is_resized() ) disp.resize();
  172.             }
  173.             disp.set_key();
  174.             pause = false;
  175.         }
  176.         background.shift( 0, -20 / ( int )speed, 0, 0, 2 );
  177.         if ( disp.is_resized() ) disp.resize();
  178.     }
  179.     // End of game reached, display the score and do a 'game over' animation
  180.     cimg_forXYC( visu, x, y, k ) if ( x % 2 || y % 2 ) visu( x, y, k ) = 0;
  181.     visu.display( disp );
  182.     char tmp[1024];
  183.     std::sprintf( tmp, "Game Over !\n\nYour score : %d", score );
  184.     cimg::dialog( "CImg Tetris", tmp, "Quit" );
  185.     return 0;
  186. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP