Python實(shí)現(xiàn)貪吃蛇小游戲(雙人模式)_第1頁
Python實(shí)現(xiàn)貪吃蛇小游戲(雙人模式)_第2頁
Python實(shí)現(xiàn)貪吃蛇小游戲(雙人模式)_第3頁
Python實(shí)現(xiàn)貪吃蛇小游戲(雙人模式)_第4頁
Python實(shí)現(xiàn)貪吃蛇小游戲(雙人模式)_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第Python實(shí)現(xiàn)貪吃蛇小游戲(雙人模式)簡單用py寫了一個(gè)貪吃蛇游戲,有單人、雙人模式,比較簡單,適合初學(xué)者練手。本上每行重要的語句都有注釋,做了什么事一目了然

這里介紹雙人模式

單人模式戳這里:Python簡易貪吃蛇小游戲(單人模式)

一、游戲設(shè)計(jì)要點(diǎn)

1.游戲主體窗口(尺寸)、畫布(尺寸、位置)、按鈕(尺寸、位置)、文字(大小、顏色、位置)、圖像、背景音樂及相關(guān)響應(yīng)函數(shù)(主要是鼠標(biāo)移動及點(diǎn)擊的響應(yīng))的設(shè)計(jì)與合理排布

2.蛇與食物的類的屬性設(shè)計(jì)

3.蛇位置的更新(根據(jù)鍵盤輸入)、吃到食物加分的判定、食物的更新

4.蛇死亡的判定條件設(shè)計(jì)

二、主要模塊

1.pygame

2.sys

3.random

三、用到的類

1.Snake類,定義蛇頭蛇身元素的位置

2.Food類,定義食物元素的位置及單個(gè)元素的顏色

四、主要函數(shù)

1.new_food(),功能:生成一個(gè)不與蛇頭位置重合的食物并返回該食物對象

defnew_food(head):

whileTrue:

#循環(huán),不斷實(shí)例化new_food對象直到生成一個(gè)不與蛇頭重合的食物

new_food=Food(randint(0,45)*20,randint(0,28)*20,(randint(10,255),randint(10,255),randint(10,255)))

#若new_food和蛇頭重合則不創(chuàng)鍵

ifnew_food.x!=head.xandnew_food.y!=head.y:

break

else:

continue

returnnew_food

2.draw_snake()、draw_food()函數(shù),功能:繪制蛇與食物的圖像,傳入?yún)?shù)為顏色和對象:

#在窗體中繪制貪吃蛇

#形參:一個(gè)是顏色另一個(gè)是實(shí)例化對象

defdraw_snake(color,object):

pygame.draw.circle(window,color,(object.x,object.y),10)

#在窗體中繪制食物

#形參:實(shí)例化對象

defdraw_food(food):

pygame.draw.circle(window,food.color,(food.x,food.y),10)

3.show_end函數(shù),功能:顯示雙人模式結(jié)束時(shí)的得分界面:

defshow_end():

whileTrue:

window.blit(init_background,(0,0))

foreventinpygame.event.get():

ifevent.type==pygame.QUIT:

exit_end()

#定義標(biāo)題

pygame.display.set_caption("貪吃蛇大冒險(xiǎn)")

#定義提示文字

font=pygame.font.SysFont("simHei",40)

fontsurf=font.render('游戲結(jié)束!玩家1得分:%s玩家2得分:%s'%(score1,score2),True,black)

window.blit(fontsurf,(150,100))

button("返回主菜單",370,300,200,40,blue,brightred,into_game)

button("退出游戲",370,470,200,40,red,brightred,exit_end)

pygame.display.update()

clock.tick(20)

4.exit_end()函數(shù),功能:在初始界面和游戲結(jié)束顯示得分界面點(diǎn)擊右上角的"×"時(shí),直接退出整個(gè)游戲:

#初始界面和游戲中途點(diǎn)擊退出游戲時(shí)

defexit_end():

pygame.quit()

sys.exit()

5.start_game_double()函數(shù),功能:實(shí)現(xiàn)雙人正常模式:

defstart_game_double():

#播放音樂

pygame.mixer.music.play(-1)

#定義存分?jǐn)?shù)的全局變量

globalscore1

globalscore2

score1=score2=0

#初始化存放玩家鍵盤輸入運(yùn)動方向的變量

run_direction1="right"

run_direction2="up"

#初始化貪吃蛇運(yùn)動方向的變量

run1=run_direction1

run2=run_direction2

#實(shí)例化貪吃蛇和食物對象

head1=Snake(randint(0,30)*20,randint(0,20)*20)

