首页 > 编程语言 >用Python的Pygame包做飞行棋

用Python的Pygame包做飞行棋

时间:2023-10-27 11:57:49浏览次数:40  
标签:draw Python pygame 飞行棋 sur circle SIZE RED Pygame

最近学了下pygame, 感觉非常有意思, 于是用自己的理解纯手工敲了几个游戏, 下面记录一下我做飞行棋的思路过程:

 

运行结果

玩家轮流投骰子然后移动飞机, 全程只用鼠标操作, 右上方会提示当前的轮次及操作

 

基础设置

1) 首先是导包和初始化一些变量, 定义SIZE=40表示长方形的宽, 里面的长方形地区长宽比为2:1, 三角形直角边等于长方形的长, 出发地的边长等于长方形宽度的4倍

2) 游戏里设置了100帧, 设置几百都没问题(只要电脑带的动)

3) 没有导入pygame包的话就在终端输入pip install pygame即可自动下载.



import pygame, random
from pygame.locals import *

# 基础设置 pygame.init() WIDTH = 680 # 正方形棋盘边长 SIZE = 40 # 小格子正方形大小 sur = pygame.display.set_mode((WIDTH+100, WIDTH)) pygame.display.set_caption('FlightChess') # 标题 FPS = 100 # 帧率 fpsClock = pygame.time.Clock()

 

颜色变量

一些颜色RGB值变量的初始化, RGB值就是用红绿蓝三个色度来表示最终的颜色, 每个色度为0-255, 例如(0, 0, 0)表示黑色

# 颜色变量
# 颜色变量
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 128, 0)
BLACK = (0, 0, 0)
YELLOW = (233, 233, 0)
BLUE = (62, 105, 22

 

画棋盘

首先先看几个函数的定义

1) 在圆心为(x, y)半径为R的圆中画一个颜色为color的飞机

def draw_plane(x, y, color):
    # 机身
    pygame.draw.line(sur, color, (x+9, y), (x-8, y), 3)
    pygame.draw.line(sur, color, (x+9, y), (x+12, y), 2)
    # 尾部
    pygame.draw.line(sur, color, (x-8, y), (x-11, y-4), 3)
    pygame.draw.line(sur, color, (x-8, y), (x-11, y+4), 3)
    # 机翼
    pygame.draw.line(sur, color, (x+3, y), (x-3, y-6), 3)
    pygame.draw.line(sur, color, (x-3, y-6), (x-6, y-9), 2)
    pygame.draw.line(sur, color, (x+3, y), (x-3, y+6), 3)
    pygame.draw.line(sur, color, (x-3, y+6), (x-6, y+9), 2)

2) 在圆心为(x, y)的地方画一个白色圆, 半径为R

def draw_circle(x, y):
    pygame.draw.circle(sur, WHITE, (x, y), R, R)
    pygame.draw.circle(sur, BLACK, (x, y), R, 1)

3) 在左上角(x, y)坐标处开始画一个三角形, 三角形有4中形态

  type==0 时直角在左上角, type==1时直角在右上角, type==2时直角在右下角, type==3时直角在左下角

zdef draw_triangle(x, y, color, type):
    if not type:
        pygame.draw.polygon(sur, color, ((x, y), (x+SIZE*2, y), (x, y+SIZE*2)))
        draw_circle(x+L, y+L)
        pygame.draw.polygon(sur, BLACK, ((x, y), (x+SIZE*2, y), (x, y+SIZE*2)), 2)
    elif type == 1:
        pygame.draw.polygon(sur, color, ((x, y), (x + SIZE * 2, y), (x+SIZE*2, y + SIZE * 2)))
        draw_circle(x+R+SIZE, y+L)
        pygame.draw.polygon(sur, BLACK, ((x, y), (x + SIZE * 2, y), (x+SIZE*2, y + SIZE * 2)), 2)
    elif type == 2:
        pygame.draw.polygon(sur, color, ((x, y + SIZE * 2), (x + SIZE * 2, y), (x + SIZE * 2, y + SIZE * 2)))
        draw_circle(x + R+SIZE, SIZE+y + R)
        pygame.draw.polygon(sur, BLACK, ((x, y+SIZE*2), (x + SIZE * 2, y), (x+SIZE*2, y + SIZE * 2)), 2)
    else:
        pygame.draw.polygon(sur, color, ((x, y), (x + SIZE * 2, y + SIZE * 2), (x, y + SIZE * 2)))
        draw_circle(x + L, y + R+SIZE)
        pygame.draw.polygon(sur, BLACK, ((x, y), (x + SIZE * 2, y+SIZE*2), (x, y + SIZE * 2)), 2)

4) 在(x, y)画一格颜色为color的长方形

  type=0为横着, 1为竖着

def draw_block(x, y, color, type):
    if type:  # 竖
        sur.fill(color, (x, y, SIZE, SIZE * 2))
        pygame.draw.polygon(sur, BLACK, ((x, y), (x+SIZE, y), (x+SIZE, y+SIZE*2), (x, y+SIZE*2)), 2)
        draw_circle(x+20, y+40)

    else:  # 横
        sur.fill(color, (x, y, SIZE * 2, SIZE))
        pygame.draw.polygon(sur, BLACK, ((x, y), (x+SIZE*2, y), (x+SIZE*2, y+SIZE), (x, y+SIZE)), 2)
        draw_circle(x+40, y+20)

 

