Python游戏趣味编程(二)

勇闯地下一百层

按键说明

keyboard.up       按下键盘向上方向键

keyboard.down     按下键盘向下方向键

keyboard.a        按下键盘上的A键

keyboard.space     按下键盘上的空格键

keyboard. k_0      按下主键盘上的数字0键

keyboard. kp1       按下小键盘区上的数字1键

keyboard.rshift      按下键盘上右边的Shift键

造型标志

图片[1]-Python游戏趣味编程(二)-四曲博客

实现代码

import pgzrun
import random
​
WIDTH = 500
HEIGHT = 700
​
playerSpeed = 4 #设置玩家左右移动
brickSpeed = 1  #方块向上移动的速度
​
bricks = [] #方块列表
brick_count = 5 #每次显示的方块个数
isplayerOnGround = False    #判断玩家是否在方块上
isLoose = False #游戏是否结束
score = 1   #分数变量
lastAlienY = 0  #记录玩家在上一个方块上的位置
isdown = False  #判断玩家是否在下降
​
#导入资源
alien = Actor("alien.png")
alien_2 = Actor("alien_falling.png")
background = Actor("b.png")
​
#设置玩家初始位置
alien.x = 200
alien.y = 240
​
#创建方块,并设置相应的位置
for i in range(brick_count):
    brick = Actor("brick.jpg")
    brick.pos = 100 *(i + 1),150 * (i + 1)
    bricks.append(brick)
​
def draw():
    screen.clear()  #清楚屏幕
    background.draw()   #绘制背景
    for brick in bricks:    #绘制方块
        brick.draw()
    if isdown:  #如果落下,则绘制另外一个造型
        alien_2.draw()
    else:   #绘制玩家造型
        alien.draw()
​
    if isLoose: #游戏结束,则显示游戏结束
        screen.draw.text("Game over",(WIDTH/2 - 50,HEIGHT/2),fontsize = 60,color = "red")
​
    #绘制分数
    screen.draw.text("score:"+str(score),(20,20),fontsize = 40,color = "white")
​
def update():
    global isplayerOnGround,isLoose,brickSpeed,playerSpeed,score,lastAlienY,isdown
​
    #分数是10的倍数,则加快方块移动速度
    if score % 10 == 0:
        score += 1
        brickSpeed += 1
​
    #判断玩家是否出界,出界则游戏结束
    if alien.bottom > HEIGHT or alien.top < 0:
        playerSpeed = 0
        brickSpeed = 0
        isLoose = True
​
    #设置玩家在方块上
    isplayerOnGround = False
​
    #遍历每一个方块,如果玩家在方块上,则可以左右移动
    for brick in bricks:
        if abs(alien.bottom - brick.top) < 5 and brick.left - alien.left < alien.width*2/3 \
        and alien.right - brick.right < alien.width * 2/3 and not isLoose:
            isdown = False  #设置掉落为false
            isplayerOnGround = True #将玩家在方块上设为True
            
            #按键移动
            if keyboard.left:   
                alien.x -= playerSpeed
            if keyboard.right:
                alien.x += playerSpeed
​
            #将玩家以方块的速度向上移动,保持一直在方块上
            alien.y -= brickSpeed
​
            #如果发现玩家下降到下一个方块,则分数增加
            if lastAlienY < alien.y:
                score += 1
​
    lastAlienY = alien.y
​
    #如果玩家不在方块上
    if isplayerOnGround == False:
        isdown = True   #设置掉落标志为True
        alien.y += 5    #让玩家进行下降
​
        #掉落过程中进行按键判断
        if keyboard.left:
            alien.x -= 3
        if keyboard.right:
            alien.x += 3
​
    #遍历每一个方块,让方块进行移动
    for brick in bricks:
        brick.y -= brickSpeed
​
    #如果发现最上面的方块超出界面,则删除,重新创建
    if bricks[0].y < 10:
        del bricks[0]
        brick = Actor("brick.jpg")
        brick.x = random.randint(100,500)
        brick.y = HEIGHT
        bricks.append(brick)
​
    #更新第二个造型的坐标
    alien_2.x = alien.x
    alien_2.y = alien.y
​
pgzrun.go()
图片[2]-Python游戏趣味编程(二)-四曲博客

贪吃蛇

clock.schedule_unique(output,1)
#将output隔一秒之后运行一次
import pgzrun
num = 0
def output():
    global num
    num += 1
    print(num)
    clock.schedule_unique(output,1)
