【入门书籍】Python 编程-从入门到实践【下】
Chapter_12 项目 外星人入侵
点击先看一下本部分目录
项目 1 外星人入侵 ...................................... 202
第 12 章 武装飞船 ....................................... 203
12.1 规划项目 ............................................. 203
12.2 安装 Pygame........................................ 204
12.2.1 使用 pip 安装 Python 包 ......... 204
12.2.2 在 Linux 系统中安装Pygame ................................... 206
12.2.3 在 OS X 系统中安装Pygame ................................... 207
12.2.4 在 Windows 系统中安装Pygame ................................... 207
12.3 开始游戏项目 ...................................... 207
12.3.1 创建 Pygame 窗口以及响应用户输入 ................................ 208
12.3.2 设置背景色 ............................ 209
12.3.3 创建设置类 ............................ 210
12.4 添加飞船图像 ...................................... 211
12.4.1 创建 Ship 类 ........................... 212
12.4.2 在屏幕上绘制飞船 ................. 213
12.5 重构:模块 game_functions ................ 214
12.5.1 函数 check_events() .............. 214
12.5.2 函数 update_screen() ............ 215
12.6 驾驶飞船 ............................................. 216
12.6.1 响应按键 ................................ 216
12.6.2 允许不断移动 ........................ 217
12.6.3 左右移动 ................................ 219
12.6.4 调整飞船的速度 ..................... 220
12.6.5 限制飞船的活动范围 ............. 221
12.6.6 重构 check_events() .............. 222
12.7 简单回顾 .............................................. 223
12.7.1 alien_invasion.py .................... 223
12.7.2 settings.py ............................... 223
12.7.3 game_functions.py .................. 223
12.7.4 ship.py .................................... 223
12.8 射击 ..................................................... 224
12.8.1 添加子弹设置 ......................... 224
12.8.2 创建 Bullet 类 ........................ 224
12.8.3 将子弹存储到编组中 ............. 226
12.8.4 开火 ........................................ 227
12.8.5 删除已消失的子弹 ................. 228
12.8.6 限制子弹数量 ......................... 229
12.8.7 创建函数 update_bullets() ... 229
12.8.8 创建函数 fire_bullet() ......... 230
12.9 小结 ..................................................... 231
第一次迭代
| 以下是所需源码与素材 |
|---|
| alien_invasion.py |
| settings.py |
| ship.py |
![]() |
点击查看 alien_invasion.py 代码
import sys
import pygame
from settings import Settings
from ship import Ship
def run_game():
# 初始化游戏并创建一个屏幕对象
pygame.init()
game_settings = Settings()
screen = pygame.display.set_mode(game_settings.screen_size)
pygame.display.set_caption("外星人入侵")
ship = Ship(screen)
while True:
# 监视键盘和鼠标事件
screen.fill(game_settings.bg_color)
ship.blitme()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
pygame.display.flip()
run_game()
点击查看 settings.py 代码
class Settings():
"""存储外星人入侵所有设置的类"""
def __init__(self):
"""初始化游戏的设置"""
self.screen_size = (1200, 800)
self.bg_color = (230, 230, 230)
点击查看 ship.py 代码
import pygame
class Ship():
def __init__(self, screen):
self.screen = screen
self.image = pygame.image.load("./images/ship.bmp")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
def blitme(self):
"""在指定位置绘制飞船"""
self.screen.blit(self.image, self.rect)
第二次迭代
| 我学到了什么? |
|---|
| 第一:响应按键,每当用户按键时,都将在 Pygame 中注册一个事件 |
| 第二:事件都是通过方法pygame.event.get()获取的 |
| 第三:不断移动的逻辑:使用KEYDOWN 和 KEYUP的方法,结合一个布尔类型变量 moving_right 即可 |
点击查看所有按键事件名称
# encoding: utf-8
# module pygame.constants
# from D:\Tools\python3.9.6\lib\site-packages\pygame\constants.cp39-win_amd64.pyd
# by generator 1.147
""" Constants defined by SDL and needed in Pygame. """
# no imports
# Variables with simple values
ACTIVEEVENT = 32768
ANYFORMAT = 268435456
APPACTIVE = 2
APPFOCUSMOUSE = 0
APPINPUTFOCUS = 1
ASYNCBLIT = 4
AUDIODEVICEADDED = 4352
AUDIODEVICEREMOVED = 4353
AUDIO_ALLOW_ANY_CHANGE = 15
AUDIO_ALLOW_CHANNELS_CHANGE = 4
AUDIO_ALLOW_FORMAT_CHANGE = 2
AUDIO_ALLOW_FREQUENCY_CHANGE = 1
AUDIO_S16 = 32784
AUDIO_S16LSB = 32784
AUDIO_S16MSB = 36880
AUDIO_S16SYS = 32784
AUDIO_S8 = 32776
AUDIO_U16 = 16
AUDIO_U16LSB = 16
AUDIO_U16MSB = 4112
AUDIO_U16SYS = 16
AUDIO_U8 = 8
BIG_ENDIAN = 4321
BLENDMODE_ADD = 2
BLENDMODE_BLEND = 1
BLENDMODE_MOD = 4
BLENDMODE_NONE = 0
BLEND_ADD = 1
BLEND_ALPHA_SDL2 = 18
BLEND_MAX = 5
BLEND_MIN = 4
BLEND_MULT = 3
BLEND_PREMULTIPLIED = 17
BLEND_RGBA_ADD = 6
BLEND_RGBA_MAX = 16
BLEND_RGBA_MIN = 9
BLEND_RGBA_MULT = 8
BLEND_RGBA_SUB = 7
BLEND_RGB_ADD = 1
BLEND_RGB_MAX = 5
BLEND_RGB_MIN = 4
BLEND_RGB_MULT = 3
BLEND_RGB_SUB = 2
BLEND_SUB = 2
BUTTON_LEFT = 1
BUTTON_MIDDLE = 2
BUTTON_RIGHT = 3
BUTTON_WHEELDOWN = 5
BUTTON_WHEELUP = 4
BUTTON_X1 = 6
BUTTON_X2 = 7
CONTROLLERAXISMOTION = 1616
CONTROLLERBUTTONDOWN = 1617
CONTROLLERBUTTONUP = 1618
CONTROLLERDEVICEADDED = 1619
CONTROLLERDEVICEREMAPPED = 1621
CONTROLLERDEVICEREMOVED = 1620
CONTROLLERTOUCHPADDOWN = 1622
CONTROLLERTOUCHPADMOTION = 1623
CONTROLLERTOUCHPADUP = 1624
CONTROLLER_AXIS_INVALID = -1
CONTROLLER_AXIS_LEFTX = 0
CONTROLLER_AXIS_LEFTY = 1
CONTROLLER_AXIS_MAX = 6
CONTROLLER_AXIS_RIGHTX = 2
CONTROLLER_AXIS_RIGHTY = 3
CONTROLLER_AXIS_TRIGGERLEFT = 4
CONTROLLER_AXIS_TRIGGERRIGHT = 5
CONTROLLER_BUTTON_A = 0
CONTROLLER_BUTTON_B = 1
CONTROLLER_BUTTON_BACK = 4
CONTROLLER_BUTTON_DPAD_DOWN = 12
CONTROLLER_BUTTON_DPAD_LEFT = 13
CONTROLLER_BUTTON_DPAD_RIGHT = 14
CONTROLLER_BUTTON_DPAD_UP = 11
CONTROLLER_BUTTON_GUIDE = 5
CONTROLLER_BUTTON_INVALID = -1
CONTROLLER_BUTTON_LEFTSHOULDER = 9
CONTROLLER_BUTTON_LEFTSTICK = 7
CONTROLLER_BUTTON_MAX = 21
CONTROLLER_BUTTON_RIGHTSHOULDER = 10
CONTROLLER_BUTTON_RIGHTSTICK = 8
CONTROLLER_BUTTON_START = 6
CONTROLLER_BUTTON_X = 2
CONTROLLER_BUTTON_Y = 3
DOUBLEBUF = 1073741824
DROPBEGIN = 4098
DROPCOMPLETE = 4099
DROPFILE = 4096
DROPTEXT = 4097
FINGERDOWN = 1792
FINGERMOTION = 1794
FINGERUP = 1793
FULLSCREEN = -2147483648
GL_ACCELERATED_VISUAL = 15
GL_ACCUM_ALPHA_SIZE = 11
GL_ACCUM_BLUE_SIZE = 10
GL_ACCUM_GREEN_SIZE = 9
GL_ACCUM_RED_SIZE = 8
GL_ALPHA_SIZE = 3
GL_BLUE_SIZE = 2
GL_BUFFER_SIZE = 4
GL_CONTEXT_DEBUG_FLAG = 1
GL_CONTEXT_FLAGS = 20
GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 2
GL_CONTEXT_MAJOR_VERSION = 17
GL_CONTEXT_MINOR_VERSION = 18
GL_CONTEXT_PROFILE_COMPATIBILITY = 2
GL_CONTEXT_PROFILE_CORE = 1
GL_CONTEXT_PROFILE_ES = 4
GL_CONTEXT_PROFILE_MASK = 21
GL_CONTEXT_RELEASE_BEHAVIOR = 24
GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 1
GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0
GL_CONTEXT_RESET_ISOLATION_FLAG = 8
GL_CONTEXT_ROBUST_ACCESS_FLAG = 4
GL_DEPTH_SIZE = 6
GL_DOUBLEBUFFER = 5
GL_FRAMEBUFFER_SRGB_CAPABLE = 23
GL_GREEN_SIZE = 1
GL_MULTISAMPLEBUFFERS = 13
GL_MULTISAMPLESAMPLES = 14
GL_RED_SIZE = 0
GL_SHARE_WITH_CURRENT_CONTEXT = 22
GL_STENCIL_SIZE = 7
GL_STEREO = 12
GL_SWAP_CONTROL = 0
HAT_CENTERED = 0
HAT_DOWN = 4
HAT_LEFT = 8
HAT_LEFTDOWN = 12
HAT_LEFTUP = 9
HAT_RIGHT = 2
HAT_RIGHTDOWN = 6
HAT_RIGHTUP = 3
HAT_UP = 1
HIDDEN = 128
HWACCEL = 256
HWPALETTE = 536870912
HWSURFACE = 1
JOYAXISMOTION = 1536
JOYBALLMOTION = 1537
JOYBUTTONDOWN = 1539
JOYBUTTONUP = 1540
JOYDEVICEADDED = 1541
JOYDEVICEREMOVED = 1542
JOYHATMOTION = 1538
KEYDOWN = 768
KEYUP = 769
KMOD_ALT = 768
KMOD_CAPS = 8192
KMOD_CTRL = 192
KMOD_GUI = 3072
KMOD_LALT = 256
KMOD_LCTRL = 64
KMOD_LGUI = 1024
KMOD_LMETA = 1024
KMOD_LSHIFT = 1
KMOD_META = 3072
KMOD_MODE = 16384
KMOD_NONE = 0
KMOD_NUM = 4096
KMOD_RALT = 512
KMOD_RCTRL = 128
KMOD_RGUI = 2048
KMOD_RMETA = 2048
KMOD_RSHIFT = 2
KMOD_SHIFT = 3
KSCAN_0 = 39
KSCAN_1 = 30
KSCAN_2 = 31
KSCAN_3 = 32
KSCAN_4 = 33
KSCAN_5 = 34
KSCAN_6 = 35
KSCAN_7 = 36
KSCAN_8 = 37
KSCAN_9 = 38
KSCAN_A = 4
KSCAN_AC_BACK = 270
KSCAN_APOSTROPHE = 52
KSCAN_B = 5
KSCAN_BACKSLASH = 49
KSCAN_BACKSPACE = 42
KSCAN_BREAK = 72
KSCAN_C = 6
KSCAN_CAPSLOCK = 57
KSCAN_CLEAR = 156
KSCAN_COMMA = 54
KSCAN_CURRENCYSUBUNIT = 181
KSCAN_CURRENCYUNIT = 180
KSCAN_D = 7
KSCAN_DELETE = 76
KSCAN_DOWN = 81
KSCAN_E = 8
KSCAN_END = 77
KSCAN_EQUALS = 46
KSCAN_ESCAPE = 41
KSCAN_EURO = 180
KSCAN_F = 9
KSCAN_F1 = 58
KSCAN_F10 = 67
KSCAN_F11 = 68
KSCAN_F12 = 69
KSCAN_F13 = 104
KSCAN_F14 = 105
KSCAN_F15 = 106
KSCAN_F2 = 59
KSCAN_F3 = 60
KSCAN_F4 = 61
KSCAN_F5 = 62
KSCAN_F6 = 63
KSCAN_F7 = 64
KSCAN_F8 = 65
KSCAN_F9 = 66
KSCAN_G = 10
KSCAN_GRAVE = 53
KSCAN_H = 11
KSCAN_HELP = 117
KSCAN_HOME = 74
KSCAN_I = 12
KSCAN_INSERT = 73
KSCAN_INTERNATIONAL1 = 135
KSCAN_INTERNATIONAL2 = 136
KSCAN_INTERNATIONAL3 = 137
KSCAN_INTERNATIONAL4 = 138
KSCAN_INTERNATIONAL5 = 139
KSCAN_INTERNATIONAL6 = 140
KSCAN_INTERNATIONAL7 = 141
KSCAN_INTERNATIONAL8 = 142
KSCAN_INTERNATIONAL9 = 143
KSCAN_J = 13
KSCAN_K = 14
KSCAN_KP0 = 98
KSCAN_KP1 = 89
KSCAN_KP2 = 90
KSCAN_KP3 = 91
KSCAN_KP4 = 92
KSCAN_KP5 = 93
KSCAN_KP6 = 94
KSCAN_KP7 = 95
KSCAN_KP8 = 96
KSCAN_KP9 = 97
KSCAN_KP_0 = 98
KSCAN_KP_1 = 89
KSCAN_KP_2 = 90
KSCAN_KP_3 = 91
KSCAN_KP_4 = 92
KSCAN_KP_5 = 93
KSCAN_KP_6 = 94
KSCAN_KP_7 = 95
KSCAN_KP_8 = 96
KSCAN_KP_9 = 97
KSCAN_KP_DIVIDE = 84
KSCAN_KP_ENTER = 88
KSCAN_KP_EQUALS = 103
KSCAN_KP_MINUS = 86
KSCAN_KP_MULTIPLY = 85
KSCAN_KP_PERIOD = 99
KSCAN_KP_PLUS = 87
KSCAN_L = 15
KSCAN_LALT = 226
KSCAN_LANG1 = 144
KSCAN_LANG2 = 145
KSCAN_LANG3 = 146
KSCAN_LANG4 = 147
KSCAN_LANG5 = 148
KSCAN_LANG6 = 149
KSCAN_LANG7 = 150
KSCAN_LANG8 = 151
KSCAN_LANG9 = 152
KSCAN_LCTRL = 224
KSCAN_LEFT = 80
KSCAN_LEFTBRACKET = 47
KSCAN_LGUI = 227
KSCAN_LMETA = 227
KSCAN_LSHIFT = 225
KSCAN_LSUPER = 227
KSCAN_M = 16
KSCAN_MENU = 118
KSCAN_MINUS = 45
KSCAN_MODE = 257
KSCAN_N = 17
KSCAN_NONUSBACKSLASH = 100
KSCAN_NONUSHASH = 50
KSCAN_NUMLOCK = 83
KSCAN_NUMLOCKCLEAR = 83
KSCAN_O = 18
KSCAN_P = 19
KSCAN_PAGEDOWN = 78
KSCAN_PAGEUP = 75
KSCAN_PAUSE = 72
KSCAN_PERIOD = 55
KSCAN_POWER = 102
KSCAN_PRINT = 70
KSCAN_PRINTSCREEN = 70
KSCAN_Q = 20
KSCAN_R = 21
KSCAN_RALT = 230
KSCAN_RCTRL = 228
KSCAN_RETURN = 40
KSCAN_RGUI = 231
KSCAN_RIGHT = 79
KSCAN_RIGHTBRACKET = 48
KSCAN_RMETA = 231
KSCAN_RSHIFT = 229
KSCAN_RSUPER = 231
KSCAN_S = 22
KSCAN_SCROLLLOCK = 71
KSCAN_SCROLLOCK = 71
KSCAN_SEMICOLON = 51
KSCAN_SLASH = 56
KSCAN_SPACE = 44
KSCAN_SYSREQ = 154
KSCAN_T = 23
KSCAN_TAB = 43
KSCAN_U = 24
KSCAN_UNKNOWN = 0
KSCAN_UP = 82
KSCAN_V = 25
KSCAN_W = 26
KSCAN_X = 27
KSCAN_Y = 28
KSCAN_Z = 29
K_0 = 48
K_1 = 49
K_2 = 50
K_3 = 51
K_4 = 52
K_5 = 53
K_6 = 54
K_7 = 55
K_8 = 56
K_9 = 57
K_a = 97
K_AC_BACK = 1073742094
K_AMPERSAND = 38
K_ASTERISK = 42
K_AT = 64
K_b = 98
K_BACKQUOTE = 96
K_BACKSLASH = 92
K_BACKSPACE = 8
K_BREAK = 1073741896
K_c = 99
K_CAPSLOCK = 1073741881
K_CARET = 94
K_CLEAR = 1073741980
K_COLON = 58
K_COMMA = 44
K_CURRENCYSUBUNIT = 1073742005
K_CURRENCYUNIT = 1073742004
K_d = 100
K_DELETE = 127
K_DOLLAR = 36
K_DOWN = 1073741905
K_e = 101
K_END = 1073741901
K_EQUALS = 61
K_ESCAPE = 27
K_EURO = 1073742004
K_EXCLAIM = 33
K_f = 102
K_F1 = 1073741882
K_F10 = 1073741891
K_F11 = 1073741892
K_F12 = 1073741893
K_F13 = 1073741928
K_F14 = 1073741929
K_F15 = 1073741930
K_F2 = 1073741883
K_F3 = 1073741884
K_F4 = 1073741885
K_F5 = 1073741886
K_F6 = 1073741887
K_F7 = 1073741888
K_F8 = 1073741889
K_F9 = 1073741890
K_g = 103
K_GREATER = 62
K_h = 104
K_HASH = 35
K_HELP = 1073741941
K_HOME = 1073741898
K_i = 105
K_INSERT = 1073741897
K_j = 106
K_k = 107
K_KP0 = 1073741922
K_KP1 = 1073741913
K_KP2 = 1073741914
K_KP3 = 1073741915
K_KP4 = 1073741916
K_KP5 = 1073741917
K_KP6 = 1073741918
K_KP7 = 1073741919
K_KP8 = 1073741920
K_KP9 = 1073741921
K_KP_0 = 1073741922
K_KP_1 = 1073741913
K_KP_2 = 1073741914
K_KP_3 = 1073741915
K_KP_4 = 1073741916
K_KP_5 = 1073741917
K_KP_6 = 1073741918
K_KP_7 = 1073741919
K_KP_8 = 1073741920
K_KP_9 = 1073741921
K_KP_DIVIDE = 1073741908
K_KP_ENTER = 1073741912
K_KP_EQUALS = 1073741927
K_KP_MINUS = 1073741910
K_KP_MULTIPLY = 1073741909
K_KP_PERIOD = 1073741923
K_KP_PLUS = 1073741911
K_l = 108
K_LALT = 1073742050
K_LCTRL = 1073742048
K_LEFT = 1073741904
K_LEFTBRACKET = 91
K_LEFTPAREN = 40
K_LESS = 60
K_LGUI = 1073742051
K_LMETA = 1073742051
K_LSHIFT = 1073742049
K_LSUPER = 1073742051
K_m = 109
K_MENU = 1073741942
K_MINUS = 45
K_MODE = 1073742081
K_n = 110
K_NUMLOCK = 1073741907
K_NUMLOCKCLEAR = 1073741907
K_o = 111
K_p = 112
K_PAGEDOWN = 1073741902
K_PAGEUP = 1073741899
K_PAUSE = 1073741896
K_PERCENT = 37
K_PERIOD = 46
K_PLUS = 43
K_POWER = 1073741926
K_PRINT = 1073741894
K_PRINTSCREEN = 1073741894
K_q = 113
K_QUESTION = 63
K_QUOTE = 39
K_QUOTEDBL = 34
K_r = 114
K_RALT = 1073742054
K_RCTRL = 1073742052
K_RETURN = 13
K_RGUI = 1073742055
K_RIGHT = 1073741903
K_RIGHTBRACKET = 93
K_RIGHTPAREN = 41
K_RMETA = 1073742055
K_RSHIFT = 1073742053
K_RSUPER = 1073742055
K_s = 115
K_SCROLLLOCK = 1073741895
K_SCROLLOCK = 1073741895
K_SEMICOLON = 59
K_SLASH = 47
K_SPACE = 32
K_SYSREQ = 1073741978
K_t = 116
K_TAB = 9
K_u = 117
K_UNDERSCORE = 95
K_UNKNOWN = 0
K_UP = 1073741906
K_v = 118
K_w = 119
K_x = 120
K_y = 121
K_z = 122
LIL_ENDIAN = 1234
MIDIIN = 32771
MIDIOUT = 32772
MOUSEBUTTONDOWN = 1025
MOUSEBUTTONUP = 1026
MOUSEMOTION = 1024
MOUSEWHEEL = 1027
MULTIGESTURE = 2050
NOEVENT = 0
NOFRAME = 32
NUMEVENTS = 65535
OPENGL = 2
OPENGLBLIT = 10
PREALLOC = 16777216
QUIT = 256
RESIZABLE = 16
RLEACCEL = 16384
RLEACCELOK = 8192
SCALED = 512
SCRAP_BMP = 'image/bmp'
SCRAP_CLIPBOARD = 0
SCRAP_PBM = 'image/pbm'
SCRAP_PPM = 'image/ppm'
SCRAP_SELECTION = 1
SCRAP_TEXT = 'text/plain'
SHOWN = 64
SRCALPHA = 65536
SRCCOLORKEY = 4096
SWSURFACE = 0
SYSTEM_CURSOR_ARROW = 0
SYSTEM_CURSOR_CROSSHAIR = 3
SYSTEM_CURSOR_HAND = 11
SYSTEM_CURSOR_IBEAM = 1
SYSTEM_CURSOR_NO = 10
SYSTEM_CURSOR_SIZEALL = 9
SYSTEM_CURSOR_SIZENESW = 6
SYSTEM_CURSOR_SIZENS = 8
SYSTEM_CURSOR_SIZENWSE = 5
SYSTEM_CURSOR_SIZEWE = 7
SYSTEM_CURSOR_WAIT = 2
SYSTEM_CURSOR_WAITARROW = 4
SYSWMEVENT = 513
TEXTEDITING = 770
TEXTINPUT = 771
TIMER_RESOLUTION = 0
USEREVENT = 32850
USEREVENT_DROPFILE = 4096
VIDEOEXPOSE = 32770
VIDEORESIZE = 32769
WINDOWCLOSE = 32787
WINDOWENTER = 32783
WINDOWEXPOSED = 32776
WINDOWFOCUSGAINED = 32785
WINDOWFOCUSLOST = 32786
WINDOWHIDDEN = 32775
WINDOWHITTEST = 32789
WINDOWLEAVE = 32784
WINDOWMAXIMIZED = 32781
WINDOWMINIMIZED = 32780
WINDOWMOVED = 32777
WINDOWRESIZED = 32778
WINDOWRESTORED = 32782
WINDOWSHOWN = 32774
WINDOWSIZECHANGED = 32779
WINDOWTAKEFOCUS = 32788
# no functions
# no classes
# variables with complex values
__all__ = [
'LIL_ENDIAN',
'BIG_ENDIAN',
'SWSURFACE',
'HWSURFACE',
'RESIZABLE',
'ASYNCBLIT',
'OPENGL',
'OPENGLBLIT',
'ANYFORMAT',
'HWPALETTE',
'DOUBLEBUF',
'FULLSCREEN',
'HWACCEL',
'SRCCOLORKEY',
'RLEACCELOK',
'RLEACCEL',
'SRCALPHA',
'PREALLOC',
'NOFRAME',
'SHOWN',
'HIDDEN',
'SCALED',
'GL_RED_SIZE',
'GL_GREEN_SIZE',
'GL_BLUE_SIZE',
'GL_ALPHA_SIZE',
'GL_BUFFER_SIZE',
'GL_DOUBLEBUFFER',
'GL_DEPTH_SIZE',
'GL_STENCIL_SIZE',
'GL_ACCUM_RED_SIZE',
'GL_ACCUM_GREEN_SIZE',
'GL_ACCUM_BLUE_SIZE',
'GL_ACCUM_ALPHA_SIZE',
'GL_ACCELERATED_VISUAL',
'GL_CONTEXT_MAJOR_VERSION',
'GL_CONTEXT_MINOR_VERSION',
'GL_SHARE_WITH_CURRENT_CONTEXT',
'GL_CONTEXT_FLAGS',
'GL_CONTEXT_DEBUG_FLAG',
'GL_CONTEXT_FORWARD_COMPATIBLE_FLAG',
'GL_CONTEXT_ROBUST_ACCESS_FLAG',
'GL_CONTEXT_RESET_ISOLATION_FLAG',
'GL_CONTEXT_PROFILE_MASK',
'GL_CONTEXT_PROFILE_CORE',
'GL_CONTEXT_PROFILE_COMPATIBILITY',
'GL_CONTEXT_PROFILE_ES',
'GL_FRAMEBUFFER_SRGB_CAPABLE',
'GL_CONTEXT_RELEASE_BEHAVIOR',
'GL_CONTEXT_RELEASE_BEHAVIOR_NONE',
'GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH',
'BLENDMODE_NONE',
'BLENDMODE_BLEND',
'BLENDMODE_ADD',
'BLENDMODE_MOD',
'GL_STEREO',
'GL_MULTISAMPLEBUFFERS',
'GL_MULTISAMPLESAMPLES',
'GL_SWAP_CONTROL',
'GL_ACCELERATED_VISUAL',
'TIMER_RESOLUTION',
'AUDIO_U8',
'AUDIO_S8',
'AUDIO_U16LSB',
'AUDIO_S16LSB',
'AUDIO_U16MSB',
'AUDIO_S16MSB',
'AUDIO_U16',
'AUDIO_S16',
'AUDIO_U16SYS',
'AUDIO_S16SYS',
'SCRAP_TEXT',
'SCRAP_BMP',
'SCRAP_PPM',
'SCRAP_PBM',
'SCRAP_CLIPBOARD',
'SCRAP_SELECTION',
'BLEND_ADD',
'BLEND_SUB',
'BLEND_MULT',
'BLEND_MIN',
'BLEND_MAX',
'BLEND_RGB_ADD',
'BLEND_RGB_SUB',
'BLEND_RGB_MULT',
'BLEND_RGB_MIN',
'BLEND_RGB_MAX',
'BLEND_RGBA_ADD',
'BLEND_RGBA_SUB',
'BLEND_RGBA_MULT',
'BLEND_RGBA_MIN',
'BLEND_RGBA_MAX',
'BLEND_PREMULTIPLIED',
'BLEND_ALPHA_SDL2',
'NOEVENT',
'ACTIVEEVENT',
'KEYDOWN',
'KEYUP',
'MOUSEMOTION',
'MOUSEBUTTONDOWN',
'MOUSEBUTTONUP',
'JOYAXISMOTION',
'JOYBALLMOTION',
'JOYHATMOTION',
'JOYBUTTONDOWN',
'JOYBUTTONUP',
'VIDEORESIZE',
'VIDEOEXPOSE',
'QUIT',
'SYSWMEVENT',
'MIDIIN',
'MIDIOUT',
'USEREVENT',
'NUMEVENTS',
'HAT_CENTERED',
'HAT_UP',
'HAT_RIGHTUP',
'HAT_RIGHT',
'HAT_RIGHTDOWN',
'HAT_DOWN',
'HAT_LEFTDOWN',
'HAT_LEFT',
'HAT_LEFTUP',
'BUTTON_LEFT',
'BUTTON_MIDDLE',
'BUTTON_RIGHT',
'FINGERMOTION',
'FINGERDOWN',
'FINGERUP',
'MULTIGESTURE',
'AUDIODEVICEADDED',
'AUDIODEVICEREMOVED',
'MOUSEWHEEL',
'TEXTINPUT',
'TEXTEDITING',
'WINDOWSHOWN',
'WINDOWHIDDEN',
'WINDOWEXPOSED',
'WINDOWMOVED',
'WINDOWRESIZED',
'WINDOWSIZECHANGED',
'WINDOWMINIMIZED',
'WINDOWMAXIMIZED',
'WINDOWRESTORED',
'WINDOWENTER',
'WINDOWLEAVE',
'WINDOWFOCUSGAINED',
'WINDOWFOCUSLOST',
'WINDOWCLOSE',
'WINDOWTAKEFOCUS',
'WINDOWHITTEST',
'CONTROLLERAXISMOTION',
'CONTROLLERBUTTONDOWN',
'CONTROLLERBUTTONUP',
'CONTROLLERDEVICEADDED',
'CONTROLLERDEVICEREMOVED',
'CONTROLLERDEVICEREMAPPED',
'CONTROLLERTOUCHPADDOWN',
'CONTROLLERTOUCHPADMOTION',
'CONTROLLERTOUCHPADUP',
'JOYDEVICEADDED',
'JOYDEVICEREMOVED',
'BUTTON_X1',
'BUTTON_X2',
'BUTTON_WHEELUP',
'BUTTON_WHEELDOWN',
'AUDIO_ALLOW_FREQUENCY_CHANGE',
'AUDIO_ALLOW_FORMAT_CHANGE',
'AUDIO_ALLOW_CHANNELS_CHANGE',
'AUDIO_ALLOW_ANY_CHANGE',
'DROPFILE',
'DROPTEXT',
'DROPBEGIN',
'DROPCOMPLETE',
'CONTROLLER_AXIS_INVALID',
'CONTROLLER_AXIS_LEFTX',
'CONTROLLER_AXIS_LEFTY',
'CONTROLLER_AXIS_RIGHTX',
'CONTROLLER_AXIS_RIGHTY',
'CONTROLLER_AXIS_TRIGGERLEFT',
'CONTROLLER_AXIS_TRIGGERRIGHT',
'CONTROLLER_AXIS_MAX',
'CONTROLLER_BUTTON_INVALID',
'CONTROLLER_BUTTON_A',
'CONTROLLER_BUTTON_B',
'CONTROLLER_BUTTON_X',
'CONTROLLER_BUTTON_Y',
'CONTROLLER_BUTTON_BACK',
'CONTROLLER_BUTTON_GUIDE',
'CONTROLLER_BUTTON_START',
'CONTROLLER_BUTTON_LEFTSTICK',
'CONTROLLER_BUTTON_RIGHTSTICK',
'CONTROLLER_BUTTON_LEFTSHOULDER',
'CONTROLLER_BUTTON_RIGHTSHOULDER',
'CONTROLLER_BUTTON_DPAD_UP',
'CONTROLLER_BUTTON_DPAD_DOWN',
'CONTROLLER_BUTTON_DPAD_LEFT',
'CONTROLLER_BUTTON_DPAD_RIGHT',
'CONTROLLER_BUTTON_MAX',
'K_AC_BACK',
'KSCAN_AC_BACK',
'K_UNKNOWN',
'KSCAN_UNKNOWN',
'K_BACKSPACE',
'KSCAN_BACKSPACE',
'K_TAB',
'KSCAN_TAB',
'K_CLEAR',
'KSCAN_CLEAR',
'K_RETURN',
'KSCAN_RETURN',
'K_PAUSE',
'KSCAN_PAUSE',
'K_ESCAPE',
'KSCAN_ESCAPE',
'K_SPACE',
'KSCAN_SPACE',
'K_QUOTE',
'KSCAN_APOSTROPHE',
'K_COMMA',
'KSCAN_COMMA',
'K_MINUS',
'KSCAN_MINUS',
'K_PERIOD',
'KSCAN_PERIOD',
'K_SLASH',
'KSCAN_SLASH',
'K_0',
'KSCAN_0',
'K_1',
'KSCAN_1',
'K_2',
'KSCAN_2',
'K_3',
'KSCAN_3',
'K_4',
'KSCAN_4',
'K_5',
'KSCAN_5',
'K_6',
'KSCAN_6',
'K_7',
'KSCAN_7',
'K_8',
'KSCAN_8',
'K_9',
'KSCAN_9',
'K_SEMICOLON',
'KSCAN_SEMICOLON',
'K_EQUALS',
'KSCAN_EQUALS',
'K_LEFTBRACKET',
'KSCAN_LEFTBRACKET',
'K_BACKSLASH',
'KSCAN_BACKSLASH',
'K_RIGHTBRACKET',
'KSCAN_RIGHTBRACKET',
'K_BACKQUOTE',
'KSCAN_GRAVE',
'K_a',
'KSCAN_A',
'K_b',
'KSCAN_B',
'K_c',
'KSCAN_C',
'K_d',
'KSCAN_D',
'K_e',
'KSCAN_E',
'K_f',
'KSCAN_F',
'K_g',
'KSCAN_G',
'K_h',
'KSCAN_H',
'K_i',
'KSCAN_I',
'K_j',
'KSCAN_J',
'K_k',
'KSCAN_K',
'K_l',
'KSCAN_L',
'K_m',
'KSCAN_M',
'K_n',
'KSCAN_N',
'K_o',
'KSCAN_O',
'K_p',
'KSCAN_P',
'K_q',
'KSCAN_Q',
'K_r',
'KSCAN_R',
'K_s',
'KSCAN_S',
'K_t',
'KSCAN_T',
'K_u',
'KSCAN_U',
'K_v',
'KSCAN_V',
'K_w',
'KSCAN_W',
'K_x',
'KSCAN_X',
'K_y',
'KSCAN_Y',
'K_z',
'KSCAN_Z',
'K_DELETE',
'KSCAN_DELETE',
'K_KP_0',
'KSCAN_KP_0',
'K_KP_1',
'KSCAN_KP_1',
'K_KP_2',
'KSCAN_KP_2',
'K_KP_3',
'KSCAN_KP_3',
'K_KP_4',
'KSCAN_KP_4',
'K_KP_5',
'KSCAN_KP_5',
'K_KP_6',
'KSCAN_KP_6',
'K_KP_7',
'KSCAN_KP_7',
'K_KP_8',
'KSCAN_KP_8',
'K_KP_9',
'KSCAN_KP_9',
'K_KP0',
'KSCAN_KP0',
'K_KP1',
'KSCAN_KP1',
'K_KP2',
'KSCAN_KP2',
'K_KP3',
'KSCAN_KP3',
'K_KP4',
'KSCAN_KP4',
'K_KP5',
'KSCAN_KP5',
'K_KP6',
'KSCAN_KP6',
'K_KP7',
'KSCAN_KP7',
'K_KP8',
'KSCAN_KP8',
'K_KP9',
'KSCAN_KP9',
'K_KP_PERIOD',
'KSCAN_KP_PERIOD',
'K_KP_DIVIDE',
'KSCAN_KP_DIVIDE',
'K_KP_MULTIPLY',
'KSCAN_KP_MULTIPLY',
'K_KP_MINUS',
'KSCAN_KP_MINUS',
'K_KP_PLUS',
'KSCAN_KP_PLUS',
'K_KP_ENTER',
'KSCAN_KP_ENTER',
'K_KP_EQUALS',
'KSCAN_KP_EQUALS',
'K_UP',
'KSCAN_UP',
'K_DOWN',
'KSCAN_DOWN',
'K_RIGHT',
'KSCAN_RIGHT',
'K_LEFT',
'KSCAN_LEFT',
'K_INSERT',
'KSCAN_INSERT',
'K_HOME',
'KSCAN_HOME',
'K_END',
'KSCAN_END',
'K_PAGEUP',
'KSCAN_PAGEUP',
'K_PAGEDOWN',
'KSCAN_PAGEDOWN',
'K_F1',
'KSCAN_F1',
'K_F2',
'KSCAN_F2',
'K_F3',
'KSCAN_F3',
'K_F4',
'KSCAN_F4',
'K_F5',
'KSCAN_F5',
'K_F6',
'KSCAN_F6',
'K_F7',
'KSCAN_F7',
'K_F8',
'KSCAN_F8',
'K_F9',
'KSCAN_F9',
'K_F10',
'KSCAN_F10',
'K_F11',
'KSCAN_F11',
'K_F12',
'KSCAN_F12',
'K_F13',
'KSCAN_F13',
'K_F14',
'KSCAN_F14',
'K_F15',
'KSCAN_F15',
'K_NUMLOCKCLEAR',
'KSCAN_NUMLOCKCLEAR',
'K_NUMLOCK',
'KSCAN_NUMLOCK',
'K_CAPSLOCK',
'KSCAN_CAPSLOCK',
'K_SCROLLLOCK',
'KSCAN_SCROLLLOCK',
'K_SCROLLOCK',
'KSCAN_SCROLLOCK',
'K_RSHIFT',
'KSCAN_RSHIFT',
'K_LSHIFT',
'KSCAN_LSHIFT',
'K_RCTRL',
'KSCAN_RCTRL',
'K_LCTRL',
'KSCAN_LCTRL',
'K_RALT',
'KSCAN_RALT',
'K_LALT',
'KSCAN_LALT',
'K_RGUI',
'KSCAN_RGUI',
'K_RMETA',
'KSCAN_RMETA',
'K_LGUI',
'KSCAN_LGUI',
'K_LMETA',
'KSCAN_LMETA',
'K_LSUPER',
'KSCAN_LSUPER',
'K_RSUPER',
'KSCAN_RSUPER',
'K_MODE',
'KSCAN_MODE',
'K_HELP',
'KSCAN_HELP',
'K_PRINTSCREEN',
'KSCAN_PRINTSCREEN',
'K_PRINT',
'KSCAN_PRINT',
'K_SYSREQ',
'KSCAN_SYSREQ',
'K_BREAK',
'KSCAN_BREAK',
'K_MENU',
'KSCAN_MENU',
'K_POWER',
'KSCAN_POWER',
'K_CURRENCYUNIT',
'KSCAN_CURRENCYUNIT',
'K_CURRENCYSUBUNIT',
'KSCAN_CURRENCYSUBUNIT',
'K_EURO',
'KSCAN_EURO',
'KSCAN_INTERNATIONAL1',
'KSCAN_INTERNATIONAL2',
'KSCAN_INTERNATIONAL3',
'KSCAN_INTERNATIONAL4',
'KSCAN_INTERNATIONAL5',
'KSCAN_INTERNATIONAL6',
'KSCAN_INTERNATIONAL7',
'KSCAN_INTERNATIONAL8',
'KSCAN_INTERNATIONAL9',
'KSCAN_LANG1',
'KSCAN_LANG2',
'KSCAN_LANG3',
'KSCAN_LANG4',
'KSCAN_LANG5',
'KSCAN_LANG6',
'KSCAN_LANG7',
'KSCAN_LANG8',
'KSCAN_LANG9',
'KSCAN_NONUSBACKSLASH',
'KSCAN_NONUSHASH',
'K_EXCLAIM',
'K_QUOTEDBL',
'K_HASH',
'K_DOLLAR',
'K_AMPERSAND',
'K_PERCENT',
'K_LEFTPAREN',
'K_RIGHTPAREN',
'K_ASTERISK',
'K_PLUS',
'K_COLON',
'K_LESS',
'K_GREATER',
'K_QUESTION',
'K_AT',
'K_CARET',
'K_UNDERSCORE',
'KMOD_NONE',
'KMOD_LSHIFT',
'KMOD_RSHIFT',
'KMOD_LCTRL',
'KMOD_RCTRL',
'KMOD_LALT',
'KMOD_RALT',
'KMOD_LGUI',
'KMOD_LMETA',
'KMOD_RGUI',
'KMOD_RMETA',
'KMOD_NUM',
'KMOD_CAPS',
'KMOD_MODE',
'KMOD_CTRL',
'KMOD_SHIFT',
'KMOD_ALT',
'KMOD_GUI',
'KMOD_META',
'APPFOCUSMOUSE',
'APPINPUTFOCUS',
'APPACTIVE',
'SYSTEM_CURSOR_ARROW',
'SYSTEM_CURSOR_IBEAM',
'SYSTEM_CURSOR_WAIT',
'SYSTEM_CURSOR_CROSSHAIR',
'SYSTEM_CURSOR_WAITARROW',
'SYSTEM_CURSOR_SIZENWSE',
'SYSTEM_CURSOR_SIZENESW',
'SYSTEM_CURSOR_SIZEWE',
'SYSTEM_CURSOR_SIZENS',
'SYSTEM_CURSOR_SIZEALL',
'SYSTEM_CURSOR_NO',
'SYSTEM_CURSOR_HAND',
'USEREVENT_DROPFILE',
]
优化飞船的移动方式
目标:调整飞船的速度;限制飞船的移动距离,以免它移到屏幕外面去。
首先熟悉一下坐标系

