象棋小游戏(pygame)代码汇总

点击查看象棋小游戏系列目录导航

流程图:
象棋小游戏(pygame)代码汇总_第1张图片
效果图:
象棋小游戏(pygame)代码汇总_第2张图片
主函数代码:

import pygame
from pygame.locals import *
import sys
import time
import traceback
import ChessPieces
import random


# 初始化
pygame.init()
try:
    pygame.mixer.init()
except:
    print("您没有音频设备!")
    raise Exception

bg_size = width,height = 474,663
screen = pygame.display.set_mode(bg_size)
bg_rect = screen.get_rect()
pygame.display.set_caption("象棋小游戏")

# 初始化音乐
pygame.mixer.music.load('./sounds/bg.ogg')

# 初始化图片

chess_pan_img = pygame.image.load('./pic/chess_bg.png').convert()
chess_select1_img = pygame.image.load('./pic/selected.png').convert()
chess_select2_img = pygame.image.load('./pic/selected2.png').convert()

# 初始化移动,翻棋子,吃棋子
choosed = False

# 初始化字体
my_font = pygame.font.Font('./font/simhei.ttf',25)

# 定义颜色
WHITE = (255,255,255)
BLACK = (0,0,0)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)

# 象棋 1*将 + 2*(士+象+马+车+炮)+ 5 * 兵 = 一共16子*2 = 32 子
chess_class = [] #[shi_chess,xiang_chess,ma_chess,che_chess,pao_chess]*2
for j in range(2):
    for i in range(2):
        chess_class.append(ChessPieces.ShiChess(bg_rect))
        chess_class.append(ChessPieces.XiangChess(bg_rect))
        chess_class.append(ChessPieces.MaChess(bg_rect))
        chess_class.append(ChessPieces.CheChess(bg_rect))
        chess_class.append(ChessPieces.PaoChess(bg_rect))

    chess_class.append(ChessPieces.JiangChess(bg_rect))
    for i in range(5):
        chess_class.append(ChessPieces.ZuChess(bg_rect))

