Pygame实现自定义的生命游戏

仅是尝试,还有待提高(v0)。

主要目的:想了解如何交互,获取鼠标点击位置并进行相应操作。

此次生命游戏的规则:
每一轮用户通过鼠标点击增加一个细胞;
所有细胞向其八邻域中的一个分裂新细胞;
细胞的八邻域若多于3个细胞,则认为营养不足、毒素增多,该细胞凋亡;
细胞最多只能存活三轮。


def count_score(current_cells):
    '''
    现在存在的细胞总数
    '''
    return np.sum(current_cells)

def add_new_cell(x,y,current_cells):
    '''
    加入一个新细胞
    '''
    current_cells[x][y] = 1

def add_cells_lives(current_cells,cells_life):
    '''
    对所有细胞增加细胞周期
    '''
    for i in range(len(cells_life)):
        for j in range(len(cells_life[0])):
            if(current_cells[i][j]==1):
                cells_life[i][j] = cells_life[i][j]+1

def cells_death1(current_cells,cells_life):
    '''
    进行细胞凋亡操作(细胞活多于3周期,则死亡)
    '''
    for i in range(len(cells_life)):
        for j in range(len(cells_life[0])):
            if(cells_life[i][j] > 3):
                cells_life[i][j] = 0
                current_cells[i][j] = 0

def cells_death2(current_cells,cells_life):
    '''
    进行细胞凋亡操作(细胞周围八邻域多于3个细胞,则死亡)
    '''
    xn = [-1,-1,-1,0,1,1,1,0]
    yn = [1,0,-1,-1,-1,0,1,1]
    for i in range(len(current_cells)):
        for j in range(len(current_cells[0])):
            if(current_cells[i][j]==1):
                count_n_cells = 0
                for k in range(8):
                    xx = i+xn[k]
                    yy = j+yn[k]
                    if(xx>=0 and xx<len(current_cells) and yy>=0 and yy<len(current_cells[0]) and current_cells[xx][yy]==1):
                        count_n_cells += 1
                if(count_n_cells>3):
                    current_cells[i][j] = 0
                    cells_life[i][j] = 0

def cells_division(current_cells):
    '''
    细胞分裂(细胞周围如果有空位,则分裂)(简便起见,先检测到哪就往哪分裂)
    '''
    xn = [-1,-1,-1,0,1,1,1,0]
    yn = [1,0,-1,-1,-1,0,1,1]
    for i in range(len(current_cells)):
        for j in range(len(current_cells[0])):
            if(current_cells[i][j]==1):
                for k in range(8):
                    xx = i+xn[k]
                    yy = j+yn[k]
                    if(xx >=0 and xx<len(current_cells) and yy>=0 and yy<len(current_cells[0]) and current_cells[xx][yy]==0):
                        current_cells[xx][yy] = 2
                        break
    for i in range(len(current_cells)):
        for j in range(len(current_cells[0])):
            if(current_cells[i][j]==2):
                current_cells[i][j] = 1

def one_circle(x,y,current_cells,cells_life):
    '''
    一次交互,增加细胞,细胞分裂,细胞凋亡
    '''
    if(current_cells[x][y]==1):
        return
    else:
        add_new_cell(x, y, current_cells)
        cells_division(current_cells)
        add_cells_lives(current_cells,cells_life)
        cells_death1(current_cells,cells_life)
        cells_death2(current_cells,cells_life)

        score = count_score(current_cells)
        print(score)

WIDTH = 700
HEIGHT = 700
NUMGRID = 16
GRIDSIZE = 36
XMARGIN = (WIDTH - NUMGRID*GRIDSIZE) // 2
YMARGIN = (HEIGHT - NUMGRID*GRIDSIZE) // 2

score = 0
current_cells = np.zeros((NUMGRID,NUMGRID))
cells_life = np.zeros((NUMGRID,NUMGRID))

用于判断鼠标点击的方格位置:


