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. 打包(如果有資源文件,如圖片等,則需要按同樣目錄複製到exe同目錄下)
pyinstaller -F -w walk.py
注意:
(1).如出現"failed to execute main
"錯誤,則執行下面命令(顯示詳細報錯信息):
pyinstaller -D main.py
(2).如出現以下錯誤,則執行命令:
pyinstaller --clean --win-private-assemblies -F XXXX.py
備註:
--clean清除pyinstaller的緩存並移除之前建立的臨時文件,
--win-私人組件把跟這個程序捆綁的共享的組件都改爲私有的
調試階段不用-w,因爲如果有錯誤就打印在終端了而不是閃退
3. 嘚瑟
請自行腦補