outpit()
pgzrun.go()

贪吃蛇核心代码思想

  • 每次移动的时候按照不同的方向来添加舌头
  • 当没有吃到食物的时候,保持蛇尾被删除,那么即可让蛇进行移动,并且保持蛇的长度不同
  • 当吃到食物的时候,保持蛇尾不被删除,那么即可让蛇的长度增加
import pgzrun
import time
import random
​
TILE_SIZE = 20  #设置蛇方格的宽度
​
WIDTH = 40 * TILE_SIZE  #计算界面宽度
HEIGHT = 30 * TILE_SIZE #计算界面高度
direction = "right" #将初始方式改为right
isLoose = False #设置判断游戏是否结束按钮
score = 0   #记录分数
​
#创建一个蛇头
snkaeHead = Actor("snake1")
snkaeHead.x = WIDTH/2
snkaeHead.y = HEIGHT/2
​
#创建食物
food = Actor("cookie")
food.x = random.randint(TILE_SIZE,WIDTH)
food.y = random.randint(TILE_SIZE,HEIGHT)
food.isEat = False
​
#创建蛇方格的列表
Snake = []
Snake.append(snkaeHead)
​
#创建4个蛇身体,作为初始
for i in range(4):
    snakebody = Actor("snake1")
    snakebody.x = Snake[i].x - TILE_SIZE
    snakebody.y = Snake[i].y
    Snake.append(snakebody)
​
def update():
    global direction,isLoose,Snake,TILE_SIZE,score
​
    #如果游戏没有结束,则执行下面的代码
    if not isLoose:
        #没帧都新建一个舌头
        newSnakeHead = Actor("snake1")
​
        #按照键盘不同按键进行修改方向,不能按反方向键
        if keyboard.left and direction != "right":
            direction = "left"
        if keyboard.right and direction != "left":
            direction = "right"
        if keyboard.up and direction != "down":
            direction = "up"
        if keyboard.down and direction != "up":
            direction = "down"
​
        #按键不同的方向来修改新建蛇头的位置
        if direction == "right":
            newSnakeHead.x = Snake[0].x + TILE_SIZE
            newSnakeHead.y = Snake[0].y
        if direction == "left":
            newSnakeHead.x = Snake[0].x - TILE_SIZE
            newSnakeHead.y = Snake[0].y
        if direction == "up":
            newSnakeHead.x = Snake[0].x
            newSnakeHead.y = Snake[0].y - TILE_SIZE
        if direction == "down":
            newSnakeHead.x = Snake[0].x
            newSnakeHead.y = Snake[0].y + TILE_SIZE
​
        #遍历蛇身体,看是否和蛇头相撞,这段代码必须放在插入蛇头之前
        for snakebody in Snake:
            if newSnakeHead.x == snakebody.x and newSnakeHead.y == snakebody.y:
                isLoose = True
                break
​
        #如果碰到边界,则游戏结束
        if Snake[0].x <= 0 or Snake[0].x >= WIDTH or Snake[0].y <= 0 or Snake[0].y >= HEIGHT:
            isLoose = True
​
        #如果游戏没有结束,则将蛇头加入到列表的首部
        if not isLoose:
            Snake.insert(0,newSnakeHead)
​
        #如果蛇头与食物碰撞,则更新食物的状态,并增加分数
        if newSnakeHead.colliderect(food):
            food.isEat = True
            score += 1
        else:
            #如果没有碰到食物,则删除蛇尾,保持长度不变
            del Snake[len(Snake) - 1]
​
        #如果食物被迟,则更新食物的位置,并更新食物的状态
        if food.isEat:
            food.x = random.randint(TILE_SIZE,WIDTH - TILE_SIZE)
            food.y = random.randint(TILE_SIZE,HEIGHT - TILE_SIZE)
            food.isEat = False
​
        #暂停0.1秒钟,保证蛇的行驶速度不会太快
        time.sleep(0.1)
​
def draw():
    screen.clear()  #清除屏幕
    food.draw() #绘制食物
    if isLoose: #显示游戏结束
        screen.draw.text("Game over",(WIDTH/2 - 50,HEIGHT/2),fontsize = 60,color = "red")
    screen.draw.text("score:"+str(score),(20,20),fontsize = 40,color = "white")
    for snakebody in Snake: #绘制蛇
        snakebody.draw()
​
pgzrun.go()
图片[3]-Python游戏趣味编程(二)-四曲博客

