Learning Python's Pygame Development Contra (16)

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')

insert image description here

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

insert image description here

4. Increase the sound effect of hitting the boss's vital points

Come to the bullet class and modify the collideEnemy() function
insert image description here

5. Hitting the enemy sound effect

Or add code to the collideEnemy() function of the bullet class
insert image description here

    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).

insert image description here

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

insert image description here

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

insert image description here
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)

insert image description here
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

insert image description here

insert image description here
Add endGame() function

insert image description here

def endGame():
    MainGame.isEnd = True

Here you need to modify the logic, come to the updateEnemyPosition() function

insert image description here
Change the original endGame function to victory, indicating that the player has won

Let's temporarily define this function

def victory():
    pass

insert image description here
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.

Guess you like

Origin blog.csdn.net/qq_37354060/article/details/130409973