PyGame游戲開發(含源碼+演示視頻+開結題報告+設計文檔)

前言:

? ? ? ? 大二小學期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深度學習了,以后從業也基本與游戲無緣了,還是有些可惜。最后還是祝各位能永遠熱愛你所熱愛的!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/80602.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80602.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/80602.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用 React 實現語音識別并轉換功能

在現代 Web 開發中&#xff0c;語音識別技術的應用越來越廣泛。它為用戶提供了更加便捷、自然的交互方式&#xff0c;例如語音輸入、語音指令等。本文將介紹如何使用 React 實現一個簡單的語音識別并轉換的功能。 功能概述 我們要實現的功能是一個語音識別測試頁面&#xff0…

C++ 雙峰高斯函數擬合

C 雙峰高斯函數擬合 一維高斯函數二維高斯函數多維高斯函數一維雙峰高斯函數代碼實現 二維雙峰高斯函數代碼實現 多維多峰高斯函數 在數據分析與清洗中經常遇到這樣的數據&#xff1a;數據不僅僅向單個中心靠攏&#xff0c;而是類似分段的向兩個甚至多個中心靠攏。數據向單個中…

【RP2350】香瓜樹莓派RP2350之LED

本文最后修改時間&#xff1a;2025年05月10日 01:57 一、本節簡介 本節以樹莓派pico2開發板為例&#xff0c;舉例如何寫一個LED驅動加進工程里。 二、實驗平臺 1、硬件平臺 1&#xff09;樹莓派pico2開發板 ①樹莓派pico2開發板&#xff08;作為仿真器&#xff09; ②micr…

機器人運動控制原理淺析-UC Berkeley超視覺模態模型

加州伯克利發布的超視覺多感知模態融合(FuSe, Fuse Heterogeneous Sensory Data)模型&#xff0c;基于視覺、觸覺、聽覺、本體及語言等模態&#xff0c;利用自然語言跨模態對齊(Cross-Modal Grounding)優調視覺語言動作等通用模型&#xff0c;提高模型任務成功率。 總體框架 …

【Bootstrap V4系列】學習入門教程之 組件-媒體對象(Media object)

Bootstrap V4系列 學習入門教程之 組件-媒體對象&#xff08;Media object&#xff09; 媒體對象&#xff08;Media object&#xff09;一、Example二、Nesting 嵌套三、Alignment 對齊四、Order 順序五、Media list 媒體列表 媒體對象&#xff08;Media object&#xff09; B…

解決VirtualBox中虛擬機(ubuntu)與主機(windows)之間互相復制粘貼(文本)

一.開始的設置 1.在VirtualBox中打開設置&#xff0c;常規中修改主機與虛擬機交互設置 2.虛擬機關閉狀態下&#xff0c;存儲中選中控制器SATA&#xff0c;勾選‘使用主機輸入輸出’ 3.選中操作系統對應的虛擬文件&#xff0c;.vdi文件&#xff0c;勾選右邊的固態驅動器。 4.啟…

java 多核,多線程,分布式 并發編程的現狀 :從本身的jdk ,到 spring ,到其它第三方。

Java 在多核、多線程和高性能編程領域提供了豐富的現成框架和工具&#xff0c;既有標準庫中的并發組件&#xff0c;也有第三方框架。以下是一些關鍵框架及其應用場景的總結&#xff1a;便于后面我們站在巨人的肩膀上&#xff0c;繼續前行 一、Java 標準庫中的多線程框架 Execut…

Nodejs核心機制

文章目錄 前言 前言 結合 Node.js 的核心機制進行說明&#xff1a; 解釋事件循環的各個階段。 答案 Node.js 事件循環分為 6 個階段&#xff0c;按順序執行&#xff1a; Timers&#xff1a;執行 setTimeout 和 setInterval 的回調。 Pending I/O Callbacks&#xff1a;處理系…

C++筆記6:數字字面量后綴和前綴總結

在C中&#xff0c;可以在數字字面量后面添加字母后綴&#xff08;或前綴&#xff09;來表示特定的數據類型。這些后綴能夠明確指定字面量的類型&#xff0c;避免類型轉換帶來的潛在問題。以下是常見的幾種類型后綴及其含義&#xff1a; 1. 整數后綴 u 或 U&#xff1a;表示 u…

50.輻射抗擾RS和傳導抗擾CS測試環境和干擾特征分析

輻射抗擾RS和傳到抗擾CS測試環境和干擾特征分析 1. 輻射抗擾RS2. 傳導抗擾CS 1. 輻射抗擾RS 輻射抗擾RS考察對外界電磁場干擾得抗擾能力&#xff0c;測試頻段為80MHz~2000MHz&#xff0c;用1KHz得正弦波進行調幅&#xff0c;在電波暗室內進行。測試標準&#xff1a;IEC 61000-…

