一. 概述:
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. 嘚瑟
请自行脑补