外星人入侵开发总结
设置屏幕大小、游戏名称、背景颜色
pygame.init() #初始化背景设置
ai_settings = Settings()
screen = pygame.display.set_mode((120, 800))
pygame.display.set_caption("外星人入侵")
set_mode()就是设置游戏屏幕宽高的函数,坐标原点在电脑屏幕左上角。
set_caption()就是设置游戏名称的函数
背景颜色
#设置背景颜色
bg_color = (230, 230, 230)
screen.fill(ai_settings.bg_color) #只能有一个参数
screen.fill()函数只能传递一个参数,设置背景的颜色。
这些基本的参数可用在一个文件中写,然后在其他文件中引用。
让屏幕绘制可见
# 让最近绘制的屏幕可见
pygame.display.flip()
这句代码必须有,不然所有的screen设置都无法显示。 正常在每个循环中都会重新设置
设置键盘和鼠标监听事件
def check_events(ai_settings,screen,ship,bullets):
""" 响应按键和鼠标事件,在这个方法中指定需要检查的事件 """
# 事件都是通过pygame.event.get()方法获取
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 每次按键都会注册一个KEYDOWN
# 检测到KEYDOWN事件时,我们需要检查按下的是否是特定的键
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,ai_settings,screen,ship,bullets)
# 松开方向键时触发的事件,将moving_right or moving_left设为false
elif event.type == pygame.KEYUP:
check_keyup_events(event,ship)
为了能够访问Pygame检测到的事件,需要使用pygame.event.get()函数,获取事件,然后再通过event.type来判断获取的事件类型
键盘按键事件编码大全
KeyASCII | ASCII | Common Name |
---|---|---|
K_BACKSPACE | \b | backspace |
K_TAB | \t | tab |
K_CLEAR | clear | |
K_RETURN | \r | return |
K_PAUSE | pause | |
K_ESCAPE | ^[ | escape |
K_SPACE | space | |
K_EXCLAIM | ! | exclaim |
K_QUOTEDBL | " | quotedbl |
K_HASH | # | hash |
K_DOLLAR | $ | dollar |
K_AMPERSAND | & | ampersand |
K_QUOTE | quote | |
K_LEFTPAREN | ( | left parenthesis |
K_RIGHTPAREN | ) | right parenthesis |
K_ASTERISK | * | asterisk |
K_PLUS | + | plus sign |
K_COMMA | , | comma |
K_MINUS | - | minus sign |
K_PERIOD | . | period |
K_SLASH | / | forward slash |
K_0 | 0 | 0 |
K_1 | 1 | 1 |
K_2 | 2 | 2 |
K_3 | 3 | 3 |
K_4 | 4 | 4 |
K_5 | 5 | 5 |
K_6 | 6 | 6 |
K_7 | 7 | 7 |
K_8 | 8 | 8 |
K_9 | 9 | 9 |
K_COLON | : | colon |
K_SEMICOLON | ; | semicolon |
K_LESS | < | less-than sign |
K_EQUALS | = | equals sign |
K_GREATER | > | greater-than sign |
K_QUESTION | ? | question mark |
K_AT | @ | at |
K_LEFTBRACKET | [ | left bracket |
K_BACKSLASH | \ | backslash |
K_RIGHTBRACKET | ] | right bracket |
K_CARET | ^ | caret |
K_UNDERSCORE | _ | underscore |
K_BACKQUOTE | ` | grave |
K_a | a | a |
K_b | b | b |
K_c | c | c |
K_d | d | d |
K_e | e | e |
K_f | f | f |
K_g | g | g |
K_h | h | h |
K_i | i | i |
K_j | j | j |
K_k | k | k |
K_l | l | l |
K_m | m | m |
K_n | n | n |
K_o | o | o |
K_p | p | p |
K_q | q | q |
K_r | r | r |
K_s | s | s |
K_t | t | t |
K_u | u | u |
K_v | v | v |
K_w | w | w |
K_x | x | x |
K_y | y | y |
K_z | z | z |
K_DELETE | delete | |
K_KP0 | keypad 0 | |
K_KP1 | keypad 1 | |
K_KP2 | keypad 2 | |
K_KP3 | keypad 3 | |
K_KP4 | keypad 4 | |
K_KP5 | keypad 5 | |
K_KP6 | keypad 6 | |
K_KP7 | keypad 7 | |
K_KP8 | keypad 8 | |
K_KP9 | keypad 9 | |
K_KP_PERIOD | . | keypad period |
K_KP_DIVIDE | / | keypad divide |
K_KP_MULTIPLY | * | keypad multiply |
K_KP_MINUS | - | keypad minus |
K_KP_PLUS | + | keypad plus |
K_KP_ENTER | \r | keypad enter |
K_KP_EQUALS | = | keypad equals |
K_UP | up arrow | |
K_DOWN | down arrow | |
K_RIGHT | right arrow | |
K_LEFT | left arrow | |
K_INSERT | insert | |
K_HOME | home | |
K_END | end | |
K_PAGEUP | page up | |
K_PAGEDOWN | page down | |
K_F1 | F1 | |
K_F2 | F2 | |
K_F3 | F3 | |
K_F4 | F4 | |
K_F5 | F5 | |
K_F6 | F6 | |
K_F7 | F7 | |
K_F8 | F8 | |
K_F9 | F9 | |
K_F10 | F10 | |
K_F11 | F11 | |
K_F12 | F12 | |
K_F13 | F13 | |
K_F14 | F14 | |
K_F15 | F15 | |
K_NUMLOCK | numlock | |
K_CAPSLOCK | capslock | |
K_SCROLLOCK | scrollock | |
K_RSHIFT | right shift | |
K_LSHIFT | left shift | |
K_RCTRL | right control | |
K_LCTRL | left control | |
K_RALT | right alt | |
K_LALT | left alt | |
K_RMETA | right meta | |
K_LMETA | left meta | |
K_LSUPER | left Windows key | |
K_RSUPER | right Windows key | |
K_MODE | mode shift | |
K_HELP | help | |
K_PRINT | print screen | |
K_SYSREQ | sysrq | |
K_BREAK | break | |
K_MENU | menu | |
K_POWER | power | |
K_EURO | Euro |
加载图片 添加图片元素
以ship.py为例
class Ship():
def __init__(self,ai_settings, screen):
""" 初始化飞船设置其初始化位置"""
self.screen = screen
self.ai_settings = ai_settings
# 加载飞船图像并获取其外接矩形
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
# 在飞船的属性center中存储小数值
self.center = float(self.rect.centerx)
# 添加一个向右移动的属性 初始化为False
# 在向右键按下时,为真,松开为False,实现按住持续移动
self.moving_right = False
self.moving_left = False
通过pygame.image.load()函数加载图片,存放图片素材的文件最好与ship.py在同一级目录。
self.image.get_rect() 是获取图片所占用的矩形,此后就像操作一个矩形一样操控图片,简单快捷高效。
screen.get_rect() 同理就是获取屏幕的矩形。
两个获取的矩形rect其实都是为了获取对象的参数,方便设置位置等。可用使用矩形的四角和中心(x,y)坐标来设置图片的位置。
rect的对象还有center,centerx,centery属性。
属性 | 作用 |
---|---|
center | 即矩形中心,返回的是矩形中心的坐标 |
centerx | 矩形x轴的中心,返回的是矩形x轴中心的x值 |
centery | 矩形y轴的中心,返回的是矩形y轴中心的y值 |
top | 矩形顶部 |
bottom | 矩形底部 |
left | 矩形左边 |
right | 矩形右边 |
这些值都是可用修改的。
在指定位置绘制图片元素
""" 在指定位置绘制飞船"""
self.screen.blit(self.image,self.rect)
blit()向屏幕添加图片元素,self.image传递的是图片,self.rect传递是矩形元素,通过rect的centerx和bottom属性设置的矩形图片在屏幕中的位置
事件响应
def check_keydown_events(event,ai_settings,screen,ship,bullets):
# 响应按键 右方向键
# 通过读取event.key,检查按下的是否是右箭头键
if event.key == pygame.K_RIGHT:
# 向右移动飞船
# ship.rect.centerx += 1 飞船向右移动
ship.moving_right = True
elif event.key == pygame.K_LEFT:
# 向左移动飞船
# ship.rect.centerx -= 1
ship.moving_left = True
elif event.key == pygame.K_SPACE: # 设置开火指令
fire_bullet(ai_settings, screen, ship, bullets)
# 按下Q时退出游戏
elif event.key == pygame.K_q:
sys.exit()
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(ai_settings,screen,ship,bullets):
""" 响应按键和鼠标事件,在这个方法中指定需要检查的事件 """
# 事件都是通过pygame.event.get()方法获取
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 每次按键都会注册一个KEYDOWN
# 检测到KEYDOWN事件时,我们需要检查按下的是否是特定的键
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,ai_settings,screen,ship,bullets)
# 松开方向键时触发的事件,将moving_right or moving_left设为false
elif event.type == pygame.KEYUP:
check_keyup_events(event,ship)
简单的讲,就是按某个键,pygame检测到这个键被触发,然后找到对应的处理方法,然后触发相应的响应事件。
这里就是控制飞船的移动,也就是修改飞船的位置参数。
有按键按下事件,松开事件,单击按动事件
将子弹设置成从飞船顶部发出
# 设置子弹的位置,位于飞船的正上方。
self.rect.centerx = ship.rect.centerx
self.rect.top = ship.rect.top
理解:pygame中元素的布局其实是相对布局。将A元素的rect参数设置成B元素的rect,则B元素是相对于A元素的布局位置
创建元素编组,存储生成的元素
# 创建一个用于存储子弹的编组,存储所有有效的子弹,
# 管理发射出去的子弹
bullets = Group()
# 创建一个空编组,用于存储全部外星人
aliens=Group()
其实就是将元素建个数组存起来,方便在需要的查找到该元素。
飞船开火事件
这种开火事件其实就是按一下空格生成一颗子弹,并且让子弹移动。
elif event.key == pygame.K_SPACE: # 设置开火指令
fire_bullet(ai_settings, screen, ship, bullets)
def fire_bullet(ai_settings, screen, ship, bullets):
# 如果还没有到达限制,就发射一颗子弹
# 创建一颗子弹,并将其加入到编组bullets中
# 按下空格时,发射子弹,并且限制子弹数量
if len(bullets) < ai_settings.bullets_allowed:
new_bullet = Bullet(ai_settings, screen, ship)
bullets.add(new_bullet)
感想
这样的游戏开发其实非常简单,就是添加几个元素,然后通过修改它的位置属性来实现它的移动。
对动态的理解,游戏的动态效果其实就是基于电脑高速的计算速度,每一次的绘制其实都是静态的,但是通过非常快的速度对飞船的位置进行细微的修改,就实现了动态的效果,也就在不断的循环刷新游戏界面,所以一般电脑屏幕刷新率高的游戏更流畅,电脑运行速度快的也更流畅。系统里面其实有一个死循环,在不停的根据事件响应来删掉旧的,更新添加。所以在游戏开发中这个循环是必不可少的,而且最好是while循环来实现