Python小游戏(附带详细注释)

import pygame
from pygame.locals import *
import graphics
import sys
import time
SIZE = 16   #多少条线
UNIT = 35
BORDER_WIDTH = 50 #边框宽度
C_WRITE = (255,255,255)#纯白
C_BLACK = (0,0,0)
screen = None
chess_map = []

his_stack = []#颜色,X,Y坐标,坐标从(0,0)开始


# 获取当前状态
# 0 ~ 未开局
# 1 ~ 等待黑棋落子
# 2 ~ 等待白棋落子
# 3 ~ 结束(一方获胜)
status = 2
winner = 0.
#游戏初始化
def game_init():
    pygame.init()
    global screen,chess_map,his_stack,sound_black,sound_white,sound_win,\
    sound_error

    #初始化二维map
    #0~无棋子,1~黑旗,-1~白旗
    chess_map = [[0 for y in range(0,SIZE)] for x in range(0,SIZE)]
    #设置背景显示格式,横是X,竖是Y
    screen = pygame.display.set_mode((2*BORDER_WIDTH+UNIT*(SIZE-1),
                                      2*BORDER_WIDTH+UNIT*(SIZE-1)))
    #设置标题
    pygame.display.set_caption("五子棋")
    sy_img = pygame.image.load('img.png')

         #(0,0)是对其的坐标
    screen.blit(sy_img,(0,0))

     # 设置标题
    pygame.display.set_caption("五子棋")
    sound_black = pygame.mixer.Sound('1.wav')
    sound_white = pygame.mixer.Sound('2.wav')
    sound_win = pygame.mixer.Sound('3.wav')
    sound_error = pygame.mixer.Sound('4.wav')
#绘制棋盘
def draw_map():
    #设置字体
    s_font= pygame.font.SysFont('arial',16)

    #行
    for row in range(SIZE):
         pygame.draw.line(screen,C_BLACK,
                          (BORDER_WIDTH,BORDER_WIDTH+UNIT*row),
                          (BORDER_WIDTH+UNIT*(SIZE-1),BORDER_WIDTH+UNIT*row))
         #设置字母下标,ord函数返回ASCII数值
         s_surface = s_font.render(chr(ord('A')+row),True,C_BLACK)
         screen.blit(s_surface,(BORDER_WIDTH+UNIT*row-4,BORDER_WIDTH-25))
    #列
    for col in range(SIZE):
         pygame.draw.line(screen,C_BLACK,
                          (BORDER_WIDTH+UNIT*col,BORDER_WIDTH),
                          (BORDER_WIDTH+UNIT*col,BORDER_WIDTH+UNIT*(SIZE-1)))
         s_surface = s_font.render(f'{col}', True, C_BLACK)
         screen.blit(s_surface, (BORDER_WIDTH-20, BORDER_WIDTH+UNIT*col-8))

# 判断输赢的算法: 只需要判断当前落子相关的四条直线(横、竖、左斜、右斜),是否形成5个连子。
# 将直线上的落子(~ 1,白~ -1),依次相加,连续的子绝对值之和达到5,即可判定为胜利
def __check_winner_():
        tmp = 0
        last_step = his_stack[-1]
        # 竖向直线, x 固定
        a=last_step[1]
        b=last_step[2]
        for y in range(0, SIZE):
            # 必须是连续的,last_step[1]为上一步的X坐标
            tmp = 0
            if abs(chess_map[a][y-1]) > 0:

              tmp += abs(chess_map[a][y-1])
            if  tmp >= 5:

                tmp = 0
                for x in range(0, SIZE):
                 # 必须是连续的,last_step[2]为上一步的Y坐标
                    if abs(chess_map[x-1][b]) > 0:

                        tmp += abs(chess_map[x-1][b])
                    if abs(tmp) >= 5:
                        return last_step[0]



        # # 横向直线, y 固定
        # tmp = 0
        # for x in range(0, SIZE):
        #     # 必须是连续的,last_step[2]为上一步的Y坐标
        #     if x > 0 \
        #             and chess_map[x][b] != chess_map[x - 1][b]:
        #         tmp = 0
        #     tmp += chess_map[x][b]
        #     if abs(tmp) >= 5:
        #         return last_step[0]

        # 右斜直线,计算出左上角顶点的坐标。然后x,y都递增,到达最右下角顶点。
        tmp = 0
        min_dist = min(last_step[1], last_step[2])
        top_point = [last_step[1] - min_dist, last_step[2] - min_dist]
        for incr in range(0, SIZE):
            # 不能超出棋盘边界
            if top_point[0] + incr > SIZE - 1 \
                    or top_point[1] + incr > SIZE - 1:
                break
            # 必须是连续的
            if incr > 0 \
                    and chess_map[top_point[0] + incr][top_point[1] + incr] \
                    != chess_map[top_point[0] + incr - 1][top_point[1] + incr - 1]:
                tmp = 0
            tmp += chess_map[top_point[0] + incr][top_point[1] + incr]
            if abs(tmp) >= 5:
                return last_step[0]

        # 左斜直线,计算出右上角顶点的坐标。然后x递减、y递增,到达最左下角顶点。
        tmp = 0
        min_dist = min(SIZE - 1 - last_step[1], last_step[2])
        top_point = [last_step[1] + min_dist, last_step[2] - min_dist]
        for incr in range(0, SIZE):
            # 不能超出棋盘边界
            if top_point[0] - incr < 0 \
                    or top_point[1] + incr > SIZE - 1:
                break
            # 必须是连续的
            if incr > 0 \
                    and chess_map[top_point[0] - incr][top_point[1] + incr] \
                    != chess_map[top_point[0] - incr + 1][top_point[1] + incr - 1]:
                tmp = 0
            tmp += chess_map[top_point[0] - incr][top_point[1] + incr]
            if abs(tmp) >= 5:
                return last_step[0]

        return 0