5) 画棋盘

下面是画棋盘的一部分代码

    draw_triangle(0, 160, GREEN, 2)
    draw_block(80, 160, RED, 1)
    draw_block(120, 160, YELLOW, 1)
    draw_triangle(160, 160, BLUE, 3)
    draw_triangle(160, 160, GREEN, 1)
    draw_block(160, 120, RED, 0)
    draw_block(160, 80, YELLOW, 0)
    draw_triangle(160, 0, BLUE, 2)
    draw_block(240, 0, GREEN, 1)
    draw_block(280, 0, RED, 1)
    draw_path((240, 160+L), (440, 183), GREEN)
    pygame.draw.circle(sur, BLACK, (L, 160+L), R, 2)
    draw_end_place(YELLOW)
    draw_start_place(0, 0, RED)

画出了差不多这一部分(不完全准确), 剩下的自行根据坐标来定义即可

 

变量思路

做完了界面, 就该考虑逻辑怎么实现了

首先我把棋盘分成了三个部分来放飞机, 出发地, 周围一圈, 终点路径

 

出发地

init_pos = [[0 for _ in range(5)] for _ in range(4)]

 

 周围一圈

grid = [0 for _ in range(52)]

 

终点路径

end_pos = {RED: [False for _ in range(6)],
           YELLOW: [False for _ in range(6)],
           BLUE: [False for _ in range(6)],
           GREEN: [False for _ in range(6)]}

 

飞机类, 表示一架飞机, 包含目前的所有信息

class Chess:
    step = STEP  # 还差多少步到终点
    start = 0  # 飞机目前的状态, 0未出发, 1在棋盘上, 2在终点路径
    color = (0, 0, 0)  # 颜色
    x, y = 0, 0  # 界面的笛卡尔坐标
    idx = 0  # 棋盘对应部分的下标
    def __init__(self, color, x, y, start, idx):
        self.color = color  # 飞机颜色
        self.x, self.y = x, y

 

接下来在每次循环里面都画出飞机即可, 遍历每个部分是否有飞机

    while True:
        draw_grid()
        draw_point()

        # 画出出生地的飞机
        for i in range(len(init_pos)):  # 4
            for j in range(len(init_pos[0])):  # 5
                if init_pos[i][j]:
                    draw_plane(init_pos[i][j].x, init_pos[i][j].y, init_pos[i][j].color)
        # 画出棋盘中的飞机
        for c in grid:
            if c:  # 此格有飞机, 画出飞机
                draw_plane(c.x, c.y, c.color)
        # 画终点路径的飞机
        for i in end_pos:
            for c in end_pos[i]:
                if c:
                    draw_plane(c.x, c.y, c.color)

 

关于投骰子, 用random随机数来获取点数, 并将其显示在棋盘右边的位置, 投骰子的时间为0.5s, 实现的方法:

t = 0
  while True:
     ...
if not moving and geting_point: # 投色子 t += 1/FPS point = get_point() if t >= 0.5: t = 0 geting_point = False move = True

 

核心逻辑

大致思路:

1. 点击后判断点击的位置是否在棋盘内

  1) 在棋盘内

    找到点击位置的飞机, 然后根据一系列规则和更新来维护棋盘

  2) 在棋盘外

    点击到了骰子, 若条件满足则开始投骰子

  3) 无效点击

    指点击了没反应, 在棋盘内没点击到棋子或者点击到了不是此轮此的棋子或者无法移动的棋子

           在棋盘外点击了除骰子以外的地方或者条件不符合投骰子

 

2. 中途包含了非常多的细节, 这里就不一一叙述, 感兴趣请看全部代码.

 

全部代码

规则一览:

  1) 点数 >= 5 时飞机才能出发, 若场上没有可移动的飞机, 自动跳过回合

  2) 对于可移动的飞机, 点数丢到多少就可移动多少格

  3) 飞机落点在同色块时会自动跳到下一个同色块(4格), 若是有虚线的同色块, 则会沿着虚线跨越到对面(12格)

  4) 相同颜色飞机无法落在同一格, 此时会无法点击想要移动的飞机

  5) 若落点处有不同颜色的飞机, 会将其打回出发点

import pygame, random
from pygame.locals import *

# 基础设置
pygame.init()
WIDTH = 680  # 正方形棋盘边长
SIZE = 40  # 小格子正方形大小
sur = pygame.display.set_mode((WIDTH+100, WIDTH))
pygame.display.set_caption('FlightChess')
FPS = 100
fpsClock = pygame.time.Clock()

# 颜色变量
WHITE = (255, 255, 255)
RED  = (255, 0, 0)
GREEN = (0, 128, 0)
BLACK = (0, 0, 0)
YELLOW = (233, 233, 0)
BLUE = (62, 105, 225)

