Pygame开发学习

项目名称:da飞机游戏

pygame安装好了,经过很长的时间python基本语法也已经学习完了,接下来继续进行项目的开发:

导入sys模块控制退出游戏
导入pygame模块

主程序代码:

import sys

import pygame

from settings import Settings

class AlienInvasion:

    def __init__(self):
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")

    def run_game(self):
        while True:

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()

            self.screen.fill(self.settings.bg_color)

            pygame.display.flip()

if __name__ == '__main__':
    ai = AlienInvasion()
    ai.run_game()

设置部分代码:(创建设置类),并用他来访问设置

class Settings:

    def __init__(self):
        self.screen_width = 1200
        self.screen_height = 800
        self.bg_color = (230, 230, 230)

现在窗口设置好了,可以出现游戏窗口了,一切正常,进行添加游戏元素:
同理,设置一个新的模块 ship.py用于管理飞船的大部分行为:

import pygame

class Ship:
    """管理飞船的类"""
    def __init__(self, ai_game):
        """初始化飞船并设置其初始位置"""
        self.screen = ai_game.screen
        self.screen_rect = ai_game.screen.get_rect()

        self.image = pygame.image.load(
            r'C:/Users/TOMMY/Documents/coding/.vscode/alien_invasion/ship.bmp')
        self.rect = self.image.get_rect()

        self.rect.midbottom = self.screen_rect.midbottom

    def blitme(self):
        """在指定位置绘制飞船"""
        self.screen.blit(self.image, self.rect)

更新一下alien_invasion.py,创建一艘飞船:

import pygame, sys

from settings import Settings
from ship import Ship

class AlienInvasion:

    def __init__(self):
        """初始化游戏并创建游戏资源"""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")

        self.bg_color = (230, 230, 230)

        self.ship = Ship(self)

    def run_game(self):
        """开始游戏的主循环"""
        while True:
            self._check_events()
            self._update_screen()

    def _check_events(self):

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

    def _update_screen(self):

        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()

        pygame.display.flip()

if __name__ == '__main__':

    ai = AlienInvasion()
    ai.run_game()

其中上述操作中都包含了对主程序的重构,把主程序的游戏循环进行了重构,这样能一眼就明白游戏循环到底是干嘛的,它的功能是什么,把他们独立到两个单独的方法中实现时,利用他的功能可以使用句点访问法。
调用过程:

def run_game(self):
    while True:
        self._check_events()
        self._update_screen()

def _check_events(self):
    -----snip------

def _update_screen():
    ----snip-----

尽量先在主程序内编写,等调试成功后吗,在进行代码的重构,使主程序更清晰,简单,有助于对主程序功能的更新以及下一步的代码编写!!!

代码运行成功结果:

Pygame开发学习

实现键盘控制飞船移动:

通过方法 pygame.event.get()获取事件,每次按下键盘都被注册为一次KEYDOWN事件,所以在 __check_events()方法内的循环内添加一个选项,如果用户按下一个键盘右箭头,那么图像就向右移动一个位置:

def _check_event(self):

    --snip--

    elif event.type == pygame.KEYDOWN:
        if event.type == pygame.K_RIGHT:
            self.ship.rect.x += 1

每按右箭头一次,飞船就向右移动一个像素,但是不能连续移动,现在令移动高效:支持连续移动:

    def _check_events(self):

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    self.ship.moving_right = True
                elif event.key == pygame.K_LEFT:
                    self.ship.moving_left = True

            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_RIGHT:
                    self.ship.moving_right = False
                elif event.key == pygame.K_LEFT:
                    self.ship.moving_left = False

在这里能使用elif代码块,是因为每个键只与一个事件相关联,每一个事件有单独的两个区块分别执行,是分开执行的,所以当同时按下左右键时他时两个不同的事件,所以分别进入到两个分区进行处理,互不影响,表现出来飞船在原位置不动。

在ship模块内进行更新:

import pygame

class Ship:
    """管理飞船的类"""
    def __init__(self, ai_game):

        --snip--

        self.moving_right = False
        self.moving_left = False

    def update(self):
        if self.moving_right:
            self.rect.x += 1
        if self.moving_left:
            self.rect.x -= 1

    def blitme(self):
        """在指定位置绘制飞船"""
        self.screen.blit(self.image, self.rect)

添加一个设置飞船移动速度的设置,以便于控制飞船的移动速度,并且设置一个每一次移动一个小数的像素,以便于精准的控制,但是rect无法储存小数,只能自动转化成整数,所以要想实现精准控制,要加一个变量,间接的实现飞船的像素位置更新:

class Settings:
    --snip--
    self.ship_speed = 0.5

接下来对ship类进行更新:

import pygame

class Ship:
    """管理飞船的类"""
    def __init__(self, ai_game):
        """初始化飞船并设置其初始位置"""
        self.screen = ai_game.screen
        self.settings = ai_game.settings
        self.screen_rect = ai_game.screen.get_rect()

        self.image = pygame.image.load(
            r'C:/Users/TOMMY/Documents/coding/.vscode/alien_invasion/ship.bmp')
        self.rect = self.image.get_rect()

        self.rect.midbottom = self.screen_rect.midbottom

        self.x = float(self.rect.x)

        self.moving_right = False
        self.moving_left = False

    def update(self):
        if self.moving_right:
            self.x += self.settings.ship_speed
        if self.moving_left:
            self.x -= self.settings.ship_speed

        self.rect.x = self.x

    def blitme(self):
        """在指定位置绘制飞船"""
        self.screen.blit(self.image, self.rect)

给ship类添加属性seetings以便能在update方法中使用它

self.rect.x = self.x

这一行代码是设置小数位像素的核心,就算是这样赋值后他的最后的值即便是小数,赋值给rect后,也会转化成整数型,但是如果在settings类中设置的初始移动位数为0.5,那么第一次的更新和赋值在飞船的像素位置变化转化为整形后为0,所以这个位置的变化的奇数次看来是无效的,在偶数次是有效的,所以有效的实际的移动时间差变长了,所以在连续移动的效果下看到的是移动速度变慢,并且更精准。

限制飞船的活动范围:

当飞船到达游戏窗口的左或右边界时,停止运动:

    def update(self):
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.x += self.settings.ship_speed
        if self.moving_left and self.rect.left > 0:
            self.x -= self.settings.ship_speed

        self.rect.x = self.x

Original: https://blog.csdn.net/qq_51960163/article/details/116657562
Author: Tommy Vercetti
Title: Pygame开发学习

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/781832/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球