head2=Snake(randint(0,30)*20,randint(0,20)*20)

#實(shí)例化蛇身長度為2個(gè)單位

snake_body1=[Snake(head1.x,head1.y+20),Snake(head1.x,head1.y+40)]

snake_body2=[Snake(head2.x,head2.y+20),Snake(head2.x,head2.y+40)]

#實(shí)例化食物列表,列表隨著其中食物被吃掉應(yīng)該不斷縮短

food_list=[Food(randint(0,45)*20,randint(0,28)*20,(randint(10,255),randint(10,255),randint(10,255)))]

foriinrange(1,24):

food_list.append(Food(randint(0,45)*20,randint(0,28)*20,(randint(10,255),randint(10,255),randint(10,255))))

#實(shí)例化單個(gè)食物,方便循環(huán)內(nèi)生成單個(gè)新食物

food=Food(randint(0,45)*20,randint(0,28)*20,(randint(10,255),randint(10,255),randint(10,255)))

whileTrue:

window.blit(background,(0,0))

#監(jiān)聽玩家鍵盤輸入的運(yùn)動方向值,并根據(jù)輸入轉(zhuǎn)為up、down、right或left,方便程序中調(diào)用

#pygame.event.get()返回一個(gè)列表,存放本次game執(zhí)行中程序遇到的一連串事件(按時(shí)間順序依次存放)

foreventinpygame.event.get():

#pygame.QUIT事件是指用戶點(diǎn)擊窗口右上角的"×"

ifevent.type==pygame.QUIT:

#顯示結(jié)果界面

show_end()

#若事件類型是按下鍵盤,分↑↓←→四種情況討論

elifevent.type==pygame.KEYDOWN:

#若事件類型是按下鍵盤↑

#key是鍵值,表示按下去的鍵值是什么

ifevent.key==pygame.K_UP:

run_direction2="up"

#若事件類型是按下鍵盤↓

ifevent.key==pygame.K_DOWN:

run_direction2="down"

#若事件類型是按下鍵盤←

ifevent.key==pygame.K_LEFT:

run_direction2="left"

#若事件類型是按下鍵盤→

ifevent.key==pygame.K_RIGHT:

run_direction2="right"

#若事件類型是按下鍵盤↑

ifevent.key==ord('w'):

run_direction1="up"

#若事件類型是按下鍵盤↓

ifevent.key==ord('s'):

run_direction1="down"

#若事件類型是按下鍵盤←

ifevent.key==ord('a'):

run_direction1="left"

#若事件類型是按下鍵盤→

ifevent.key==ord('d'):

run_direction1="right"

#繪制初始化的25個(gè)食物圖像(24+1=25)

#隨著該列表中的食物被吃掉,列表應(yīng)該不斷pop以清除已經(jīng)被吃的事物

foriteminfood_list:

draw_food(item)

#繪制被貪吃蛇吃掉后新增的食物圖像

draw_food(food)

#繪制蛇頭圖像

#在繪制蛇頭之前先檢查是不是已經(jīng)死亡,如果已死亡,則不繪制

#??!不能通過die_flag判斷是否死亡因?yàn)槊看窝h(huán)一開頭die_flag都初始化為False

#因此最好的方法是通過snake_body是否為空判斷

iflen(snake_body1)!=0:

draw_snake(black,head1)

iflen(snake_body2)!=0:

draw_snake(black,head2)

#繪制蛇身圖像

foriteminsnake_body1:

draw_snake(blue,item)

foriteminsnake_body2:

draw_snake(green,item)

#若蛇未死亡,則插入蛇頭位置到蛇身列表中

#即:若蛇已死亡,則保持snake_body為空不變

iflen(snake_body1)!=0:

snake_body1.insert(0,Snake(head1.x,head1.y))

iflen(snake_body2)!=0:

snake_body2.insert(0,Snake(head2.x,head2.y))

#判斷貪吃蛇原運(yùn)動方向(run)與玩家鍵盤輸入的運(yùn)動方向(run_direction)是否違反正常運(yùn)動情況

ifrun1=="up"andnotrun_direction1=="down":

run1=run_direction1

ifrun1=="down"andnotrun_direction1=="up":

run1=run_direction1

ifrun1=="left"andnotrun_direction1=="right":

run1=run_direction1

ifrun1=="right"andnotrun_direction1=="left":

run1=run_direction1

ifrun2=="up"andnotrun_direction2=="down":

run2=run_direction2

ifrun2=="down"andnotrun_direction2=="up":

run2=run_direction2

ifrun2=="left"andnotrun_direction2=="right":

run2=run_direction2

ifrun2=="right"andnotrun_direction2=="left":

