基于Python實現(xiàn)自制拼圖小游戲
咱們Python 集中營有一個專題就是分享一些有意思的東西,今天大概看了一下pygame的這個非標準庫就想著使用它來做個小游戲-拼圖。
通過加入自己定義的圖片,對這個圖片完成一定數(shù)量的拆分后再將拆分后的小圖片進行隨機打亂,這也算是實現(xiàn)一個拼圖小游戲的基本思路吧。
為了將其做成一個桌面應(yīng)用,這里使用的是pygame這一個非標準庫。python環(huán)境中還沒有pygame的話可以選擇使用pip的方式安裝一下。
pip?install?-i?https://pypi.tuna.tsinghua.edu.cn/simple/
下面將開發(fā)中使用到的python庫都列舉一下,除了pygame處理游戲之外,還有sys、random分別用來做系統(tǒng)操作和隨機數(shù)的處理。
#?Importing?the?pygame,?sys,?and?random?modules. import?pygame,?sys,?random #?Importing?all?the?constants?from?the?pygame.locals?module. from?pygame.locals?import?*
創(chuàng)建一個python類GameMain,將所有的游戲處理相關(guān)的業(yè)務(wù)全部寫到這個類中進行處理,包括一些初始化操作等等,最后我們通過main函數(shù)調(diào)用啟動整個拼圖游戲。
class?GameMain(): ????def?__init__(self,?window_width,?window_height,?background_color, ?????????????????fps,?colums,?max_round_time,?game_image): ????????self.init_static_data(window_width=window_width,?window_height=window_height, ??????????????????????????????background_color=background_color,?fps=fps,?colums=colums,?max_round_time=max_round_time) ????????self.init_game_data(game_image='./wd.jpeg') ????????self.init_game_main()
通過GameMain類的初始化函數(shù)init來做類的初始化并且分別調(diào)用init_static_data、init_game_data、init_game_main三個主要的實現(xiàn)函數(shù)。
init_static_data函數(shù)主要用來將一些全局的靜態(tài)參數(shù)進行初始化賦值,為了避免沒有值時候的報錯默認分別給這些參數(shù)都賦值,包括背景顏色、拼圖游戲分割成小圖片的列數(shù)等等。
def?init_static_data(self,?window_width=500,?window_height=500, ?????????????????????????background_color=(255,?255,?255),?fps=40,?colums=3,?max_round_time=100): ????????""" ????????????????The?function?initializes?the?game?data?and?the?game?main ????????????????:param?window_width:?The?width?of?the?game?window ????????????????:param?window_height:?The?height?of?the?game?window ????????????????:param?background_color:?The?background?color?of?the?game?window ????????????????:param?fps:?The?number?of?frames?per?second?that?the?game?will?run?at ????????????????:param?colums:?The?number?of?columns?in?the?game ????????????????:param?max_round_time:?The?maximum?time?for?each?round ????????????????:param?game_image:?The?image?that?will?be?used?for?the?game ????????????????""" ????????self.window_width?=?window_width ????????self.window_height?=?window_height ????????self.background_color?=?background_color ????????self.black_color?=?(0,?0,?0) ????????self.fps?=?fps ????????self.colums?=?colums ????????self.cell_nums?=?self.colums?*?self.colums ????????self.max_round_time?=?max_round_time
init_game_data函數(shù),主要將游戲執(zhí)行過程中的一些參數(shù)進行計算或者計算之后的數(shù)據(jù)值進行保存,因為在后面的游戲主循環(huán)中肯定是需要用到的,包括游戲載入的一整張圖片的路徑以及游戲窗口的標題等等。
def?init_game_data(self,?game_image='./wd.jpeg'): ????????""" ????????>?This?function?initializes?the?game?data?by?reading?the?game?image?and?extracting?the?game?data?from?it ????????:param?game_image:?The?image?of?the?game?you?want?to?play,?defaults?to?./wd.jpeg?(optional) ????????""" ????????pygame.init() ????????self.main_clock?=?pygame.time.Clock() ????????self.game_image?=?pygame.image.load(game_image) ????????self.game_rect?=?self.game_image.get_rect() ????????self.window_surface?=?pygame.display.set_mode((self.game_rect.width,?self.game_rect.height)) ????????pygame.display.set_caption('拼圖游戲') ????????self.cell_width?=?int(self.game_rect.width?/?self.colums) ????????self.cell_height?=?int(self.game_rect.height?/?self.colums) ????????self.finished?=?False ????????self.game_board,?self.black_cell?=?self.generate_game_borad()
init_game_main函數(shù)中加入了死循環(huán)的方式讓游戲一直處于執(zhí)行中的狀態(tài),除非是已經(jīng)完成了游戲或是直接退出游戲了才會停止。主要實現(xiàn)的是游戲步驟以及鍵盤的監(jiān)聽或鼠標的點擊事件維持整個游戲狀態(tài)的運行。
def?init_game_main(self): ????????""" ????????>?This?function?initializes?the?game?data?by?reading?the?game?image?and?extracting?the?game?data?from?it ????????:param?game_image:?The?image?of?the?game?you?want?to?play,?defaults?to?./wd.jpeg?(optional),?defaults?to?./wd.jpeg ????????(optional) ????????""" ????????while?True: ????????????for?event?in?pygame.event.get(): ????????????????if?event.type?==?QUIT: ????????????????????self.game_exit() ????????????????if?self.finished: ????????????????????continue ????????????????if?event.type?==?KEYDOWN: ????????????????????if?event.key?==?K_LEFT?or?event.key?==?ord('a'): ????????????????????????self.black_cell?=?self.move_left(self.game_board,?self.black_cell) ????????????????????if?event.key?==?K_RIGHT?or?event.key?==?ord('d'): ????????????????????????self.black_cell?=?self.move_right(self.game_board,?self.black_cell) ????????????????????if?event.key?==?K_UP?or?event.key?==?ord('w'): ????????????????????????self.black_cell?=?self.move_up(self.game_board,?self.black_cell) ????????????????????if?event.key?==?K_DOWN?or?event.key?==?ord('s'): ????????????????????????self.black_cell?=?self.move_down(self.game_board,?self.black_cell) ????????????????if?event.type?==?MOUSEBUTTONDOWN?and?event.button?==?1: ????????????????????x,?y?=?pygame.mouse.get_pos() ????????????????????col?=?int(x?/?self.cell_width) ????????????????????row?=?int(y?/?self.cell_height) ????????????????????index?=?col?+?row?*?self.colums ????????????????????if?( ????????????????????????????index?==?self.black_cell?-?1?or?index?==?self.black_cell?+?1?or?index?==?self.black_cell?-?self.colums?or?index?==?self.black_cell?+?self.colums): ????????????????????????self.game_board[self.black_cell],?self.game_board[index]?=?self.game_board[index],?\ ???????????????????????????????????????????????????????????????????????????????????self.game_board[self.black_cell] ????????????????????????self.black_cell?=?index ????????????if?(self.is_finished(self.game_board)): ????????????????self.game_board[self.black_cell]?=?self.cell_nums?-?1 ????????????????self.finished?=?True ????????????self.window_surface.fill(self.background_color) ????????????for?i?in?range(self.cell_nums): ????????????????row_dst?=?int(i?/?self.colums) ????????????????col_dst?=?int(i?%?self.colums) ????????????????rect_dst?=?pygame.Rect(col_dst?*?self.cell_width,?row_dst?*?self.cell_height,?self.cell_width, ???????????????????????????????????????self.cell_height) ????????????????if?self.game_board[i]?==?-1: ????????????????????continue ????????????????row_area?=?int(self.game_board[i]?/?self.colums) ????????????????col_area?=?int(self.game_board[i]?%?self.colums) ????????????????rect_area?=?pygame.Rect(col_area?*?self.cell_width,?row_area?*?self.cell_height,?self.cell_width, ????????????????????????????????????????self.cell_height) ????????????????self.window_surface.blit(self.game_image,?rect_dst,?rect_area) ????????????for?i?in?range(self.colums?+?1): ????????????????pygame.draw.line(self.window_surface,?self.black_color,?(i?*?self.cell_height,?0), ?????????????????????????????????(i?*?self.cell_width,?self.game_rect.height)) ????????????for?i?in?range(self.colums?+?1): ????????????????pygame.draw.line(self.window_surface,?self.black_color,?(0,?i?*?self.cell_height), ?????????????????????????????????(self.game_rect.width,?i?*?self.cell_height)) ????????????pygame.display.update() ????????????self.main_clock.tick(self.fps)
game_exit函數(shù),執(zhí)行游戲退出操作。
def?game_exit(self): ????????""" ????????It?exits?the?game. ????????""" ????????pygame.quit() ????????sys.exit()
generate_game_borad函數(shù),生成游戲運行的主布局。
def?generate_game_borad(self): ????????""" ????????It?generates?the?game?board. ????????""" ????????board?=?[] ????????for?i?in?range(self.cell_nums): ????????????board.append(i) ????????black_cell?=?self.cell_nums?-?1 ????????board[black_cell]?=?-1 ????????for?i?in?range(self.max_round_time): ????????????direction?=?random.randint(0,?3) ????????????if?(direction?==?0): ????????????????black_cell?=?self.move_left(board,?black_cell) ????????????elif?(direction?==?1): ????????????????black_cell?=?self.move_right(board,?black_cell) ????????????elif?(direction?==?2): ????????????????black_cell?=?self.move_up(board,?black_cell) ????????????elif?(direction?==?3): ????????????????black_cell?=?self.move_down(board,?black_cell) ????????return?board,?black_cell
move_right函數(shù),執(zhí)行向右移動的操作。
def?move_right(self,?board,?black_cell): ????????""" ????????>?The?function?`move_right`?takes?in?a?board?and?a?black?cell?and?returns?the?board?after?the?black?cell?has?moved ????????right ????????:param?board:?the?board?that?the?game?is?being?played?on ????????:param?black_cell:?the?cell?that?is?currently?black ????????""" ????????if?black_cell?%?self.colums?==?0: ????????????return?black_cell ????????board[black_cell?-?1],?board[black_cell]?=?board[black_cell],?board[black_cell?-?1] ????????return?black_cell?-?1
move_left函數(shù),執(zhí)行向左移動的操作。
def?move_left(self,?board,?black_cell): ????????""" ????????It?moves?the?black?cell?to?the?left. ????????:param?board:?the?board?that?the?game?is?being?played?on ????????:param?black_cell:?the?cell?that?is?currently?black ????????""" ????????if?black_cell?%?self.colums?==?self.colums?-?1: ????????????return?black_cell ????????board[black_cell?+?1],?board[black_cell]?=?board[black_cell],?board[black_cell?+?1] ????????return?black_cell?+?1
move_down函數(shù),執(zhí)行向下移動的操作。
def?move_left(self,?board,?black_cell): ????????""" ????????It?moves?the?black?cell?to?the?left. ????????:param?board:?the?board?that?the?game?is?being?played?on ????????:param?black_cell:?the?cell?that?is?currently?black ????????""" ????????if?black_cell?%?self.colums?==?self.colums?-?1: ????????????return?black_cell ????????board[black_cell?+?1],?board[black_cell]?=?board[black_cell],?board[black_cell?+?1] ????????return?black_cell?+?1 def?move_down(self,?board,?black_cell): ????????""" ????????It?moves?the?black?cell?down. ????????:param?board:?the?board?that?the?game?is?being?played?on ????????:param?black_cell:?the?cell?that?the?player?is?currently?on ????????""" ????????if?black_cell?<?self.colums: ????????????return?black_cell ????????board[black_cell?-?self.colums],?board[black_cell]?=?board[black_cell],?board[black_cell?-?self.colums] ????????return?black_cell?-?self.colums
move_up函數(shù),執(zhí)行向下移動的操作。
def?move_up(self,?board,?black_cell): ????????""" ????????It?moves?the?black?cell?up?one?space. ????????:param?board:?the?board?that?the?game?is?being?played?on ????????:param?black_cell:?the?cell?that?the?player?is?currently?on ????????""" ????????if?black_cell?>=?self.cell_nums?-?self.colums: ????????????return?black_cell ????????board[black_cell?+?self.colums],?board[black_cell]?=?board[black_cell],?board[black_cell?+?self.colums] ????????return?black_cell?+?self.colums
is_finished函數(shù),校驗拼圖是否已經(jīng)完成的操作。
def?is_finished(self,?board): ????????""" ????????If?the?board?is?full,?the?game?is?over ????????:param?board:?a?2D?array?representing?the?current?state?of?the?board.?The?board?is?composed?of?3?characters:?'X', ????????'O',?and?'?'.?'X'?and?'O'?represent?the?two?players.?'?'?represents?an?empty?space ????????""" ????????for?i?in?range(self.cell_nums?-?1): ????????????if?board[i]?!=?i: ????????????????return?False ????????return?True
最后,只需要通過main的主函數(shù)將這個游戲應(yīng)用調(diào)用就可以直接打開拼圖游戲了,并且可以設(shè)置相關(guān)的圖片參數(shù)想對哪個圖片拼圖就設(shè)置哪個,一般建議設(shè)置1024像素以內(nèi)的圖片效果會比較好。
#?This?is?a?special?variable?in?Python?that?is?set?when?the?program?is?run.?If?the?program?is?being?run?directly?(as #?opposed?to?being?imported),?then?`__name__`?will?be?set?to?`'__main__'`. if?__name__?==?'__main__': ????""" ????????????It?moves?the?black?cell?up?one?space ????????????:param?board:?the?board?that?the?game?is?being?played?on ????????????:param?black_cell:?the?cell?that?the?player?is?currently?on ????????????:return:?The?new?position?of?the?black?cell. ????????????""" ????GameMain(window_width=500,?window_height=500, ?????????????background_color=(255,?255,?255),?fps=40, ?????????????colums=3,?max_round_time=100,?game_image='./wd.jpeg')
以上就是基于Python實現(xiàn)自制拼圖小游戲的詳細內(nèi)容,更多關(guān)于Python拼圖游戲的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
安裝并免費使用Pycharm專業(yè)版(學(xué)生/教師)
這篇文章主要介紹了安裝并免費使用Pycharm專業(yè)版(學(xué)生/教師),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Python數(shù)據(jù)持久化存儲實現(xiàn)方法分析
這篇文章主要介紹了Python數(shù)據(jù)持久化存儲實現(xiàn)方法,結(jié)合實例形式分析了Python基于pymongo及mysql模塊的數(shù)據(jù)持久化存儲操作相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2019-12-12在Qt中正確的設(shè)置窗體的背景圖片的幾種方法總結(jié)
今天小編就為大家分享一篇在Qt中正確的設(shè)置窗體的背景圖片的幾種方法總結(jié),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-06-06使用Python實現(xiàn)發(fā)送郵件的常用方法小結(jié)
在日常工作中,我們可能經(jīng)常會用到發(fā)送郵件,但如果每次都人工來發(fā)送,那豈不是很麻煩,今天我們就來講解下如何通過python語言來優(yōu)雅地發(fā)送郵件2024-04-04一文帶你掌握Pyecharts地理數(shù)據(jù)可視化的方法
這篇文章主要介紹了一文帶你掌握Pyecharts地理數(shù)據(jù)可視化的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02