pygame實現(xiàn)一個類似滿天星游戲流程詳解
編寫類滿天星游戲,目前自己設定需要用到的算法內(nèi)容,包括第一點點擊某一個圖標后,自動檢查圖標上下左右是有與之相同的圖形,如果包括自身在內(nèi)有三個以上的圖形,則可以消除。第二,當界面中有圖形消除后,那么需要根據(jù)列來下移圖標,同時產(chǎn)生新的圖標。第三,自動檢查界面中是否還有能夠匹配的圖案,如果沒有,那么重新生成游戲。第四,游戲機制設定為倒計時,在倒計時完成前,盡可能多消除,多得分。并且考慮每次消除4個以上,按比例增加時間。
首先完成最簡單的部分,配置pygame的基本參數(shù),并且繪制游戲界面,也就是畫橫縱線。
考慮把游戲界面畫成一個10*10的方格,并且在上方留出空位顯示等分等信息,具體還需不需要別的,待定…
直接使用之前貪食蛇的畫格子和初始化的代碼,先略作修改。
import random
import time
import pygame
# 30幀
fps = 30
fps_clock = pygame.time.Clock()
screen_width = 1024
screen_height = 768
# 分辨率,標題
display = pygame.display.set_mode((screen_width, screen_height), 0, 32)
pygame.display.set_caption('好似滿天星')
tile_size = 60
tile_width = 60
tile_height = 60
x_margin = 400
y_margin = 100
# 列
columns = 10
# 行
rows = 11
# 配色RGB
white = (255, 255, 255)
black = 'black'
bg_color = 'sky blue'
border_color = white
body_color = 'purple'
inter_body_color = 'green'
line_color = white
directions = ['up', 'down', 'left', 'right']
text_color = (144, 59, 28)
my_score = 0
snake = []
# 畫格子
def draw_chest():
for i in range(rows + 1):
pygame.draw.line(display, border_color, (x_margin/2, y_margin/2 + i * tile_size),
(x_margin/2 + (columns * tile_size), y_margin/2 + i * tile_size), 2)
for j in range(columns + 1):
pygame.draw.line(display, border_color, (x_margin/2 + j * tile_size, y_margin/2),
(x_margin/2 + j * tile_size, y_margin/2 + (rows * tile_size)), 2)
if __name__ == '__main__':
pygame.init()
bad_touch = pygame.mixer.Sound('badswap.wav')
match_three = pygame.mixer.Sound('match3.wav')
match_more_than_three = pygame.mixer.Sound('match4.wav')
display.fill(bg_color)
while True:
draw_chest()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
pygame.display.update()
fps_clock.tick(fps)目前不知道后續(xù)還有些什么需求,所以簡單修改一下,后期有需要再來修改代碼。
運行結果如下:

有一個大體的框架了,接下來就是把星星放到游戲界面當中來了。嗯,因為我們有星星,所以我找了免費的餅干來代替星星。這些餅干也是五子連珠的棋子??。

一共有七種餅干,考慮到游戲的難度,我們一開始只使用其中的四種。
把之前snake = []刪除,新創(chuàng)建一個列表,用來存放"星星"
stars = [‘Cookie’, ‘Croissant’, ‘Cupcake’, ‘Danish’]
在方框內(nèi)放滿“星星”。
生成一個二維列表,列表中隨機放入“星星”
def make_stars():
board = []
for i in range(rows):
temp = []
for j in range(columns):
star = random.choice(stars)
temp.append(star)
board.append(temp)
return board
還需要繪制星星的函數(shù),在繪制星星之前呢,需要確定星星的位置,同時還是按照下標來計算游戲界面橫縱坐標,那么:
def get_left_top_location(x, y):
left_position = y * tile_size + x_margin/2
top_position = x * tile_size + y_margin/2
return left_position, top_position
def draw_stars(board):
for i in range(len(board)):
for j in range(len(board[i])):
path = 'gems/' + board[i][j] + '.png'
star = pygame.image.load(path)
star = pygame.transform.scale(star, (tile_size-5, tile_size-5))
left, top = get_left_top_location(i, j)
# 微調(diào)一下,這樣圖片比較居中,誰讓釘在左上角呢
display.blit(star, (left+3, top+3))在主程序中增加繪制星星代碼
if __name__ == '__main__':
pygame.init()
bad_touch = pygame.mixer.Sound('badswap.wav')
match_three = pygame.mixer.Sound('match3.wav')
match_more_than_three = pygame.mixer.Sound('match4.wav')
display.fill(bg_color)
main_board = make_stars()
print(main_board)
while True:
draw_chest()
draw_stars(main_board)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
pygame.display.update()
fps_clock.tick(fps)運行程序