run2=run_direction2

#根據(jù)玩家鍵入方向進(jìn)行蛇頭坐標(biāo)的更新

ifrun1=="up":

head1.y-=20

ifrun1=="down":

head1.y+=20

ifrun1=="left":

head1.x-=20

ifrun1=="right":

head1.x+=20

ifrun2=="up":

head2.y-=20

ifrun2=="down":

head2.y+=20

ifrun2=="left":

head2.x-=20

ifrun2=="right":

head2.x+=20

#判斷兩條蛇是否死亡

#初始化四個(gè)死亡標(biāo)志為False

die_flag1=die_flag2=False

#此時(shí)snake_body1,2中均已包含蛇頭

#snake_body1,2第一個(gè)元素是蛇頭,故不能從0號元素開始比較

#因?yàn)樵撋呱哳^必然和自己重合

#這里snake_body1,2均從1號元素開始

#所以snake_body1[1:]+snake_body2[1:]是純粹存儲蛇身的列表

forbodyinsnake_body1[1:]+snake_body2[1:]:

ifhead1.x==body.xandhead1.y==body.y:

die_flag1=True

ifhead2.x==body.xandhead2.y==body.y:

die_flag2=True

ifdie_flag1==Trueorhead1.x0orhead1.x960orhead1.y0orhead1.y600:

#注意:這邊雖然蛇身列表清空,但head1對象仍存在

#故必須要在上面的繪制蛇頭代碼前面加上if先判斷蛇是否死亡

snake_body1.clear()

ifdie_flag2==Trueorhead2.x0orhead2.x960orhead2.y0orhead2.y600:

die_flag2=True

#注意:這邊雖然蛇身列表清空,但head1對象仍存在

#故必須要在上面的繪制蛇頭代碼前面加上if先判斷蛇是否死亡

snake_body2.clear()

#若兩條蛇都死亡

#同樣地,只能通過snake_body是否為空判斷蛇是否死亡

iflen(snake_body1)==0andlen(snake_body2)==0:

show_end()

#判斷蛇頭和食物坐標(biāo),若相等,則加分,并生成新的食物

#定義標(biāo)志,表明是否找到和蛇頭相等的食物

globalflag1

globalflag2

flag1=flag2=0

#如果蛇頭和食物重合

foriteminfood_list:

#在蛇1沒死且蛇頭1和某一食物坐標(biāo)相等的條件下

iflen(snake_body1)!=0and(head1.x==item.xandhead1.y==item.yorhead1.x==food.xandhead1.y==food.y):

flag1=1

score1+=1

#彈出被吃掉的這個(gè)食物

food_list.pop(food_list.index(item))

#再產(chǎn)生一個(gè)食物

food=new_food(head1)

#把新食物插入food_list,下一次循環(huán)中會更新繪制食物全體

food_list.append(food)

break

#在蛇2沒死的且蛇頭2和某一食物坐標(biāo)相等的條件下

eliflen(snake_body2)!=0andhead2.x==item.xandhead2.y==item.yorhead2.x==food.xandhead2.y==food.y:

flag2=1

score2+=1

#彈出被吃掉的這個(gè)食物

food_list.pop(food_list.index(item))

#再產(chǎn)生一個(gè)食物

food=new_food(head2)

#把新食物插入food_list,下一次循環(huán)中會更新繪制食物全體

food_list.append(food)

break

#蛇1必須沒死,否則pop會引發(fā)異常

iflen(snake_body1)!=0andflag1==0:

snake_body1.pop()

#蛇2必須沒死,否則pop會引發(fā)異常

iflen(snake_body2)!=0andflag2==0:

snake_body2.pop()

font=pygame.font.SysFont("simHei",25)

mode_title1=mode_title2=font.render('正常模式',False,grey)

socre_title1=font.render('得分:%s'%score1,False,grey)

socre_title2=font.render('得分:%s'%score2,False,grey)

window.blit(mode_title1,(50,30))

window.blit(socre_title1,(50,65))

window.blit(mode_title2,(800,30))

window.blit(socre_title2,(800,65))

#更新蛇頭蛇身和食物的數(shù)據(jù)

pygame.display.update()

#通過幀率設(shè)置貪吃蛇速度

clock.tick(8)

6.start_kgame_double()函數(shù),功能:實(shí)現(xiàn)雙人穿墻模式:

defstart_kgame_double():

#播放音樂

pygame.mixer.music.play(-1)

#定義存分?jǐn)?shù)的全局變量

globalscore1

globalscore2

score1=score2=0

#初始化存放玩家鍵盤輸入運(yùn)動方向的變量

