Learning Python's Pygame Development Contra (16)
-
- Complete the final Contra
-
- 1. Create the Sound class
- 2. Add background music
- 3. Add the sound effect of the player firing bullets
- 4. Increase the sound effect of hitting the boss's vital points
- 5. Hitting the enemy sound effect
- 6. Add entry animation
- 7. Solve the problem of players falling out of the map and dying
- 8. Improve the player's game failure function
- 9. Summary
Complete the final Contra
In the last blog to learn Python Pygame development Contra (fifteen) , we added a boss. So far, the main part of Contra has been completed. The next step is to add a little enemy in other places and set the entry animation , victory animation, failure animation and sound effects, in this blog, we add sound effects and join the entry animation.
The following is the material and source code of the picture, I also put the source code on the network disk
Link: https://pan.baidu.com/s/1X7tESkes_O6nbPxfpHD6hQ?pwd=hdly
Extraction code: hdly
1. Create the Sound class
import pygame
class Sound:
def __init__(self, filename):
self.filename = filename
pygame.mixer.init()
self.sound = pygame.mixer.Sound(self.filename)
def play(self, loops = 0):
self.sound.play(loops)
def stop(self):
self.sound.stop()
def setVolume(self):
self.sound.set_volume(0.2)
return self
Import this class into the class that needs to play sound effects
2. Add background music
Add the following code to the constructor of the main class, and play background music in the run() function
# 加载音乐
self.backgroundMusic = Sound('../Sound/1.mp3')
Be careful not to join the loop
3. Add the sound effect of the player firing bullets
Come to the player 1 category, find the fire() function, and modify the code
def fire(self, currentTime, playerBulletList):
self.isFiring = True
# 潜水状态下不能开火
if not (self.isInWater and self.isSquating):
if len(playerBulletList) < PLAYER_BULLET_NUMBER:
if currentTime - self.fireLastTimer > 150:
Sound('../Sound/commonFire.mp3').play()
playerBulletList.append(Bullet(self))
self.fireLastTimer = currentTime
4. Increase the sound effect of hitting the boss's vital points
Come to the bullet class and modify the collideEnemy() function
5. Hitting the enemy sound effect
Or add code to the collideEnemy() function of the bullet class
def collideEnemy(self, enemyList, explodeList):
for enemy in enemyList:
if pygame.sprite.collide_rect(self, enemy):
if enemy.type == 3 or enemy.type == 4:
enemy.life -= 1
Sound('../Sound/hitWeakness.mp3').play()
if enemy.life <= 0:
self.isDestroy = True
enemy.isDestroy = True
explodeList.append(Explode(enemy, ExplodeVariety.BRIDGE))
else:
Sound('../Sound/enemyDie.mp3').play()
self.isDestroy = True
enemy.isDestroy = True
explodeList.append(Explode(enemy))
Since the blogger has no other sound effects, I can only add this part. If you find the sound effects yourself, you can add them to make the game more complete
6. Add entry animation
Add the loading and entering animation function to the main class
def loadApproachAnimation(self):
# 读取进场图片
approach = pygame.image.load('../Image/Map/1/Background/First(Approach).png')
approachRect = self.background.get_rect()
approach = pygame.transform.scale(
approach,
(int(approachRect.width * 1),
int(approachRect.height * 1))
)
approachRect.x = 0
# 设置进场图片移动速度
cameraAdaption = 3
# 记录当前时间
currentTime = 0
# 创建一张黑色的图片,用来盖住选择图标
image = pygame.Surface((50, 50)).convert()
image.fill((0, 0, 0))
# 记录是否播放音效,播放了就要画了
isPlayed = False
showTime = pygame.time.get_ticks()
lastingTime = pygame.time.get_ticks()
keys = ''
while 1:
MainGame.window.blit(approach, approachRect)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
# 上上下下左右左右BABA A是跳跃键,B是射击键
if event.key == pygame.K_w:
keys += 'w'
elif event.key == pygame.K_s:
keys += 's'
elif event.key == pygame.K_j:
keys += 'b'
elif event.key == pygame.K_k:
keys += 'a'
elif event.key == pygame.K_RETURN:
if not isPlayed:
approachRect.x = -1435
Sound('../Sound/start.mp3').play()
currentTime = time.time()
isPlayed = True
# 让背景向右走这么多距离
if approachRect.x > -1435:
approachRect.x -= cameraAdaption
if isPlayed:
# 设置图标一闪一闪的
if abs(lastingTime - pygame.time.get_ticks()) > 400:
if 1200 > abs(showTime - pygame.time.get_ticks()) > 0:
MainGame.window.blit(image, (190, 390))
else:
showTime = pygame.time.get_ticks()
lastingTime = pygame.time.get_ticks()
# 更新窗口
pygame.display.update()
# 设置帧率
self.clock.tick(self.fps)
fps = self.clock.get_fps()
caption = '魂斗罗 - {:.2f}'.format(fps)
pygame.display.set_caption(caption)
# 如果时间超过60,就开始加载第一关
if 100 > abs(time.time() - currentTime) * 10 > 60:
print(keys)
if keys == 'wwssbaba':
initPlayer1(30)
break
Here are a few things to explain
# 当按键按下,直接结束进场动画,播放音乐,让图标还是闪烁,一定时间后进入第一关
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
# 上上下下左右左右BABA A是跳跃键,B是射击键
if event.key == pygame.K_w:
keys += 'w'
elif event.key == pygame.K_s:
keys += 's'
elif event.key == pygame.K_j:
keys += 'b'
elif event.key == pygame.K_k:
keys += 'a'
elif event.key == pygame.K_RETURN:
if not isPlayed:
approachRect.x = -1435
Sound('../Sound/start.mp3').play()
currentTime = time.time()
isPlayed = True
This part is to allow the player to play music directly after pressing Enter, and go directly to the player selection interface (as shown in the figure below).
if isPlayed:
# 设置图标一闪一闪的
if abs(lastingTime - pygame.time.get_ticks()) > 400:
if 1200 > abs(showTime - pygame.time.get_ticks()) > 0:
MainGame.window.blit(image, (190, 390))
else:
showTime = pygame.time.get_ticks()
lastingTime = pygame.time.get_ticks()
This part is to make the icon flash. The overall idea is to create a black cloth (pure black picture), cover the original icon for a period of time, and not cover it for a period of time. The above code is to achieve this function, abs(lastingTime - pygame. time.get_ticks()) > 400 This code is not covered, and lastingTime is the time not covered, if it exceeds 400, enter the body of the if statement, let the black cloth be displayed, cover the icon, and the covered time is 1200, if it is greater than 1200, it will not be covered.
Pay attention to importing modules, otherwise the following error will appear
Added the runGame() function to the main class
def runGame(self):
self.loadApproachAnimation()
self.run()
This function is the running function of the game
Modify the main() function
Let's run the game and see the effect
You can see that the interface is moving slowly. If you press any key, the sound will be played. After a few seconds, you will enter the first level
7. Solve the problem of players falling out of the map and dying
In the current game, the player does not die after falling to the cliff. We need to modify it.
Come to the updatePlayerPosition() function of the main class
Add the following code
if tempPlayer.rect.y > 610:
if MainGame.player1.damage(1):
initPlayer1(MainGame.player1.life)
This code is that if the player's y coordinate is greater than 610, even if the player dies, reload the player
8. Improve the player's game failure function
Turn the isEnd attribute of the main class into a class attribute
Add endGame() function
def endGame():
MainGame.isEnd = True
Here you need to modify the logic, come to the updateEnemyPosition() function
Change the original endGame function to victory, indicating that the player has won
Let's temporarily define this function
def victory():
pass
Then continue to modify the logic of the endGame() function
Now run the game and see if the game will quit if the player has no life
discovery is possible
9. Summary
At this point, Contra as a whole is complete. Since the blogger has not passed the map and the sound effect of the explosion, there is no way to add it here.
You can expand in the future. The blogger has not perfected the game ending and game victory interface. If I find the corresponding material later, I will add it to the game and post a blog
The tank battle was developed in a week and completed. Compared with the tank war, Contra has been written for about a month and a half. In fact, it can be completed very early. The blogger was busy preparing for the re-examination for the postgraduate entrance examination, so there was nothing to do during this time. Thinking that you can't give up halfway, just finish Contra.
Finally, thank you all for your study and support.
I will put the overall code and material on the network disk, and friends who need it can get it by themselves.