赞
踩
注:以下程序为本人原创,写的不好,若有好的建议,望留言告知。而若能帮助一二访客,幸甚!
最近搞“科研”搞的蛋都碎了。。。
思吾之理想是将计算机玩弄于股掌之上(将计算机组成原理、操作系统、程序运行机理、程序设计语言、计算机网络、算法数据结构学扎实了…呃,理想而已,至今所以这些选项都学得不达标。。),而如今却为了毕业在跟着一群数学家“搞科研”,而实验又做来做去都那个样,一点效果也没有,真是蛋疼啊。
昨晚照着Andre LaMothe大师《Windows游戏编程大师技巧》一书第一章示例程序,略作修改做了一个打砖块游戏以学习Win32 程序组织技巧,略有所得。今晚决定尝试使用Python + pyGame 实现一个类似的程序,以学习Python,聊以解闷。
当然实现一个几乎相同的要简单些,但为了更有成就感,决定功能上略作修改:昨晚实现的程序,按照书上的实现,当小球落地没接住,会减100分,但不会死亡,今晚决定实现一个更普遍的打砖块,即小球落地,会生命减1,生命没了就Game over。
俗话说大事化小,小事化无;又曰天下难事,必作于易。
虽然写个打砖块并非太难的事,但将它分解开来,分解的足够简单还是有必要的。
现将一个打砖块的主要功能分解如下:
1)实现一个小球在屏幕上移动
2)碰到边缘要能够反弹
3)挡板绘制和移动
4)砖块的绘制
5)游戏流程和控制逻辑
6)绘制文字显示游戏信息
7)加个背景音乐
这几个功能应该都是在一定时间内能够实现的简单功能,而只要将他们合理的组合起来就是一个完整的打砖块游戏了~
画个小球?怎么画来?忘了……
好吧,把古老的pyGame 做的 Hello World 找出来看看吧,看来积累还是很重要的,毕竟一个打砖块最终划分成了若干个Hello world 嘛~~
连上注释30几行代码,先做出一个游戏界面框架来:
- '''
- 功能:使用pyGame实现一个简单的打砖块游戏
- Created on Nov 30, 2012
- @author: liury_lab
- '''
-
- import pygame, sys, time #@UnusedImport
- from pygame.locals import * #@UnusedWildImport
-
- # 一些关于宽度和高度的常量定义
- WINDOWWIDTH = 640
- WINDOWHEIGHT = 480
-
- # 一些颜色常量定义
- BACKGROUNDCOLOR = (0, 0, 0)
-
- # 游戏的初始化
- pygame.init()
- mainClock = pygame.time.Clock()
-
- windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
- pygame.display.set_caption('打砖块')
-
- # 游戏主循环
- while True:
- # 事件监听
- for event in pygame.event.get():
- if event.type == QUIT:
- pygame.quit()
- exit()
-
- windowSurface.fill(BACKGROUNDCOLOR)
-
- pygame.display.update()
- mainClock.tick(30)
-

下面画个会动的小球吧:
- # 游戏主循环
- while True:
- # 事件监听
- for event in pygame.event.get():
- if event.type == QUIT:
- pygame.quit()
- exit()
-
- if game_state == GAME_STATE_INIT:
- # 初始化游戏
- ball_x = random.randint(8, WINDOW_WIDTH-8)
- ball_y = BALL_START_Y
- ball_dx = random.randint(-4, 4)
- ball_dy = random.randint( 6, 8)
-
- game_state = GAME_STATE_START_LEVEL
- elif game_state == GAME_STATE_START_LEVEL:
- # 新的一关
- game_state = GAME_STATE_RUN
- elif game_state == GAME_STATE_RUN:
- # 游戏运行
- ball_x += ball_dx;
- ball_y += ball_dy;
- windowSurface.fill(BACKGROUND_COLOR)
- pygame.draw.circle(windowSurface, BALL_COLOR, (ball_x, ball_y), BALL_SIZE, 0)
- elif game_state == GAME_STATE_SHUTDOWN:
- game_state = GAME_STATE_EXIT
-
- pygame.display.update()
- mainClock.tick(30)