# 一半的棋子为黑色
for i in range(len(chess_class)//2):
    chess_class[i].role = ChessPieces.BLACK_ROLE

running = True

# 首先翻牌的为type 为 0
player_role = ChessPieces.BLACK_ROLE

def getChessList():
    # 产生随机数 0-31
    resultList = random.sample(range(0,32), 32);
    j = 0;
    #print('chess_class 的长度 %d  resultList 的长度 %d' % (len(chess_class),len(resultList)))
    for i in resultList:
        #print((i,j,chess_class[j].type))
        chess_class[j].position = (86+(i%4)*90, \
                                   66+((i//4))*71)
        chess_class[j].rect.left = 86+(i%4)*90
        chess_class[j].rect.top = 66+((i//4))*71
        #print(chess_class[j].position)
        j+=1
    return chess_class

def is_chess_clicked(chess_list,event):
    for each in chess_list:
        if (each.rect.collidepoint(event.pos)):
            return each
    return None

def operation_completed():
    global player_role
    if player_role == ChessPieces.BLACK_ROLE:
        player_role = ChessPieces.RED_ROLE
    else:
        player_role = ChessPieces.BLACK_ROLE

def draw_text(text,font_color,center):
    mytext = my_font.render(text, True, font_color)
    text_rect = mytext.get_rect()
    text_rect.center = center
    screen.blit(mytext,text_rect)

def main():
    global player_role
    overturn_count = 0
    # 初始化音乐
    pygame.mixer.music.play(-1)
    clock = pygame.time.Clock()
    # 获得打乱之后,并且有位置信息的对象数组
    chess_list = getChessList()
    selected_img_rect = chess_select1_img.get_rect()
    selected_img_rect.left = -20
    select_chess = None
    #is_start = False

    player1_role = ChessPieces.BLACK_ROLE
    player2_role = ChessPieces.BLACK_ROLE

    player1_color = BLACK
    player2_color = BLACK
    global running

    while running:

        # 首先绘制棋盘
        screen.blit(chess_pan_img, (10, 10))

        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN:
                if event.button == 1:# 按下鼠标左键
                    #print(event.pos)
                    selected = is_chess_clicked(chess_list,event)
                    #print(selected)
                    if selected is not None:
                        # 本次点击点击到了棋子
                        if selected.state == ChessPieces.CHOOSED_STATE:
                            pass
                        elif selected.state == ChessPieces.ACTIVE_STATE:
                            if player_role == selected.role:
                                # 当前用户点击自己的棋子
                                select_chess = selected
                                selected.state = ChessPieces.ACTIVE_STATE
                                selected_img_rect.left = selected.rect.left + 4
                                selected_img_rect.top = selected.rect.top + 4
                            else:
                                # 当前用户点击别人的棋子
                                if select_chess is not None:
                                    # 判断是否可以吃该子
                                    if select_chess.eat(selected,event.pos,chess_list):
                                        operation_completed()
                                        select_chess = None

                        elif selected.state == ChessPieces.HIDDEN_STATE:
                            # 翻转
                            selected.state = ChessPieces.ACTIVE_STATE
                            selected_img_rect.left = selected.rect.left + 4
                            selected_img_rect.top = selected.rect.top + 4
                            #is_start = True  暂时认为该标签无用
                            if overturn_count == 0:
                                player_role = selected.role
                            # 统计翻转的次数
                            overturn_count += 1
                            # 如果当前翻出的是对方的棋子,则 对方自动选中该子
                            if selected.role is not player_role:
                                select_chess = selected
                            else:
                                select_chess = None
                            # 翻转之后相当于一次操作完成
                            operation_completed()
                    else:
                        # 本次点击没有点击棋子,只是点击到了棋盘
                        print('本次点击没有点击棋子,只是点击到了棋盘')
                        print(select_chess)

                        if select_chess is not None:
                            # 判断被选中的棋子是否可以移动到当前位置
                            if select_chess.move(event.pos):
                                operation_completed()
                                select_chess=None

        # 绘制棋子
        for each in chess_list:
            #pass
            if each.state is not ChessPieces.DEAD_STATE:
                screen.blit(each.getImage(each.role),each.rect)
            #print(each.position)
        #绘制被选中的图标
        #print(player_role)
        if player_role == ChessPieces.BLACK_ROLE:
            screen.blit(chess_select1_img, selected_img_rect)
        else:
            screen.blit(chess_select2_img, selected_img_rect)

        # 绘制当前玩家提示
        marked_words = ''
        font_color = RED
        if overturn_count == 1:
            print('---------------------------------111111')
            player1_role = player_role
            if player1_role == ChessPieces.BLACK_ROLE:
                player1_color = BLACK
            else:
                player1_color = RED

        if overturn_count == 2:
            print('---------------------------------222222')
            player2_role = player_role
            if player2_role == ChessPieces.BLACK_ROLE:
                player2_color = BLACK
            else:
                player2_color = RED

        if player_role == player1_role:
            marked_words = '玩家1'
            font_color = player1_color
        else:
            marked_words = '玩家2'
            font_color = player2_color
        # 确定颜色
        if overturn_count == 0:
            marked_words = '未选定颜色,请玩家1翻牌'
            font_color = GREEN

        draw_text(marked_words,font_color,(width // 2, 25))

        # 判断游戏是否结束
        # 方法,计算棋盘上存活的棋子数量,如果为零就,停止
        black_count = 0
        red_count = 0
        for each in chess_list:
            if each.state == ChessPieces.ACTIVE_STATE or each.state == ChessPieces.HIDDEN_STATE:
                if each.role == ChessPieces.BLACK_ROLE:
                    black_count +=1
                else:
                    red_count+=1

        if black_count == 0:
            # 红方胜利
            draw_text('红方胜利!',RED,(width//2,height//2))
        elif red_count ==0:
            # 黑方胜利
            draw_text('黑方胜利',BLACK,(width//2,height//2))

        pygame.display.flip()
        clock.tick(60)

if __name__ == "__main__":
    try:
       main()
    except SystemExit:
        print("游戏正常退出")
    except:
        print("游戏退出异常")
        traceback.print_exc()
        pygame.quit()
        input()

象棋类代码:

import pygame
from pygame.locals import *
import math

RED_ROLE = 0
BLACK_ROLE = 1

HIDDEN_STATE = 3
ACTIVE_STATE = 4
DEAD_STATE = 5
CHOOSED_STATE = 6

JIANG_TYPE = 11
SHI_TYPE = 12
XIANG_TYPE = 13
CHE_TYPE = 14
MA_TYPE = 15
PAO_TYPE = 16
ZU_TYPE = 17

to_left = (-90,0)
to_right = (90,0)
to_up = (0,-66)
to_down = (0,66)

bg_image = pygame.image.load('./pic/blankchess.png')

def can_eat(typea,typeb):
    if typea in (JIANG_TYPE,PAO_TYPE):
        return True
    elif typea in (SHI_TYPE,XIANG_TYPE,MA_TYPE,CHE_TYPE):
        if typea <= typeb:
            return True
    elif typea == ZU_TYPE:
        if typeb == JIANG_TYPE or typeb == ZU_TYPE:
            return True
    return False

def can_move_one_step(self,pos):
    # 首先判断移动方向,然后进行移动
    # 判断移动方向
    # 判断是否在棋盘之内
    if pos[0] < 80 or pos[0] > 399 or pos[1] < 63 or pos[1] > 596:
        print("点击超出了范围")
    elif self.rect.left - 90 < pos[0] < self.rect.left - 50 and self.rect.top < pos[1] < self.rect.top + 50:
        # 需要向左移动一位
        self.rect.left -= 90
        print('需要向左移动一位')
        return True
    elif self.rect.left < pos[0] < self.rect.left + 40 and self.rect.top - 70 < pos[1] < self.rect.top - 40:
        # 需要向上移动一位
        self.rect.top -= 71
        print('需要向上移动一位')
        return True
    elif self.rect.left + 90 < pos[0] < self.rect.left + 130 and self.rect.top < pos[1] < self.rect.top + 40:
        # 需要向右移动一位
        self.rect.left += 90
        print('需要向右移动一位')
        return True
    elif self.rect.left < pos[0] < self.rect.left + 40 and self.rect.top + 70 < pos[1] < self.rect.top + 110:
        # 需要向下移动一位
        self.rect.top += 71
        print('需要向下移动一位')
        return True

#-----------------------------------------------------------------------------------------1111 将
class JiangChess:
    def __init__(self,rect):
        self.r_image = pygame.image.load('./pic/rshuai.png')
        self.b_image = pygame.image.load('./pic/bjiang.png')
        self.position = x,y = 86,66
        self.state = HIDDEN_STATE
        self.type = JIANG_TYPE
        self.role = RED_ROLE
        self.rect = self.b_image.get_rect()


    def getImage(self,role):
        if self.state == HIDDEN_STATE:
            return bg_image
        elif self.state == DEAD_STATE:
            return -1
        else:
            if role == RED_ROLE:
                return self.r_image
            elif role == BLACK_ROLE:
                return self.b_image
            else:
                print('传入参数有误,无法判断是红方还是黑方!')
                return -1

    def move(self,pos):
        return can_move_one_step(self,pos)

    # 将 可以吃 其它所有
    # 是否可吃需要满足两个条件
    # 1、是否满足该子的行走规律
    # 2、是否满足该子的吃子规律
    def eat(self,enemy_chess,pos,chess_list):
        if can_eat(self.type,enemy_chess.type):
            if self.move(pos):
                self.rect.left = enemy_chess.rect.left
                self.rect.top = enemy_chess.rect.top
                enemy_chess.state = DEAD_STATE
                enemy_chess.rect.left = -100
                enemy_chess.rect.top = -100
                return True
            else:
                print('点击位置不在范围内,无法吃子')
        return False

#----------------------------------------------------------------------------------------2222 士
class ShiChess:
    def __init__(self,rect):
        self.r_image = pygame.image.load('./pic/rshi.png')
        self.b_image = pygame.image.load('./pic/bshi.png')
        self.position = x,y = 86,66
        self.state = HIDDEN_STATE
        self.type = SHI_TYPE
        self.role = RED_ROLE
        self.rect = self.b_image.get_rect()

    def getImage(self,role):
        if self.state == HIDDEN_STATE:
            return bg_image
        elif self.state == DEAD_STATE:
            return -1
        else:
            if role == RED_ROLE:
                return self.r_image
            elif role == BLACK_ROLE:
                return self.b_image
            else:
                print('传入参数有误,无法判断是红方还是黑方!')
                return -1

    def move(self,pos):
        return can_move_one_step(self,pos)

    # 将 可以吃 其它所有
    # 是否可吃需要满足两个条件
    # 1、是否满足该子的行走规律
    # 2、是否满足该子的吃子规律
    def eat(self,enemy_chess,pos,chess_list):
        if can_eat(self.type,enemy_chess.type):
            if self.move(pos):
                self.rect.left = enemy_chess.rect.left
                self.rect.top = enemy_chess.rect.top
                enemy_chess.state = DEAD_STATE
                enemy_chess.rect.left = -100
                enemy_chess.rect.top = -100
                return True
            else:
                print('点击位置不在范围内,无法吃子')
        return False

#----------------------------------------------------------------------------------------3333 象
class XiangChess:
    def __init__(self,rect):
        self.r_image = pygame.image.load('./pic/rxiang.png')
        self.b_image = pygame.image.load('./pic/bxiang.png')
        self.position = x,y = 86,66
        self.state = HIDDEN_STATE
        self.type = XIANG_TYPE
        self.role = RED_ROLE
        self.rect = self.b_image.get_rect()

    def getImage(self,role):
        if self.state == HIDDEN_STATE:
            return bg_image
        elif self.state == DEAD_STATE:
            return -1
        else:
            if role == RED_ROLE:
                return self.r_image
            elif role == BLACK_ROLE:
                return self.b_image
            else:
                print('传入参数有误,无法判断是红方还是黑方!')
                return -1

    def move(self,pos):
        return can_move_one_step(self,pos)

    # 将 可以吃 其它所有
    # 是否可吃需要满足两个条件
    # 1、是否满足该子的行走规律
    # 2、是否满足该子的吃子规律
    def eat(self,enemy_chess,pos,chess_list):
        if can_eat(self.type,enemy_chess.type):
            if self.move(pos):
                self.rect.left = enemy_chess.rect.left
                self.rect.top = enemy_chess.rect.top
                enemy_chess.state = DEAD_STATE
                enemy_chess.rect.left = -100
                enemy_chess.rect.top = -100
                return True
            else:
                print('点击位置不在范围内,无法吃子')
        return False

#----------------------------------------------------------------------------------------4444 马
class MaChess:
    def __init__(self,rect):
        self.r_image = pygame.image.load('./pic/rma.png')
        self.b_image = pygame.image.load('./pic/bma.png')
        self.position = x,y = 86,66
        self.state = HIDDEN_STATE
        self.type = MA_TYPE
        self.role = RED_ROLE
        self.rect = self.b_image.get_rect()


    def getImage(self,role):
        if self.state == HIDDEN_STATE:
            return bg_image
        elif self.state == DEAD_STATE:
            return -1
        else:
            if role == RED_ROLE:
                return self.r_image
            elif role == BLACK_ROLE:
                return self.b_image
            else:
                print('传入参数有误,无法判断是红方还是黑方!')
                return -1

    def move(self,pos):
        return can_move_one_step(self,pos)

    # 将 可以吃 其它所有
    # 是否可吃需要满足两个条件
    # 1、是否满足该子的行走规律
    # 2、是否满足该子的吃子规律
    def eat(self,enemy_chess,pos,chess_list):
        if can_eat(self.type,enemy_chess.type):
            if self.move(pos):
                self.rect.left = enemy_chess.rect.left
                self.rect.top = enemy_chess.rect.top
                enemy_chess.state = DEAD_STATE
                enemy_chess.rect.left = -100
                enemy_chess.rect.top = -100
                True
            else:
                print('点击位置不在范围内,无法吃子')
        return False

#-----------------------------------------------------------------------------------------5555 车
class CheChess:
    def __init__(self,rect):
        self.r_image = pygame.image.load('./pic/rche.png')
        self.b_image = pygame.image.load('./pic/bche.png')
        self.position = x,y = 86,66
        self.state = HIDDEN_STATE
        self.type = CHE_TYPE
        self.role = RED_ROLE
        self.rect = self.b_image.get_rect()


    def getImage(self,role):
        if self.state == HIDDEN_STATE:
            return bg_image
        elif self.state == DEAD_STATE:
            return -1
        else:
            if role == RED_ROLE:
                return self.r_image
            elif role == BLACK_ROLE:
                return self.b_image
            else:
                print('传入参数有误,无法判断是红方还是黑方!')
                return -1

    def move(self,pos):
        return can_move_one_step(self,pos)

    # 将 可以吃 其它所有
    # 是否可吃需要满足两个条件
    # 1、是否满足该子的行走规律
    # 2、是否满足该子的吃子规律
    def eat(self,enemy_chess,pos,chess_list):
        if can_eat(self.type,enemy_chess.type):
            if self.move(pos):
                self.rect.left = enemy_chess.rect.left
                self.rect.top = enemy_chess.rect.top
                enemy_chess.state = DEAD_STATE
                enemy_chess.rect.left = -100
                enemy_chess.rect.top = -100
                return True
            else:
                print('点击位置不在范围内,无法吃子')
        return False
#----------------------------------------------------------------------------------------5555 炮
class PaoChess:
    def __init__(self,rect):
        self.r_image = pygame.image.load('./pic/rpao.png')
        self.b_image = pygame.image.load('./pic/bpao.png')
        self.position = x,y = 86,66
        self.state = HIDDEN_STATE
        self.type = PAO_TYPE
        self.role = RED_ROLE
        self.rect = self.b_image.get_rect()


    def getImage(self,role):
        if self.state == HIDDEN_STATE:
            return bg_image
        elif self.state == DEAD_STATE:
            return -1
        else:
            if role == RED_ROLE:
                return self.r_image
            elif role == BLACK_ROLE:
                return self.b_image
            else:
                print('传入参数有误,无法判断是红方还是黑方!')
                return -1

    def move(self,pos):
       return can_move_one_step(self,pos)

    # 将 可以吃 其它所有
    # 是否可吃需要满足两个条件
    # 1、是否满足该子的行走规律
    # 2、是否满足该子的吃子规律
    def eat(self,enemy_chess,pos,chess_list):
        if can_eat(self.type,enemy_chess.type):
            if self.can_move_and_eat(enemy_chess,pos,chess_list):
                self.rect.left = enemy_chess.rect.left
                self.rect.top = enemy_chess.rect.top
                enemy_chess.state = DEAD_STATE
                enemy_chess.rect.left = -100
                enemy_chess.rect.top = -100
                return True
            else:
                print('点击位置不在范围内,无法吃子')
        return False

    def can_move_and_eat(self,enemy_chess,pos,chess_list):
        # 首先判断,pos 和当前棋子是否在同一行或同一列
        # 然后判断,两个棋子之间有几个棋子
        if self.rect.left -10 < enemy_chess.rect.left < self.rect.left + 50:
            # 说明在同一列
            count = 0
            for each in chess_list:
                if self.rect.left -10 < each.rect.left < self.rect.left + 50 \
                        and min(self.rect.center[1],enemy_chess.rect.center[1]) < \
                        each.rect.center[1] < max(self.rect.center[1],enemy_chess.rect.center[1]):
                    count+=1
            if count==1:
                return True
        elif self.rect.top -10 < enemy_chess.rect.top < self.rect.top +50:
            # 说明在同一行
            count = 0
            for each in chess_list:
                if self.rect.top -10 < each.rect.top < self.rect.top +50 and \
                        min(self.rect.center[0], enemy_chess.rect.center[0]) < \
                            each.rect.center[0] < max(self.rect.center[0], enemy_chess.rect.center[0]):
                    count += 1
            if count==1:
                return True
        return False

#----------------------------------------------------------------------------------------5555 卒
class ZuChess:
    def __init__(self,rect):
        self.r_image = pygame.image.load('./pic/rbing.png')
        self.b_image = pygame.image.load('./pic/bzu.png')
        self.position = x,y = 86,66
        self.state = HIDDEN_STATE
        self.type = ZU_TYPE
        self.role = RED_ROLE
        self.rect = self.b_image.get_rect()


    def getImage(self,role):
        if self.state == HIDDEN_STATE:
            return bg_image
        elif self.state == DEAD_STATE:
            return -1
        else:
            if role == RED_ROLE:
                return self.r_image
            elif role == BLACK_ROLE:
                return self.b_image
            else:
                print('传入参数有误,无法判断是红方还是黑方!')
                return -1

    def move(self,pos):
        return can_move_one_step(self,pos)

    # 将 可以吃 其它所有
    # 是否可吃需要满足两个条件
    # 1、是否满足该子的行走规律
    # 2、是否满足该子的吃子规律
    def eat(self,enemy_chess,pos,chess_list):
        if can_eat(self.type,enemy_chess.type):
            if self.move(pos):
                self.rect.left = enemy_chess.rect.left
                self.rect.top = enemy_chess.rect.top
                enemy_chess.state = DEAD_STATE
                enemy_chess.rect.left = -100
                enemy_chess.rect.top = -100
                return True
            else:
                print('点击位置不在范围内,无法吃子')
        return False

你可能感兴趣的:(pygame,象棋小游戏)