A full record of using pygame to write a star-like game 2

Continue to study how to realize the downward movement after elimination, the general idea has been said, and start to write functions.

First find the elements that need to be moved down in the first round.

def find_fall_stars(board):
    all_stars = []
    single_star = {}
    find_fall_star = False
    for column in range(columns):
        # 从底部往上找,每一个减少的row值都相当于往上走一行
        for row in range(rows-2, -1, -1):
            # 此位置星星可以下降,记录,使用字典记录类型,处于二维列表中的位置,然后放入all_stars中
            if board[row][column] != 'empty' and board[row+1][column] == 'empty':
                print(row, column)
                single_star['type'] = board[row][column]
                single_star['x'] = row
                single_star['y'] = column
                all_stars.append(single_star)
                single_star = {}
                find_fall_star = True
    # 返回当前找到的星星,同时返回标志位,为下次寻找作准备
    return find_fall_star, all_stars

First make a function that moves down a fixed position alone.

def one_column_falling_stars(board, star, speed):
    move_x = 0
    speed *= 0.01
    move_y = int(speed * tile_size)
    basex = star['x']
    basey = star['y']
    left_location = x_margin / 2 + (basey * tile_size) + 3
    top_location = y_margin / 2 + (basex * tile_size) + 3
    r = pygame.Rect((left_location + move_x, top_location + move_y, tile_size, tile_size))
    path = 'gems/' + board[basex][basey] + '.png'
    star = pygame.image.load(path)
    star = pygame.transform.scale(star, (tile_size - 5, tile_size - 5))
    display.blit(star, r)

Give the coordinates of the star to be moved, because it must be moved downward, so the final deviation appears on the y coordinate, and the speed is the deviation of the downward movement of the graph drawn each time. The greater the speed, the faster the movement. This function needs to be called multiple times to realize the moving process.

Then write a function that moves down one space given all the stars.

def animate_falling_stars(board, stars):
    speed = 0
    while speed < 110:
        display.fill(bg_color)
        draw_chest()
        draw_stars(board)
        for star in stars: # Draw each gem.
            one_column_falling_stars(board, star, speed)
        pygame.display.update()
        fps_clock.tick(fps)
        speed += 30

Running the game, there is indeed movement, but because this is only an animation process, the actual two-dimensional list content has not changed, so the game interface does not appear to move, but moves after copying, and if the drawing is redrawn at this moment, all interfaces will be changed. It's back to normal.

Please add a picture description

Now consider deleting the stars that need to be moved in the two-dimensional list before drawing the animation. After the animation is completed, put the stars at the specified position, complete the data exchange, and then look for the stars that can be moved in the next round.

Modify the function of finding stars, and add part of data deletion. This data processing process faintly feels inappropriate...

def find_fall_stars(board):
    all_stars = []
    single_star = {}
    find_fall_star = False
    for column in range(columns):
        # 从底部往上找,每一个减少的row值都相当于往上走一行
        for row in range(rows-2, -1, -1):
            # 此位置星星可以下降,记录,使用字典记录类型,处于二维列表中的位置,然后放入all_stars中
            if board[row][column] != 'empty' and board[row+1][column] == 'empty':
                print(row, column)
                single_star['type'] = board[row][column]
                single_star['x'] = row
                single_star['y'] = column
                # 先从二维列表中清除原来的类型,主要是绘制动画需要
                board[row][column] = 'empty'
                all_stars.append(single_star)
                single_star = {}
                find_fall_star = True
    # 返回当前找到的星星,同时返回标志位,为下次寻找作准备
    return find_fall_star, all_stars

When the animation is complete, the star type at the end position of the animation needs to be put into the actual data.

def animate_falling_stars(board, stars):
    speed = 0
    while speed < 120:
        display.fill(bg_color)
        draw_chest()
        draw_stars(board)
        for star in stars: # Draw each gem.
            one_column_falling_stars(board, star, speed)
        pygame.display.update()
        fps_clock.tick(fps)
        speed += 30
    for star in stars:
        # 下移完成后交换数据
        board[star['x']+1][star['y']] = star['type']

Because only one row is currently moved down, it is called in a loop until there is nothing to move.

                    if remove_or_not:
                        remove_stars(main_board, need_to_removed)
                        while True:
                            print(main_board)
                            falling_or_not, falling_stars = find_fall_stars(main_board)
                            if falling_or_not:
                                animate_falling_stars(main_board, falling_stars)
                            else:
                                break

Run the program to see the effect.

Please add a picture description

It can be seen that the effect is not bad, because there is no function to add stars, so there will be empty.

Adhering to the principle of eliminating a few stars and adding a few stars, we started to add new stars. The process of increasing also requires animation effects.

The idea of ​​falling stars is to search for the current number of stars that need to be dropped for the first time according to the empty position, and randomly generate stars. The position of the star subscript [x][-1] is the whereabouts on the game interface. After completing the current whereabouts, look for the empty position on the game interface again, and repeat the previous operation.

def show_new_fall_stars(board):
    limit_x = -1
    signal_star = {}
    new_stars = []
    # 从最后一行开始寻找
    for row in range(rows-1, -1, -1):
        # 每一行从左往右找
        for column in range(columns):
            # 找到当前最下面一行,最左边的空白点
            if board[row][column] == 'empty' and row > limit_x:
                signal_star['type'] = random.choice(stars)
                signal_star['x'] = -1
                signal_star['y'] = column
                new_stars.append(signal_star)
                signal_star = {}
    return new_stars

Then check in the loop to see if it needs to be filled.

        if len(new_falling_stars):
            animate_falling_stars(main_board, new_falling_stars)
            while True:
                falling_or_not, falling_stars = find_fall_stars(main_board)
                if falling_or_not:
                    animate_falling_stars(main_board, falling_stars)
                else:
                    break

When the first filling is completed, the situation is similar to that of the previous elimination, so use the same method as the elimination to drop again. After completing such an operation, the loop will continue to fill in the gaps until all gaps are filled.

Run the game, the effect is as follows:

Please add a picture description

Leaving aside the known and unknown bugs, I feel that I have come to an end at the moment. All that needs to be done then is to set up a mechanism for the game to end. Then the simpler method is to use a timing mechanism. For example, the game has 60 seconds to play, and see how many points you can get at most during the game. You can consider adding a little time if you eliminate more than 6 stars at a time. Also, what if there is a situation that cannot be eliminated at all?

Considering that there may be a situation that cannot be eliminated at all, then you can add a check mechanism in the game. During the game, you can constantly check the game state, use the previous elimination algorithm, and keep looking for whether there are still stars that can be eliminated. If there is no , the board is regenerated. This is very simple, so I won’t do it. I am a little lazy and modify the game mechanism, that is, as long as there are more than 2 identical stars, they can be eliminated, and then the game may not be eliminated. Set the situation where only 2 stars are eliminated as no scoring or deduction.

At this point, the remaining part does not have any algorithmic content and difficulty at all. I won’t release the specific process, just look at the picture.

Please add a picture description

Guess you like

Origin blog.csdn.net/jackwsd/article/details/126555688
Recommended