感覺“星星”太少了,所以還是再加點吧。
stars = [‘Cookie’, ‘Croissant’, ‘Cupcake’, ‘Danish’, ‘Donut’, ‘Ginger’, ‘Macaroon’]

感覺好多了。接下來開始消除吧。
消除部分,比較簡單,需要編寫的內(nèi)容主要是當鼠標點擊時,我們需要知道是哪個位置的哪個“星星”被點擊了,也就是說我們需要定位到main_board的具體下標是多少。是[0][0],[1][2],或者是別的。然后我們確定位置和“星星后”,找到該位置“星星”的上下左右,看能否找到相同的“星星”,如果有且數(shù)量大于或者等于3,那么可以實現(xiàn)消除。同時為了以后動畫效果,我準備使用一個列表中帶字典變量的方式來存儲這些相同的“星星”的位置和種類信息。
先完成第一步,對應二維列表下標。
# 將游戲中的界面坐標轉(zhuǎn)換為main_board中的位置
def get_spot_clicked(board, x, y):
for i in range(len(board)):
for j in range(len(board[i])):
# 注意在二維數(shù)組里我們的查詢順序是比如maze[3][5]代表第四行第六列,但是對應游戲界面的坐標則3用來計算y坐標,5用來計算x坐標
left, top = get_left_top_location(i, j)
tile_rect = pygame.Rect(left, top, tile_width, tile_height)
if tile_rect.collidepoint(x, y):
return i, j
return None, None
然后在主循環(huán)中加入鼠標響應代碼。根據(jù)鼠標點擊位置,打印出二維列表下標,看看效果。
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.MOUSEBUTTONUP:
# 鼠標左鍵點擊后抬起
if event.button == 1:
pos_x, pos_y = event.pos
print(get_spot_clicked(main_board, pos_x, pos_y))
實際測試,鼠標點擊位置和二維列表下標匹配。
接下來則需要開始尋找點擊位置四個方向上是否有相同"星星"。
# 查找"星星"的相同情況
def check_around(board, star_pos):
store_stars = set()
has_three_stars = False
shape_type = board[star_pos[0]][star_pos[1]]
# 查找上下兩個方向是否有與當前棋子類型一樣的棋子
store_stars.add(star_pos)
# 向上的方向上尋找
star_i = star_pos[0] - 1
up_and_down_star = set()
while star_i >= 0 and board[star_i][star_pos[1]] == shape_type:
store_stars.add((star_i, star_pos[1]))
star_i -= 1
# 向下的方向?qū)ふ?
star_i = star_pos[0] + 1
while star_i < rows and board[star_i][star_pos[1]] == shape_type:
store_stars.add((star_i, star_pos[1]))
star_i += 1
# 向左的方向上尋找
star_j = star_pos[1] - 1
while star_j >= 0 and board[star_pos[0]][star_j] == shape_type:
store_stars.add((star_pos[0], star_j))
star_j -= 1
# 向右的方向?qū)ふ?
star_j = star_pos[1] + 1
while star_j < columns and board[star_pos[0]][star_j] == shape_type:
store_stars.add((star_pos[0], star_j))
star_j += 1
if len(store_stars) >= 3:
has_three_stars = True
return store_stars, has_three_stars
該函數(shù)返回所有需要消除的點的二維列表下標。再編寫一個函數(shù)用于清除對坐標的二維列表中的內(nèi)容。把需要清除的位置設定為empty。然后在主循環(huán)中調(diào)用。
def remove_stars(board, removed_stars):
for star in removed_stars:
board[star[0]][star[1]] = 'empty'
if event.button == 1:
pos_x, pos_y = event.pos
x, y = get_spot_clicked(main_board, pos_x, pos_y)
need_to_removed, remove_or_not = check_around(main_board, (x, y))
if remove_or_not:
remove_stars(main_board, need_to_removed)
display.fill(bg_color)
draw_chest()
draw_stars(main_board)
運行程序。
程序報錯了,因為繪制“星星”的函數(shù)并沒有考慮到二維列表的內(nèi)容為empty的情況,所以需要修改這個函數(shù)內(nèi)容。
def draw_stars(board):
for i in range(len(board)):
for j in range(len(board[i])):
if board[i][j] != 'empty':
path = 'gems/' + board[i][j] + '.png'
star = pygame.image.load(path)
star = pygame.transform.scale(star, (tile_size-5, tile_size-5))
left, top = get_left_top_location(i, j)
display.blit(star, (left+3, top+3))
運行程序