拼图游戏

import pgzrun
import random
import datetime
​
start = datetime.datetime.now() #记录游戏开始时间
​
#导入所有的图片素材
tiles = [Actor("3×3_01.jpg"),Actor("3×3_02.jpg"),Actor("3×3_03.jpg"),
        Actor("3×3_04.jpg"),Actor("3×3_05.jpg"),Actor("3×3_06.jpg"),
        Actor("3×3_07.jpg"),Actor("3×3_08.jpg"),Actor("3×3_09.jpg")]
​
images_count = 3    #设置每行的图片个数
​
WIDTH = images_count * tiles[0].width #根据图数来计算界面宽度与高度
HEIGHT = images_count * tiles[0].height
​
gird = []   #用于存储打乱后的图片
first_click = -1    #存储第一次点击的序号
second_click = -1   #存储第二次点击的序号
click_count = 0     #记录点击的次数
allright = False    #判断是否完全正确
​
#设置图片个位置,并加入到gird中
for i in range(images_count):
    for j in range(images_count):
        tile = tiles[i * 3 + j]
        tile.top = i * tile.height
        tile.left = j * tile.width 
        gird.append(tile)
​
#将i号和j号的图片进行交换
def swapPosition(i,j):
    gird[i].x,gird[j].x = gird[j].x,gird[i].x
    gird[i].y,gird[j].y = gird[j].y,gird[i].y
​
#将图片进行打乱,并将打乱后的结果放到gird中
for k in range(10):
    i = random.randint(0,len(tiles) - 1)
    j = random.randint(0,len(tiles) - 1)
    swapPosition(i,j)
​
​
def draw():
    screen.clear()  #清除屏幕
​
    #绘制图片
    for i in range(len(gird)):
        gird[i].draw()
        
        #如果图片被选中,则绘制四条线围绕该格子
        if i == first_click or i == second_click:
            screen.draw.line((gird[i].left,gird[i].top),(gird[i].right,gird[i].top),"red")
            screen.draw.line((gird[i].left,gird[i].bottom),(gird[i].right,gird[i].bottom),"red")
            screen.draw.line((gird[i].left,gird[i].top),(gird[i].left,gird[i].bottom),"red")
            screen.draw.line((gird[i].right,gird[i].top),(gird[i].right,gird[i].bottom),"red")
    #如果全国正确,则显示so cool
    if allright:
        screen.draw.text("So Cool",(WIDTH/2 - 50,HEIGHT/2),fontsize = 60,color = "red")
        end = datetime.datetime.now()   #记录游戏结束时间
​
        #游戏时间显示
        screen.draw.text("time:"+str((end-start).seconds),(WIDTH/2 - 50,HEIGHT/2 - 100),fontsize = 60,color = "red")
​
​
#当点击鼠标时执行
def on_mouse_down(pos,button):
    global click_count,first_click,second_click,allright
    click_count += 1    #点击一次,次数增加1
    allright = True     #将allright默认设置为True
​
    for i in range(3):
        for j in range(3):
            tile = gird[i * 3 + j]
            if tile.left != j * gird[0].width:  #如果发现位置不正确,则将allright设置为False
                allright = False
                break
​
    #遍历gird
    for k in range(len(gird)):
        if gird[k].collidepoint(pos):   #如果grid中的元素与鼠标的点击位置碰撞了,则执行代码
            if click_count == 1:    #如果发现次数等于1,那么记录第一次点击的图片序号
                first_click = k
            elif click_count == 2:  #如果发现次数等于2,则记录第二次点击的图片序号
                second_click = k    
                swapPosition(first_click,second_click)  #交换两个图片的位置
                click_count = 0     #将点击次数归0
                first_click = -1    #将记录变量改为默认
                second_click = -1
            break
pgzrun.go()
​
图片[4]-Python游戏趣味编程(二)-四曲博客

消灭星星

import pgzrun
import random
import copy
​
TILE_SIZE = 50  #设置每个格子的大小
WIDTH = 10 * TILE_SIZE  #设置宽度
HEIGHT = 10 * TILE_SIZE #设置高度
​
stars = []  #用于记录星星的数值,不同的数值代表不同的颜色
​
for i in range(10): #随机创建每个星星的数值
    row = []
    for j in range(10):
        x = random.randint(1,6)
        row.append(x)
    stars.append(row)