# 游戏变量
R = 18  # 圆的半径, 框中的偏差量
DIF = SIZE - R
L, RR = 23, 57
grid = [0 for _ in range(52)]  # 棋盘, 仅包括周围一圈, 不包括飞机的出生点
GRID_COLOR = (GREEN, RED, YELLOW, BLUE, GREEN, RED, YELLOW, BLUE, GREEN, RED, YELLOW, BLUE,
              GREEN, RED, YELLOW, BLUE, GREEN, RED, YELLOW, BLUE, GREEN, RED, YELLOW, BLUE,
              GREEN, RED, YELLOW, BLUE, GREEN, RED, YELLOW, BLUE, GREEN, RED, YELLOW, BLUE,
              GREEN, RED, YELLOW, BLUE, GREEN, RED, YELLOW, BLUE, GREEN, RED, YELLOW, BLUE,
              GREEN, RED, YELLOW, BLUE,)  # 对应格子的颜色
STEP = 56  # 每个棋子要走的总步数
QUICK_CROSS = 12  # 碰见机场会少走的步数
QUICK_PATH = {RED: 17, YELLOW: 30, BLUE: 43, GREEN: 4}
LAST_STEP = 5  # 最后五步会被移出棋盘
START_POINT = 5  # 飞机必须大于等于5才能从机场出发
# pause = False  # 是否暂停游戏, 棋子在移动中途自动暂停
# game_start = False  # 游戏是否开始
INIT = {RED: 0, YELLOW: 13, BLUE: 26, GREEN: 39}  # 各颜色棋子的出发点在棋盘中的索引
init_pos = [[0 for _ in range(5)] for _ in range(4)]  # 各棋子出生地和出发地, 红黄蓝绿
INIT_POS = ((40, 40), (40+R*2+DIF*2, 40), (40, 40+R*2+DIF*2), (40+R*2+DIF*2, 40+R*2+DIF*2), (L, 160+L),  # 红
            (560, 40), (560+R*2+DIF*2, 40), (560, 40+R*2+DIF*2), (560+R*2+DIF*2, 40+R*2+DIF*2), (520-L, L),  # 黄
            (560, 560), (560+R*2+DIF*2, 560), (560, 560+R*2+DIF*2), (560+R*2+DIF*2, 560+R*2+DIF*2), (680-L, 520-L),  # 蓝
            (40, 560), (40+R*2+DIF*2, 560), (40, 560+R*2+DIF*2), (40+R*2+DIF*2, 560+R*2+DIF*2), (160+L, 680-L))  # 绿
COLOR_IDX = [RED, YELLOW, BLUE, GREEN]  # 数字对应的颜色索引
# 棋盘对应具体坐标
PLACE = ((80-L, 240-L), (100, 200), (140, 200), (160+L, 240-L), (240-L, 160+L),
         (200, 140), (200, 100), (240-L, 80-L), (260, 40), (300, 40), (340, 40),
         (380, 40), (420, 40), (440+L, 80-L), (480, 100), (480, 140), (440+L, 160+L),
         (520-L, 240-L), (540, 200), (580, 200), (600+L, 240-L), (640, 260), (640, 300),
         (640, 340), (640, 380), (640, 420), (600+L, 440+L), (580, 480), (540, 480),
         (520-L, 440+L), (440+L, 520-L), (480, 540), (480, 580), (440+L, 600+L),
         (420, 640), (380, 640), (340, 640), (300, 640), (260, 640), (240-L, 600+L),
         (200, 580), (200, 540), (240-L, 520-L), (160+L, 440+L), (140, 480), (100, 480),
         (80-L, 440+L), (40, 420), (40, 380), (40, 340), (40, 300), (40, 260))
# 终点路径的棋子
end_pos = {RED: [False for _ in range(6)],
           YELLOW: [False for _ in range(6)],
           BLUE: [False for _ in range(6)],
           GREEN: [False for _ in range(6)]}
# 终点路径的坐标
END_PLACE = {RED: ((), (260, 340), (220, 340), (180, 340), (140, 340), (100, 340)),
             YELLOW: ((), (340, 260), (340, 220), (340, 180), (340, 140), (340, 100)),
             BLUE: ((), (420, 340), (460, 340), (500, 340), (540, 340), (580, 340)),
             GREEN: ((), (340, 420), (340, 460), (340, 500), (340, 540), (340, 580))}
mousechess = False  # 鼠标上的棋子
prechess = False  # 之前一个棋子
point = 0  # 点数
turn = RED # 轮次
TURN = {RED: YELLOW, YELLOW: BLUE, BLUE: GREEN, GREEN: RED}  # 轮番顺序
TURN_NAME = {RED: '红色', YELLOW: '黄色', BLUE: '蓝色', GREEN: '绿色'}
TURN_IDX = {RED: 0, YELLOW: 1, BLUE: 2, GREEN: 3}  # 颜色对应索引
FONT1 = pygame.font.SysFont("SimHei", 15)
FONT2 = pygame.font.SysFont("SimHei", 20)
FONT3 = pygame.font.SysFont("SimHei", 100)
move = False  # 为true的时候就该某一色移动棋子
moving = False  # 正在移动, 画路径
remain_plane = {RED: 4, YELLOW: 4, BLUE: 4, GREEN: 4}  # 未到终点的飞机数量
dif = 0  # 跳跃量
geting_point = False  # 正在摇骰子



