20192416 實驗四 《Python程序設計》 綜合實踐報告
課程:《Python程序設計》
班級:1924
姓名:不願透露姓名的はんたくさん
學號:20192416
實驗教師:王志強老師
實驗日期:2020年6月11日
必修/選修: 公選課
1.實驗分析
相較之下個人對游戲比較感興趣,於是選擇了趣味性較強且容易上手的pygame作為綜合實踐的內容。
通過觀看嵩天教授的視頻進行自學,在事件處理機制中學會了通過鍵盤、鼠標進行交互以及時間的計算方法。
於是想把所學到的結合起來,制作一個可以通過鍵盤與鼠標操縱、並根據通關時間結算最終得分的小游戲,恰好想起上次考科目三沒過,於是以考試線路為地圖進行制作。
2.實驗設計
第一步:設計地圖
這里以科目三考試線路為原型,最終得出了一個1400×900的地圖
將障礙分為橫豎兩類,分別導入各自的位置上。
第二步:操縱小飛船
鍵盤上通過KEYDOWN、KEYUP事件實現小飛船的加速減速
鼠標通過MOUSEBUTTONDOWN、MOUSEBUTTONUP以及MOUSEMOTION事件使小飛船能在鼠標按下的時候隨鼠標移動
這是小飛船:
第三步:判斷失敗及成功條件
失敗條件判斷:既小飛船與障礙重合時,可以通過循環分別判斷各個障礙是否與小飛船有重合部分
成功條件判斷:當小飛船完全進入右下方區域時成功
位置判斷用.left .right 等屬性進行分析
第四步:結果
成功與失敗都有各自的圖片出現在屏幕中央,點擊圖片退出游戲,退出前打印游戲結果
圖片的點擊利用MOUSEBUTTONDOWN事件的.button屬性判斷左鍵的按下。
.pos[]返回的鼠標位置在圖片范圍內來確定游戲的退出。
循環中遞增的num值計算當前時間以計算得分。
3.實驗內容
- 爬蟲、數據處理、可視化、機器學習、神經網絡、游戲、網絡安全等。
- 我選擇用pygame制作了一個飛船小游戲
4. 實驗過程及結果
功能
- 飛船小游戲
- 能通過鍵盤和鼠標操控飛船
- 碰到障礙則失敗,彈出失敗圖片,點擊圖片退出游戲
- 到達右下角的終點則成功,彈出成功圖片,點擊圖片退出游戲
- 根據通關的時間決定分數
代碼
import pygame,sys #將pygame庫導入到python程序中
from pygame.locals import * #然后需要引入pygame中的所有常量
pygame.init() #初始化
size = width,height = 1400,900
screen = pygame.display.set_mode(size) #定義窗口大小
pygame.display.set_caption("我的第一個pygame") #設置窗口標題
speed = [0,0] #初始速度
nspeed = [0,5]
WHITE = 255,255,255
num = 0
n = 0
n1 = 33 #障礙數
n2 = 39
still = False #以上均為對各變量的初始定義
car = pygame.image.load(r'D:/abiancheng/. python/tu/car.jpg')
lose = pygame.image.load(r'D:/abiancheng/. python/tu/lose.jpg')
win = pygame.image.load(r'D:/abiancheng/. python/tu/win.gif')
mod = {} #導入障礙物的圖像
mod[0] = pygame.image.load(r'D:/abiancheng/. python/tu/橫障礙.png') #橫障礙物
mod[1] = pygame.image.load(r'D:/abiancheng/. python/tu/豎障礙.png') #豎障礙物
carrect = car.get_rect() #返回矩形圖像
carrect = carrect.move(10,420)
loserect = lose.get_rect()
loserect = loserect.move(1000,1000)
winrect = win.get_rect()
winrect = winrect.move(1000,1000)
fps = 50
fclock = pygame.time.Clock()
HENG = {}
i=0
while i<=n1:
HENG[i] = mod[0].get_rect()
i+=1
SHU = {}
i=0
while i<=n2:
SHU[i] = mod[1].get_rect()
i+=1
i = 0
while i<=8:
HENG[i] = HENG[i].move((i+1)*100,0)
i+=1
while i<=13:
HENG[i] = HENG[i].move((i-6)*100,100)
i+=1
while i<=18:
HENG[i] = HENG[i].move((i-11)*100,200)
i+=1
HENG[19] = HENG[19].move(0,400)
HENG[20] = HENG[20].move(0,500)
i = 21
while i<=24:
HENG[i] = HENG[i].move((i-11)*100,700)
i+=1
while i<=30:
HENG[i] = HENG[i].move((i-17)*100,895)
i+=1
while i<=33:
HENG[i] = HENG[i].move((i-21)*100,800)
i+=1
i=0
while i<=3:
SHU[i] = SHU[i].move(100,i*100)
i+=1
while i<=7:
SHU[i] = SHU[i].move(100,(i+1)*100)
i+=1
while i<=13:
SHU[i] = SHU[i].move(200,(i-6)*100)
i+=1
while i<=20:
SHU[i] = SHU[i].move(300,(i-12)*100)
i+=1
while i<=27:
SHU[i] = SHU[i].move(800,(i-19)*100)
i+=1
while i<=32:
SHU[i] = SHU[i].move(900,(i-26)*100)
i+=1
while i<=39:
SHU[i] = SHU[i].move(1000,(i-33)*100)
i+=1
#以上均為各單位的初始位置設置
while True: #無限循環,直到游戲結束時退出
for event in pygame.event.get(): #從pygame的事件隊列中取出事件,並從隊列中刪除該事件
if event.type == pygame.QUIT: #pygame.QUIT是pygame中定義的事件常量
sys.exit() #用於退出結束游戲並退出
elif event.type == pygame.KEYDOWN: #鍵盤的松放進行對應方向速度的增加
if event.key == pygame.K_LEFT:
speed[0] = speed[0] - 1
elif event.key == pygame.K_RIGHT:
speed[0] = speed[0] + 1
elif event.key == pygame.K_UP:
speed[1] = speed[1] - 1
elif event.key == pygame.K_DOWN:
speed[1] = speed[1] + 1
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
speed[0] = speed[0] - 1
elif event.key == pygame.K_RIGHT:
speed[0] = speed[0] + 1
elif event.key == pygame.K_UP:
speed[1] = speed[1] - 1
elif event.key == pygame.K_DOWN:
speed[1] = speed[1] + 1
elif event.type == pygame.MOUSEBUTTONDOWN: #鼠標控制小飛船移動
if event.button == 1:
still = True
elif event.type == pygame.MOUSEBUTTONUP:
still = False
if event.button == 1:
carrect = carrect.move(event.pos[0] - carrect.left - 20,event.pos[1] - carrect.top - 20)
elif event.type == pygame.MOUSEMOTION:
if event.buttons[0] == 1:
carrect = carrect.move(event.pos[0] - carrect.left - 20,event.pos[1] - carrect.top - 20)
num +=1
i = 0
while i <= n2: #判斷是否碰到障礙
if carrect.left<SHU[i].left and carrect.right>SHU[i].right and ((carrect.top>SHU[i].top and carrect.top<SHU[i].bottom) or (carrect.bottom>SHU[i].top and carrect.bottom<SHU[i].bottom)):
speed[0]=speed[1]=0
loserect = lose.get_rect()
loserect = loserect.move(500,250)
screen.blit(lose,loserect)
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if event.pos[0] > loserect.left and event.pos[0] < loserect.right and event.pos[1] > loserect.top and event.pos[1] < loserect.bottom:
print("lose")
sys.exit()
i +=1
i = 0
while i <= n1:
if carrect.top<HENG[i].top and carrect.bottom>HENG[i].bottom and ((carrect.right>HENG[i].left and carrect.right<HENG[i].right) or (carrect.left>SHU[i].left and carrect.left<SHU[i].right)):
speed[0]=speed[1]=0
loserect = lose.get_rect()
loserect = loserect.move(500,250)
screen.blit(lose,loserect)
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if event.pos[0] > loserect.left and event.pos[0] < loserect.right and event.pos[1] > loserect.top and event.pos[1] < loserect.bottom:
print("you lose")
sys.exit()
i +=1
if carrect.left>1300 and carrect.right<1400 and carrect.top>700 and carrect.bottom<900: #判斷是否進入目標區域
speed[0]=speed[1]=0
winrect = win.get_rect()
winrect = winrect.move(600,350)
screen.blit(win,winrect)
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if event.pos[0] > winrect.left and event.pos[0] < winrect.right and event.pos[1] > winrect.top and event.pos[1] < winrect.bottom:
print("you win")
if num>1000:
print("score:0/1000")
else:
print("score:",1000-num,"/1000")
sys.exit()
carrect = carrect.move(speed[0],speed[1]) #車的慣性移動
if carrect.left < 0 or carrect.right > width: #車的碰壁反彈
speed[0]=-speed[0]
if carrect.top < 0 or carrect.bottom > height:
speed[1]=-speed[1]
screen.fill(WHITE) #屏幕刷新
screen.blit(car,carrect)
screen.blit(lose,loserect)
screen.blit(win,winrect)
i=0
while i<=n1:
screen.blit(mod[0],HENG[i])
i+=1
i=0
while i<=n2:
screen.blit(mod[1],SHU[i])
i+=1
pygame.display.update() #刷新顯示窗口
fclock.tick(fps)
實驗結果截圖
以及
3. 實驗過程中遇到的問題和解決過程
- 問題1:邊界判定比較復雜
- 問題1解決方案:冷靜分析
- 問題2:導入圖片失敗
- 問題2解決方案:通過上網查找以及視頻彈幕得知pygame.image.load()括號中填r+"絕對路徑"
- 問題3:成功及失敗時,最后的圖片沒有顯示出來
- 問題3解決方案:經過數次嘗試,發現要及時刷新屏幕,不然圖片是無法出現的。屏幕的刷新是pygame的核心部分。
課程感想體會
上了王老師的課的第一感受就是王老師的教學水平很高,總是能將復雜晦澀抽象的東西簡單化,讓我們對其有更加深入的理解。此外,王老師也總是和學生們打成一片,和學生對發表情包的老師又有誰不愛呢?至於我自身的學習方面,因為大一上學期的自學python讓我有了一定基礎,在課程前期的學習中比較輕松。但隨着學習內容的深入,我開始漸漸有些難以跟上老師教學的步伐了。由於基礎不夠扎實,總是會遇到各種各樣的問題,雖然雲班課中的教學資源非常充足,但過多的視頻學習資源同時讓人生畏,難以提起學習積極性來。在上課時,我總覺得有些知識點還沒弄透就學到了下一章節,對於基礎不好的同學不夠友好。所以我建議老師開設單雙學期的課程,單學期教授基礎課程,雙學期教授提高課程,讓萌新與大佬分隔開來,各取所需。即便如此學習的路程磕磕絆絆,我依然還是隨着老師的腳步,對python各個方面的內容都進行了一定方面的學習,尤其是網絡編程技術與網絡爬蟲,給我打開了新世界的大門,感謝王老師的辛勤付出及一個學期的陪伴。