​
Tiles = []  #用于存储图片角色
​
#每次重新导入角色进行绘制
def updateTiles():
    for i in range(10):
        for j in range(10): 
            tile = Actor('star'+str(stars[i][j]))
            tile.left = j * TILE_SIZE
            tile.top =  i * TILE_SIZE
            Tiles.append(tile)
​
updateTiles()   #执行一次角色更新
​
​
def draw(): #进行绘制
    screen.clear()
    for tile in Tiles:
        tile.draw()
​
#按下鼠标时的操作
def on_mouse_down(pos,button):
    iClicked = int(pos[1]/TILE_SIZE)    #找到鼠标按下方块的坐标
    jClicked = int(pos[0]/TILE_SIZE)
#   stars[iClicked][jClicked] = 0
    connectedSet = {(iClicked,jClicked)}    #将它放入元组中,该元组用于收集所有颜色连续的星星
​
    #查找所有连续的元组
    for i in range(20): #进行20次查找
        temset = copy.deepcopy(connectedSet)    #将收集元组进行拷贝,放入临时变量中
        for each in temset: #遍历临时变量,找到里面每个星星的上下左右四个位置,是否有相同的颜色
            i = each[0]
            j = each[1]
            selectStar = stars[i][j]
​
            #如果发现有,则加入到收集元组中
            if i < 9 and stars[i + 1][j] == selectStar:
                connectedSet.add((i + 1,j))
            if i > 0 and stars[i - 1][j] == selectStar:
                connectedSet.add((i - 1,j))
            if j < 9 and stars[i][j + 1] == selectStar:
                connectedSet.add((i,j + 1))
            if j > 0 and stars[i][j - 1] == selectStar:
                connectedSet.add((i,j - 1))
        temset.clear()  #对临时元组进行清空
​
    #如果收集元组大于2,那么则将对应左边的星星颜色,设置为0,0代表黑色
    if len(connectedSet) >= 2:
        for each in connectedSet:
            stars[each[0]][each[1]] = 0
    
    #执行10次,将每一列已经消除的星星删除,并将它上面的星星方块进行下落
    for j in range(10):
        temlist = []
        for i in range(10):
            temlist.append(stars[i][j])
​
        count = 0
        while 0 in temlist:
            temlist.remove(0)
            count += 1
        for i in range(count):
            temlist.insert(0,0)
        for i in range(10):
            stars[i][j] = temlist[i]
​
    #执行完毕后,更新一次星星角色信息
    updateTiles()
​
pgzrun.go()
图片[5]-Python游戏趣味编程(二)-四曲博客

坚持100秒

import pgzrun
import random
​
WIDTH = 400
HEIGHT = 600
time = 0
balls = []
game_run = True
live = 3
is_win = False
​
#创建一个球类
class Ball:
    #设置相关属性
    x = WIDTH / 2
    y = HEIGHT / 2
    vx = 3
    vy = 5
    radius = 30
    color = 'red'
​
    def __init__(self,x,y,vx,vy,r,color):   #初始化函数
        self.x = x
        self.y = y 
        self.vx = vx
        self.vy = vy
        self.radius = r
        self.color = color
​
    def draw(self): #绘制函数
        screen.draw.filled_circle((self.x,self.y),self.radius,self.color)
​
    def update(self):   #更新小球位置
        self.x += self.vx
        self.y += self.vy
        if self.x < self.radius or self.x > WIDTH - self.radius:
            self.vx = - self.vx
        if self.y < self.radius or self.y > HEIGHT - self.radius:
            self.vy = - self.vy
​
hero = Actor("hero.jpg")    #创建飞船
​
liveors = []    #创建飞船生命值,用于显示生命值
​
for i in range(live):   #创建用于显示生命值的小飞船
    liveor = Actor("hero_small.jpg")
    liveor.x = (i + 1) * 50
    liveor.y = 40
    liveors.append(liveor)
​
def draw():
    screen.fill("white")    #设置背景色
    hero.draw() #绘制飞船
    for ball in balls:  #绘制小球
        ball.draw()
    for liveor in liveors:  #绘制生命值
        liveor.draw()
​
    if not game_run:    #如果游戏结束,则显示
        screen.draw.text("game over",(30,30),fontsize = 50,color = "red")
    if game_run:    #如果游戏运行,则显示
        screen.draw.text(str(time),(200,30),fontsize = 50,color = "red")
    if is_win:  #如果游戏胜利,则显示
        screen.draw.text("win",(200,30),fontsize = 50,color = "green")