BOARDRECTS = []
for x in range(WIDTH):
    BOARDRECTS.append([])
    for y in range(HEIGHT):
        r = pygame.Rect((XMARGIN+x*GRIDSIZE),(YMARGIN+y*GRIDSIZE),GRIDSIZE,GRIDSIZE)
        BOARDRECTS[x].append(r)

def CheckValidClick(pos):
    '''
    检查点击是否在面板上
    '''
    for x in range(WIDTH):
        for y in range(HEIGHT):
            if(BOARDRECTS[x][y].collidepoint(pos[0],pos[1])):
                ans = [x,y]
                return ans
    return None

准备细胞图片和输出信息:


CELL = pygame.image.load('C:\\Users\\Administrator\\Desktop\\cell.jpg')
CELL = pygame.transform.scale(CELL, (GRIDSIZE-2,GRIDSIZE-2))

CELLNUMS = 0
ROUND = 0
SCORE = 0
POS1 = [20,20]
POS2 = [300,20]
POS3 = [520,20]
pygame.font.init()
font1 = pygame.font.Font(None,30)

pygame.init()
screen = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption('Life Game')

screen.fill((255,255,220))
for x in range(NUMGRID):
    for y in range(NUMGRID):
        rect = pygame.Rect((XMARGIN+x*GRIDSIZE,YMARGIN+y*GRIDSIZE,GRIDSIZE,GRIDSIZE))
        pygame.draw.rect(screen,(255,165,0),rect,2)
        pygame.display.flip()
        pygame.display.update()
CLICKX = None
CLICKY = None

while True:

    screen.fill((255,255,220))
    for x in range(NUMGRID):
        for y in range(NUMGRID):
            rect = pygame.Rect((XMARGIN+x*GRIDSIZE,YMARGIN+y*GRIDSIZE,GRIDSIZE,GRIDSIZE))
            pygame.draw.rect(screen,(255,165,0),rect,2)

    ClickedSpace = None
    for event in pygame.event.get():
        if(event.type==pygame.QUIT):
            pygame.quit()
            sys.exit()
        elif(event.type==pygame.MOUSEBUTTONDOWN):
            CLICKX,CLICKY = event.pos
            print(CLICKX,CLICKY)
        elif(event.type==pygame.MOUSEBUTTONUP):
            if(event.pos==(CLICKX,CLICKY)):
                ClickedSpace = CheckValidClick(event.pos)
                print('ClickedSpace: ',ClickedSpace)

    if(ClickedSpace!=None):
        if(current_cells[ClickedSpace[0]][ClickedSpace[1]]==1):
            continue
        one_circle(ClickedSpace[0],ClickedSpace[1], current_cells, cells_life)
        CELLNUMS = count_score(current_cells)
        ROUND = ROUND+1
        SCORE = CELLNUMS + ROUND
        surface1 = font1.render('Cellnums: %d'%CELLNUMS,1,(125,125,255))
        surface2 = font1.render('Round: %d'%ROUND,1,(125,125,255))
        surface3 = font1.render('Score: %d'%SCORE,1,(125,125,255))
        screen.blit(surface1,POS1)
        screen.blit(surface2,POS2)
        screen.blit(surface3,POS3)
        pygame.display.update()

        for i in range(NUMGRID):
            for j in range(NUMGRID):
                if(current_cells[i][j]==1):
                    screen.blit(CELL,(BOARDRECTS[i][j][0],BOARDRECTS[i][j][1]))
                    pygame.display.update()
                    pygame.display.flip()

1、游戏的规则可以继续改进:比如只改变点击点周围的细胞的情况等。不管怎么点都不会得到一个差的结果,规则设置得没有让人思考的欲望;
2、采用每个循环都重新绘制,可以寻找动态显示出细胞分裂、凋亡的方法。

1、pygame需要在 循环中不断 获取事件不断更新,以达到动态游戏的目的。所以,如果没有这一步,窗口会显示无响应。
2、显示图像:先创建surface,再blit,再update。
3、获取鼠标点击相应位置的方法。

Original: https://blog.csdn.net/weixin_47903162/article/details/122259450
Author: weixin_47903162
Title: Pygame实现自定义的生命游戏

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/779880/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球