- Pygame是一个开源的Python模块,专门用于多媒体应用(如电子游戏)的开发,其中包含对图像、声音、视频、事件、碰撞等的支持。Pygame建立在SDL的基础上,SDL是一套跨平台的多媒体开发库,用C语言实现,被广泛的应用于游戏、模拟器、播放器等的开发。而Pygame让游戏开发者不再被底层语言束缚,可以更多的关注游戏的功能和逻辑。
对于pygame我看到了一个可以练习一下的项目:
github上一百天熟悉python的项目
简单安装pygame库
pip install pygame
- 首先就是绘制窗口
import pygame
#初始化导入的pygame模块
pygame.init()
#设置窗口大小
screen = pygame.display.set_mode((800,600))
#设置标题
pygame.display.set_caption('球球')
running = True
#开启事件循环处理发生事件
while running:
#处理从消息队列获取的事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
窗口绘制结果如下:
- 然后是绘图,需要知道的是:pygame中表示颜色用的是色光三原色表示法,即通过一个元组或列表来指定颜色的RGB值,每个值都在0~255之间,因为是每种原色都用一个8位(bit)的值来表示,三种颜色相当于一共由24位构成,这也就是常说的“24位颜色表示法”。
另外,屏幕坐标系是将屏幕左上角设置为坐标原点(0, 0),向右是x轴的正向,向下是y轴的正向,在表示位置或者设置尺寸的时候,我们默认的单位都是像素。所谓像素就是屏幕上的一个点,你可以用浏览图片的软件试着将一张图片放大若干倍,就可以看到这些点。
import pygame
#初始化导入的pygame模块
pygame.init()
#设置窗口大小
screen = pygame.display.set_mode((800,600))
#设置标题
pygame.display.set_caption('球球')
#设置窗口背景色
screen.fill((242, 242, 242))
#绘制一个圆(屏幕,颜色,圆心位置,半径,0表示填充圆)
#(255,0,0)表示红色,(0,255,0)表示绿色,(0,0,255)表示蓝色
pygame.draw.circle(screen, (255, 0, 0,), (100, 100), 30, 0)
#刷新当前窗口
pygame.display.flip()
running = True
#开启事件循环处理发生事件
while running:
#处理从消息队列获取的事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
绘图结果如下:
- 不想绘图实现呢,也可以通过加载图片来实现游戏中的球球,比如通过pygame中image模块的函数加载图片,再用blit渲染
import pygame
#初始化导入的pygame模块
pygame.init()
#设置窗口大小
screen = pygame.display.set_mode((800,600))
#设置标题
pygame.display.set_caption('球球')
#设置窗口背景色
screen.fill((242, 242, 242))
#指定文件加载图像,要注意,加载文件要用反斜杠或者在原本粘贴的路径前加上r,不然会无法识别
ball_image = pygame.image.load('C:/Users/samu/Pictures/精灵球.jpeg')
#渲染图像
screen.blit(ball_image, (50,50))
#刷新当前窗口
pygame.display.flip()
running = True
#开启事件循环处理发生事件
while running:
#处理从消息队列获取的事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
- 动画显示,动画可以说是不连续图片的播放,只要到了一定帧数,就可以让图片流畅地“动”起来。
import pygame
#初始化导入的pygame模块
pygame.init()
#设置窗口大小
screen = pygame.display.set_mode((800,600))
#设置标题
pygame.display.set_caption('球球')
#定义变量来表示小球在屏幕中的位置
x, y = 50, 50
#刷新当前窗口
pygame.display.flip()
running = True
#开启事件循环处理发生事件
while running:
#处理从消息队列获取的事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#设置背景色
screen.fill((255,255,255))
pygame.draw.circle(screen, (0, 0, 255,), (x, y), 30, 0)
pygame.display.flip()
#每隔50ms就改变小球位置并刷新窗口
pygame.time.delay(100)
x, y = x + 5, y + 5
这是动图,单是截图无法看到效果,不过大家可以自行编译一下
- 处理事件,对于球之间的碰撞事件,检测两个球心间距离是否小于半径之和即可判断。
到这里,我们进行汇总并设计,鼠标点击屏幕即可生成随机大小、随机颜色的球球,球球间碰撞,大的吃掉小的然后变得更大。
import pygame,time
from math import sqrt
from enum import Enum, unique
from random import randint
@unique
class Color(Enum):
Red = (255, 0, 0)
Green = (0, 255, 0)
Blue = (0, 0, 255)
Gray = (242, 242, 242)
White = (255, 255, 255)
Black = (0, 0, 0)
@staticmethod
def random_color():
r = randint(0, 255)
g = randint(0, 255)
b = randint(0, 255)
return (r, g, b)
class Ball():
def __init__(self, x, y, r, sx, sy, color = Color.Blue):
self.x = x
self.y = y
self.r = r
self.sx = sx
self.sy = sy
self.color = color
self.alive = True
def move(self, screen):
self.x += self.sx
self.y += self.sy
if self.x - self.r <= 0 or self.x + self.r >= screen.get_width():
self.sx = -self.sx
if self.y - self.r <= 0 or self.y + self.r >= screen.get_height():
self.sy = -self.sy
def eat(self, other):
if self.alive and other.alive and self != other:
dx, dy = self.x - other.x, self.y - other.y
distance = sqrt(dx ** 2 + dy ** 2)
if distance < self.r + other.r and self.r > other.r:
other.alive = False
self.r = self.r + int(other.r * 0.138)
def draw(self, screen):
pygame.draw.circle(screen, self.color, (self.x, self.y), self.r, 0)
def main():
balls = []
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption('球球吃球球')
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
time.sleep(5)
return
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
x, y = event.pos
r = randint(10, 100)
sx, sy = randint(-10, 10), randint(-10, 10)
color = Color.random_color()
ball = Ball(x, y, r, sx, sy, color)
balls.append(ball)
screen.fill((255, 255, 255))
for ball in balls:
if ball.alive:
ball.draw(screen)
else:
balls.remove(ball)
pygame.display.flip()
pygame.time.delay(50)
for ball in balls:
ball.move(screen)
for other in balls:
ball.eat(other)
if __name__ == '__main__':
main()