# 飞机类, 代表一个飞机的个体
class Chess:
    step = STEP  # 还差多少步到终点
    start = 0  # 飞机目前的状态, 0未出发, 1在棋盘上, 2在终点路径
    color = (0, 0, 0)  # 颜色
    x, y = 0, 0  # 界面的笛卡尔坐标
    idx = 0  # 棋盘对应部分的下标
    def __init__(self, color, x, y, start, idx):
        self.color = color  # 飞机颜色
        self.x, self.y = x, y




def get_point():
    return random.randint(1, 6)

# 在圆心为(x, y)半径为R的圆中画一个颜色为color的飞机
def draw_plane(x, y, color):
    # 机身
    pygame.draw.line(sur, color, (x+9, y), (x-8, y), 3)
    pygame.draw.line(sur, color, (x+9, y), (x+12, y), 2)
    # 尾部
    pygame.draw.line(sur, color, (x-8, y), (x-11, y-4), 3)
    pygame.draw.line(sur, color, (x-8, y), (x-11, y+4), 3)
    # 机翼
    pygame.draw.line(sur, color, (x+3, y), (x-3, y-6), 3)
    pygame.draw.line(sur, color, (x-3, y-6), (x-6, y-9), 2)
    pygame.draw.line(sur, color, (x+3, y), (x-3, y+6), 3)
    pygame.draw.line(sur, color, (x-3, y+6), (x-6, y+9), 2)


# 在圆心为(x, y)处画白色圆, 半径为R
def draw_circle(x, y):
    pygame.draw.circle(sur, WHITE, (x, y), R, R)
    pygame.draw.circle(sur, BLACK, (x, y), R, 1)

# 在(x, y)画一格颜色为color的长方形, 长是宽的两倍, type=0为横着, 1为竖着
def draw_block(x, y, color, type):
    if type:  # 竖
        sur.fill(color, (x, y, SIZE, SIZE * 2))
        pygame.draw.polygon(sur, BLACK, ((x, y), (x+SIZE, y), (x+SIZE, y+SIZE*2), (x, y+SIZE*2)), 2)
        draw_circle(x+20, y+40)

    else:  # 横
        sur.fill(color, (x, y, SIZE * 2, SIZE))
        pygame.draw.polygon(sur, BLACK, ((x, y), (x+SIZE*2, y), (x+SIZE*2, y+SIZE), (x, y+SIZE)), 2)
        draw_circle(x+40, y+20)




# 在(x, y)画一格颜色为color的三角形, 长是宽的两倍
# type=0为左上角直角, 1为右上角直角, 2为右下角直角, 3左下角直角
def draw_triangle(x, y, color, type):
    if not type:
        pygame.draw.polygon(sur, color, ((x, y), (x+SIZE*2, y), (x, y+SIZE*2)))
        draw_circle(x+L, y+L)
        pygame.draw.polygon(sur, BLACK, ((x, y), (x+SIZE*2, y), (x, y+SIZE*2)), 2)
    elif type == 1:
        pygame.draw.polygon(sur, color, ((x, y), (x + SIZE * 2, y), (x+SIZE*2, y + SIZE * 2)))
        draw_circle(x+R+SIZE, y+L)
        pygame.draw.polygon(sur, BLACK, ((x, y), (x + SIZE * 2, y), (x+SIZE*2, y + SIZE * 2)), 2)
    elif type == 2:
        pygame.draw.polygon(sur, color, ((x, y + SIZE * 2), (x + SIZE * 2, y), (x + SIZE * 2, y + SIZE * 2)))
        draw_circle(x + R+SIZE, SIZE+y + R)
        pygame.draw.polygon(sur, BLACK, ((x, y+SIZE*2), (x + SIZE * 2, y), (x+SIZE*2, y + SIZE * 2)), 2)
    else:
        pygame.draw.polygon(sur, color, ((x, y), (x + SIZE * 2, y + SIZE * 2), (x, y + SIZE * 2)))
        draw_circle(x + L, y + R+SIZE)
        pygame.draw.polygon(sur, BLACK, ((x, y), (x + SIZE * 2, y+SIZE*2), (x, y + SIZE * 2)), 2)


# 在(x, y)处画颜色为color的出生地
def draw_start_place(x, y, color):
    sur.fill(color, (x, y, 4 * SIZE, 4 * SIZE))
    draw_circle(x+40, y+40)
    draw_circle(x+40 + R * 2 + DIF * 2, y+40)
    draw_circle(x+40, y+40 + R * 2 + DIF * 2)
    draw_circle(x+40 + R * 2 + DIF * 2, y+40 + R * 2 + DIF * 2)
    pygame.draw.polygon(sur, BLACK, ((x, y), (x+160, y), (x+160, y+160), (x, y+160)), 2)