1)会动的小球画好了,但很快它就跑到屏幕外头再也不会来了…
2)我不得不承认小球跑的太快,我无法抓图抓住它,只好做了个不会动的小球截了个图…
3)呃,没按计划办事,游戏的流程在这里就写好了,当然,有昨晚大师的Win32 程序做基础,这个流程还是很容易写的
小球一出来就开始跑,一会儿就不见了。这一步要让它碰到边界就反弹回去。
这个速度的改变有点类似于光的反射。
只需要添加下面几行代码就好了:
- elif game_state == GAME_STATE_RUN:
- # 游戏运行
- ball_x += ball_dx;
- ball_y += ball_dy;
-
- if ball_x > (WINDOW_WIDTH-BALL_SIZE) or ball_x < BALL_SIZE:
- ball_dx = -ball_dx
- ball_x += ball_dx;
- elif ball_y > (WINDOW_HEIGHT-BALL_SIZE) or ball_y < BALL_SIZE:
- ball_dy = -ball_dy
- ball_y += ball_dy
然后就是实现一个能够根据玩家输入移动的挡板,来阻挡小球。
当然上面的代码需要修改,若小球超出了下边界而没有被挡板挡住,则损失一条生命,此是后话,此处值实现绘制和移动,先不检测与球的碰撞。
- # 游戏主循环
- while True:
- # 事件监听
- for event in pygame.event.get():
- if event.type == QUIT:
- pygame.quit()
- exit()
- if event.type == KEYDOWN:
- if event.key == K_LEFT:
- paddle_move_left = True
- if event.key == K_RIGHT:
- paddle_move_right = True
- if event.type == KEYUP:
- if event.key == K_LEFT:
- paddle_move_left = False
- if event.key == K_RIGHT:
- paddle_move_right = False
- # 游戏控制流程
- if game_state == GAME_STATE_INIT:
- # 初始化游戏
- ball_x = random.randint(8, WINDOW_WIDTH-8)
- ball_y = BALL_START_Y
- ball_dx = random.randint(-4, 4)
- ball_dy = random.randint( 6, 8)
-
- paddle['rect'].left = PADDLE_START_X
- paddle['rect'].top = PADDLE_START_Y
-
- paddle_move_left = False
- paddle_move_right = False
-
- game_state = GAME_STATE_START_LEVEL
- elif game_state == GAME_STATE_START_LEVEL:
- # 新的一关
- game_state = GAME_STATE_RUN
- elif game_state == GAME_STATE_RUN:
- # 游戏运行
-
- # 球的运动
- ball_x += ball_dx;
- ball_y += ball_dy;
-
- if ball_x > (WINDOW_WIDTH-BALL_SIZE) or ball_x < BALL_SIZE:
- ball_dx = -ball_dx
- ball_x += ball_dx;
- elif ball_y > (WINDOW_HEIGHT-BALL_SIZE) or ball_y < BALL_SIZE:
- ball_dy = -ball_dy
- ball_y += ball_dy
-
- # 挡板的运动
- if paddle_move_left:
- paddle['rect'].left -= 8
- if paddle['rect'].left < 0:
- paddle['rect'].left = 0
- if paddle_move_right:
- paddle['rect'].left += 8
- if paddle['rect'].left > WINDOW_WIDTH-PADDLE_WIDTH:
- paddle['rect'].left = WINDOW_WIDTH-PADDLE_WIDTH
-
- # 绘制过程
- windowSurface.fill(BACKGROUND_COLOR)
- pygame.draw.rect(windowSurface, paddle['color'], paddle['rect'])
- pygame.draw.circle(windowSurface, BALL_COLOR, (ball_x, ball_y), BALL_SIZE, 0)
- elif game_state == GAME_STATE_SHUTDOWN:
- game_state = GAME_STATE_EXIT
-
- pygame.display.update()
- mainClock.tick(30)