Java多態詳解

Java多態詳解 什么是多態&#xff1f; 比如我們說&#xff1a;“駕駛一輛車”&#xff0c;有人開的是自行車&#xff0c;有人開的是摩托車&#xff0c;有人開的是汽車。雖然我們都說“開車”&#xff0c;但“怎么開”是由具體的車類型決定的&#xff1a;“開”是統一的動作&a…

問題及解決01-面板無法隨著窗口的放大而放大

在MATLAB的App Designer中&#xff0c;默認情況下&#xff0c;組件的位置是固定的&#xff0c;不會隨著父容器的大小變化而改變。問題圖如下圖所示。 解決&#xff1a; 為了讓Panel面板能夠隨著UIFigure父容器一起縮放&#xff0c;需要使用布局管理器&#xff0c;我利用 MATLA…

【GESP真題解析】第 20 集 GESP 二級 2025 年 3 月編程題 2:時間跨越

大家好,我是莫小特。 這篇文章給大家分享 GESP 二級 2025 年 3 月編程題第 2 題:時間跨越。 題目鏈接 洛谷鏈接:B4260 時間跨越 一、完成輸入 根據題意,輸入包含五行,每行一個正整數,分別代表 y,m,d,h,k。 注意到數據范圍:對于全部數據,保證有 2000≤y≤3000,1≤m≤…

GTS-400 系列運動控制器板卡介紹(二十一)---電子齒輪跟隨

運動控制器函數庫的使用 運動控制器驅動程序、dll 文件、例程、Demo 等相關文件請通過固高科技官網下載,網 址為:www.googoltech.com.cn/pro_view-3.html 1 Windows 系統下動態鏈接庫的使用 在 Windows 系統下使用運動控制器,首先要安裝驅動程序。在安裝前需要提前下載運動…

軟件工程之需求分析涉及的圖與工具

需求分析與規格說明書是一項十分艱巨復雜的工作。用戶與分析員之間需要溝通的內容非常的多&#xff0c;在雙方交流信息的過程中很容易出現誤解或遺漏&#xff0c;也可能存在二義性。如何才能更加準確的表達雙方的意思&#xff0c;且清楚明了&#xff0c;繪制各類圖形就顯得非常…

藍橋杯14屆 數三角

問題描述 小明在二維坐標系中放置了 n 個點&#xff0c;他想在其中選出一個包含三個點的子集&#xff0c;這三個點能組成三角形。然而這樣的方案太多了&#xff0c;他決定只選擇那些可以組成等腰三角形的方案。請幫他計算出一共有多少種選法可以組成等腰三角形&#xff1f; 輸…

在Fiddler中添加自定義HTTP方法列并高亮顯示

在Fiddler中添加自定義HTTP方法列并高亮顯示 Fiddler 是一款強大的 Web 調試代理工具&#xff0c;允許開發者檢查和操作 HTTP 流量。一個常見需求是自定義 Web Sessions 列表&#xff0c;添加顯示 HTTP 方法&#xff08;GET、POST 等&#xff09;的列&#xff0c;并通過顏色區…

數據庫分庫分表實戰指南:從原理到落地

1. 為什么要分庫分表&#xff1f; 1.1 單庫瓶頸表現 存儲瓶頸&#xff1a;單表數據超過5000萬行&#xff0c;查詢性能急劇下降性能瓶頸&#xff1a;單庫QPS超過5000后響應延遲顯著增加可用性風險&#xff1a;單點故障導致全系統不可用 1.2 突破性優勢 --------------------…

Selenium的driver.get_url 和 手動輸入網址, 并點擊的操作,有什么不同?

我在搞爬取的時候&#xff0c;發現有些網站直接用driver.get(url) 跳轉到目標特定的網址的時候&#xff0c;會被強制跳轉到其他的網址上&#xff0c;但是如果是自己手動&#xff0c;在網址欄那里輸入網址&#xff0c;并點回車&#xff0c;卻能完成跳轉。 這是在使用 Selenium …

Java【06】數組查找(二分查找)、排序(冒泡排序、簡單選擇排序)

1. 數組的操作 1.1 數組的反轉 int[] arrs{3,5,7,8,9}; 編寫程序&#xff0c;讓arrs中的數據進行反轉{9,8,7,5,3} 1.2數組的查找 ① 順序查找 從頭到尾一個一個的找&#xff01; ② 二分查找 對數組有一個要求&#xff1a;數組必須是有序(大小)的&#xff01; int num3; int[]…