# 画出终点的路
def draw_end_place(color):
    if color == YELLOW:
        pygame.draw.polygon(sur, YELLOW,
                            ((320, 0), (360, 0), (360, 280), (400, 280), (340, 340), (280, 280), (320, 280)))
        pygame.draw.polygon(sur, BLACK,
                            ((320, 0), (360, 0), (360, 280), (400, 280), (340, 340), (280, 280), (320, 280)), 2)
        draw_circle(340, 40)
        draw_circle(340, 100)
        draw_circle(340, 140)
        draw_circle(340, 180)
        draw_circle(340, 220)
        draw_circle(340, 260)
        draw_circle(340, 300)
    elif color == BLUE:
        pygame.draw.polygon(sur, BLUE,
                            ((340, 340), (400, 280), (400, 320), (WIDTH, 320), (WIDTH, 360), (400, 360), (400, 400)))
        pygame.draw.polygon(sur, BLACK,
                            ((340, 340), (400, 280), (400, 320), (WIDTH, 320), (WIDTH, 360), (400, 360), (400, 400)), 2)
        draw_circle(640, 340)
        draw_circle(580, 340)
        draw_circle(540, 340)
        draw_circle(500, 340)
        draw_circle(460, 340)
        draw_circle(420, 340)
        draw_circle(380, 340)

    elif color == GREEN:
        pygame.draw.polygon(sur, GREEN,
                            ((340, 340), (400, 400), (360, 400), (360, WIDTH), (320, WIDTH), (320, 400), (280, 400)))
        pygame.draw.polygon(sur, BLACK,
                            ((340, 340), (400, 400), (360, 400), (360, WIDTH), (320, WIDTH), (320, 400), (280, 400)), 2)
        draw_circle(340, 640)
        draw_circle(340, 580)
        draw_circle(340, 540)
        draw_circle(340, 500)
        draw_circle(340, 460)
        draw_circle(340, 420)
        draw_circle(340, 380)
    else:  # RED
        pygame.draw.polygon(sur, RED,
                            ((340, 340), (280, 400), (280,360), (0, 360), (0, 320), (280, 320), (280, 280)))
        pygame.draw.polygon(sur, BLACK,
                            ((340, 340), (280, 400), (280, 360), (0, 360), (0, 320), (280, 320), (280, 280)), 2)
        draw_circle(40, 340)
        draw_circle(100, 340)
        draw_circle(140, 340)
        draw_circle(180, 340)
        draw_circle(220, 340)
        draw_circle(260, 340)
        draw_circle(300, 340)


# 在两点之间画颜色color的虚线
def draw_path(p1, p2, color):
    if p1[0] == p2[0]:  # 画竖线
        x = p1[0]
        for i in range(min(p1[1], p2[1]), max(p1[1], p2[1]), 10):
            pygame.draw.line(sur, color, (x, i), (x, i+5), 2)
    else:  # 画横线
        y = p1[1]
        for j in range(min(p1[0], p2[0]), max(p1[0], p2[0]), 10):
            pygame.draw.line(sur, color, (j, y), (j+5, y), 2)

# 画棋盘
def draw_grid():
    sur.fill(WHITE)

    draw_triangle(0, 160, GREEN, 2)
    draw_block(80, 160, RED, 1)
    draw_block(120, 160, YELLOW, 1)
    draw_triangle(160, 160, BLUE, 3)
    draw_triangle(160, 160, GREEN, 1)
    draw_block(160, 120, RED, 0)
    draw_block(160, 80, YELLOW, 0)
    draw_triangle(160, 0, BLUE, 2)
    draw_block(240, 0, GREEN, 1)
    draw_block(280, 0, RED, 1)
    draw_path((240, 160+L), (440, 183), GREEN)
    pygame.draw.circle(sur, BLACK, (L, 160+L), R, 2)
    draw_end_place(YELLOW)
    draw_start_place(0, 0, RED)

    draw_block(360, 0, BLUE, 1)
    draw_block(400, 0, GREEN, 1)
    draw_triangle(440, 0, RED, 3)
    draw_block(440, 80, YELLOW, 0)
    draw_block(440, 120, BLUE, 0)
    draw_triangle(440, 160, GREEN, 0)
    draw_triangle(440, 160, RED, 2)
    draw_block(520, 160, YELLOW, 1)
    draw_block(560, 160, BLUE, 1)
    draw_triangle(600, 160, GREEN, 3)
    draw_block(600, 240, RED, 0)
    draw_block(600, 280, YELLOW, 0)
    draw_end_place(BLUE)
    pygame.draw.circle(sur, BLACK, (520-L, L), R, 2)
    draw_path((440+RR, 240), (440+RR, 440), RED)
    draw_start_place(520, 0, YELLOW)

    draw_block(600, 360, GREEN, 0)
    draw_block(600, 400, RED, 0)
    draw_triangle(600, 440, YELLOW, 0)
    draw_block(560, 440, BLUE, 1)
    draw_block(520, 440, GREEN, 1)
    draw_triangle(440, 440, RED, 1)
    draw_triangle(440, 440, YELLOW, 3)
    draw_block(440, 520, BLUE, 0)
    draw_block(440, 560, GREEN, 0)
    draw_triangle(440, 600, RED, 0)
    draw_block(400, 600, YELLOW, 1)
    draw_block(360, 600, BLUE, 1)
    draw_end_place(GREEN)
    pygame.draw.circle(sur, BLACK, (680-L, 520-L), R, 2)
    draw_path((240, 440+RR), (440, 440+RR), YELLOW)
    draw_start_place(0, 520, GREEN)

    draw_block(280, 600, RED, 1)
    draw_block(240, 600, YELLOW, 1)
    draw_triangle(160, 600, BLUE, 1)
    draw_block(160, 560, GREEN, 0)
    draw_block(160, 520, RED, 0)
    draw_triangle(160, 440, BLUE, 0)
    draw_triangle(160, 440, YELLOW, 2)
    draw_block(120, 440, GREEN, 1)
    draw_block(80, 440, RED, 1)
    draw_triangle(0, 440, YELLOW, 1)
    draw_block(0, 400, BLUE, 0)
    draw_block(0, 360, GREEN, 0)
    draw_block(0, 280, YELLOW, 0)
    draw_block(0, 240, BLUE, 0)
    draw_end_place(RED)
    pygame.draw.circle(sur, BLACK, (160+L, 680-L), R, 2)
    draw_path((160+L, 240), (160+L, 440), BLUE)
    draw_start_place(520, 520, BLUE)


