python3小游戏(1):吃苹果小游戏

发布时间:2019-08-05 16:32:52编辑:auto阅读(1508)

     

    python小白群交流:861480019

    注意,申请时说明加入原因,另外这个群都是一群和我一样的小白,大家谁也不说谁,共同进步(ps:写这个文章时,只有我一人)

    一. 概述:

    1.本文是基于pygame库开发的小游戏,主要功能有:

    (1).可以通过键盘的上下左右四个键来控制主人公小刘的位置(同是移动方向不同,小刘的姿势也不同)

    (2).游戏开始界面会随机飘着大约40个苹果,如果小刘碰到苹果,会把它吃掉,同是增加界面下方显示的血量

    (3).吃完苹果,game over

     

     

    2.从游戏开发及完成的全过程看,分为个步骤:

     

    (1).开发工具:pycharm;python版本python3.6;window版本win7 64位

     

    (2).需要安装pygame库,

    (3).如果要打包成exe可执行程序,则需要安装pyinstaller库,

    二.干活(安装库的过程就不写了,网上一大堆,需要提醒的是python版本和这些库版本一定要匹配):

    1.造个小小小库(哈~可见有多小):

            (1).之所以造库是因为我们这个小游戏中有两个活物:主人公小刘和苹果;这个库有两功能:

                        a.主人公小刘,我们有一个矩阵图片如下,拿出“找泥妹”的眼里看一下有啥区别。(一天后。。。)。                        昨天我们让你看下面图片找出区别,我公布答案吧,每一行代表一个方向,同一行内,每一列代表小刘走一步需                          要怎么迈步。我们需要一个方法在小刘拐弯时知道他拐哪边,在下图聚焦到一个姿势显示到界面。(下面图片想用的话,直接右键下载即可)

                       

                         b.苹果:我们因为需要在游戏开始在界面漂浮40个苹果,并在小刘吃了一个后把他去掉,这样不可能一个一个创建,这 里也需要一个方法

              (2).代码实现(我把这文件命名为myLibrary.py)

     

    # -*- coding: utf-8 -*-
    # @Time    : 2018/5/17 0017 上午 8:32
    # @Author  : silents
    # @FileName: myLibrary.py
    # @Software: PyCharm
    # @Blog    :http://blog.csdn.net/chq1005613740
    import pygame
    from pygame.locals import *
    class Point():
        def __init__(self, x,y):
            self.X =x
            self.Y =y
    
    class MySprite(pygame.sprite.Sprite):
        def __init__(self):
            pygame.sprite.Sprite.__init__(self)
            self.master_image = None
            self.frame = 0
            self.old_frame = -1
            self.frame_width = 1
            self.frame_height = 1
            self.first_frame = 0
            self.last_frame = 0
            self.columns = 1
            self.last_time = 0
            self.direction = 0
            self.X = 0
            self.Y = 0
            #新增了velocity属性,他是一个point
            self.velocity = Point(0.0,0.0)
    
        def load(self, filename, position, bg_size):
            self.image = pygame.image.load(filename).convert_alpha()
            self.rect = self.image.get_rect()
            #苹果的位置
            self.rect.left, self.rect.top = position
            #self.speed = speed
            self.width, self.height = bg_size[0], bg_size[1]
    
        def load_column(self, filename, position, bg_size, columns):
            self.master_image = pygame.image.load(filename).convert_alpha()
            self.frame_width = bg_size[0]
            self.frame_height = bg_size[1]
            self.position = position
            self.rect  = self.master_image.get_rect()
            self.ori_frame_width = self.rect.width
            self.ori_frame_height = self.rect.height
            self.rect.left, self.rect.top = position
            self.rect.width,self.rect.height = bg_size[0],bg_size[1]
            self.columns = columns
            self.last_frame = (self.ori_frame_width // bg_size[0]) * (self.ori_frame_height // bg_size[1]) - 1
    
        def update(self, current_time, rate=60):
            if current_time > self.last_time + rate:
                self.frame += 1
                if self.frame > self.last_frame:
                    self.frame = self.first_frame
                self.last_time = current_time
            if self.frame != self.old_frame:
                frame_x = (self.frame % self.columns) * self.frame_width
                frame_y = (self.frame // self.columns) * self.frame_height
                # rect = ( self.X, self.Y, self.frame_width, self.frame_height )
                rect = ( frame_x, frame_y, self.frame_width, self.frame_height )
                self.rect.left, self.rect.top = self.X, self.Y
                self.image = self.master_image.subsurface(rect)
                self.old_frame = self.frame

    可以看出代码很少,主要分三部分(请自行忽略初始化部分):

    a.  方法load:主要是为创建苹果而准备,

            加载图片 -->  获取图片大小  -->  获取图片位置  

    b.  方法load_column:主要为小刘而准备,

            加载图片 --> 获取图片位置 --> 获取图片大小  --> 把图片切割成64块(每块一个姿势)

    c.  方法update:也为小刘而准备,

           对load_colunm中切割完的64块piece进行切换,同时移动位置

    2.写一个小小调用(可见比上面少了一个“小”,有点麻烦,心脏不好,高血压勿进):

      (1). 开始之前需要先了解几个概念:

               a. 精灵:你可以简单的理解为一个需要显示的图片

               b. 精灵组:你可以简单的理解为一组需要显示的图片

               c.碰撞检测:在程序中,我们理解为两个精灵是否碰撞,精灵和精灵组是否碰撞,精灵组和精灵组是否碰撞

       (2). 大致流程:

              a.创建玩家精灵组:里面是上面切割完的64块小刘

              b. 创建苹果精灵组:里面是在界面位置随机的40个苹果

              c. 设置定时器:定时更新界面

              d.检测键盘按键:作为小刘移动的依据

              e.移动小刘:让他去吃苹果

              f.检测碰撞:此游戏中属于精灵和精灵组的碰撞(两次检测,逐一分析代码),把碰撞的苹果吃掉

              g. 更新血量:小刘吃一个苹果就增加一点血

       (3). 代码搬运(此文件我把它叫walk.py)

    # -*- coding: utf-8 -*-
    # @Time       : 2018/5/17 0017 上午 10:30
    # @Author     : silents
    # @FileName   : fifth_walk.py
    # @Software   : PyCharm
    # @Blog       :http://blog.csdn.net/chq1005613740
    # @Description: Buttons to control the movement of people,
    #               people eat apples,
    #               people eat apples will increase blood,
    #               eat blood over
    
    import itertools, sys, time, random, math, pygame
    from pygame.locals import *
    from game_go.myLibrary import *
    
    def calc_velocity(direction, vel=1.0):
        velocity = Point(0, 0)
        if direction == 0:  # 上
            velocity.Y = -vel
        elif direction == 2:  # 右
            velocity.X = vel
        elif direction == 4:  # 下
            velocity.Y = vel
        elif direction == 6:  # 左
            velocity.X = -vel
        return velocity
    
    
    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    pygame.display.set_caption("吃苹果")
    font = pygame.font.SysFont('arial',36)
    timer = pygame.time.Clock()
    
    # 创建精灵组
    player_group = pygame.sprite.Group()
    food_group = pygame.sprite.Group()
    
    # 初始化玩家精灵组
    #def load_column(self, filename, position, bg_size, columns):
    position = 800/2-10,600/2+10
    bg_size = 62.5, 62.5
    player = MySprite()
    player.load_column("res//walk.png",position, bg_size, 8)
    # player.position = 80, 80
    player.direction = 4
    player_group.add(player)
    
    # 初始化food精灵组
    
    for n in range(1, 40):
        food = MySprite();
        position = random.randint(0, 750), random.randint(0, 550)
        bg_size = 50, 48
        food.load("res//apple.png", position, bg_size)
        food_group.add(food)
    
    game_over = False
    player_moving = False
    player_health = 0
    
    while True:
        timer.tick(30)
        ticks = pygame.time.get_ticks()
    
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
        keys = pygame.key.get_pressed()
        if keys[K_ESCAPE]:
            sys.exit()
        elif keys[K_UP] or keys[K_w]:
            player.direction = 0
            player_moving = True
        elif keys[K_RIGHT] or keys[K_d]:
            player.direction = 2
            player_moving = True
        elif keys[K_DOWN] or keys[K_s]:
            player.direction = 4
            player_moving = True
        elif keys[K_LEFT] or keys[K_a]:
            player.direction = 6
            player_moving = True
        else:
            player_moving = False
    
        if not game_over:
            # 根据角色的不同方向,使用不同的动画帧
            player.first_frame = player.direction * player.columns
            player.last_frame = player.first_frame + player.columns - 1
            if player.frame != player.first_frame:
                player.frame = player.first_frame
    
            if not player_moving:
                # 当停止按键(即人物停止移动的时候),停止更新动画帧
                player.frame = player.first_frame = player.last_frame
            else:
                player.velocity = calc_velocity(player.direction, 2)
                player.velocity.X *= 2
                player.velocity.Y *= 2
    
            # 更新玩家精灵组
            player_group.update(ticks, 50)
    
            # 移动玩家
            if player_moving:
                player.X += player.velocity.X
                player.Y += player.velocity.Y
                if player.X  < 0:
                    player.X = 0
                elif player.X > 700:
                    player.X = 700
                if player.Y  <0:
                    player.Y = 0
                elif player.Y > 500:
                    player.Y = 500
            myfont = pygame.font.SysFont('arial',36)
            white = 255, 255, 255
            textImage = myfont.render("Hello Pygame:%i-%i" %(player.X,player.Y), True, white)
    
            # 检测玩家是否与食物冲突,是否吃到果实
            attacker = None
            attacker = pygame.sprite.spritecollide(player, food_group, False, pygame.sprite.collide_circle)
            if len(attacker) !=0:
                for atta in attacker:
                    # if pygame.sprite.collide_circle(player, atta):
                    if pygame.sprite.collide_circle_ratio(0.65)(player, atta):
                        player_health += 2;
                        food_group.remove(atta);
            if player_health > 100: player_health = 100
            # 更新食物精灵组
            # food_group.update(ticks, 50)
    
            if len(food_group) == 0:
                game_over = True
        # 清屏
        screen.fill((50, 50, 100))
    
        # 绘制精灵
        food_group.draw(screen)
        player_group.draw(screen)
    
        # 绘制玩家血量条
        pygame.draw.rect(screen, (50, 150, 50, 180), Rect(300, 570, player_health * 2, 25))
        pygame.draw.rect(screen, (100, 200, 100, 180), Rect(300, 570, 200, 25), 2)
    
        if game_over:
            textImage = font.render("G A M E   O V E R", True, (0,0,0))
            screen.blit(textImage, (100,100))
            # print_text(font, 300, 100, "G A M E   O V E R")
    
        screen.blit(textImage, (300,500))
        pygame.display.update()

     

    (因为本人菜鸟,大家过程中有问题就留言,我会的肯定马上回复,不像某些大神那么忙)

     

     

    三. 打包,发货

          现在我们可以把py打包成exe了,嘤嘤嘤。。。

    1.安装pyinstaller库

        cmd到python3路径下,执行如下命令:

                pip3 install pyinstaller

    2. 打包

        pyinstaller -F -w walk.py

    3. 嘚瑟

         请自行脑补

关键字