#判断·是否结束
def __check_end():
        # global  winner
        # # 赢了,winner记录谁赢了
        winner = __check_winner_()

        if winner != 0:
            return 1
        # 未结束
        return 0
def move(pos):
    #X,Y不能越界
    global status
    if pos[0]<BORDER_WIDTH or pos[0]>BORDER_WIDTH+UNIT*(SIZE-1)\
            or pos[1]<BORDER_WIDTH or pos[1]>BORDER_WIDTH+UNIT*(SIZE-1):
        sound_error.play()
        return
    x = round((pos[0] - BORDER_WIDTH)/UNIT)
    y = round((pos[1] - BORDER_WIDTH) / UNIT)
    #已经有棋子
    if chess_map[x][y]!= 0:
        return
    #加音效
    if status == 1:
       sound_black.play()
    else:
        sound_white.play()

    t = 1 if status == 1 else -1
    his_stack.append([t,x,y])
    #表示这个位置新加了棋子
    chess_map[x][y] = t

    status = 2 if status == 1 else 1
    pygame.draw.circle(screen, t,
                       (BORDER_WIDTH + UNIT * x, BORDER_WIDTH + UNIT * y),
                       int(UNIT / 2.5))
    pygame.display.flip()
    if __check_end() == 1:
        sound_win.play()
        time.sleep(3)
        sys.exit()
#游戏运行
def game_run():
    while True:
        for event in pygame.event.get():   #监听用户事件
            if event.type == pygame.QUIT:   # 判断用户是否点击了关闭按钮
                exit()
            if event.type == MOUSEBUTTONUP:
                move(event.pos)
        # 刷新画面
        pygame.display.flip()
if __name__== '__main__':
    game_init()
    draw_map()
    game_run()

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当然,这是一个简单的Python烟花代码,附带详细注释: ```python import pygame import random # 初始化pygame pygame.init() # 设置屏幕尺寸 screen_width = 800 screen_height = 600 screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("Fireworks") # 定义烟花的颜色 colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255), (0, 255, 255)] # 定义烟花的粒子数量 num_particles = 100 # 定义烟花粒子的大小范围 min_size = 1 max_size = 5 # 定义烟花粒子的速度范围 min_speed = 1 max_speed = 5 # 定义烟花爆炸的半径范围 min_radius = 20 max_radius = 50 # 定义烟花爆炸的持续时间 explosion_time = 50 # 定义烟花的类 class Firework: def __init__(self): self.x = random.randint(0, screen_width) self.y = screen_height self.color = random.choice(colors) self.size = random.randint(min_size, max_size) self.speed = random.randint(min_speed, max_speed) self.radius = random.randint(min_radius, max_radius) self.particles = [] for _ in range(num_particles): dx = random.uniform(-1, 1) dy = random.uniform(-1, 1) speed = random.uniform(0, self.speed) self.particles.append([dx * speed, dy * speed]) def explode(self): for _ in range(explosion_time): for particle in self.particles: particle[0] *= 0.98 particle[1] *= 0.98 self.x += particle[0] self.y += particle[1] pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.size) pygame.display.update() pygame.time.delay(10) # 创建烟花并让其爆炸 firework = Firework() firework.explode() # 游戏循环 running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False pygame.display.flip() # 退出pygame pygame.quit() ``` 这段代码使用了Pygame库来实现烟花效果。它首先初始化Pygame并设置屏幕尺寸。然后定义了烟花的颜色、粒子数量、大小范围、速度范围、爆炸半径范围和持续时间。 接下来定义了一个Firework类,包含烟花的初始位置、颜色、大小、速度、爆炸半径和粒子列表。在类的初始化方法中,随机生成粒子的速度和方向,并将它们加入粒子列表。 类中还定义了一个explode方法,用于让烟花爆炸。在爆炸过程中,粒子的速度逐渐减小,同时更新烟花的位置并绘制粒子的圆形。爆炸过程通过循环进行,并使用pygame.draw.circle函数绘制圆形。 最后,创建一个烟花实例并调用其explode方法来触发爆炸效果。然后进入游戏循环,等待退出事件。 希望这个代码能满足你的需要!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小王子y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值