def draw_point():
    pygame.draw.polygon(sur, BLACK, ((WIDTH, 0), (WIDTH, WIDTH), (WIDTH+97, WIDTH), (WIDTH+97, 0)), 10)
    pygame.draw.polygon(sur, BLACK, ((WIDTH+30, 150), (WIDTH+70, 150), (WIDTH+70, 190), (WIDTH+30, 190)), 2)
    if point == 1:  # 画点数
        pygame.draw.circle(sur, RED, (WIDTH+50, 170), 5, 5)
    elif point == 2:
        pygame.draw.circle(sur, RED, (WIDTH + 40, 170), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 60, 170), 5, 5)
    elif point == 3:
        pygame.draw.circle(sur, RED, (WIDTH + 50, 160), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 40, 180), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 60, 180), 5, 5)
    elif point == 4:
        pygame.draw.circle(sur, RED, (WIDTH + 40, 160), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 60, 160), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 40, 180), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 60, 180), 5, 5)
    elif point == 5:
        pygame.draw.circle(sur, RED, (WIDTH + 50, 170), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 40, 160), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 60, 160), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 40, 180), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 60, 180), 5, 5)
    elif point == 6:
        pygame.draw.circle(sur, RED, (WIDTH + 40, 160), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 60, 160), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 40, 170), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 60, 170), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 40, 180), 5, 5)
        pygame.draw.circle(sur, RED, (WIDTH + 60, 180), 5, 5)


# 检查是否能够移动
def check_movable():
    global turn
    lst = [i for i in init_pos[TURN_IDX[turn]]][:-1]
    count = 0
    for i in lst:
        if i: count += 1
    if remain_plane[turn] == count and point <= 4:  # 剩余飞机全部在家且点数小于4无法移动
        return False

    return True

# 检查是否有胜者
def check_winner():
    winner = False
    for i in remain_plane:
        if not remain_plane[i]:
            winner = i
            break
    if winner:
        for i in TURN:
            if TURN[i] == winner:
                TURN[i] = TURN[winner]
                break


def update(i):
    global move, turn, point, mousechess
    mousechess.x, mousechess.y = PLACE[i]
    mousechess.idx = i
    grid[i] = mousechess
    move = False
    turn = TURN[turn]
    point = 0

# 是否跳过
def jump_4(idx):
    global mousechess, dif
    if mousechess.color == GRID_COLOR[idx] and mousechess.step > 6+point:  # 到达同色地带, +4
        dif += 4
        return (idx + 4) % len(grid)
    return idx


def plane_back(idx):
    global mousechess
    if not grid[idx]: return True  # 可以移动
    c = grid[idx]
    if c.color == mousechess.color: return False  # 队友, 不能移动
    # 将别人的棋子打回去
    x = TURN_IDX[c.color]
    for i in range(len(init_pos[x])):
        if not init_pos[x][i]:  # 找到空位重新生成一个飞机
            c.step = STEP
            c.x, c.y = INIT_POS[x*5+i]
            init_pos[x][i] = c
            return True

def draw_moving():
    if mousechess.start == prechess.start:  # 两者在同一棋盘上移动, 直接画
        for i in range(prechess.idx, mousechess.idx+1):
            if not mousechess.start:  # 在出生点
                break
            elif mousechess.start == 1:  # 在外圈
                pass
    pass

