免费注册 查看新帖 |

Chinaunix

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

python实现的“打砖块”游戏 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-04-19 17:13 |只看该作者 |倒序浏览

               
                python实现的“打砖块”游戏。根据摩托罗拉C289手机上的同名游戏写成。
  1. #!/usr/bin/python
  2. #
  3. # Brick & Ball in Python
  4. # by Jerry Fleming
  5. #
  6. # This is a small game adapted from that in Motorola Mobile C289, and my first game in python :)
  7. #
  8. # This progrma is best run under linux. Since Windows port of Python has poor curses support,
  9. # play it under Windows is not recommended. If you have no linux box available, try Cygwin,
  10. # though it too has poor curses support.
  11. #
  12. # As I am a newbie to python, please tell me if you have a better implementation or any suggestions.
  13. #
  14. # TODO:
  15. # re-implemente it with wxPython, so one does not have to rely on the ugly curses.
  16. # session support.
  17. # pausing, especially when confirming
  18. # resize terminal at run time
  19. #
  20. # HISTORY
  21. # 2006-04-19: first version
  22. #
  23. #
  24. import curses
  25. import _curses
  26. import thread
  27. from time import sleep
  28. from string import split
  29. from random import randint
  30. # parameters: adjust them to fit you terminal
  31. brick_width = 7
  32. brick_gap_x = 1
  33. brick_gap_y = 1
  34. speed = 0.1 # sleep time to control moving speed of the ball
  35. # terminal initialization
  36. stdscr = curses.initscr()
  37. curses.noecho()
  38. curses.cbreak()
  39. curses.curs_set(0)
  40. stdscr.keypad(1)
  41. screen_height, screen_width = stdscr.getmaxyx()
  42. screen_height = screen_height - 1
  43. screen_width = screen_width - 1
  44. brick_rows = screen_height / 4
  45. if brick_rows > 7: brick_rows = 7
  46. brick_cols = (screen_width + brick_gap_x) / (brick_width + brick_gap_x)
  47. brick_margin = (screen_width - brick_cols * (brick_width + brick_gap_x) + brick_gap_x)/2
  48. pad_position = randint(0, screen_width - brick_width)
  49. ball_position = [screen_height - 3, randint(0, screen_width - brick_width)]
  50. ball_direction = [-1, 1] # abs(tan(a)) must be 1
  51. pad_direction = ''
  52. bricks = []
  53. game_score = 0
  54. tStart = '''
  55. ______        _       _         ___      ______        _ _     _          ______             _                 
  56. (____  \      (_)     | |       / _ \    (____  \      | | |   (_)        (_____ \        _  | |               
  57. ____)  ) ____ _  ____| |  _   ( (_) )    ____)  )_____| | |    _ ____     _____) )   _ _| |_| |__   ___  ____  
  58. |  __  ( / ___) |/ ___) |_/ )   ) _ (    |  __  ((____ | | |   | |  _ \   |  ____/ | | (_   _)  _ \ / _ \|  _ \
  59. | |__)  ) |   | ( (___|  _ (   ( (/  \   | |__)  ) ___ | | |   | | | | |  | |    | |_| | | |_| | | | |_| | | | |
  60. |______/|_|   |_|\____)_| \_)   \__/\_)  |______/\_____|\_)_)  |_|_| |_|  |_|     \__  |  \__)_| |_|\___/|_| |_|
  61.                                                                                  (____/                        
  62.                                by Jerry Fleming
  63.                                           GAME STARTING ...
  64.                        (this assumes that your terminal be larger that 130x40)
  65. '''
  66. tExit = '''
  67.                                                88888                         88888
  68. 88888888888             88       ad88888ba     88 8b        d8      d8          88
  69. 88                      ""   ,d d8"     "8b    88  Y8,    ,8P     ,8P'          88
  70. 88                           88 ""      a8P    88   Y8,  ,8P     d8"            88
  71. 88aaaaa     8b,     ,d8 88 MM88MMM   ,a8P"     88    "8aa8"    ,8P' 8b,dPPYba,  88
  72. 88"""""      `Y8, ,8P'  88   88     d8"        88     `88'    d8"   88P'   `"8a 88
  73. 88             )888(    88   88     ""         88      88   ,8P'    88       88 88
  74. 88           ,d8" "8b,  88   88,    aa         88      88  d8"      88       88 88
  75. 88888888888 8P'     `Y8 88   "Y888  88         88      88 8P'       88       88 88
  76.                                                88888                         88888
  77. '''
  78. tOver = '''
  79.   ,ad8888ba,                                                                                            88
  80. d8"'    `"8b                                                                                           88
  81. d8'                                                                                                     88
  82. 88            ,adPPYYba, 88,dPYba,,adPYba,   ,adPPYba,     ,adPPYba,  8b       d8  ,adPPYba, 8b,dPPYba, 88
  83. 88      88888 ""     `Y8 88P'   "88"    "8a a8P_____88    a8"     "8a `8b     d8' a8P_____88 88P'   "Y8 88
  84. Y8,        88 ,adPPPPP88 88      88      88 8PP"""""""    8b       d8  `8b   d8'  8PP""""""" 88         ""
  85. Y8a.    .a88 88,    ,88 88      88      88 "8b,   ,aa    "8a,   ,a8"   `8b,d8'   "8b,   ,aa 88         aa
  86.   `"Y88888P"  `"8bbdP"Y8 88      88      88  `"Ybbd8"'     `"YbbdP"'      "8"      `"Ybbd8"' 88         88
  87. '''
  88. tGoon = '''
  89.                                                                 88888                         88888
  90.   ,ad8888ba,                                      ad88888ba     88 8b        d8      d8          88
  91. d8"'    `"8b                                    d8"     "8b    88  Y8,    ,8P     ,8P'          88
  92. d8'                                              ""      a8P    88   Y8,  ,8P     d8"            88
  93. 88             ,adPPYba,      ,adPPYba,  8b,dPPYba,   ,a8P"     88    "8aa8"    ,8P' 8b,dPPYba,  88
  94. 88      88888 a8"     "8a    a8"     "8a 88P'   `"8a d8"        88     `88'    d8"   88P'   `"8a 88
  95. Y8,        88 8b       d8    8b       d8 88       88 ""         88      88   ,8P'    88       88 88
  96. Y8a.    .a88 "8a,   ,a8"    "8a,   ,a8" 88       88 aa         88      88  d8"      88       88 88
  97.   `"Y88888P"   `"YbbdP"'      `"YbbdP"'  88       88 88         88      88 8P'       88       88 88
  98.                                                                 88888                         88888
  99. '''
  100. def init_game():
  101.     global bricks
  102.     # display the bricks
  103.     for row in range(brick_rows):
  104.         y = row * (1 + brick_gap_y)
  105.         for col in range(brick_cols):
  106.             x = col * (brick_gap_x + brick_width) + brick_margin
  107.             stdscr.addstr(y, x, ' ' * brick_width, curses.A_REVERSE)
  108.             bricks.append([y, x])
  109.     # move the pad to center of bottom at starting up
  110.     stdscr.addstr(screen_height - 1, pad_position, ' ' * brick_width, curses.A_REVERSE)
  111.     # move the ball to left bottom side at starting up
  112.     stdscr.addstr(ball_position[0], ball_position[1], ' ', curses.A_REVERSE)
  113.     # display score board
  114.     stdscr.addstr(screen_height, 0, ' SCORE: '+ ('%03d' % game_score) + ' '* 4, curses.A_REVERSE)
  115.     stdscr.addstr(screen_height, 15, 'USE q to quit' + ' '* (screen_width - 28), curses.A_REVERSE)
  116.     # final step to init display
  117.     stdscr.refresh()
  118. # move the pad to catch the ball
  119. def move_pad(lock):
  120.     global pad_position
  121.     char = stdscr.getch()
  122.     if char == ord('q'):
  123.         quit_game(lock)
  124.     else:
  125.         if char == curses.KEY_LEFT: pad_position = pad_position - 1; pad_direction = 'left'
  126.         if char == curses.KEY_RIGHT: pad_position = pad_position + 1; pad_direction = 'right'
  127.     if pad_position = screen_width - brick_width: pad_position = screen_width - brick_width
  128.     stdscr.addstr(screen_height - 1, 0, ' ' * screen_width)
  129.     stdscr.addstr(screen_height - 1, pad_position, ' ' * brick_width, curses.A_REVERSE)
  130.     stdscr.refresh()
  131.     move_pad(lock)
  132. # move the ball to a direction
  133. def move_ball(lock):
  134.     global ball_position, ball_direction
  135.     # clear the old position, do not if in pad
  136.     if ball_position[0] != screen_height - 1:
  137.         stdscr.addstr(ball_position[0], ball_position[1], ' ')
  138.     ball_position[0] = ball_position[0] + ball_direction[0]
  139.     ball_position[1] = ball_position[1] + ball_direction[1]
  140.     stdscr.addstr(ball_position[0], ball_position[1], ' ', curses.A_REVERSE)
  141.     detect_collision(lock)
  142.     stdscr.refresh()
  143.     sleep(speed)
  144.     move_ball(lock)
  145. # detect whether the ball has hit something, change direction if yes
  146. def detect_collision(lock):
  147.     global bricks, ball_direction, game_score
  148.     # hit upper wall
  149.     if ball_position[0] == 0 :
  150.         ball_direction = [- ball_direction[0], ball_direction[1]]
  151.     # hit left and right wall
  152.     if ball_position[1] == 0 or ball_position[1] == screen_width:
  153.         ball_direction = [ball_direction[0], - ball_direction[1]]
  154.     # hit brick
  155.     for brick in bricks:
  156.         # hit from bottom or upper direction
  157.         if brick[1] <= ball_position[1] + ball_direction[1] <= brick[1] + brick_width \
  158.         and ball_position[0] + ball_direction[0] == brick[0]:
  159.             ball_direction[0] = - ball_direction[0]
  160.             stdscr.addstr(brick[0], brick[1], ' '* brick_width)
  161.             game_score = game_score + 10
  162.             stdscr.addstr(screen_height, 8, '%03d' % game_score, curses.A_REVERSE)
  163.             bricks.remove(brick)
  164.             # another level to continue the game
  165.             if not len(bricks): another_level()
  166.     # hit body of pad
  167.     if ball_position[0] == screen_height - 2 and pad_position <= ball_position[1] <= pad_position + brick_width:
  168.         ball_direction[0] = - ball_direction[0]
  169.     # hit bottom
  170.     elif ball_position[0] == screen_height - 1:
  171.         ball_direction[0] = - ball_direction[0]
  172.     # hit left side of pad (hit bottom already)
  173.     if ball_position[1] == pad_position and  pad_direction == 'left' and ball_direction[1]:
  174.         ball_direction[1] = - ball_direction[1]
  175.     # hit right side of pad (hit bottom already)
  176.     if ball_position[1] == pad_position + brick_width and  pad_direction == 'right' and not ball_direction[1]:
  177.         ball_direction[1] = - ball_direction[1]
  178.     # hit bottom wall, game over
  179.     if ball_position[0] == screen_height - 1 and not pad_position <= ball_position[1] <= pad_position + brick_width:
  180.             line_num = 0
  181.         for line in split(tOver, "\n"):
  182.             stdscr.addstr(screen_height / 2 + line_num, 10, line)
  183.             line_num = line_num + 1
  184.         stdscr.refresh()
  185.         curses.flash()
  186.         sleep(1)
  187.         curses.flash()
  188.         sleep(1)
  189.         lock.release()
  190. # confirm quit the game
  191. def quit_game(lock):
  192.     line_num = 0
  193.     for line in split(tExit, "\n"):
  194.         stdscr.addstr(screen_height / 2 + line_num, 10, line)
  195.         line_num = line_num + 1
  196.     stdscr.refresh()
  197.     char = stdscr.getch()
  198.     if char == ord('N') or char == ord('n'):
  199.         line_num = 0
  200.         for line in split(tExit, "\n"):
  201.             stdscr.addstr(screen_height / 2 + line_num, 10, ' ' * len(line) )
  202.             line_num = line_num + 1
  203.             stdscr.refresh()
  204.     else:
  205.         lock.release()
  206. # confirm another level of the game
  207. def another_level():
  208.     line_num = 0
  209.     for line in split(tGoon, "\n"):
  210.         stdscr.addstr(screen_height / 2 + line_num, 10, line)
  211.         line_num = line_num + 1
  212.     stdscr.refresh()
  213.     char = stdscr.getch()
  214.     if char == ord('N') or char == ord('n'):
  215.         lock.release()
  216.     else:
  217.         line_num = 0
  218.         for line in split(tGoon, "\n"):
  219.             stdscr.addstr(screen_height / 2 + line_num, 10, ' ' * len(line) )
  220.             line_num = line_num + 1
  221.             stdscr.refresh()
  222.         init_game()
  223. # main loop starts here
  224. if __name__ == "__main__":
  225.     try:
  226.         line_num = 0
  227.         for line in split(tStart, "\n"):
  228.             stdscr.addstr(screen_height /4 + line_num, 10, line)
  229.             line_num = line_num + 1
  230.         stdscr.refresh()
  231.         sleep(1)
  232.         stdscr.erase()
  233.         running = 1
  234.         init_game()
  235.         locks = []
  236.         for i in range(2):
  237.             lock = thread.allocate_lock()
  238.             lock.acquire()
  239.             locks.append(lock)
  240.         thread.start_new_thread(move_ball, (locks[0],))
  241.         thread.start_new_thread(move_pad, (locks[1],))
  242.     except _curses.error, diag:
  243.         msg = 'Your terminal is too small: ' + str(diag)
  244.         running = 0
  245.     except:
  246.         msg = 'An unknown error occured.'
  247.         running = 0
  248.     else:
  249.         msg = 'Game stopped.'
  250.     while running:
  251.         for i in range(len(locks)):
  252.             if locks[i].locked()==False: running = 0
  253.         if running == 0:
  254.             for i in range(len(locks)):
  255.                 if locks[i].locked(): locks[i].release()
  256.     curses.curs_set(1)
  257.     stdscr.keypad(0)
  258.     curses.nocbreak()
  259.     curses.echo()
  260.     curses.endwin()
  261.     print msg