run_direction1="right"

run_direction2="up"

#初始化貪吃蛇運(yùn)動方向的變量

run1=run_direction1

run2=run_direction2

#實(shí)例化貪吃蛇和食物對象

head1=Snake(randint(0,30)*20,randint(0,20)*20)

head2=Snake(randint(0,30)*20,randint(0,20)*20)

#實(shí)例化蛇身長度為2個(gè)單位

snake_body1=[Snake(head1.x,head1.y+20),Snake(head1.x,head1.y+40)]

snake_body2=[Snake(head2.x,head2.y+20),Snake(head2.x,head2.y+40)]

#實(shí)例化食物列表,列表隨著其中食物被吃掉應(yīng)該不斷縮短

food_list=[Food(randint(0,45)*20,randint(0,28)*20,(randint(10,255),randint(10,255),randint(10,255)))]

foriinrange(1,24):

food_list.append(Food(randint(0,45)*20,randint(0,28)*20,(randint(10,255),randint(10,255),randint(10,255))))

#實(shí)例化單個(gè)食物,方便循環(huán)內(nèi)生成單個(gè)新食物

food=Food(randint(0,45)*20,randint(0,28)*20,(randint(10,255),randint(10,255),randint(10,255)))

whileTrue:

window.blit(background,(0,0))

#監(jiān)聽玩家鍵盤輸入的運(yùn)動方向值,并根據(jù)輸入轉(zhuǎn)為up、down、right或left,方便程序中調(diào)用

#pygame.event.get()返回一個(gè)列表,存放本次game執(zhí)行中程序遇到的一連串事件(按時(shí)間順序依次存放)

foreventinpygame.event.get():

#pygame.QUIT事件是指用戶點(diǎn)擊窗口右上角的"×"

ifevent.type==pygame.QUIT:

#顯示結(jié)果界面

show_end()

#若事件類型是按下鍵盤,分↑↓←→四種情況討論

elifevent.type==pygame.KEYDOWN:

#若事件類型是按下鍵盤↑

#key是鍵值,表示按下去的鍵值是什么

ifevent.key==pygame.K_UP:

run_direction2="up"

#若事件類型是按下鍵盤↓

ifevent.key==pygame.K_DOWN:

run_direction2="down"

#若事件類型是按下鍵盤←

ifevent.key==pygame.K_LEFT:

run_direction2="left"

#若事件類型是按下鍵盤→

ifevent.key==pygame.K_RIGHT:

run_direction2="right"

#若事件類型是按下鍵盤↑

ifevent.key==ord('w'):

run_direction1="up"

#若事件類型是按下鍵盤↓

ifevent.key==ord('s'):

run_direction1="down"

#若事件類型是按下鍵盤←

ifevent.key==ord('a'):

run_direction1="left"

#若事件類型是按下鍵盤→

ifevent.key==ord('d'):

run_direction1="right"

#繪制初始化的25個(gè)食物圖像(24+1=25)

#隨著該列表中的食物被吃掉,列表應(yīng)該不斷pop以清除已經(jīng)被吃的事物

foriteminfood_list:

draw_food(item)

#繪制被貪吃蛇吃掉后新增的食物圖像

draw_food(food)

#繪制蛇頭圖像

#在繪制蛇頭之前先檢查是不是已經(jīng)死亡,如果已死亡,則不繪制

iflen(snake_body1)!=0:

draw_snake(black,head1)

iflen(snake_body2)!=0:

draw_snake(black,head2)

#繪制蛇身圖像

foriteminsnake_body1:

draw_snake(blue,item)

foriteminsnake_body2:

draw_snake(green,item)

#插入蛇頭位置到蛇身列表中

iflen(snake_body1)!=0:

snake_body1.insert(0,Snake(head1.x,head1.y))

iflen(snake_body2)!=0:

snake_body2.insert(0,Snake(head2.x,head2.y))

#判斷貪吃蛇原運(yùn)動方向(run)與玩家鍵盤輸入的運(yùn)動方向(run_direction)是否違反正常運(yùn)動情況

ifrun1=="up"andnotrun_direction1=="down":

run1=run_direction1

ifrun1=="down"andnotrun_direction1=="up":

run1=run_direction1

ifrun1=="left"andnotrun_direction1=="right":

run1=run_direction1

ifrun1=="right"andnotrun_direction1=="left":

run1=run_direction1

ifrun2=="up"andnotrun_direction2=="down":

run2=run_direction2

ifrun2=="down"andnotrun_direction2=="up":

run2=run_direction2

ifrun2=="left"andnotrun_direction2=="right":

run2=run_direction2