def main():
    global point, pause, mousechess, turn, move, game_start, dif, geting_point, moving
    # 前四个位置填充飞机
    for i in range(4):
        init_pos[0][i] = Chess(RED, INIT_POS[i][0], INIT_POS[i][1], 0, i)
        init_pos[1][i] = Chess(YELLOW, INIT_POS[i+5][0], INIT_POS[i+5][1], 0, i)
        init_pos[2][i] = Chess(BLUE, INIT_POS[i+10][0], INIT_POS[i+10][1], 0, i)
        init_pos[3][i] = Chess(GREEN, INIT_POS[i+15][0], INIT_POS[i+15][1], 0, i)

    t = 0  # 动画计时
    Text1 = FONT1.render("现在轮到", True, BLACK)
    Text4 = FONT1.render("无法移动", True, BLACK)
    Text5 = FONT1.render("跳过此玩家", True, BLACK)
    while True:
        draw_grid()
        draw_point()
        check_winner()

        # 画出出生地的飞机
        for i in range(len(init_pos)):  # 4
            for j in range(len(init_pos[0])):  # 5
                if init_pos[i][j]:
                    draw_plane(init_pos[i][j].x, init_pos[i][j].y, init_pos[i][j].color)
        # 画出棋盘中的飞机
        for c in grid:
            if c:  # 此格有飞机, 画出飞机
                draw_plane(c.x, c.y, c.color)
        # 画终点路径的飞机
        for i in end_pos:
            for c in end_pos[i]:
                if c:
                    draw_plane(c.x, c.y, c.color)


        Text2 = FONT2.render(TURN_NAME[turn], True, turn)
        Text3 = FONT2.render("移动" if move else '投掷', True, BLACK)

        if not moving and geting_point:  # 投色子
            t += 1/FPS
            point = get_point()
            if t >= 0.5:
                t = 0
                geting_point = False
                move = True


        if not moving and move and not geting_point and not check_movable():  # True可移动, 否则不可移动, 直接跳到下一个玩家
            t += 1/FPS
            sur.blit(Text4, (WIDTH+10, 250))
            sur.blit(Text5, (WIDTH+10, 280))
            if t >= 1:
                point = 0
                turn = TURN[turn]
                move = False
                game_start = False
                t = 0

        sur.blit(Text1, (WIDTH+10, 50))
        sur.blit(Text2, (WIDTH+30, 70))
        sur.blit(Text3, (WIDTH+30, 100))

        for e in pygame.event.get():
            if e.type == QUIT:
                pygame.quit()
                exit()
            elif not moving and e.type == MOUSEBUTTONDOWN:
                x, y = e.pos
                # 棋盘内点击
                if not geting_point and move and 0 <= x <= WIDTH and 0 <= y <= WIDTH:
                    for i in range(len(INIT_POS)):  # 遍历出生点
                        tx, ty = i // 5, i % 5
                        if init_pos[tx][ty] and x-R <= init_pos[tx][ty].x <= x+R and y-R <= init_pos[tx][ty].y <= y+R:  # 选择到了棋子
                            mousechess = init_pos[tx][ty]
                            prechess = init_pos[tx][ty]
                            if mousechess.color != turn:
                                continue
                            elif ty == 4:  # 在出发点
                                idx = point+INIT[mousechess.color]-1
                                idx = jump_4(idx)
                                if plane_back(idx):  # 可以移动
                                    mousechess.step -= point+dif
                                    mousechess.start = 1  # 到达棋盘1的部分
                                    dif = 0
                                    init_pos[tx][ty] = False  # 清空原来的飞机
                                    moving = True
                                    update(idx)

                            elif ty < 4 and point >= START_POINT and not init_pos[tx][4]:  # 在出生点
                                mousechess.x, mousechess.y = INIT_POS[tx*5+4]
                                mousechess.idx = 4
                                init_pos[tx][4] = mousechess
                                init_pos[tx][ty] = False  # 清空原来的飞机
                                move = False
                                turn = TURN[turn]
                                point = 0

                    for i in range(len(PLACE)):  # 遍历棋盘
                        if grid[i] and x-R <= grid[i].x <= x+R and y-R <= grid[i].y <= y+R:
                            mousechess, prechess = grid[i], grid[i]
                            if mousechess.color != turn:
                                continue
                            grid[i] = False  # 清空原来的棋子
                            if mousechess.step-point < 6:  # 走终点路径
                                mousechess.step -= point
                                if mousechess.step:  # 未到达终点
                                    mousechess.x, mousechess.y = END_PLACE[mousechess.color][mousechess.step]
                                    mousechess.start, mousechess.idx = 2, mousechess.step
                                    end_pos[mousechess.color][mousechess.step] = mousechess
                                    point = 0
                                else:  # 到达终点
                                    remain_plane[turn] -= 1
                                moving = True
                                turn = TURN[turn]

                            else:  # 在棋盘上继续移动
                                idx, tem_i = i, (i+point) % len(grid)
                                if tem_i == QUICK_PATH[turn]:  # 到达飞机场 +12
                                    tem_i = (tem_i+12) % len(grid)
                                    dif += 12
                                else:
                                    tem_i = jump_4(tem_i)  # 到达同色块, +4
                                    if tem_i == QUICK_PATH[turn]:  # +4 后到达飞机场 +12
                                        tem_i = (tem_i + 12) % len(grid)
                                        dif += 12
                                if plane_back(tem_i):  # 可以移动才会更新idx和step
                                    mousechess.step -= dif+point
                                    dif = 0
                                    idx = tem_i
                                    moving = True
                                update(idx)

                    for i in end_pos:  # 访问终点路劲的字典
                        for j in range(6):
                            if end_pos[i][j] and x-R <= end_pos[i][j].x <= x+R and y-R <= end_pos[i][j].y <= y+R:
                                mousechess = end_pos[i][j]
                                if mousechess.color != turn:
                                    continue

                                tem_i = abs(mousechess.step-point)  # 计算落点坐标
                                if end_pos[i][tem_i]:  # 落点处有棋子, 自己或者同色
                                    continue  # 不能移动直接跳过
                                prechess = end_pos[i][j]
                                end_pos[i][j] = False  # 可以移动, 清空原地棋子
                                mousechess.step = tem_i
                                move, moving = False, True
                                point = 0
                                if mousechess.step:  # 返回
                                    mousechess.x, mousechess.y = END_PLACE[mousechess.color][mousechess.step]
                                    mousechess.idx = mousechess.step
                                    end_pos[mousechess.color][mousechess.step] = mousechess
                                else:
                                    remain_plane[turn] -= 1
                                turn = TURN[turn]

                else:  # 棋盘外点击
                    if not geting_point and not move and WIDTH+30 <= x <= WIDTH+70 and 150 <= y <= 190:  # 点击骰子
                        geting_point = True


        pygame.display.update()
        fpsClock.tick(FPS)