確實能消除了,但是出現(xiàn)了一個意外情況,比如上圖[4][3]這個位置的甜甜圈有三個相同的圖形,我所編寫的算法里,只是檢查了點擊處的上下左右,那么如果我點擊[4][3]這個位置,[4][2],[4][3],[5][3]的內(nèi)容都會消失,這個沒問題,但是如果我點擊的是[5][3],那么根據(jù)算法,該位置上有左右僅有一個相同的,所以不會發(fā)生消除情況。這貌似與滿天星游戲方式不同,所以,我們需要修改消除算法。算法應該修改為從一個位置出發(fā),尋找上下左右相同的圖標,如果找到,再以該位置作為中心,繼續(xù)尋找上下左右是否有相同點,直到?jīng)]有為止??梢钥紤]使用回溯+棧的方式來修改算法。
# 查找"星星"的相同情況
def check_around(board, star_pos):
stars_temp = []
store_stars = set()
has_three_stars = False
shape_type = board[star_pos[0]][star_pos[1]]
# 查找上下兩個方向是否有與當前棋子類型一樣的棋子
store_stars.add(star_pos)
stars_temp.append(star_pos)
while len(stars_temp):
current_star = stars_temp[0]
del stars_temp[0]
# 向上的方向上尋找
star_i = current_star[0] - 1
while star_i >= 0 and board[star_i][current_star[1]] == shape_type:
if (star_i, current_star[1]) not in store_stars:
store_stars.add((star_i, current_star[1]))
stars_temp.append((star_i, current_star[1]))
star_i -= 1
# 向下的方向?qū)ふ?
star_i = current_star[0] + 1
while star_i < rows and board[star_i][current_star[1]] == shape_type:
if (star_i, current_star[1]) not in store_stars:
store_stars.add((star_i, current_star[1]))
stars_temp.append((star_i, current_star[1]))
star_i += 1
# 向左的方向上尋找
star_j = current_star[1] - 1
while star_j >= 0 and board[current_star[0]][star_j] == shape_type:
if (current_star[0], star_j) not in store_stars:
store_stars.add((current_star[0], star_j))
stars_temp.append((current_star[0], star_j))
star_j -= 1
# 向右的方向?qū)ふ?
star_j = current_star[1] + 1
while star_j < columns and board[current_star[0]][star_j] == shape_type:
if (current_star[0], star_j) not in store_stars:
store_stars.add((current_star[0], star_j))
stars_temp.append((current_star[0], star_j))
star_j += 1
if len(store_stars) >= 2:
has_three_stars = True
#print('stars: ', store_stars)
#input()
return store_stars, has_three_stars修改以后,從任意點擊位置開始,都可以發(fā)現(xiàn)所有相同“星星了”
馬上開始比較麻煩的地方了,動畫下移。
關于動畫下移的思路則是首先,按列尋找需要下移的“星星”,找到以后,無論這個星星(不加引號了,太麻煩),下面有多少空間都只移動一格,找到所有的需要移動的星星,動畫移動一格,然后再尋找可以移動的星星,移動一格,再尋找,直到?jīng)]有可以移動的為止。
到此這篇關于pygame實現(xiàn)一個類似滿天星游戲流程詳解的文章就介紹到這了,更多相關pygame滿天星游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Pygame改編飛機大戰(zhàn)制作兔子接月餅游戲
- Python+Pygame實現(xiàn)海洋之神大冒險游戲
- Python pygame 動畫游戲循環(huán)游戲時鐘實現(xiàn)原理
- Python+Pygame實戰(zhàn)之實現(xiàn)小蜜蜂歷險記游戲
- Python+Pygame實戰(zhàn)之英文版猜字游戲的實現(xiàn)
- Pygame游戲開發(fā)之太空射擊實戰(zhàn)盾牌篇
- Pygame游戲開發(fā)之太空射擊實戰(zhàn)碰撞改進篇
- Pygame游戲開發(fā)之太空射擊實戰(zhàn)添加圖形篇
- Pygame游戲開發(fā)之太空射擊實戰(zhàn)子彈與碰撞處理篇
相關文章
Python中定時器用法詳解之Timer定時器和schedule庫
目前所在的項目組需要經(jīng)常執(zhí)行一些定時任務,于是選擇使用 Python 的定時器,下面這篇文章主要給大家介紹了關于Python中定時器用法詳解之Timer定時器和schedule庫的相關資料,需要的朋友可以參考下2024-02-02
Python開發(fā)之迭代器&生成器的實戰(zhàn)案例分享
在 Python 中,迭代器和生成器都是用來遍歷數(shù)據(jù)集合的工具,可以按需逐個生成或返回數(shù)據(jù),從而避免一次性加載整個數(shù)據(jù)集合所帶來的性能問題和內(nèi)存消耗問題。本文主要和大家分享幾個貼近實際運維開發(fā)工作中的場景案例,希望對大家有所幫助2023-04-04