ifrun2=="right"andnotrun_direction2=="left":

run2=run_direction2

#根據(jù)玩家鍵入方向進(jìn)行蛇頭坐標(biāo)的更新

ifrun1=="up":

head1.y-=20

ifrun1=="down":

head1.y+=20

ifrun1=="left":

head1.x-=20

ifrun1=="right":

head1.x+=20

ifrun2=="up":

head2.y-=20

ifrun2=="down":

head2.y+=20

ifrun2=="left":

head2.x-=20

ifrun2=="right":

head2.x+=20

#實(shí)現(xiàn)穿墻

#蛇頭穿出窗體共有8種情況

ifhead1.x0:

head1.x=960

ifhead1.x960:

head1.x=0

ifhead1.y0:

head1.y=600

ifhead1.y600:

head1.y=0

ifhead2.x0:

head2.x=960

ifhead2.x960:

head2.x=0

ifhead2.y0:

head2.y=600

ifhead2.y600:

head2.y=0

#定義死亡標(biāo)志位

die_flag1=die_flag2=False

forbodyinsnake_body1[1:]+snake_body2[1:]:

ifhead1.x==body.xandhead1.y==body.y:

die_flag1=True

ifhead2.x==body.xandhead2.y==body.y:

die_flag2=True

ifdie_flag1==True:

snake_body1.clear()

ifdie_flag2==True:

snake_body2.clear()

#若兩條蛇都死亡

iflen(snake_body1)==0andlen(snake_body2)==0:

show_end()

#判斷蛇頭和食物坐標(biāo),若相等,則加分,并生成新的食物

#定義標(biāo)志,表明是否找到和蛇頭相等的食物

globalflag1

globalflag2

flag1=flag2=0

#如果蛇頭和食物重合

foriteminfood_list:

#在蛇1沒死且蛇頭1和某一食物坐標(biāo)相等的條件下

iflen(snake_body1)!=0and(head1.x==item.xandhead1.y==item.yorhead1.x==food.xandhead1.y==food.y):

flag1=1

score1+=1

#彈出被吃掉的這個(gè)食物

food_list.pop(food_list.index(item))

#再產(chǎn)生一個(gè)食物

food=new_food(head1)

#把新食物插入food_list,下一次循環(huán)中會更新繪制食物全體

food_list.append(food)

break

#在蛇2沒死的且蛇頭2和某一食物坐標(biāo)相等的條件下

eliflen(snake_body2)!=0andhead2.x==item.xandhead2.y==item.yorhead2.x==food.xandhead2.y==food.y:

flag2=1

score2+=1

#彈出被吃掉的這個(gè)食物

food_list.pop(food_list.index(item))

#再產(chǎn)生一個(gè)食物

food=new_food(head2)

#把新食物插入food_list,下一次循環(huán)中會更新繪制食物全體

food_list.append(food)

break

#蛇1必須沒死,否則pop會引發(fā)異常

iflen(snake_body1)!=0andflag1==0:

snake_body1.pop()

#蛇2必須沒死,否則pop會引發(fā)異常

iflen(snake_body2)!=0andflag2==0:

snake_body2.pop()

font=pygame.font.SysFont("simHei",25)

mode_title1=mode_title2=font.render('穿墻模式',False,grey)

socre_title1=font.render('得分:%s'%score1,False,grey)

socre_title2=font.render('得分:%s'%score2,False,grey)

window.blit(mode_title1,(50,30))

window.blit(socre_title1,(50,65))

window.blit(mode_title2,(800,30))

window.blit(socre_title2,(800,65))

#更新蛇頭蛇身和食物的數(shù)據(jù)

pygame.display.update()

#通過幀率設(shè)置貪吃蛇速度

clock.tick(8)

7.button()函數(shù),功能:實(shí)現(xiàn)按鈕樣式設(shè)計(jì)和響應(yīng)鼠標(biāo)操作:

defbutton(msg,x,y,w,h,ic,ac,action=None):

#獲取鼠標(biāo)位置

mouse=pygame.mouse.get_pos()

#獲取鼠標(biāo)點(diǎn)擊情況

click=pygame.mouse.get_pressed()

ifx+wmouse[0]xandy+hmouse[1]y:

pygame.draw.rect(window,ac,(x,y,w,h))

ifclick[0]==1andaction!=None:

action()

else:

pygame.draw.rect(window,ic,(x,y,w,h))

#設(shè)置按鈕中的文字樣式和居中對齊

font=pygame.font.SysFont('simHei',20)

smallfont=font.render(msg,True,white)

smallrect=smallfont.get_rect()

small

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論