main()

 

最后

本人只是一介菜鸡本科生, 代码若有bug或者不足谢谢各位大佬们指出!

 

标签:draw,Python,pygame,飞行棋,sur,circle,SIZE,RED,Pygame
From: https://www.cnblogs.com/xanderChou/p/17791941.html

相关文章

  • 【视频】支持向量机算法原理和Python用户流失数据挖掘SVM实例|附代码数据
    最近我们被客户要求撰写关于用户流失数据挖掘的研究报告,包括一些图形和统计输出。即使是同一种植物,由于生长的地理环境的不同,它们的特征会有所差异。例如鸢尾花,可分为山鸢尾、杂色鸢尾、维吉尼亚鸢尾。假设此时您得到了一朵鸢尾花,如何判断它属于哪一类呢?支持向量机算法原理·其......
  • Python用正则化Lasso、岭回归预测房价、随机森林交叉验证鸢尾花数据可视化2案例
    机器学习模型的表现不佳通常是由于过度拟合或欠拟合引起的,我们将重点关注客户经常遇到的过拟合情况。过度拟合是指学习的假设在训练数据上拟合得非常好,以至于对未见数据的模型性能造成负面影响。该模型对于训练数据中没有的新实例的泛化能力较差。复杂模型,如随机森林、神经网络和X......
  • Python给你一个字符串,你怎么判断是不是ipv4地址?手写这段代码,并写出测试用例【杭州多测
    ipv4地址的格式:(1~255).(0 ~255).(0 ~255).(0 ~255)1.正则表达式importredefcheck_ip(one_str):compile_ip=re.compile('^(([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$')ifcompile_ip.match(one_str):......
  • 在线问诊 Python、FastAPI、Neo4j — 创建症状节点
    目录症状数据创建节点附学习电子病历中,患者主诉对应的相关检查,得出的诊断以及最后的用药情况。症状一般可以从主诉中提取。症状数据symptom_data.csvCSV中,没有直接一行一个症状,主要想后面将症状=>疾病做关联,最后会在一个Excel中表达所以每行实际对应一个症病,但在创建节点......
  • window安装python3
    win10安装python3a.下载python3网址https://www.python.org/downloads/,点击下图中红框内的按钮下载Python3b.安装python3打开上一步中下载好的文件,显示如下图所示界面。先勾选下图中红色框内的复选框,然后点击紫色框内的“InstallNow”进行安装安装完成后,显示下......
  • 一周学会python2-IDE
    2-IDE2.1集成开发环境的特点与库和框架的简单集成集成面向对象设计语法高亮代码自动完成版本控制除了这些功能,集成开发环境还能为开发人员提供高级调试功能。2.2PyCharmPyCharm是由软件工具开发领域的先驱JetBrains开发的仅用于Python的集成开发环境。最初,JetBrains......
  • 21.8 Python 使用BeautifulSoup库
    BeautifulSoup库用于从HTML或XML文件中提取数据。它可以自动将复杂的HTML文档转换为树形结构,并提供简单的方法来搜索文档中的节点,使得我们可以轻松地遍历和修改HTML文档的内容。广泛用于Web爬虫和数据抽取应用程序中。读者如果需要使用这个库,同样需要执行pip命令用以安装:安装PI......
  • python 字符串str与字典dict转换
    目录python字符串str与字典dict转换字典转字符串字符串转字典带引号不带引号python字符串str与字典dict转换字典转字符串c={'a':'1','b':'1'}b=str(c)print(b,type(b))字符串转字典字符串转字典分两种情况,需要根据你的字符串内容是否带引号决定,如#带引号c={'a......
  • Python 继承和子类示例:从 Person 到 Student 的演示
    继承允许我们定义一个类,该类继承另一个类的所有方法和属性。父类是被继承的类,也叫做基类。子类是从另一个类继承的类,也叫做派生类。创建一个父类任何类都可以成为父类,因此语法与创建任何其他类相同:示例,创建一个名为Person的类,具有firstname和lastname属性以及一个printna......
  • Python 继承和子类示例:从 Person 到 Student 的演示
    继承允许我们定义一个类,该类继承另一个类的所有方法和属性。父类是被继承的类,也叫做基类。子类是从另一个类继承的类,也叫做派生类。创建一个父类任何类都可以成为父类,因此语法与创建任何其他类相同:示例,创建一个名为Person的类,具有firstname和lastname属性以及一个printn......