首先要有个数组记录砖块是否已经被打掉了,然后把未被打掉的绘制在窗口上部
初始化砖块二维数组:
- # 初始化砖块数组
- def InitBlocks():
- blocks = [[1] * NUM_BLOCK_COLUMNS] * NUM_BLOCK_ROWS
- return blocks
'运行
- elif game_state == GAME_STATE_START_LEVEL:
- # 新的一关
- blocks = InitBlocks()
- game_state = GAME_STATE_RUN
- elif game_state == GAME_STATE_RUN:
- # 游戏运行
-
- # 球的运动
- ball_x += ball_dx;
- ball_y += ball_dy;
-
- if ball_x > (WINDOW_WIDTH-BALL_SIZE) or ball_x < BALL_SIZE:
- ball_dx = -ball_dx
- ball_x += ball_dx;
- elif ball_y > (WINDOW_HEIGHT-BALL_SIZE) or ball_y < BALL_SIZE:
- ball_dy = -ball_dy
- ball_y += ball_dy
-
- # 挡板的运动
- if paddle_move_left:
- paddle['rect'].left -= 8
- if paddle['rect'].left < 0:
- paddle['rect'].left = 0
- if paddle_move_right:
- paddle['rect'].left += 8
- if paddle['rect'].left > WINDOW_WIDTH-PADDLE_WIDTH:
- paddle['rect'].left = WINDOW_WIDTH-PADDLE_WIDTH
-
- # 绘制过程
- windowSurface.fill(BACKGROUND_COLOR)
- # 绘制挡板
- pygame.draw.rect(windowSurface, paddle['color'], paddle['rect'])
- # 绘制小球
- pygame.draw.circle(windowSurface, BALL_COLOR, (ball_x, ball_y),
- BALL_SIZE, 0)
- # 绘制砖块
- cur_x = BLOCK_ORIGIN_X
- cur_y = BLOCK_ORIGIN_Y
- for row in range(NUM_BLOCK_ROWS):
- cur_x = BLOCK_ORIGIN_X
- for col in range(NUM_BLOCK_COLUMNS):
- print(blocks[row][col])
- if (blocks[row][col] == 1):
- pygame.draw.rect(windowSurface, BLOCK_COLOR,
- (cur_x, cur_y, BLOCK_WIDTH, BLOCK_HEIGHT))
- cur_x += BLOCK_X_GAP
- cur_y += BLOCK_Y_GAP

随便写了个RGB,好鲜亮的砖块颜色,很合我意,最起码比昨晚蒙的那个Win32 版的好……
边角的工作都做完了,只差游戏的逻辑了,正所谓万事俱备,只欠东风。
1)把砖块打破
2)被挡板挡住才返回,落没挡住则要减少一条生命
3)生命用完了则Game Over
4)砖块打完了要进入下一关或宣告胜利
- elif game_state == GAME_STATE_RUN:
- # 游戏运行
-
- # 球的运动
- ball_x += ball_dx;
- ball_y += ball_dy;
-
- if ball_x > (WINDOW_WIDTH-BALL_SIZE) or ball_x < BALL_SIZE:
- ball_dx = -ball_dx
- ball_x += ball_dx;
- elif ball_y < BALL_SIZE:
- ball_dy = -ball_dy
- ball_y += ball_dy
- elif ball_y > WINDOW_HEIGHT-BALL_SIZE:
- if life_left == 0:
- game_state = GAME_STATE_GAMEOVER
- else:
- life_left -= 1
- # 初始化游戏
- ball_x = paddle['rect'].left + PADDLE_WIDTH // 2
- ball_y = BALL_START_Y
- ball_dx = random.randint(-4, 5)
- ball_dy = random.randint( 6, 9)
-
- # 检测球是否与挡板碰撞
- if ball_y > WINDOW_HEIGHT // 2:
- if (ball_x+BALL_SIZE >= paddle['rect'].left and \
- ball_x-BALL_SIZE <= paddle['rect'].left+PADDLE_WIDTH and \
- ball_y+BALL_SIZE >= paddle['rect'].top and \
- ball_y-BALL_SIZE <= paddle['rect'].top+PADDLE_HEIGHT):
- ball_dy = - ball_dy
- ball_y += ball_dy
- if paddle_move_left:
- ball_dx -= random.randint(0, 2)
- elif paddle_move_right:
- ball_dx += random.randint(0, 2)
- else:
- ball_dx += random.randint(-1, 2)
-
- # 检测球是否与砖块碰撞
- cur_x = BLOCK_ORIGIN_X
- cur_y = BLOCK_ORIGIN_Y
- for row in range(NUM_BLOCK_ROWS):
- cur_x = BLOCK_ORIGIN_X
- for col in range(NUM_BLOCK_COLUMNS):
- if blocks[row][col] != 0:
- if (ball_x+BALL_SIZE >= cur_x and \
- ball_x-BALL_SIZE <= cur_x+BLOCK_WIDTH and \
- ball_y+BALL_SIZE >= cur_y and \
- ball_y-BALL_SIZE <= cur_y+BLOCK_HEIGHT):
- blocks[row][col] = 0
- blocks_hit += 1
- ball_dy = -ball_dy
- ball_dx += random.randint(-1, 2)
- score += 5 * (level + abs(ball_dx))
- cur_x += BLOCK_X_GAP
- cur_y += BLOCK_Y_GAP
-
- if blocks_hit == NUM_BLOCK_ROWS * NUM_BLOCK_COLUMNS:
- level += 1
- game_state = GAME_STATE_START_LEVEL
-
- # 挡板的运动
- if paddle_move_left:
- paddle['rect'].left -= 8
- if paddle['rect'].left < 0:
- paddle['rect'].left = 0
- if paddle_move_right:
- paddle['rect'].left += 8
- if paddle['rect'].left > WINDOW_WIDTH-PADDLE_WIDTH:
- paddle['rect'].left = WINDOW_WIDTH-PADDLE_WIDTH
-
- # 绘制过程
- windowSurface.fill(BACKGROUND_COLOR)
- # 绘制挡板
- pygame.draw.rect(windowSurface, paddle['color'], paddle['rect'])
- # 绘制小球
- pygame.draw.circle(windowSurface, BALL_COLOR, (ball_x, ball_y),
- BALL_SIZE, 0)
- # 绘制砖块
- cur_x = BLOCK_ORIGIN_X
- cur_y = BLOCK_ORIGIN_Y
- for row in range(NUM_BLOCK_ROWS):
- cur_x = BLOCK_ORIGIN_X
- for col in range(NUM_BLOCK_COLUMNS):
- if blocks[row][col] != 0:
- pygame.draw.rect(windowSurface, BLOCK_COLOR,
- (cur_x, cur_y, BLOCK_WIDTH, BLOCK_HEIGHT))
- cur_x += BLOCK_X_GAP
- cur_y += BLOCK_Y_GAP
- elif game_state == GAME_STATE_GAMEOVER:
- continue
- elif game_state == GAME_STATE_SHUTDOWN:
- game_state = GAME_STATE_EXIT
-
- pygame.display.update()
- mainClock.tick(30)

- # 显示文字
- def DrawText(text, font, surface, x, y):
- text_obj = font.render(text, 1, TEXT_COLOR)
- text_rect = text_obj.get_rect()
- text_rect.topleft = (x, y)
- surface.blit(text_obj, text_rect)
'运行
- # 游戏主循环
- while True:
- # 事件监听
- for event in pygame.event.get():
- if event.type == QUIT:
- pygame.quit()
- exit()
- if event.type == KEYDOWN:
- if event.key == K_LEFT:
- paddle_move_left = True
- if event.key == K_RIGHT:
- paddle_move_right = True
- if event.type == KEYUP:
- if event.key == K_LEFT:
- paddle_move_left = False
- if event.key == K_RIGHT:
- paddle_move_right = False
- # 游戏控制流程
- if game_state == GAME_STATE_INIT:
- # 初始化游戏
- ball_x = random.randint(8, WINDOW_WIDTH-8)
- ball_y = BALL_START_Y
- ball_dx = random.randint(-3, 4)
- ball_dy = random.randint( 5, 8)
-
- paddle['rect'].left = PADDLE_START_X
- paddle['rect'].top = PADDLE_START_Y
-
- paddle_move_left = False
- paddle_move_right = False
-
- life_left = TOTAL_LIFE
- game_over = False
- blocks_hit = 0
- score = 0
- level = 1
- game_state = GAME_STATE_START_LEVEL
- elif game_state == GAME_STATE_START_LEVEL:
- # 新的一关
- blocks = InitBlocks()
- game_state = GAME_STATE_RUN
- elif game_state == GAME_STATE_RUN:
- # 游戏运行
-
- # 球的运动
- ball_x += ball_dx;
- ball_y += ball_dy;
-
- if ball_x > (WINDOW_WIDTH-BALL_SIZE) or ball_x < BALL_SIZE:
- ball_dx = -ball_dx
- ball_x += ball_dx;
- elif ball_y < BALL_SIZE:
- ball_dy = -ball_dy
- ball_y += ball_dy
- elif ball_y > WINDOW_HEIGHT-BALL_SIZE:
- if life_left == 0:
- game_state = GAME_STATE_GAMEOVER
- else:
- life_left -= 1
- # 初始化游戏
- ball_x = paddle['rect'].left + PADDLE_WIDTH // 2
- ball_y = BALL_START_Y
- ball_dx = random.randint(-4, 5)
- ball_dy = random.randint( 6, 9)
-
- # 检测球是否与挡板碰撞
- if ball_y > WINDOW_HEIGHT // 2:
- if (ball_x+BALL_SIZE >= paddle['rect'].left and \
- ball_x-BALL_SIZE <= paddle['rect'].left+PADDLE_WIDTH and \
- ball_y+BALL_SIZE >= paddle['rect'].top and \
- ball_y-BALL_SIZE <= paddle['rect'].top+PADDLE_HEIGHT):
- ball_dy = - ball_dy
- ball_y += ball_dy
- if paddle_move_left:
- ball_dx -= random.randint(0, 2)
- elif paddle_move_right:
- ball_dx += random.randint(0, 2)
- else:
- ball_dx += random.randint(-1, 2)
-
- # 检测球是否与砖块碰撞
- cur_x = BLOCK_ORIGIN_X
- cur_y = BLOCK_ORIGIN_Y
- for row in range(NUM_BLOCK_ROWS):
- cur_x = BLOCK_ORIGIN_X
- for col in range(NUM_BLOCK_COLUMNS):
- if blocks[row][col] != 0:
- if (ball_x+BALL_SIZE >= cur_x and \
- ball_x-BALL_SIZE <= cur_x+BLOCK_WIDTH and \
- ball_y+BALL_SIZE >= cur_y and \
- ball_y-BALL_SIZE <= cur_y+BLOCK_HEIGHT):
- blocks[row][col] = 0
- blocks_hit += 1
- ball_dy = -ball_dy
- ball_dx += random.randint(-1, 2)
- score += 5 * (level + abs(ball_dx))
- cur_x += BLOCK_X_GAP
- cur_y += BLOCK_Y_GAP
-
- if blocks_hit == NUM_BLOCK_ROWS * NUM_BLOCK_COLUMNS:
- level += 1
- blocks_hit = 0
- score += 1000
- game_state = GAME_STATE_START_LEVEL
-
- # 挡板的运动
- if paddle_move_left:
- paddle['rect'].left -= 8
- if paddle['rect'].left < 0:
- paddle['rect'].left = 0
- if paddle_move_right:
- paddle['rect'].left += 8
- if paddle['rect'].left > WINDOW_WIDTH-PADDLE_WIDTH:
- paddle['rect'].left = WINDOW_WIDTH-PADDLE_WIDTH
-
- # 绘制过程
- windowSurface.fill(BACKGROUND_COLOR)
- # 绘制挡板
- pygame.draw.rect(windowSurface, paddle['color'], paddle['rect'])
- # 绘制小球
- pygame.draw.circle(windowSurface, BALL_COLOR, (ball_x, ball_y),
- BALL_SIZE, 0)
- # 绘制砖块
- cur_x = BLOCK_ORIGIN_X
- cur_y = BLOCK_ORIGIN_Y
- for row in range(NUM_BLOCK_ROWS):
- cur_x = BLOCK_ORIGIN_X
- for col in range(NUM_BLOCK_COLUMNS):
- if blocks[row][col] != 0:
- pygame.draw.rect(windowSurface, BLOCK_COLOR,
- (cur_x, cur_y, BLOCK_WIDTH, BLOCK_HEIGHT))
- cur_x += BLOCK_X_GAP
- cur_y += BLOCK_Y_GAP
-
- # 绘制文字描述信息
- message = 'Level: ' + str(level) + ' Life: ' + str(life_left) + ' Score: ' + str(score)
- DrawText(message, text_font, windowSurface, 8, (WINDOW_HEIGHT - 16))
- elif game_state == GAME_STATE_GAMEOVER:
- DrawText('GAME OVER', game_over_font, windowSurface, (WINDOW_WIDTH / 3), (WINDOW_HEIGHT / 3))
- DrawText('Score: ' + str(score), game_over_font, windowSurface,
- (WINDOW_WIDTH / 3)+20, (WINDOW_HEIGHT / 3) + 50)
- elif game_state == GAME_STATE_SHUTDOWN:
- game_state = GAME_STATE_EXIT
-
- pygame.display.update()
- mainClock.tick(25 + level*2)

