【python游戏开发入门】《PYTHON游戏编程入门》第九章总结

书籍:《PYTHON游戏编程入门》(More Python Programming for the Absolute Beginner)
本文为第九章知识点总结以及核心代码,欢迎交流

列表

这一章介绍了列表的概念,并且给出了一些针对列表的操作,这里对这些操作做一个总结:
可以参照python编程 从入门到实践 第四章总结

  • 列表的创建:列表是由中括号[]括起来的一些元素的集合。
  • 修改一个元素:可以通过索引编号来获取列表中的任何元素的数据,可以通过引用索引编号来修改该元素。
  • 添加一个元素:使用lst.append(elenemt)的方法把新的项添加到列表当中。
  • 插入一个元素:使用lst.insert(loc, element)的方法将一个元素插入到列表的中间,第一个参数是插入的位置索引,第二个参数是要插入的元素。
  • 计数元素:如果列表中存在重复的元素,可以通过lst.count(element)的方法对其进行计数。
  • 搜素元素:可以使用lst.index(element)的方法来搜索一个具体的元素在列表中第一次出现的位置。
  • 删除元素:使用·lst.remove(element)`方法来删除列表中的一个元素,删除的是传递的值的第一次出现,并且只会删除一次。
  • 将列表反向:使用lst.reverse()方法可以将整个列表反向,但是并不会实际修改列表中的每一个元素。
  • 排序列表:使用lst.sort()方法将列表中的元素排序(升序)
  • 对于多维度列表,可以直接写成多维的形式:grid = [[1,2,3],[4,5,6],[7,8,9]](使用方括号中带有索引的语法访问单个元素)也可以使用但唯独列表来模拟二维(多维)列表,对于二维列表,索引转换公式为:row*10+col

元组

元组与列表类似,但是元组是只读的,意味着代码中一旦进行了初始化,这些项就不可以再更改了。元组中的元素放在圆括号()中,以便与列表区分开。元组的主要优点在于他的速度很快。

  • 打包:指创建一个元组的过程。
  • 解包:指从元组中读取数据的过程。
  • 搜索元素:可以用'element' in tpl来在一定的范围内搜索我们想要的元素。
  • 计数元素:使用tpl.count(element)方法返回一个元组中具有指定的值的元素的数目。
  • 求元组长度:使用len(tpl)方法得到远足中所有元素的数目。

Block Breaker 游戏

主干思路

这个游戏的思路如下:

  • set level tuple
  • init params
  • handle player input
  • choose level
  • init the game
  • load level information
  • wait for mouse press to release the ball
  • move ball accroding to the vel now and the direction
  • move paddle according to player’s operation
  • handle collision between ball and paddle
  • handle collision between ball and block
  • update drawing

下面给出主函数部分的代码:

# main program
# init some params
pygame.init()
SCREEN_X = 800
SCREEN_Y = 600
KEYS_PADDLE_MOVE = 10.0
PADDLE_X = 90
PADDLE_Y = 60
BALL_SIZE = 20

choose_level = True
stage_clear = False
score = 0
waiting = True
game_over = False
lives = 3
level = 0
game_init()
movex = 0.0
movey = 0.0
mousex = 0.0
mousey = 0.0

while True:
    timer.tick(30)
    ticks = pygame.time.get_ticks()

    # handle events
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
        elif choose_level:
            if event.type == KEYUP:
                if event.key == K_1:
                    level = 0
                    choose_level = False
                    load_level()
                elif event.key == K_2:
                    level = 1
                    load_level()
                    choose_level = False
                elif event.key == K_3:
                    level = 2
                    load_level()
                    choose_level = False
                elif event.key == K_4:
                    level = 3
                    choose_level = False
                elif event.key == K_5:
                    level = 4
                    choose_level = False
                elif event.key == K_6:
                    level = 5
                    choose_level = False                
            '''
            if event.key == K_RETURN:
                goto_next_level()#利用回车选关
            '''
        elif event.type == MOUSEMOTION:
            movex, movey = event.rel
            mousex, mousey = event.pos
        elif event.type == MOUSEBUTTONUP:
            if waiting and not choose_level:
                waiting = False
                reset_ball()
            
    # handle key presses
    keys = pygame.key.get_pressed()
    if keys[K_ESCAPE]:
        sys.exit()
        
    screen.fill((50, 50, 50))

    if choose_level:
        printText(font_big, 150, 200, "BLOCK BREAKER")
        printText(font_t, 200, 400, 'Press 1 - 6 to choose level')

    elif stage_clear:
        stage_clear = False
        printText(font_big, 60, 260, "S T A G E  C L E A R !")
        pygame.display.update()
        time.sleep(3)
        
    else:
        print(choose_level)
        # updates
        if not game_over:
            move_paddle()
            move_ball()
            collision_ball_paddle()
            collision_ball_blocks()
            update_blocks()

        # draw
        block_group.draw(screen)
        paddle_group.draw(screen)
        ball_group.draw(screen)

        printText(font_t, 0, 0, "SCORE")
        printText(font_num, 150, 6, str(score))
        printText(font_t, 250, 0, "LEVEL")
        printText(font_num, 350, 6, str(level+1))
        printText(font_t, 450, 0, "BLOCKS")
        printText(font_num, 600, 6, str(len(block_group)))
        printText(font_t, 690, 0, "BALLS")
        printText(font_num, 780, 6, str(lives))             

        if game_over:
            printText(font_big, 100, 260, "G A M E   O V E R !")
    pygame.display.update()

set level tuple

关卡的设置通过一个二维元组来存储。
其中的数字表示砖块的硬度,即打几下可以消失。

levels = (
(0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,
 1,0,0,0,0,0,0,0,0,0,0,1),
    
(1,0,1,0,1,1,1,1,0,1,0,1, 
 1,0,1,0,1,1,1,1,0,1,0,1, 
 1,0,1,0,1,1,1,1,0,1,0,1, 
 1,0,1,0,1,1,1,1,0,1,0,1, 
 1,0,1,0,1,0,0,1,0,1,0,1, 
 1,0,1,0,1,0,0,1,0,1,0,1, 
 1,0,1,0,1,1,1,1,0,1,0,1, 
 1,0,1,0,1,1,1,1,0,1,0,1, 
 1,0,1,0,1,1,1,1,0,1,0,1, 
 1,0,1,0,1,1,1,1,0,1,0,1),


(1,1,1,1,1,1,1,1,1,1,1,1, 
 1,1,1,1,1,1,1,1,1,1,1,1, 
 1,1,1,1,1,1,1,1,1,1,1,1, 
 1,1,1,1,1,1,1,1,1,1,1,1, 
 1,1,1,1,1,0,0,1,1,1,1,1, 
 1,1,1,1,1,0,0,1,1,1,1,1, 
 1,1,1,1,1,1,1,1,1,1,1,1, 
 1,1,1,1,1,1,1,1,1,1,1,1, 
 1,1,1,1,1,1,1,1,1,1,1,1, 
 1,1,1,1,1,1,1,1,1,1,1,1),

(2,2,2,2,2,2,2,2,2,2,2,2, 
 2,1,1,2,2,2,2,2,2,1,1,2, 
 2,1,1,2,2,2,2,2,2,1,1,2, 
 2,2,2,2,2,2,2,2,2,2,2,2, 
 2,2,2,2,2,1,1,2,2,2,2,2, 
 2,2,2,2,2,1,1,2,2,2,2,2, 
 2,2,2,2,2,2,2,2,2,2,2,2, 
 2,1,1,2,2,2,2,2,2,1,1,2, 
 2,1,1,2,2,2,2,2,2,1,1,2, 
 2,2,2,2,2,2,2,2,2,2,2,2),

(3,3,3,3,3,3,3,3,3,3,3,3, 
 3,3,0,0,0,3,3,0,0,0,3,3, 
 3,3,0,0,0,3,3,0,0,0,3,3, 
 3,3,0,0,0,3,3,0,0,0,3,3, 
 3,3,3,3,3,3,3,3,3,3,3,3, 
 3,3,3,3,3,3,3,3,3,3,3,3, 
 3,3,0,0,0,3,3,0,0,0,3,3, 
 3,3,0,0,0,3,3,0,0,0,3,3, 
 3,3,0,0,0,3,3,0,0,0,3,3, 
 3,3,3,3,3,3,3,3,3,3,3,3),

(3,4,4,4,4,4,4,4,4,4,4,3, 
 4,3,2,2,2,3,3,2,2,2,3,4, 
 4,3,2,1,2,3,3,2,1,2,3,4, 
 4,3,2,2,2,3,3,2,2,2,3,4, 
 4,3,3,3,3,3,3,3,3,3,3,4, 
 4,3,3,3,3,3,3,3,3,3,3,4, 
 4,3,2,2,2,3,3,2,2,2,3,4, 
 4,3,2,1,2,3,3,2,1,2,3,4, 
 4,3,2,2,2,3,3,2,2,2,3,4, 
 3,4,4,4,4,4,4,4,4,4,4,3),

)

init the game

def game_init():
    global screen, font_t, font_num, font_big, timer
    global paddle_group, block_group, ball_group
    global paddle, block_image, block, ball
    global level, game_over, waiting, lives, score
    global SCREEN_X, SCREEN_Y, KEYS_PADDLE_MOVE
    global PADDLE_X, PADDLE_Y, BALL_SIZE
    
    screen = pygame.display.set_mode((SCREEN_X,SCREEN_Y))
    pygame.display.set_caption('Block Breaker')
    font_num = pygame.font.Font('DengXian.ttf', 30)
    font_t = pygame.font.Font('BAUHS93.TTF',36)
    font_big = pygame.font.Font('SNAP____.TTF',50)
    pygame.mouse.set_visible(True)# the players want to see the mouse
    timer = pygame.time.Clock()

    # create the sprite group
    block_group = pygame.sprite.Group()
    paddle_group = pygame.sprite.Group()
    ball_group = pygame.sprite.Group()

    # create the ball
    ball = MySprite()
    ball.load('ball.png')
    ball.pos = SCREEN_X // 2, SCREEN_Y // 2
    ball_group.add(ball)

    # create the paddle
    paddle = MySprite()
    paddle.load('paddle.png')
    paddle.pos = SCREEN_X // 2, SCREEN_Y - PADDLE_Y
    paddle_group.add(paddle)

    load_level()

load level information

# update the blocks.
# if there is no blocks left, go to the next level.
# if there is still blocks left, update them.
def update_blocks():
    global block_group, waiting, ticks, stage_clear
    if len(block_group) == 0:
        goto_next_level()
        waiting = True
        stage_clear = True
    block_group.update(ticks,50)

# set the num of 'level'.
# if arrive at the last level, rotate it from the begining.
def goto_next_level():
    global level, levels
    level += 1
    if level > len(levels) - 1:
        level = 0
    load_level()

# load blocks corresponding level number
def load_level():
    global levels, level, block, block_image, block_group, levels
    block_image = pygame.image.load('blocks.png').convert_alpha()
    block_group.empty()# clear block group
    for bx in range(0,12):
        for by in range(0,10):
            # generate a new block
            block = MySprite()
            block.set_image(block_image,58,28,4)
            x = 40 + bx * (block.frame_width + 1)
            y = 60 + by * (block.frame_height + 1)
            block.pos = x,y

            # read block texture
            num = levels[level][by*12+bx]
            if num > 0:
                block.first_frame = num - 1
                block.last_frame = num - 1
                block_group.add(block)

move ball accroding to the vel now and the direction

# reset the vel of the ball
def reset_ball():
    global ball, level
    ball.velocity = Point(4.5 + level, -7.0 - level*2)
            
# move the ball according to its velocity now
# judge if the player has missed the ball
# and judge if no balls left at the same time
def move_ball():
    global ball, game_over, lives, waiting

    #move the ball
    ball_group.update(ticks,50)
    if waiting:
        ball.x = paddle.x + 40
        ball.y = paddle.y - 10
    else:
        ball.x += ball.velocity.x
        ball.y += ball.velocity.y

    # handle collision with edge of the game
    if ball.x < 0:
        ball.x = 0
        ball.velocity.x *= -1
    elif ball.x > SCREEN_X - BALL_SIZE:
        ball.x = SCREEN_X - BALL_SIZE
        ball.velocity.x *= -1
    if ball.y < 0:
        ball.y = 0
        ball.velocity.y *= -1
    elif ball.y > SCREEN_Y - BALL_SIZE:# miss the ball
        waiting = True
        lives -= 1
        if lives < 1:
            game_over = True

move paddle according to player’s operation

# move the paddle according to move of mouse or keys of keyboard,
# which are transformed by the params extracted from main function
def move_paddle():
    global keys, waiting, mosuex, mousey #movex, movey
    paddle_group.update(ticks, 50) # about ticks?
    if keys[K_SPACE]:
        if waiting:
            waiting = False
            reset_ball()
    elif keys[K_LEFT]:
        paddle.velocity.x = -KEYS_PADDLE_MOVE
    elif keys[K_RIGHT]:
        paddle.velocity.x = KEYS_PADDLE_MOVE
    else:
        paddle.velocity.x = 0.0
        paddle.x = mousex    
    '''
    else:
        if movex < -2 or movex > 2:
            paddle.velocity.x = movex
        else:
            paddle.velocity.x = 0.0
    '''
    paddle.x += paddle.velocity.x
    
    if paddle.x < 0:
        paddle.x = 0
    elif paddle.x > 710:
        paddle.x = 710

handle collision between ball and paddle

# handle the collision between ball and paddle
def collision_ball_paddle():
    if pygame.sprite.collide_rect(ball,paddle):
        ball.velocity.y = -abs(ball.velocity.y)

handle collision between ball and block

# handle the collision between ball and blocks
def collision_ball_blocks():
    global score
    hit_block = pygame.sprite.spritecollideany(ball, block_group)
    if hit_block != None:
        score += 10
        
        # change the vel when get scores
        if ball.velocity.x > 0:
            ball.velocity.x += score / 12000
        else:
            ball.velocity.x -= score / 12000
            
        if ball.velocity.y > 0:
            ball.velocity.y += score / 6000
        else:
            ball.velocity.y -=score / 6000

        # change block when get hit
        if hit_block.first_frame > 0:
            hit_block.first_frame -= 1
            hit_block.last_frame -= 1
        else:
            block_group.remove(hit_block)
            
        bx = ball.x + BALL_SIZE / 2
        by = ball.y + BALL_SIZE / 2

        if bx >= hit_block.x and bx <= hit_block.x + hit_block.frame_width:
            ball.velocity.y *= -1
        elif by >= hit_block.y and by <= hit_block.y + hit_block.frame_height:
            ball.velocity.x *= -1
        else:
            ball.velocity.y *= -1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值