复制代码
               
               
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/8484/showart_102109.html

论坛徽章:
0
2 [报告]
发表于 2012-09-12 00:42 |只看该作者
这个程序,跑不起来啊?

论坛徽章:
0
3 [报告]
发表于 2012-11-26 11:40 |只看该作者
本帖最后由 paktc 于 2012-11-26 11:41 编辑

回复 1# jerryfleming


    运行失败了,楼主能上传文件不

There's an error in your program:
invalid syntax

第128行
  1. if (pad_position = screen_width - brick_width): pad_position = screen_width - brick_width
复制代码
"="应改为 " =="


There's an error in your program:
unindent does not match any outer indentation level

第181行
  1.     if ball_position[0] == screen_height - 1 and not pad_position <= ball_position[1] <= pad_position + brick_width:
  2.             line_num = 0
  3.         for line in split(tOver, "\n"):
  4.             stdscr.addstr(screen_height / 2 + line_num, 10, line)
复制代码
line_num = 0  
缩进过头了。。

最后
ImportError: No module named _curses

楼主  打个包给我们吧{:2_169:}

论坛徽章:
0
4 [报告]
发表于 2012-11-26 11:44 |只看该作者
本帖最后由 paktc 于 2012-11-26 11:45 编辑

网上查了一下
  1. curses是Unix/linux平台的库。windows没有。
复制代码
http://bbs.csdn.net/topics/280084540
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP