




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第pygame開發(fā):馬賽邏輯小游戲的代碼實(shí)現(xiàn)目錄一、游戲簡(jiǎn)介二、核心代碼解析三、pygame開發(fā)流程1、從創(chuàng)建窗口到棋盤繪制2、點(diǎn)擊方格改變顏色2.1、點(diǎn)擊事件2.2、碰撞檢測(cè)2.3、方格變色2.4、陣列轉(zhuǎn)換2.5、效果初見3、顯示提示信息四、游戲演示視頻
一、游戲簡(jiǎn)介
馬賽邏輯,是一個(gè)類似數(shù)獨(dú)和掃雷的邏輯小游戲,根據(jù)棋盤周圍的數(shù)據(jù)提示點(diǎn)亮方格,因外形像馬賽克而得名。在手機(jī)游戲中有多款A(yù)PP可以體驗(yàn)該游戲,如Peak、Nonogram、Crossme等。但在PC端,筆者暫時(shí)還未發(fā)現(xiàn)復(fù)刻版,于是打算自己動(dòng)手實(shí)現(xiàn)一番。
馬賽邏輯的基本玩法如下圖所示,上側(cè)橫向的各組數(shù)字為:對(duì)每一列中存在的目標(biāo)方格的標(biāo)注,如2表示該列有2個(gè)連續(xù)的目標(biāo),12表示該列有1個(gè)獨(dú)立的目標(biāo)+2個(gè)連續(xù)的目標(biāo)。左側(cè)縱向的各組數(shù)據(jù)為對(duì)每一行的標(biāo)注。通過上、左兩側(cè)的提示,將所有目標(biāo)方格點(diǎn)亮即為通關(guān)。
二、核心代碼解析
在正式開始游戲開發(fā)之前,我們可以先想想實(shí)現(xiàn)這個(gè)項(xiàng)目的關(guān)鍵點(diǎn)在哪。首先,方格有選中和未選中兩種狀態(tài),那可以用1表示選中、0表示未選中。要判斷玩家點(diǎn)亮的方格是否正確,只需將方塊矩陣映射成01矩陣,再與答案矩陣對(duì)比即可。如此一來,出題也很容易,隨機(jī)生成一串01組合即可。
而最重要的地方在于,如何生成提示數(shù)值?我們需要分別對(duì)每行每列進(jìn)行遍歷,找出單獨(dú)的1和連續(xù)的1。下面以棋盤的一行為例進(jìn)行說明。
首先,準(zhǔn)備一個(gè)列表類型的變量remind用于儲(chǔ)存多個(gè)提示數(shù)值,并準(zhǔn)備一個(gè)位移標(biāo)記flag用于記錄當(dāng)前是在答案陣列的哪一位進(jìn)行判斷,以及一個(gè)數(shù)值記錄num,再將答案陣列[0,1,1,0,1,0,0,1]傳入計(jì)數(shù)器。
當(dāng)傳入陣列長(zhǎng)度大于1時(shí)有四種情況,分別是:①當(dāng)前位0,次位1;②當(dāng)前位1,次位0;③連續(xù)多位1;④連續(xù)多位0。根據(jù)不同情況進(jìn)行位移,將新的陣列傳入計(jì)數(shù)器,并在1換0的時(shí)候記錄數(shù)值。
當(dāng)傳入陣列等于1時(shí)有兩種情況,分別是:①上位0;②上位1。根據(jù)不同的情況記錄數(shù)值。
按照這個(gè)思路,我們可以用一個(gè)簡(jiǎn)單的遞歸來實(shí)現(xiàn)這個(gè)提示算法,代碼如下:
defget_line_remind(_line):#輸出一行或一列的提示
remind=[]#一行或一列的提示記錄
num=0#提示值
deffun(line):
nonlocalremind,num
flag=0#位移
iflen(line)1:
ifline[0]==0andline[1]==1:
flag+=1
elifline[0]==line[1]==0:
flag+=2
elifline[0]==1andline[1]==0:
num+=1
remind.append(num)
num=0
flag+=2
elifline[0]==line[1]==1:
num+=1
flag+=1
fun(line[flag:])
eliflen(line)andline[0]:
ifnum:
remind.append(num+1)
else:
remind.append(1)
fun(_line)
returnremind
三、pygame開發(fā)流程
1、從創(chuàng)建窗口到棋盤繪制
棋盤的設(shè)計(jì)及玩法已經(jīng)初具雛形了,可以正式開始制作游戲了啦!~筆者采用了有超過20年歷史的游戲制作庫(kù)pygame,該游戲庫(kù)包含了用于制作簡(jiǎn)單2D游戲的基本套件,python及游戲愛好者們已經(jīng)用它制作了成千上萬(wàn)的小游戲,使用pip安裝即可使用。
第一步,對(duì)各類游戲元素的顏色、位置、尺寸等必要參數(shù)做一些設(shè)置。接著,初始化pygame,繪制一個(gè)指定大小的窗口,使用pygame.font.Font()加載指定的字體文件,以防游戲打包后運(yùn)行出錯(cuò)。
需要注意的是,pygame的所有視覺元素都建立在不斷地重新繪制上,利用pygame.display.flip()進(jìn)行整體更新。因?yàn)楹笃谛枰诎咨尘爸刑砑觿?dòng)態(tài)元素,所以將背景繪制放入主循環(huán)的首位。
在主循環(huán)中,通過遍歷事件來獲取玩家的操作,當(dāng)前僅追蹤了一個(gè)退出事件。
importpygame
importsys
#參數(shù)設(shè)置----------------------------------
blue=(159,197,232)#被選中方格的顏色
gray=(217,217,217)#棋盤網(wǎng)格線顏色
gold=(255,215,0)#游戲記錄文字顏色
black=(0,0,0)
white=(255,255,255)
start_x=240#棋盤左上角位置
start_y=150
size=2#一行/列的方塊個(gè)數(shù)
square=320#棋盤邊長(zhǎng)
length=int(square/size)#每個(gè)方塊的邊長(zhǎng)
#游戲初始化----------------------------------
pygame.init()
screen=pygame.display.set_mode((780,520))#創(chuàng)建窗口
font=pygame.font.Font(r'./data/msyh.ttf',20)#提示字體
#主循環(huán)----------------------------------
whileTrue:
screen.fill(white)#背景填充
foreventinpygame.event.get():
ifevent.type==pygame.QUIT:
pygame.quit()#退出pygame
sys.exit()#安全退出系統(tǒng)
pygame.display.flip()#更新全部顯示
運(yùn)行以上代碼可以得到一片空白(霧)。
下一步,我們來想想怎么繪制棋盤。首先,棋盤本身的尺寸是固定的,我們只需修改棋盤中的方格數(shù)量和大小,來改變棋局。因此,在第一步的參數(shù)設(shè)置中,使用start_x、start_y來確定棋盤的位置,并設(shè)置棋盤的邊長(zhǎng)square=320,以及一行中方塊的個(gè)數(shù)size和方塊邊長(zhǎng)length。
因?yàn)榉綁K是可以被點(diǎn)擊而改變顏色的,所以我們要先自定義一個(gè)方塊類。機(jī)制比較簡(jiǎn)單,初始化即傳入坐標(biāo)和邊長(zhǎng),調(diào)用pygame.draw.rect()來繪制矩形。
classItem:#自定義方塊類
def__init__(self,pos_x,pos_y,leng):
self.rect=pygame.draw.rect(screen,gray,[pos_x,pos_y,leng,leng],0)
self.state=False
再定義一個(gè)繪制棋盤的方法,從棋盤左上角開始,橫豎各畫size個(gè)方塊,返回方塊對(duì)象列表。
defcreate_chessboard():#創(chuàng)建棋盤
item_lst=[]
forvinrange(size):
forhinrange(size):
rect=Item(start_x+h*length,start_y+v*length,length)
item_lst.append(rect)
returnitem_lst
由于方塊初始顏色和背景色一樣是白色,還需要加上網(wǎng)格線,橫豎各畫size+1條線,調(diào)用pygame.draw.line()繪制線條。
defdraw_line():#繪制網(wǎng)格線
forninrange(size+1):
start=(start_x,start_y+n*length)
end=(start_x+square,start_y+n*length)
pygame.draw.line(screen,gray,start,end,2)
forninrange(size+1):
start=(start_x+n*length,start_y)
end=(start_x+n*length,start_y+square)
pygame.draw.line(screen,gray,start,end,2)
將主循環(huán)代碼修改如下,注意:網(wǎng)格線是繪制在整個(gè)圖層組的最上層,才不會(huì)被方格和背景覆蓋掉。運(yùn)行即可繪制出初始棋盤,如圖為4X4的規(guī)格。
##前文參數(shù)、初始化略
......
items=create_chessboard()#創(chuàng)建棋盤
whileTrue:
screen.fill(white)#背景填充
foreventinpygame.event.get():
ifevent.type==pygame.QUIT:
pygame.quit()#退出pygame
sys.exit()#安全退出系統(tǒng)
draw_line()#繪制棋盤網(wǎng)格線
pygame.display.flip()#更新全部顯示
2、點(diǎn)擊方格改變顏色
2.1、點(diǎn)擊事件
在事件遍歷中添加對(duì)鼠標(biāo)點(diǎn)擊事件的追蹤,并獲取點(diǎn)擊坐標(biāo),之后通過判斷點(diǎn)擊的位置是否在某個(gè)方格中,即可得知是哪個(gè)方格被點(diǎn)擊了,并作出顏色修改。
ifevent.type==pygame.MOUSEBUTTONDOWN:#鼠標(biāo)點(diǎn)擊事件
x,y=event.pos
2.2、碰撞檢測(cè)
那么來寫一個(gè)判斷方法,將之前創(chuàng)建棋盤時(shí)得到的方塊對(duì)象列表,和鼠標(biāo)坐標(biāo)傳入,遍歷方塊并通過矩形的collidepoint()方法進(jìn)行碰撞檢測(cè),若鼠標(biāo)碰撞到了矩形區(qū)域,就對(duì)方塊的狀態(tài)取反。
defcheck_click(item_lst,pos_x,pos_y):#更新每個(gè)方塊的點(diǎn)擊狀態(tài)
foriinitem_lst:
ifi.rect.collidepoint(pos_x,pos_y):
i.state=bool(1-i.state)
2.3、方格變色
defchange_color(item_lst):#根據(jù)狀態(tài)改變方塊顏色
foriinitem_lst:
ifi.state:
pygame.draw.rect(screen,blue,i.rect,0)
else:
pygame.draw.rect(screen,white,i.rect,0)
2.4、陣列轉(zhuǎn)換
再來寫一個(gè)獲取玩家操作陣列的方法,利用列表生成式將方塊狀態(tài)轉(zhuǎn)換為01列表。
defcreate_answer_array():#創(chuàng)建答案矩陣
lst=[1ifrandom()0.5else0for_inrange(size*size)]
iflist(set(lst))[0]==0:
lst[0]=1
returnlst
并通過隨機(jī)生成的方式來創(chuàng)建答案,之后通過比較兩個(gè)列表即可判斷游戲是否通關(guān)。別忘了,答案陣列中不能全都是0。
defcreate_answer_array():#創(chuàng)建答案矩陣
lst=[1ifrandom()0.5else0for_inrange(size*size)]
iflist(set(lst))[0]==0:
lst[0]=1
returnlst
2.5、效果初見
修改主循環(huán)代碼如下,運(yùn)行后嘗試點(diǎn)擊可見效果。
##前文參數(shù)、初始化略
......
answer=create_answer_array()#創(chuàng)建答案矩陣
#主循環(huán)----------------------------------
whileTrue:
screen.fill(white)#背景填充
foreventinpygame.event.get():
ifevent.type==pygame.QUIT:
pygame.quit()#退出pygame
sys.exit()#安全退出系統(tǒng)
ifevent.type==pygame.MOUSEBUTTONDOWN:#鼠標(biāo)點(diǎn)擊事件
x,y=event.pos
check_click(items,x,y)#檢查選中的方格,修改狀態(tài)
result=get_player_array(items)#獲取方格操作矩陣
print(result)
ifresult==answer:
print("YOUWIN!")
change_color(items)#根據(jù)方格狀態(tài)修改顏色
draw_line()#繪制棋盤網(wǎng)格線
pygame.display.flip()#更新全部顯示
3、顯示提示信息
沒有提示只能盲點(diǎn)怎么玩呀!趕緊把提示信息搞出來(ε(#)☆╰╮o(皿///)
前文我們已經(jīng)了解了提示算法,接下來就根據(jù)答案矩陣來整理兩側(cè)的提示信息。
defget_w_remind(answer_lst):#根據(jù)答案矩陣輸出提示列表
h_remind=[]
v_remind=[]
h_array=[answer_lst[i:i+size]foriinrange(0,len(answer_lst),size)]#橫向矩陣
forhinh_array:
h_remind.append(get_line_remind(h))
v_array=list(map(list,zip(*h_array)))#縱向矩陣
forvinv_array:
v_remind.append(get_line_remind(v))
returnh_remind,v_remind
由于筆者是直接使用一維列表來代替矩陣的,因此如果要獲取每一行的提示,則需要按照size將將答案陣列分割成多份。而要獲取每一列的提示時(shí),則需要對(duì)分割好的橫向矩陣進(jìn)行行列轉(zhuǎn)置。
之后,通過億點(diǎn)點(diǎn)數(shù)學(xué)計(jì)算得到兩側(cè)信息的顯示坐標(biāo),利用窗口對(duì)象的blit()方法將渲染好的文本對(duì)象貼上去。對(duì)橫/縱陣列逆序的目的是,將多個(gè)提示數(shù)值從外到內(nèi)顯示,以符合閱讀習(xí)慣。
defshow_remind(answer_lst):#在棋盤兩側(cè)對(duì)應(yīng)位置顯示每行/列的提示
h_remind,v_remind=get_w_remind(answer_lst)
fori,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 法學(xué)概論的條款研究與試題及答案
- 電廠地震火災(zāi)應(yīng)急預(yù)案(3篇)
- 行政法學(xué)知識(shí)拓展試題及答案解析
- 2025年VB考試全解及試題及答案
- 經(jīng)典法學(xué)概論考題試題及答案
- 醫(yī)院整體規(guī)劃與未來發(fā)展方向計(jì)劃
- 2025珠寶首飾等質(zhì)押合同
- 門診部護(hù)士長(zhǎng)工作計(jì)劃
- 2025年網(wǎng)絡(luò)管理員考試評(píng)估標(biāo)準(zhǔn)試題及答案
- 2025年考試過來人的建議試題及答案
- 第6課 全球航路的開辟 說課稿 -2023-2024學(xué)年高一下學(xué)期統(tǒng)編版(2019)必修中外歷史綱要下冊(cè)
- 《數(shù)據(jù)資產(chǎn)會(huì)計(jì)》 課件 第二章 數(shù)據(jù)的資產(chǎn)化
- 融資融券業(yè)務(wù)流程詳解
- 高考英語(yǔ)高頻詞600
- 2024年高考真題-生物(黑吉遼卷) 含解析
- YY/T 0063-2024醫(yī)用電氣設(shè)備醫(yī)用診斷X射線管組件焦點(diǎn)尺寸及相關(guān)特性
- 2024年湖北省中考地理·生物試卷(含答案解析)
- GB/T 44241-2024虛擬電廠管理規(guī)范
- JGT 160-2017 混凝土用機(jī)械錨栓
- 南通輔警考試題庫(kù)
- 連續(xù)蒸煮螺旋喂料器
評(píng)論
0/150
提交評(píng)論