【Python】趣味游戏编程练习记录


最近在阅读童晶写的《Python游戏趣味编程》,边学边记录吧,蛮有意思。

一、学习要点

1.安装游戏开发库pgzero

pip install pgzero  

 2.导入游戏开发库及基础绘图操作

import pgzrun #导入游戏开发库
def draw(): #定义绘图函数
    screen.fill('white')#屏幕填充白色背景
    screen.draw.filled_circle((300,250),50,'black')#屏幕绘制圆心坐标为(300,250),半径为50的圆,填充黑色
    screen.draw.circle((340, 250), 90, 'black')#屏幕绘制圆心坐标为(340,250),半径为90的圆,线条颜色为黑色
pgzrun.go()#运行程序

 默认屏幕横坐标为0~800,纵坐标为0~600,左上角坐标为(0,0)。

颜色填充同样可以用三原色,即(r,g,b),如:

screen.fill((0,0,0))#黑色背景

3.在函数内修改函数全局变量时,需用global声明。

a=2
b=1

def new():
    global a,b#声明修改的是全局变量a和b
    a = 3
    b = 7

4.range()是范围的意思,它其中可以有1~3个参数。

for i in range(10):#从0到9遍历
    print(i,end=' ')
print()
for j in range(5,10):#从5到9遍历
    print(j,end=' ')
print()
for k in range(0,10,2):#从0到9,步长为2进行遍历
    print(k,end=' ')
print()
for l in range(10,-7,-3):#从9到-6,步长为-3进行遍历
    print(l,end=' ')

运行效果如下: 

0 1 2 3 4 5 6 7 8 9
5 6 7 8 9
0 2 4 6 8
10 7 4 1 -2 -5

5.绘制操作应定义在draw()函数中,更新操作(随时间自动变换)应定义在update()函数中,鼠标任意键点击(鼠标任意键点击变换)应定义在on_mouse_down()函数中,鼠标移动(鼠标移动引起的变换)应定义在on_mouse_move()函数中。 

详见下面代码样例。

6.导入图片等素材可以用Actor("图片名")来引入当前py文件同级目录下images文件夹里的图片素材,不需要写图片名后缀。生成的对象自带横纵坐标的属性,调用形式为对象名.x/对象名.y。绘制调用对象名.draw()

import pgzrun # 导入游戏库
WIDTH = 350 # 设置窗口的宽度
HEIGHT = 600 # 设置窗口的高度

background = Actor('background') # 导入背景图片
bird = Actor('bird') # 导入小鸟图片
bird.x = 50         # 设置小鸟的x坐标
bird.y = HEIGHT/2     # 设置小鸟的y坐标

def draw(): # 绘制模块,每帧重复执行
    background.draw() # 绘制背景
    bird.draw()        # 绘制小鸟

pgzrun.go() # 开始执行游戏

7. 判断素材与其他素材是否重叠,如相撞,可以用对象名.colliderect(另一对象名)检验是否重叠。

#可以放在update()中
# 如果小鸟碰到障碍物上半部分或下半部分,或碰到上下边界,游戏失败
if bird.colliderect(bar_up) or bird.colliderect(bar_down) 
               or bird.y < 0 or bird.y>HEIGHT:
    print('游戏失败')

8. screen.draw.text()函数用于在游戏窗口中显示文字。

其中str(score)表示把数字score转换成字符串,(30, 30)表示要显示的x、y坐标,fontsize=50表示设定的文字大小,color='green'表示设置文字颜色为绿色

def draw(): # 绘制模块,每帧重复执行
    screen.draw.text(str(score), (30, 30), fontsize=50, color='green')

9.3个除法运算符

“5/2”中的一个斜杠/为一般除法运算符,5/2的结果就是小数2.5。

“5//2”中的两个斜杠//为整除运算符,意为取2.5的整数部分,也就是整数相除的商,因此为2。

“5%2”中的百分号%为取余运算符,5%2的结果就是两数相除的余数,因此为1。 

10.Actor对象旋转

对象名.angle表示导入图像的旋转角度,在update()函数中将其旋转角度逐渐增加,即可让其按逆时针方向自动旋转,默认以自己的中心点旋转。

也可以在导入图片时就设置好旋转的锚点/中心点。(x, y)为要设定的锚点位置,也就是其旋转轴心的相对坐标。如果不设置,则其锚点默认为图像的中心位置。

needle = Actor('needle',anchor=(x, y))

二、练习展示

1. 练习2-3

利用绘制空心圆、填充圆的函数以及坐标的定义,尝试编写代码,绘制出简易人脸效果。

import pgzrun
def draw():
    screen.fill('white')#白色背景
    screen.draw.filled_circle((300,250),50,'black')#左眼珠
    screen.draw.filled_circle((500, 250), 50, 'black')#右眼珠
    screen.draw.circle((340, 250), 90, 'black')#左眼眶
    screen.draw.circle((540, 250), 90, 'black')#右眼眶
    screen.draw.circle((440, 350), 20, 'black')#小鼻子
    screen.draw.circle((440, 470), 70, 'black')#嘴巴
    screen.draw.circle((440, 350), 240, 'black')#脸
pgzrun.go()

 

2. 练习3-8

尝试利用for语句,画出一圈黑、一圈白,共10个圆圈的效果。

import pgzrun
color = 0 
def draw():
    global color
    screen.fill('white')
    for i in range(101,1,-10): #绘图重叠的部分,新图会覆盖旧图,所以越画越小才有环的效果
        if color==0: #color为0填充黑色圆
            screen.draw.filled_circle((400, 300), i, 'black')
            color = 1
        else: #color不为0填充白色圆
            screen.draw.filled_circle((400, 300), i, 'white')
            color = 0

pgzrun.go()

3. 练习3-11

