前言:
? ? ? ? 大二小學期python課上基于pygame做的一個游戲小demo,當時老師花了一天講解了下python基礎語法后(也是整個大學四年唯一學習python的時間),便讓我們自學網課一周然后交項目,所以做的非常倉促(當時沒有面向對象概念,以及功能拆分的思想,所以所有代碼全堆在一個文件了),也算是自己做的第一個游戲,做完還是有些成就感的,不過很難崩的是結題演示的時候好多同學居然能做出植物大戰僵尸這種難度的游戲,(除去看網課去掉二十幾個小時基本每天我都在寫代碼找素材才能做一個相對完整的demo),雖然后來確實在網上看到有用pygame做植物大戰僵尸的源碼安慰自己他們可能有所參考,不過還是有挺強挫敗感的,好在老師人美心善,最后成績90+,前20%。最近計劃重裝舊電腦時,還是計劃整理下自己的項目,也算是自己大學四年的青春,如果是biter可以關注下,說不定就有你的課設分享。
最后提交內容鏈接:
Release origin · wlf728050719/BallGamehttps://github.com/wlf728050719/BallGame/releases/tag/1.0.0從release/origin下載BallGame.zip解壓即可(含源碼+演示視頻+開結題報告+設計文檔),不建議直接從code下代碼,后續可能會基于這個game用強化學習或深度學習設計下人機對戰,如果只是完成課設為目標大可不必,不過可以star下關注后續。
環境配置:
只需要安裝pygame即可
這是舊電腦沒使用anoconda的環境,python3.10.7? ?pygame 2.1.2
這是新電腦使用的anoconda的環境配置 python3.11 pygame 2.6.0
兩種配置都能運行,(雖然感覺使用任意版本的python和pygame應該都能正常運行,不過為了嚴謹還是寫下配置)
代碼:
顯然直接粘貼代碼會缺少資源文件無法運行,不過還是把代碼放上來,幫助大家了解pygame設計游戲的基本流程。(雖然無論從變量命名還是邏輯設計都能感受到當時的不成熟)
import random
import sys
import pygamepygame.init()
size = width, height = 400, 600 # 初始化屏幕speed: list[int] = [0, 0] # 小球運動速度
speed1 = [0, 0] # 擋板向上移動速度
speed2 = [0, 0] # 擋板向下移動速度
speed3 = [0, 0] # 障礙物0移動速度
speed4 = [0, 0] # 障礙物1移動速度
speed5 = [0, 0] # 障礙物2移動速度
speed6 = [0, 0] # 障礙物3移動速度speedx = [0, 0] # 緩存各對象速度
speed1x = [0, 0]
speed2x = [0, 0]
speed3x = [0, 0]
speed4x = [0, 0]
speed5x = [0, 0]
speed6x = [0, 0]active: int = 0 # 游戲運行參數 0:游戲第一次開始等待 1:游戲運行 2:游戲暫停 3:游戲結束重新開始等待
case = 0 # 緩沖參數初始化WHITE = 255, 255, 255 # 字體顏色
m: int = 0 # 當前幀數
z =0c = 0 # 初始化道具效果隨機數
last = 0 # 上一次碰撞板子
gamemap = 1 # 游戲地圖序號
speedmode = 1 # 速度模式
myfont = pygame.font.Font(None, 30) # 設置字體以及大小
long_press = {'up': False, 'down': False} # 實現連續移動
long_press2 = {'up': False, 'down': False}
bg = pygame.image.load("resources/img/page/game.png") # 設置背景圖片score1 = 0 # 設置初始得分
score2 = 0mi = True
screen = pygame.display.set_mode(size, pygame.FULLSCREEN) # 全屏
a = screen.get_width() # 獲取屏幕寬度
b = screen.get_height() # 獲取屏幕高度
pygame.display.set_caption("雙人彈球") # 標題名
fps: int = 100 # 刷新速度
# 生成 surface對象以及rect對象
ball = pygame.image.load("resources/img/component/ball/ball_0.png") # 小球運動動圖
ballrect = ball.get_rect()
ball1 = pygame.image.load("resources/img/component/ball/ball_1.png")
ball2 = pygame.image.load("resources/img/component/ball/ball_2.png")
ball3 = pygame.image.load("resources/img/component/ball/ball_3.png")
ball4= pygame.image.load("resources/img/component/ball/ball_4.png")win1 = pygame.image.load("resources/img/component/win/player1_win.png")
win2 = pygame.image.load("resources/img/component/win/player2_win.png")
start = pygame.image.load("resources/img/page/start.png")
banzi1 = pygame.image.load("resources/img/component/player/player.png")
banzi1rect = banzi1.get_rect()
banzi2 = pygame.image.load("resources/img/component/player/player.png")
banzi2rect = banzi2.get_rect()
redball = pygame.image.load("resources/img/component/red_prop/red_prop_1.png")
redballrect = redball.get_rect()barrier = pygame.image.load("resources/img/component/barrier/barrier_v.png")
barrierrect = barrier.get_rect()
barrier1 = pygame.image.load("resources/img/component/barrier/barrier_v.png")
barrier1rect = barrier1.get_rect()
barrier2 = pygame.image.load("resources/img/component/barrier/barrier_h.png")
barrier2rect = barrier2.get_rect()
barrier3 = pygame.image.load("resources/img/component/barrier/barrier_h.png")
barrier3rect = barrier3.get_rect()jiantouleft = pygame.image.load("resources/img/component/tip/left.png")
jiantouright = pygame.image.load("resources/img/component/tip/right.png")
xuanzhong = pygame.image.load("resources/img/component/tip/selected.png")
map1 = pygame.image.load("resources/img/component/map/map1.png")
map2 = pygame.image.load("resources/img/component/map/map2.png")
map3= pygame.image.load("resources/img/component/map/map3.png")banzi2rect = banzi2rect.move(a - 8, 500) # 確認各對象初始位置
banzi1rect = banzi1rect.move(0, 500)
redballrect = redballrect.move(100, 100)
ballrect = ballrect.move(a / 2, 10)
fclock = pygame.time.Clock() # 計時pygame.mixer.init() # 初始化音頻文件music = pygame.mixer.music.load("resources/audio/bgm/main_bgm_1.mp3") # 加載音樂文件
pygame.mixer.music.set_volume(0.01) # 控制背景音樂聲音大小
pygame.mixer.music.play() # 開始播放音樂流
bang = pygame.mixer.Sound("resources/audio/sound_effect/hit.wav")
pop = pygame.mixer.Sound("resources/audio/sound_effect/pop.wav")
shao = pygame.mixer.Sound("resources/audio/sound_effect/whistle.wav")
huanhu = pygame.mixer.Sound("resources/audio/sound_effect/cheer.wav")
anjian = pygame.mixer.Sound("resources/audio/sound_effect/click.wav")while True:if pygame.mixer.music.get_busy() == False: # 檢查是否正在播放音樂pygame.mixer.music.play() # 開始播放音樂流for i in pygame.event.get():if i.type == pygame.QUIT: # 退出sys.exit()elif i.type == pygame.KEYDOWN: # 擋板連續移動if i.key == pygame.K_UP:long_press['up'] = Trueif i.key == pygame.K_DOWN:long_press['down'] = Trueif i.key == pygame.K_w:long_press2['up'] = Trueif i.key == pygame.K_s:long_press2['down'] = Trueif i.key == pygame.K_h: # 選擇速度模式if active == 0:speedmode = 3anjian.play()if i.key == pygame.K_m:if active == 0:speedmode = 2anjian.play()if i.key == pygame.K_l:if active == 0:speedmode = 1anjian.play()if i.key == pygame.K_RETURN: # 按下回車開始游戲if active != 1:anjian.play()if active == 0:if speedmode == 1:speed = [1, 1] # 小球運動速度speed1 = [0, -2] # 擋板向上移動速度speed2 = [0, 2] # 擋板向下移動速度speed3 = [0, 2] # 障礙物0移動速度speed4 = [0, -2] # 障礙物1移動速度speed5 = [2, 0] # 障礙物2移動速度speed6 = [-2, 0] # 障礙物3移動速度elif speedmode == 2:speed = [2, 2] # 小球運動速度speed1 = [0, -3] # 擋板向上移動速度speed2 = [0, 3] # 擋板向下移動速度speed3 = [0, 3] # 障礙物0移動速度speed4 = [0, -3] # 障礙物1移動速度speed5 = [3, 0] # 障礙物2移動速度speed6 = [-3, 0] # 障礙物3移動速度elif speedmode == 3:speed = [3, 3] # 小球運動速度speed1 = [0, -4] # 擋板向上移動速度speed2 = [0, 4] # 擋板向下移動速度speed3 = [0, 4] # 障礙物0移動速度speed4 = [0, -4] # 障礙物1移動速度speed5 = [4, 0] # 障礙物2移動速度speed6 = [-4, 0] # 障礙物3移動速度active = 1 # 進入游戲運行狀態elif active == 3:score1 = 0score2 = 0speed = [0, 0]speed1 = [0, 0]speed2 = [0, 0]speed3 = [0, 0]speed4 = [0, 0]speed5 = [0, 0]speed6 = [0, 0]active = 0 # 游戲結束后回到開始界面if i.key == pygame.K_SPACE: # 游戲運行時按下空格暫停,再次按下繼續anjian.play()if active == 1:speedx = speed.copy()speed1x = speed1.copy()speed2x = speed2.copy()speed3x = speed3.copy()speed4x = speed4.copy()speed5x = speed5.copy()speed6x = speed6.copy()speed = [0, 0]speed1 = [0, 0]speed2 = [0, 0]speed3 = [0, 0]speed4 = [0, 0]speed5 = [0, 0]speed6 = [0, 0]active = 2elif active == 2:speed = speedx.copy()speed1 = speed1x.copy()speed2 = speed2x.copy()speed3 = speed3x.copy()speed4 = speed4x.copy()speed5 = speed5x.copy()speed6 = speed6x.copy()active = 1if i.key == pygame.K_1 or i.key == pygame.K_KP1: # 選擇地圖if active == 0:anjian.play()gamemap = 1if i.key == pygame.K_2 or i.key == pygame.K_KP2:if active == 0:anjian.play()gamemap = 2if i.key == pygame.K_3 or i.key == pygame.K_KP3:if active == 0:anjian.play()gamemap = 3elif i.key == pygame.K_ESCAPE:sys.exit()if i.type == pygame.KEYUP:if i.key == pygame.K_UP:long_press['up'] = Falseif i.key == pygame.K_DOWN:long_press['down'] = Falseif i.key == pygame.K_w:long_press2['up'] = Falseif i.key == pygame.K_s:long_press2['down'] = Falseif long_press['up']:banzi2rect = banzi2rect.move(speed1)if long_press['down']:banzi2rect = banzi2rect.move(speed2)if long_press2['up']:banzi1rect = banzi1rect.move(speed1)if long_press2['down']:banzi1rect = banzi1rect.move(speed2)if banzi1rect.top < 0: # 限制擋板高度banzi1rect.top = 0if banzi1rect.bottom > height:banzi1rect.bottom = heightif banzi2rect.top < 0:banzi2rect.top = 0if banzi2rect.bottom > height:banzi2rect.bottom = heightif active == 0: # 初始化地圖if gamemap == 1: # 地圖1barrierrect.x = a / 2 - 100barrierrect.y = b / 2barrier1rect.x = a / 2 + 100barrier1rect.y = b / 2if gamemap == 2: # 地圖2barrier2rect.x = 200barrier2rect.y = 200barrier3rect.x = 550barrier3rect.y = 400if gamemap == 3:barrierrect.x = a / 2 - 100barrierrect.y = b / 2barrier1rect.x = a / 2 + 100barrier1rect.y = b / 2barrier2rect.x = 200barrier2rect.y = 200barrier3rect.x = 550barrier3rect.y = 400if active == 1: # 設置不同地圖障礙物運行規律以及球與障礙物碰撞效果if gamemap == 1:barrierrect = barrierrect.move(speed3) # 障礙物上下移動barrier1rect = barrier1rect.move(speed4)if barrierrect.top < 0 or barrierrect.bottom > b:speed3[1] = -speed3[1]if barrier1rect.top < 0 or barrier1rect.bottom > b:speed4[1] = -speed4[1]f = ballrect.colliderect(barrierrect)v = ballrect.colliderect(barrier1rect)if f:if speed[0] > 0:ballrect.right = barrierrect.leftbang.play()speed[0] = - speed[0]elif speed[0] < 0:ballrect.left = barrierrect.rightbang.play()speed[0] = - speed[0]if v:if speed[0] > 0:ballrect.right = barrier1rect.leftbang.play()speed[0] = - speed[0]elif speed[0] < 0:ballrect.left = barrier1rect.rightbang.play()speed[0] = - speed[0]if gamemap == 2:barrier2rect = barrier2rect.move(speed5) # 障礙物左右移動barrier3rect = barrier3rect.move(speed6)if barrier2rect.left < 200 or barrier2rect.right > 600:speed5[0] = -speed5[0]if barrier3rect.left < 200 or barrier3rect.right > 600:speed6[0] = -speed6[0]f1 = ballrect.colliderect(barrier2rect)v1 = ballrect.colliderect(barrier3rect)if f1:if speed[1] > 0:ballrect.bottom = barrier2rect.topbang.play()speed[1] = - speed[1]elif speed[1] < 0:ballrect.top = barrier2rect.bottombang.play()speed[1] = - speed[1]if v1:if speed[1] > 0:ballrect.bottom = barrier3rect.topbang.play()speed[1] = - speed[1]elif speed[1] < 0:ballrect.top = barrier3rect.bottombang.play()speed[1] = - speed[1]if gamemap == 3:barrierrect = barrierrect.move(speed3) # 障礙物上下移動barrier1rect = barrier1rect.move(speed4)barrier2rect = barrier2rect.move(speed5) # 障礙物左右移動barrier3rect = barrier3rect.move(speed6)if barrierrect.top < 0 or barrierrect.bottom > b:speed3[1] = -speed3[1]if barrier1rect.top < 0 or barrier1rect.bottom > b:speed4[1] = -speed4[1]if barrier2rect.left < 200 or barrier2rect.right > 600:speed5[0] = -speed5[0]if barrier3rect.left < 200 or barrier3rect.right > 600:speed6[0] = -speed6[0]f = ballrect.colliderect(barrierrect)v = ballrect.colliderect(barrier1rect)f1 = ballrect.colliderect(barrier2rect)v1 = ballrect.colliderect(barrier3rect)if f:if speed[0] > 0:ballrect.right = barrierrect.leftbang.play()speed[0] = - speed[0]elif speed[0] < 0:ballrect.left = barrierrect.rightbang.play()speed[0] = - speed[0]if v:if speed[0] > 0:ballrect.right = barrier1rect.leftbang.play()speed[0] = - speed[0]elif speed[0] < 0:ballrect.left = barrier1rect.rightbang.play()speed[0] = - speed[0]if f1:if speed[1]>0:ballrect.bottom=barrier2rect.topbang.play()speed[1] = - speed[1]elif speed[1]<0:ballrect.top = barrier2rect.bottombang.play()speed[1] = - speed[1]if v1:if speed[1] > 0:ballrect.bottom = barrier3rect.topbang.play()speed[1] = - speed[1]elif speed[1] < 0:ballrect.top = barrier3rect.bottombang.play()speed[1] = - speed[1]screen.blit(bg, (0, 0)) # 繪制背景if active == 0: # 繪制開始界面screen.blit(start, (0, 0))if speedmode == 1: # 繪制選中速度效果screen.blit(xuanzhong, (52, 335))elif speedmode == 2:screen.blit(xuanzhong, (201, 335))elif speedmode == 3:screen.blit(xuanzhong, (346, 335))if gamemap == 1: # 繪制選中地圖效果screen.blit(xuanzhong, (49, 459))screen.blit(map1, (475, 316))elif gamemap == 2:screen.blit(xuanzhong, (201, 459))screen.blit(map2, (475, 316))elif gamemap == 3:screen.blit(xuanzhong, (346, 459))screen.blit(map3, (475, 316))if ballrect.right < 0: # 小球得分判定score2 = score2 + 1if ballrect.left > a:score1 = score1 + 1wenzi1 = str(score1)wenzi2 = str(score2)textImage1 = myfont.render("playerA:" + wenzi1, True, WHITE)textImage2 = myfont.render("playerB:" + wenzi2, True, WHITE)m = m + 1 # 記錄幀數if ballrect.right < 0 or ballrect.left > a: # 小球出界后重新發球ballrect.top = 10ballrect.left = a / 2+10last = 0speed = [0, 0]z = random.randint(1, 2)if active != 3:shao.play()case = 1if m % 400 != 0 and case == 1: # 預告小球發球方向if z == 1:screen.blit(jiantouright, (450, 300))if z == 2:screen.blit(jiantouleft, (310, 300))if m % 400 == 0 and case == 1: # 小球出界后緩沖后并以隨機速度及方向發出case = 0bang.play()if z == 1:if speedmode == 1:speed[0] = random.randint(1, 2)speed[1] = random.randint(1, 2)elif speedmode == 2:speed[0] = random.randint(2, 3)speed[1] = random.randint(2, 3)elif speedmode == 3:speed[0] = random.randint(3, 4)speed[1] = random.randint(3, 4)elif z == 2:if speedmode == 1:speed[0] = random.randint(-2, -1)speed[1] = random.randint(1, 2)elif speedmode == 2:speed[0] = random.randint(-3, -2)speed[1] = random.randint(2, 3)elif speedmode == 3:speed[0] = random.randint(-4, -3)speed[1] = random.randint(3, 4)ballrect = ballrect.move(speed) # 小球運動if ballrect.top < 0 or ballrect.bottom > height: # 小球上下運動反彈speed[1] = - speed[1]bang.play()# 球與兩邊擋板撞擊效果t = ballrect.colliderect(banzi1rect)k = ballrect.colliderect(banzi2rect)if t:ballrect.left = banzi1rect.rightspeed[0] = - speed[0]last = 1bang.play()if k:ballrect.right = banzi2rect.leftspeed[0] = - speed[0]last = 2bang.play()f = ballrect.colliderect(redballrect) # 紅色小球被吃掉效果if f == True:mi = Falsepop.play()if mi == False:redballrect.left = 2 * aredballrect.top = 2 * b # 小球被吃掉后移出屏幕產生消失效果c = random.randint(1, 2) # 生成隨機數c,產生相應效果if c == 1: # 道具效果1:讓球上一次碰撞擋板一方加分if last == 1:score1 = score1 + 5if last == 2:score2 = score2 + 5if c == 2: # 道具效果2:讓球速度最大if speed[0] > 0:speed[0] = 4if speed[0] < 0:speed[0] = -4if speed[1] > 0:speed[1] = 4if speed[1] < 0:speed[1] = -4c = 0 # 重置道具效果if m % 2000 == 0: # 小球位置隨機x = random.randint(200, 300)y = random.randint(200, 300)redballrect.left = xredballrect.top = yif int(m / 1000) % 2 == 0 and active == 1: # 紅色小球周期性出現mi = Truescreen.blit(redball, redballrect)else:redballrect.left = 2 * aredballrect.top = 2 * bif active == 1 or active == 2:if m % 5 == 0: # 實現小球滾動screen.blit(ball, ballrect)elif m % 5 == 1:screen.blit(ball1, ballrect)elif m % 5 == 2:screen.blit(ball2, ballrect)elif m % 5== 3:screen.blit(ball3, ballrect)elif m % 5 == 4:screen.blit(ball4, ballrect)if gamemap == 1:screen.blit(barrier, barrierrect)screen.blit(barrier1, barrier1rect)if gamemap == 2:screen.blit(barrier2, barrier2rect)screen.blit(barrier3, barrier3rect)if gamemap == 3:screen.blit(barrier, barrierrect)screen.blit(barrier1, barrier1rect)screen.blit(barrier2, barrier2rect)screen.blit(barrier3, barrier3rect)screen.blit(banzi1, banzi1rect)screen.blit(banzi2, banzi2rect)screen.blit(textImage1, (100, 100)) # 顯示字體,確定出現位置screen.blit(textImage2, (a - 200, 100))if score1 >= 5: # 游戲結束判定 繪制結束圖像screen.blit(win1,(300,200))active = 3if score2 >= 5:screen.blit(win2, (300, 200))active = 3if active == 3: # 一方獲勝暫停游戲speed = [0, 0]speed1 = [0, 0]speed2 = [0, 0]speed3 = [0, 0]speed4 = [0, 0]pygame.display.update()fclock.tick(fps)
印象比較深的一個bug是道具球被吃掉時,要么會持續觸發道具效果以及會一直渲染在畫面中,當時冥思苦想很久最后想出將它移動到屏幕外面,當時簡直感覺自己是天才,雖然現在感覺好像沒啥。不過好像大多數bug都是沒解決的時候很難,解決后感覺這么簡單為啥會難住自己這么久。
設計文檔:(壓縮包里有完整doc文件,這里僅做展示)
(關于分工部分,其實整個項目都是獨立開發的,為了老師那邊不出問題還是平均分的工,當然這里不是說另外一位同學是擺子,只是他在另外一個小組課設有很大投入,但我在那個項目就單純做做美工,最終也是90+,所以相當于等價交換了,如果你的課設需要有分工的話可以參考我的劃分)以及如果覺得游戲設計文檔過于簡單,可以參考我大三unity項目的設計文檔。
基于Unity3D的游戲開發項目(包含源碼與演示視頻)_汪洛飛-CSDN博客https://blog.csdn.net/wlf2030/article/details/144664436?spm=1001.2014.3001.5501
整體目標設計:
本游戲在“壁球”游戲上進行改良,擴充為雙人對抗類游戲,玩家雙方分別使用鍵盤的“W”“S”以及上下鍵分別控制屏幕最左側和最右側的擋板攔截壁球并進行反彈,屏幕上下邊緣以及屏幕中對稱排列的擋板會將壁球反彈,屏幕特定區域會定時隨機位置出現道具小球,當壁球碰撞到道具小球時會根據道具效果,改變小球的速度以及方向,或者增加壁球上一次碰撞方得分。增加開始與一輪游戲結束界面,玩家能夠自由選擇游戲難度以及游戲地圖,添加小球運動動畫效果,添加游戲背景音樂以及音效具有暫停功能,小球出界后不會直接游戲結束,會重新發球,并預告發球方向,直到一方目標達到預設得分玩家在一輪游戲結束后能夠選擇返回開始界面繼續游玩,或者直接退出。
分工說明:
游戲基本框架討論后共同搭建,游戲文件共享,并標明注釋,便于個人測試。
游戲主要功能各自提出自己看法,討論并測試后編寫
個人完成部分功能后向另外成員解釋代碼含義,發現bug后提出各自意見修復。
楊宜松:??????????????????????????????????汪洛飛:
游戲方案及類型提出????????????????????????碰撞檢測
擋板連續移動??????????????????????????????碰撞檢測改進
碰撞檢測??????????????????????????????????道具小球消失
道具小球消失??????????????????????????????道具小球消失改進
得分記錄及文本顯示????????????????????????小球發球預告
小球道具效果,音效播放????????????????????頁面跳轉及難度設置
??????????????????????????????????????????圖片,音樂素材
(以上有相同部分表示兩人對同一功能有不同的方法或共同參與設計)
代碼總體框架:
初始化各種參數,生成surface對象,rect對象。
根據游戲運行參數的不同對不同事件做出相應的處理,包括地圖參數以及速度參數的生成
根據地圖參數初始化地圖,以及地圖中障礙物的碰撞效果
繪制開始頁面時選中效果
小球得分判定
小球出界后發球以及預告
小球上下邊界以及兩邊擋板反彈效果
道具小球被吃掉以及產生道具效果
小球動圖效果以及得分文本顯示
游戲結束判定
第三方庫介紹:
本游戲僅使用pygame,sys,random庫,未引用其他第三方庫
運行環境配置以及運行指導說明:
本游戲背景圖為800*600像素大小,顯示器大小不得小于此。
游戲幀率默認設為100,若顯示器無法穩定滿足此幀率請自行在代碼第49行修改fps數值,(此數值不建議小于60,否則會產生較差視覺效果以及游戲體驗)
軟件運行截圖:
(以下圖片均為實機演示,非圖片編輯軟件修改)
完成度自我評價:
個人認為游戲開發已經十分完整,增加許多功能,已經大大超過游戲設計預期,同時游戲引導人性化,與玩家交互性高。
個人工作:
1.
if m % 5 == 0: ???# 實現小球滾動screen.blit(ball, ballrect)
elif m % 5 == 1:screen.blit(ball1, ballrect)
elif m % 5 == 2:screen.blit(ball2, ballrect)
elif m % 5== 3:screen.blit(ball3, ballrect)
elif m % 5 == 4:screen.blit(ball4, ballrect)
由于pygame不支持播放gif形式圖片,使用在不同幀數的情況下,在小球上繪制不同的圖片從而達到動圖效果的方法
2:
f = ballrect.colliderect(barrierrect)
v = ballrect.colliderect(barrier1rect)
if f:if speed[0] > 0:ballrect.right = barrierrect.leftbang.play()speed[0] = - speed[0]elif speed[0] < 0:ballrect.left = barrierrect.rightbang.play()speed[0] = - speed[0]
改進前沒有ballrect.right = barrierrect.left部分,導致小球在某些特殊情況下會出現黏在擋板上震動的效果,對游戲體驗影響較大
3:
if ballrect.right < 0 or ballrect.left > a: ?# 小球出界后重新發球ballrect.top = 10ballrect.left = a / 2+10last = 0speed = [0, 0]z = random.randint(1, 2)if active != 3:shao.play()case = 1
if m % 400 != 0 and case == 1: ?# 預告小球發球方向if z == 1:screen.blit(jiantouright, (450, 300))if z == 2:screen.blit(jiantouleft, (310, 300))
if m % 400 == 0 and case == 1: ?# 小球出界后緩沖后并以隨機速度及方向發出case = 0bang.play()if z == 1:if speedmode == 1:speed[0] = random.randint(1, 2)speed[1] = random.randint(1, 2)
在小球出界后,用幀數是否整除400來進行時間的計算,,先生成隨機數后再繪制預告圖片,并增加參數case防止預告圖片持續顯示,時間條件滿足后根據生成隨機數以及對應的速度模式發球。
4:
f = ballrect.colliderect(redballrect) ?# 紅色小球被吃掉效果
if f == True:mi = Falsepop.play()
if mi == False:redballrect.left = 2 * aredballrect.top = 2 * b ?# 小球被吃掉后移出屏幕產生消失效果c = random.randint(1, 2) ?# 生成隨機數c,產生相應效果............................................................................................................................................(道具具體效果代碼)if int(m / 1000) % 2 == 0 and active == 1: ?# 紅色小球周期性出現mi = Truescreen.blit(redball, redballrect)
else:redballrect.left = 2 * aredballrect.top = 2 * b
道具小球與球碰撞后移出屏幕外產生被吃掉效果,并映入mi這一參數,當碰撞后為false,使道具球移出,用int(m/1000)%2==0作為時間判定語句,滿足后使mi=true,小球重新回到屏幕
5:
active: int = 0 ?# 游戲運行參數?0:游戲第一次開始等待?1:游戲運行?2:游戲暫停?3:游戲結束重新開始等待......if i.key == pygame.K_1 or i.key == pygame.K_KP1: ?# 選擇地圖if active == 0:anjian.play()gamemap = 1.....................if score1 >= 6: ?# 游戲結束判定 繪制結束圖像screen.blit(win1,(300,200))active = 3....................
if active == 3: ??# 一方獲勝暫停游戲speed = [0, 0]speed1 = [0, 0]speed2 = [0, 0]speed3 = [0, 0]speed4 = [0, 0]
(由于游戲運行參數作為游戲狀態判定的依據,在游戲代碼中出現次數過多,且位于各個部分,現只展示代表性代碼)
引入游戲運行參數,使游戲避免引用pgu庫便產生多級頁面效果,并根據玩家產生的事件改變參數的數值,從而產生頁面的跳轉效果,但分析后得知,此方法僅適用于頁面較少的情況,頁面過多會導致參數值太多,代碼層次混亂,不建議大量使用。
開題PPT:(壓縮包里有完整ppt文件,這里僅做展示)
結題PPT:(壓縮包里有完整ppt文件,這里僅做展示)
演示視頻:
因為以現在的眼光確實很簡單就不上傳到b站或博客了,需要可自行解壓壓縮包查看。
最后:
? ? ? ? 興趣確實是最好的老師,寫這篇博客感覺像是和過去的自己對話,當時確實仍有滿腔熱血,能熬夜兩三點寫游戲代碼,現在讀研感覺無論找工作或是做學術都會有很大壓力,以及從我的博客也能看出比較偏向java分布式以及python深度學習了,以后從業也基本與游戲無緣了,還是有些可惜。最后還是祝各位能永遠熱愛你所熱愛的!