​
def update():
    global game_run,live,time,liveors
    if game_run:    #如果游戏正在运行,则不断更新位置,并且检测是否碰撞
        for  ball in balls:
            ball.update()
            if abs(ball.x - hero.x) < 25 and abs(ball.y - hero.y) < 30: #如果发生碰撞
                live -= 1   #生命值减少
                ball.y = 10 #让飞船远离小球,防止重复碰撞
                liveors.pop()   #让生命值列表减小一个
        if time == 100: #如果时间为100,则游戏胜利
            is_win = True
​
    if live < 1:    #如果生命值小于1,则游戏结束,切换爆炸图片
        game_run = False
        hero.image = "blowup.png"
​
​
def count():
    global time,balls
    time += 1
    if time % 1 == 0 and len(balls) <= 20:  #数量小于20,则继续创建
        x = WIDTH//2
        y = random.randint(5,HEIGHT//10)
        vx = random.choice([-3,-2,-1,1,2,3])
        vy = random.randint(1,3)
        r = 3
        color = 'black'
        ball = Ball(x,y,vx,vy,r,color)
        balls.append(ball)
    if game_run:    #如果游戏正在运行,则每次进行计时器调用
        clock.schedule_unique(count,1)
​
def on_mouse_move(pos,rel,buttons): #鼠标移动事件,让飞船跟随鼠标移动
    if game_run:
        hero.x = pos[0]
        hero.y = pos[1]
​
count()
pgzrun.go()
图片[6]-Python游戏趣味编程(二)-四曲博客

图像的相关操作

对图像进行裁剪

import pgzrun
from PIL import Image
​
im = Image.open("images/image1.jpg")
​
#对图像进行裁剪
box = (200,0,950,750)
region = im.crop(box)
region.save("images/image1_crop.jpg")   #将裁剪的图像进行保存
​
w,h = region.size
WIDTH = w
HEIGHT = h
pic = Actor('image1')
​
def draw():
    pic.draw()
​
pgzrun.go()

对图像进行编辑粘贴操作

from PIL import Image
​
pic = Image.open("images/image2.jpg")
w_pic,h_pic = pic.size
​
#拷贝一份原始图片,在其上进行修改
copyPic = pic.copy()
​
#打开Python标志图片文件
py = Image.open("images/python.jpg")
w_py,h_py = py.size
​
#将图片进行粘贴
copyPic.paste(py,(w_pic-w_py,h_pic-h_py))
​
#保存更改后的copyPic图片
copyPic.save("images/image2_python.jpg")
图片[7]-Python游戏趣味编程(二)-四曲博客

创建一个空白图像

newimage = Image.new("RGB",(800,800),'red') #创建一个新的图像
newiamge.save("images/newImages.jpg")   #保存最后的图像

创建一个国际象棋棋盘

from PIL import Image
​
#新创建一张白色背景图片
newimage_white = Image.new("RGB",(800,800),"white")
​
px = newimage_white.load()  #导入图片像素
​
#按照规律进行添加黑色方格
for i in range(800):
    for j in range(800):
        if (i // 80 + j // 80) % 2 == 1:
            px[i,j] = 0,0,0
​
#保存最终生成的图片
newimage_white.save("images//guoji.jpg")
图片[8]-Python游戏趣味编程(二)-四曲博客

生成动态像素画

from PIL import Image
import pgzrun
import random
​
#导入制作的图片
im = Image.open("images/image2.jpg")
px = im.load()  #获取图片的像素信息
w,h = im.size
​
​
r,g,b,x,y = 0,0,0,0,0
​
WIDTH = w
HEIGHT = h
color = []
pos = []
​
​
​
def draw():
    global r,g,b,x,y,pos,color
​
    #用圆形绘制挑选来的像素值
    for i in range(100):
        screen.draw.filled_circle(pos[i],5,color[i])
​
def update():
    global r,g,b,x,y,px,pos,color
    pos.clear()
    color.clear()
​
    #随机挑选100个像素,放入到列表当中
    for i in range(100):
        x = random.randint(0,w - 1)
        y = random.randint(0,h - 1)
        r,g,b = px[x,y]
​
        pos.append((x,y))
        color.append((r,g,b))
​
pgzrun.go()
图片[9]-Python游戏趣味编程(二)-四曲博客
© 版权声明
THE END
喜欢就支持以下吧
点赞8 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片