import pgzrun # 导入游戏库
import random # 导入随机库
WIDTH = 1200 # 设置窗口的宽度
HEIGHT = 800 # 设置窗口的高度
R = 100        # 大圆圈的半径

def draw():    # 绘制模块,每帧重复执行
    screen.fill('white') # 白色背景
    for x in range(0, WIDTH+2*R, 2*R): # x坐标平铺遍历
        for y in range(0, HEIGHT+2*R, 2*R): # y坐标平铺遍历
             for r in range(1, R, 10): # 同心圆半径从小到大遍历
                # 绘制一个填充圆,坐标为(x,y),半径为R-r,颜色随机
                screen.draw.filled_circle((x, y), R-r, \
                 (random.randint(0, 255), random.randint(0, 255),\
                 random.randint(0, 255)))

def on_mouse_down(): # 当按下鼠标键时
    draw() # 调用绘制函数

pgzrun.go() # 开始执行游戏

 4. 练习3-12

import pgzrun # 导入游戏库
import random # 导入随机库
WIDTH = 1200 # 设置窗口的宽度
HEIGHT = 800 # 设置窗口的高度
R = 50        # 大圆圈的半径

def draw():    # 绘制模块,每帧重复执行
    screen.fill('white') # 白色背景
    for x in range(0, WIDTH+2*R, R): # x坐标平铺遍历
        for y in range(0, HEIGHT+2*R, R): # y坐标平铺遍历
            # 绘制一个圆,坐标为(x,y),半径为R,颜色随机
            screen.draw.circle((x, y), R, \
                               (random.randint(0, 255), random.randint(0, 255), \
                                random.randint(0, 255)))

def on_mouse_down(): # 当按下鼠标键时
    draw() # 调用绘制函数

pgzrun.go() # 开始执行游戏

5. 练习4-3

尝试用[x,y]形式的列表存储小球的位置,随机生成100个小球存储在列表balls中,并调用screen.draw.filled_circle()函数进行绘制

import pgzrun  # 导入游戏库
import random  # 导入随机数

WIDTH = 800  # 设置窗口的宽度
HEIGHT = 600  # 设置窗口的高度
R = 10  # 小球的半径
balls = []  #预备存储小球坐标点空数组
for i in range(100): #遍历生成一百颗小球
    balls.append([random.randint(0,WIDTH),random.randint(0,HEIGHT)]) #以窗口的宽高为限随机生成小球位置



def draw():
    screen.fill('white')
    for i in balls: #遍历数组,画遍每一个
        #i在这里读到的均为[x,y]格式的数据,颜色随机
        screen.draw.filled_circle(i,R,(random.randint(0,255),random.randint(0,255),random.randint(0,255)))
pgzrun.go()

 6. 练习4-4

尝试修改代码4-5.py,编写用鼠标写字画图的程序,得到类似图4-8所示的效果。

import pgzrun # 导入游戏库
import random # 导入随机库
WIDTH = 800 # 设置窗口的宽度
HEIGHT = 600 # 设置窗口的高度

balls = [] # 存储所有小球的信息,初始为空列表

def draw(): # 绘制模块,每帧重复执行
    screen.fill('white') # 白色背景
    for ball in balls: # 绘制所有的圆
        screen.draw.filled_circle((ball[0], ball[1]), ball[4], (ball[5], ball[6],
                                  ball[7]))
        for x in range(1,ball[4],3): #用同心圆填充
            screen.draw.filled_circle((ball[0],ball[1]),ball[4]-x,(random.randint(ball[5],255),
                                                                  random.randint(ball[6],255),
                                                                  random.randint(ball[7],255)))

# def update(): # 更新模块,每帧重复操作
#     for ball in balls:
#         ball[0] = ball[0] + ball[2] # 利用x方向速度更新x坐标
#         ball[1] = ball[1] + ball[3] # 利用y方向速度更新y坐标
#         # 当小球碰到左右边界时,x方向速度反向
#         if ball[0] > WIDTH-ball[4] or ball[0] < ball[4]:
#             ball[2] = -ball[2]
#         # 当小球碰到上下边界时,y方向速度反向
#         if ball[1] > HEIGHT-ball[4] or ball[1] < ball[4]:
#             ball[3] = -ball[3]

def on_mouse_move(pos, rel, buttons): # 当鼠标移动时
    if mouse.LEFT in buttons:         # 当按下鼠标左键时
        x = pos[0] # 鼠标的x坐标,设为小球的x坐标
        y = pos[1] # 鼠标的y坐标,设为小球的y坐标
        speed_x = random.randint(1, 5) # 小球x方向的速度
        speed_y = random.randint(1, 5) # 小球y方向的速度
        r = 15    # 小球的半径
        colorR = random.randint(10, 255) # 小球的3个颜色分量
        colorG = random.randint(10, 255)
        colorB = random.randint(10, 255)
        # 存储小球所有信息的列表
        ball = [x, y, speed_x, speed_y, r, colorR, colorG, colorB]
        balls.append(ball) # 把该小球的信息添加到balls中

pgzrun.go() # 开始执行游戏

这里源代码就改了两处,一个是取消运行update(),另一个是小球半径r取一个大小合适的值。鼠标怎么画就怎么显示轨迹。

7.练习5-3

韩信有一队少于3000人的士兵,他想知道具体有多少人,便让士兵排队报数。按从1至5报数,最末一个士兵报的数为1;按从1至6报数,最末一个士兵报的数为5;按从1至7报数,最末一个士兵报的数为4;最后再按从1至11报数,最末一个士兵报的数为10。你知道韩信有多少士兵吗?试设计程序。
num = 2999
while num%5 != 1 or num%6!=5 or num%7!=4 or num%11!=10:
    num -= 1
print(num)

2111

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值