- game_over_sound = pygame.mixer.Sound('gameover.wav')
- game_hit_sound = pygame.mixer.Sound('hit.wav')
- pygame.mixer.music.load('background.mp3')
- # 播放背景音乐
- pygame.mixer.music.play(-1, 0.0)
- pygame.mixer.music.stop()
- game_over_sound.play()
- DrawText('pyFreakOut', game_start_font, windowSurface,
- (WINDOW_WIDTH/3), (WINDOW_HEIGHT/3 + 50))
- DrawText('Press any key to start.', game_start_font, windowSurface,
- (WINDOW_WIDTH/3)-60, (WINDOW_HEIGHT)/3+100)
- pygame.display.update()
- WaitForPlayerToPressKey()
这样就会在开始时显示上面的画面等待用户按下一个键后再开始,游戏结束后问用户按下一个键重新开始,若按下Esc则退出游戏。
- '''
- 功能:使用pyGame实现一个简单的打砖块游戏
- Created on Nov 30, 2012
- @author: liury_lab
- '''
-
- import pygame, sys, time, random #@UnusedImport
- from pygame.locals import * #@UnusedWildImport
-
- # 一些关于窗口的常量定义
- WINDOW_WIDTH = 640
- WINDOW_HEIGHT = 480
-
- # 游戏状态常量定义
- GAME_STATE_INIT = 0
- GAME_STATE_START_LEVEL = 1
- GAME_STATE_RUN = 2
- GAME_STATE_GAMEOVER = 3
- GAME_STATE_SHUTDOWN = 4
- GAME_STATE_EXIT = 5
-
- # 小球的常量定义
- BALL_START_Y = (WINDOW_HEIGHT//2)
- BALL_SIZE = 4
-
- # 挡板的常量定义
- PADDLE_START_X = (WINDOW_WIDTH/2 - 16)
- PADDLE_START_Y = (WINDOW_HEIGHT - 32);
- PADDLE_WIDTH = 32
- PADDLE_HEIGHT = 8
-
- # 砖块的常量定义
- NUM_BLOCK_ROWS = 6
- NUM_BLOCK_COLUMNS = 8
- BLOCK_WIDTH = 64
- BLOCK_HEIGHT = 16
- BLOCK_ORIGIN_X = 8
- BLOCK_ORIGIN_Y = 8
- BLOCK_X_GAP = 80
- BLOCK_Y_GAP = 32
-
- # 一些颜色常量定义
- BACKGROUND_COLOR = (0, 0, 0)
- BALL_COLOR = (0, 0, 255)
- PADDLE_COLOR = (128, 64, 64)
- BLOCK_COLOR = (255, 128, 0)
- TEXT_COLOR = (255, 255, 255)
-
- # 游戏的一些属性信息
- TOTAL_LIFE = 5
- FPS = 25
-
- # 初始化砖块数组
- def InitBlocks():
- #blocks = [[1] * NUM_BLOCK_COLUMNS] * NUM_BLOCK_ROWS
- blocks = []
- for i in range(NUM_BLOCK_ROWS): #@UnusedVarialbe
- blocks.append([i+1] * NUM_BLOCK_COLUMNS)
- return blocks
-
- # 检测小球是否与挡板或者砖块碰撞
- def ProcessBall(blocks, ball_x, ball_y, paddle):
- if (ball_y > WINDOW_HEIGHT//2):
- if (ball_x+BALL_SIZE >= paddle['rect'].left and \
- ball_x-BALL_SIZE <= paddle['rect'].left+PADDLE_WIDTH and \
- ball_y+BALL_SIZE >= paddle['rect'].top and \
- ball_y-BALL_SIZE <= paddle['rect'].top+PADDLE_HEIGHT):
- return None
-
- # 显示文字
- def DrawText(text, font, surface, x, y):
- text_obj = font.render(text, 1, TEXT_COLOR)
- text_rect = text_obj.get_rect()
- text_rect.topleft = (x, y)
- surface.blit(text_obj, text_rect)
-
- # 退出游戏
- def Terminate():
- pygame.quit()
- sys.exit()
-
- # 等待用户输入
- def WaitForPlayerToPressKey():
- while True:
- for event in pygame.event.get():
- if event.type == QUIT:
- Terminate()
- if event.type == KEYDOWN:
- if event.key == K_ESCAPE:
- Terminate()
- return
-
- # 游戏界面的初始化
- pygame.init()
- mainClock = pygame.time.Clock()
-
- # 小球的位置和速度
- ball_x = 0
- ball_y = 0
- ball_dx = 0
- ball_dy = 0
-
- # 挡板的运动控制
- paddle_move_left = False
- paddle_move_right = False
-
- # 挡板的位置和颜色
- paddle = {'rect' :pygame.Rect(0, 0, PADDLE_WIDTH, PADDLE_HEIGHT),
- 'color': PADDLE_COLOR}
-
- # 游戏状态
- game_state = GAME_STATE_INIT
- blocks = []
- life_left = TOTAL_LIFE
- game_over = False
- blocks_hit = 0
- score = 0
- level = 1
-
- game_start_font = pygame.font.SysFont(None, 48)
- game_over_font = pygame.font.SysFont(None, 48)
- text_font = pygame.font.SysFont(None, 20)
-
- game_over_sound = pygame.mixer.Sound('gameover.wav')
- game_hit_sound = pygame.mixer.Sound('hit.wav')
- pygame.mixer.music.load('background.mp3')
-
- windowSurface = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), 0, 32)
- pygame.display.set_caption('打砖块')
-
-
- DrawText('pyFreakOut', game_start_font, windowSurface,
- (WINDOW_WIDTH/3), (WINDOW_HEIGHT/3 + 50))
- DrawText('Press any key to start.', game_start_font, windowSurface,
- (WINDOW_WIDTH/3)-60, (WINDOW_HEIGHT)/3+100)
- pygame.display.update()
- WaitForPlayerToPressKey()
-
-
- # 播放背景音乐
- pygame.mixer.music.play(-1, 0.0)
-
- # 游戏主循环
- while True:
- # 事件监听
- for event in pygame.event.get():
- if event.type == QUIT:
- Terminate()
- if event.type == KEYDOWN:
- if event.key == K_LEFT:
- paddle_move_left = True
- if event.key == K_RIGHT:
- paddle_move_right = True
- if event.key == K_ESCAPE:
- Terminate()
- if event.type == KEYUP:
- if event.key == K_LEFT:
- paddle_move_left = False
- if event.key == K_RIGHT:
- paddle_move_right = False
-
- # 游戏控制流程
- if game_state == GAME_STATE_INIT:
- # 初始化游戏
- ball_x = random.randint(8, WINDOW_WIDTH-8)
- ball_y = BALL_START_Y
- ball_dx = random.randint(-3, 4)
- ball_dy = random.randint( 5, 8)
-
- paddle['rect'].left = PADDLE_START_X
- paddle['rect'].top = PADDLE_START_Y
-
- paddle_move_left = False
- paddle_move_right = False
-
- life_left = TOTAL_LIFE
- game_over = False
- blocks_hit = 0
- score = 0
- level = 1
- game_state = GAME_STATE_START_LEVEL
- elif game_state == GAME_STATE_START_LEVEL:
- # 新的一关
- blocks = InitBlocks()
- game_state = GAME_STATE_RUN
- elif game_state == GAME_STATE_RUN:
- # 游戏运行
-
- # 球的运动
- ball_x += ball_dx;
- ball_y += ball_dy;
-
- if ball_x > (WINDOW_WIDTH-BALL_SIZE) or ball_x < BALL_SIZE:
- ball_dx = -ball_dx
- ball_x += ball_dx;
- elif ball_y < BALL_SIZE:
- ball_dy = -ball_dy
- ball_y += ball_dy
- elif ball_y > WINDOW_HEIGHT-BALL_SIZE:
- if life_left == 0:
- game_state = GAME_STATE_GAMEOVER
- else:
- life_left -= 1
- # 初始化游戏
- ball_x = paddle['rect'].left + PADDLE_WIDTH // 2
- ball_y = BALL_START_Y
- ball_dx = random.randint(-4, 5)
- ball_dy = random.randint( 6, 9)
-
- # 检测球是否与挡板碰撞
- if ball_y > WINDOW_HEIGHT // 2:
- if (ball_x+BALL_SIZE >= paddle['rect'].left and \
- ball_x-BALL_SIZE <= paddle['rect'].left+PADDLE_WIDTH and \
- ball_y+BALL_SIZE >= paddle['rect'].top and \
- ball_y-BALL_SIZE <= paddle['rect'].top+PADDLE_HEIGHT):
- ball_dy = - ball_dy
- ball_y += ball_dy
- game_hit_sound.play()
- if paddle_move_left:
- ball_dx -= random.randint(0, 3)
- elif paddle_move_right:
- ball_dx += random.randint(0, 3)
- else:
- ball_dx += random.randint(-1, 2)
-
- # 检测球是否与砖块碰撞
- cur_x = BLOCK_ORIGIN_X
- cur_y = BLOCK_ORIGIN_Y
- for row in range(NUM_BLOCK_ROWS):
- cur_x = BLOCK_ORIGIN_X
- for col in range(NUM_BLOCK_COLUMNS):
- if blocks[row][col] != 0:
- if (ball_x+BALL_SIZE >= cur_x and \
- ball_x-BALL_SIZE <= cur_x+BLOCK_WIDTH and \
- ball_y+BALL_SIZE >= cur_y and \
- ball_y-BALL_SIZE <= cur_y+BLOCK_HEIGHT):
- blocks[row][col] = 0
- blocks_hit += 1
- ball_dy = -ball_dy
- ball_dx += random.randint(-1, 2)
- score += 5 * (level + abs(ball_dx))
- game_hit_sound.play()
- cur_x += BLOCK_X_GAP
- cur_y += BLOCK_Y_GAP
-
- if blocks_hit == NUM_BLOCK_ROWS * NUM_BLOCK_COLUMNS:
- level += 1
- blocks_hit = 0
- score += 1000
- game_state = GAME_STATE_START_LEVEL
-
- # 挡板的运动
- if paddle_move_left:
- paddle['rect'].left -= 8
- if paddle['rect'].left < 0:
- paddle['rect'].left = 0
- if paddle_move_right:
- paddle['rect'].left += 8
- if paddle['rect'].left > WINDOW_WIDTH-PADDLE_WIDTH:
- paddle['rect'].left = WINDOW_WIDTH-PADDLE_WIDTH
-
- # 绘制过程
- windowSurface.fill(BACKGROUND_COLOR)
- # 绘制挡板
- pygame.draw.rect(windowSurface, paddle['color'], paddle['rect'])
- # 绘制小球
- pygame.draw.circle(windowSurface, BALL_COLOR, (ball_x, ball_y),
- BALL_SIZE, 0)
- # 绘制砖块
- cur_x = BLOCK_ORIGIN_X
- cur_y = BLOCK_ORIGIN_Y
- for row in range(NUM_BLOCK_ROWS):
- cur_x = BLOCK_ORIGIN_X
- for col in range(NUM_BLOCK_COLUMNS):
- if blocks[row][col] != 0:
- pygame.draw.rect(windowSurface, BLOCK_COLOR,
- (cur_x, cur_y, BLOCK_WIDTH, BLOCK_HEIGHT))
- cur_x += BLOCK_X_GAP
- cur_y += BLOCK_Y_GAP
-
- # 绘制文字描述信息
- message = 'Level: ' + str(level) + ' Life: ' + str(life_left) + ' Score: ' + str(score)
- DrawText(message, text_font, windowSurface, 8, (WINDOW_HEIGHT - 16))
- elif game_state == GAME_STATE_GAMEOVER:
- DrawText('GAME OVER', game_over_font, windowSurface,
- (WINDOW_WIDTH / 3), (WINDOW_HEIGHT / 3))
- DrawText('Level: ' + str(level), game_over_font, windowSurface,
- (WINDOW_WIDTH / 3)+20, (WINDOW_HEIGHT / 3) + 50)
- DrawText('Score: ' + str(score), game_over_font, windowSurface,
- (WINDOW_WIDTH / 3)+20, (WINDOW_HEIGHT / 3) + 100)
- DrawText('Press any key to play again.', game_over_font, windowSurface,
- (WINDOW_WIDTH / 3)-80, (WINDOW_HEIGHT / 3) + 150)
- pygame.display.update()
-
- pygame.mixer.music.stop()
- game_over_sound.play()
-
- WaitForPlayerToPressKey()
- game_state = GAME_STATE_INIT
- elif game_state == GAME_STATE_SHUTDOWN:
- game_state = GAME_STATE_EXIT
-
- pygame.display.update()
- mainClock.tick(FPS + level*2)
-

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。