调整飞船的速度
限制飞船的移动距离
新建游戏的标准化流程
点击查看代码
1、首先编写:`游戏入口类`
其中,编写函数 `run_game()`
此函数流程为:
1. 初始化 pygame 即 `pygame.init()`
2. 实例化一个主显示并赋值给:screen `pygame.display.set_mode(game_settings.screen_size)`
3. 定义窗口名称 pygame.display.set_caption("游戏名称")
4. 实例化一个 player = Player(screen, gamesetting)
5. 编写 While True:
其中包括:按键监测、目标移动、刷新屏幕
按键监测则需要:游戏方法类
目标移动则在 Player类中实现即可
刷新屏幕:其中包括 设置窗口背景、绘制 player,最后使用 pygame.display.flip()渲染更新整个待显示的Surface对象到屏幕上
点击查看有关于 pygame.display.flip() 和 pygame.display.update() 的额外小知识
主要有两点区别:
一是:
pygame.display.flip() 更新整个待显示的 Surface 对象到屏幕上
pygame.display.update() 更新部分内容显示到屏幕上,如果没有参数,则与 flip 功能相同(上一条)
二是:
当使用OpenGL的时候,不能使用 pygame.display.update() 来更新窗口,需要使用 pygame.display.flip() 来更新
动手试一下
点击查看 12-4 按键 代码
"""
12-4 按键:创建一个程序,显示一个空屏幕。在事件循环中,每当检测到
pygame.KEYDOWN 事件时都打印属性 event.key。运行这个程序,并按各种键,看看 Pygame
如何响应
"""
import sys
import pygame
def run_game():
pygame.init()
screen = pygame.display.set_mode((700, 340))
pygame.display.set_caption("每当检测到 pygame.KEYDOWN 事件时都打印属性 event.key")
f = pygame.font.Font("C:/Windows/Fonts/simhei.ttf", 50)
textRect = (screen.get_rect().centerx, screen.get_rect().centery)
text_content = "还未按下按钮"
while True:
for event in pygame.event.get():
# 判断用户是否点了"X"关闭按钮,并执行 if 代码段
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
text_content = "event.key = " + str(event.key)
elif event.type == pygame.KEYUP:
text_content = "还未按下按钮"
screen.fill((0, 0, 0))
text = f.render(f"{text_content}", True, (255, 0, 0), (0, 0, 0))
textRect = (screen.get_rect().centerx - text.get_width() // 2, screen.get_rect().centery - text.get_height()//2)
screen.blit(text, textRect)
pygame.display.flip()
if __name__ == '__main__':
run_game()
第三次迭代
要求:下面来添加射击功能。我们将编写玩家按空格键时发射子弹(小矩形)的代码。子弹将在屏 幕中向上穿行,抵达屏幕上边缘后消失。
此时12章 完结!
查看项目完整代码:
点击查看 alien_invasion.py 代码
import pygame
from pygame.sprite import Group
import game_functions as gf
from settings import Settings
from ship import Ship
def run_game():
# 初始化游戏并创建一个屏幕对象
pygame.init()
game_settings = Settings() # 实例化一个设置对象
screen = pygame.display.set_mode(game_settings.screen_size) # 实例化一个 主显示 surface
pygame.display.set_caption("外星人入侵")
ship = Ship(screen, game_settings) # 实例化一个 飞船实例
bullets = Group()
while True:
# 监视键盘和鼠标事件
gf.check_events(game_settings, screen, ship, bullets)
ship.update()
gf.update_bullets(bullets)
# print(len(bullets))
gf.update_screen(game_settings, screen, ship, bullets)
if __name__ == '__main__':
run_game()
点击查看 bullet.py 代码
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
"""一个对飞船发射的子弹进行管理的类"""
def __init__(self, game_settings, screen, ship):
super(Bullet, self).__init__() # 等价于 super().__init__()
self.screen = screen
self.rect = pygame.Rect(0, 0, game_settings.bullet_width, game_settings.bullet_height)
self.rect.centerx = ship.rect.centerx
self.rect.centery = ship.rect.top # ship.rect.top == ship.rect.centery + ship.rect.get_height() // 2 ??
self.y = float(self.rect.y)
self.color = game_settings.bullet_color
self.speed_factor = game_settings.bullet_speed_factor
def update(self):
self.y -= self.speed_factor
self.rect.y = self.y
def draw_bullet(self):
pygame.draw.rect(self.screen, self.color, self.rect)
点击查看 game_functions.py 代码
import sys
import pygame
from bullet import Bullet
def check_KEYDOWN_events(event, game_settings, screen, ship, bullets):
if event.key == pygame.K_RIGHT:
ship.moving_right = True
elif event.key == pygame.K_LEFT:
ship.moving_left = True
elif event.key == pygame.K_SPACE:
fire_bullet(game_settings, screen, ship, bullets)
def check_KEYUP_events(event, ship):
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
def check_events(game_settings, screen, ship, bullets):
"""响应按键和鼠标事件"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_KEYDOWN_events(event, game_settings, screen, ship, bullets)
elif event.type == pygame.KEYUP:
check_KEYUP_events(event, ship)
def update_screen(game_settings, screen, ship, bullets):
""" 用于在每次执行主循环时都重绘屏幕 """
# 填充背景色 or 其实是刷新覆盖原来的页面
screen.fill(game_settings.bg_color)
# 绘制子弹
for bullet in bullets.sprites():
bullet.draw_bullet()
# 绘制飞船
ship.blitme()
pygame.display.flip()
def update_bullets(bullets):
bullets.update()
for bullet in bullets.copy():
if bullet.rect.bottom < 0:
bullets.remove(bullet)
def fire_bullet(game_settings, screen, ship, bullets):
if len(bullets) < game_settings.bullets_allowed:
new_bullet = Bullet(game_settings, screen, ship)
bullets.add(new_bullet)
点击查看 settings.py 代码
class Settings():
"""
存储外星人入侵所有设置的类
它初始化控制游戏外观和飞船速度的属性
"""
def __init__(self):
"""初始化游戏的设置"""
self.screen_size = (1200, 800)
self.bg_color = (230, 230, 230)
# 飞船的速度
self.ship_speed_factor = 0.5
# 子弹的设置参数
self.bullet_speed_factor = 0.4
self.bullet_width = 3
self.bullet_height = 15
self.bullet_color = 60, 60, 60
self.bullets_allowed = 3
点击查看 ship.py 代码
import pygame
class Ship():
def __init__(self, screen, game_settings):
self.screen = screen
self.image = pygame.image.load("./images/ship.bmp")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
self.moving_right = False
self.moving_left = False
self.game_settings = game_settings
self.center = float(self.rect.centerx)
def blitme(self):
"""在指定位置绘制飞船"""
self.screen.blit(self.image, self.rect)
def update(self):
if self.moving_right and self.rect.right < self.screen_rect.right:
# self.rect.centerx += 1
self.center += self.game_settings.ship_speed_factor
elif self.moving_left and self.rect.left > self.screen_rect.left:
# self.rect.centerx -= 1
self.center -= self.game_settings.ship_speed_factor
self.rect.centerx = self.center


浙公网安备 33010602011771号