Python进阶篇二Pygame的结构
Posted deepboat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python进阶篇二Pygame的结构相关的知识,希望对你有一定的参考价值。
目录
二、Pygame的结构
2.1 初始化程序
在使用 Pygame 编写程序前,要做的第一个步骤是“初始化程序”,代码如下所示:
pygame.init()
作用:自动检测 Pygame 软件包是否正常可用,并检查电脑的硬件调用接口、基础功能是否存在问题,比如音频、光驱、声卡驱动等设备。同时,它会完成 Pygame 中所有模块的初始化操作。
2.2 创建Surface对象
想要掌握 Pygame 的编程逻辑,首先就要理解 surface 对象的概念,它是 Pygame 中最重要的组成部分。
Pygame 中,您可以把 surface
对象理解成一张“白纸”,通过这张纸可以做许多的事情,比如在纸上添加文字、填充颜色、添加图片以及绘制任意形状的图形等。既然是“纸”就有规格尺寸,Pygame 允许您创建任意大小的纸。
Pygame 提供了多种创建 Surface 对象的方法,这里先介绍以下几种方法。
# 也叫screen对象,本质上是一个Surface,大小400*400
screen = pygame.display.set_mode((400,400))
screen 的本质上就是一个 Surface
对象,它是游戏的主窗口,也就是整个游戏中尺寸最大的“纸”,任何其他的 Surface
对象都需要附着在这张最大的“纸”上,比如创建一个包含文本的 Surface
对象,通过以下方法将它绘制在主屏幕上:
# 创建一个包含文字的Surface对象
text = f.render("Python自学网",True,(255,0,0),(0,0,0))
# 通过blit方法将其绘制在主屏幕上,这里的textRect表示位置坐标
screen.blit(text,textRect)
如果想创建一个包含图像的 surface 对象可以使用如下方法:
surface_image =pygame.image.load("图片路径")
2.3 事件监听
动画保证了玩家的视觉体验,而人机交互则是操作上的体验。通过移动和点击鼠标、按下键盘上的技能键,或是滑动手机屏幕等操作来实现人机交互,这些与游戏程序交互的操作被称为事件(Event)。
Pygame 作为一个游戏开发库,同样具有设置和监听事件的功能。它提供了一个 event
事件模块,这个模块中包含了所有常用到游戏事件。
# 循环获取事件,监听事件状态,使用get()获取事件
for event in pygame.event.get():
# 判断事件类型,用户是否点了"X"关闭按钮
# pygame.QUIT 指点击右上角窗口的"X"号
if event.type == pygame.QUIT:
#点击后,卸载所有pygame模块
pygame.quit()
2.4 游戏循环
当打我们游戏时可能会触发游戏中的各种事件,比如鼠标事件、键盘按键事件、摄像拍照事件等等,因此游戏程序需要一直循环监听玩家的操作,只有当用户点击了游戏“关闭”按钮时,监听才会结束。如果想要达到“循环监听”目的,此时就需要设置一个游戏循环(Game Loop)也称为游戏的主循环,这样才能保证人机交互的体验感。代码示例如下:
#游戏主循环(游戏循环)
while True:
# 循环获取事件,监听事件
for event in pygame.event.get():
# 判断用户是否点了关闭按钮
if event.type == pygame.QUIT:
# 当用户关闭游戏窗口时执行以下操作
# 这里必须调用quit()方法,退出游戏
pygame.quit()
#终止系统
sys.exit()
#更新并绘制屏幕内容
pygame.display.flip()
游戏主循环是每个 Pygame 游戏程序中必不可少的一部分,它主要承担着以下三个重要任务:
- 处理游戏事件
- 更新游戏状态
- 把更新后的游戏状态绘制到屏幕上
游戏画面和游戏操作状态会因为动画效果和玩家的操作而改变,因此需要以循环的方式实时地更新主屏幕(screen)的显示内容。把下列代码放入游戏主循环中即可实现实时更新和绘制屏幕内容,如下所示:
#刷新界面显示
pygame.display.flip()
除了上述方法外,Pygame 还提供了另一个方法。如下所示:
pygame.display.update()
这两个方法的主要区别是:后者可以根据选定的区域来更新部分内容,而前者则是更新整个待显示的内容。如果后者没有提供区域位置参数时,其作用和 display.flip() 相同。
Django 进阶篇二
Django Forms表单
在实际的生产环境中比如登录和验证的时候,我们一般都使用Jquery+ajax来判断用户的输入是否为空,假如JS被禁用的话,咱们这个认证屏障是不是就消失了呢?(虽然一般不会禁用掉但是还是存在风险)
所以我们一般做两种认证一种是前端做一遍认证,在后端做一遍认证
案例:
#/usr/bin/env python #-*- coding:utf-8 -*- from django.shortcuts import render # Create your views here. def user_list(request): host = request.POST.get(‘host‘) port = request.POST.get(‘port‘) mail = request.POST.get(‘mail‘) mobile = request.POST.get(‘mobile‘) # 这里有个问题,如果,这个from表单有20个input,你在这里是不是的取20次? # 验证: # 输入不能为空,并且有的可以为空有的不可以为空 # 如果email = 11123123 这样合法吗? # 如果mobile = 11123123 这样合法吗? # 如果ip = 11123123 这样合法吗? ‘‘‘ 你在这里是不是需要做一大堆的输入验证啊?并且有很多这种页面会存在这种情况,如果每个函数都这样做估计就累死了 ‘‘‘ return render(request,‘user_list.html‘)
怎样能解决这个问题呢?通过Django的form来实现,其他语言也有叫做(模型绑定)
Django的form的作用:
1、生成html标签
2、用来做用户提交的验证
一、生成html标签
views
# -*- coding:utf-8 -*- from django.shortcuts import render, redirect from usermanager import models from django import forms # Create your views here. class UserInfo(forms.Form): user = forms.CharField(required=True) # required是否可以为空,如果为False说明可以为空,默认为True pwd = forms.CharField() # 如果required不写默认为Ture port = forms.CharField() host = forms.GenericIPAddressField() # 通用IP地址格式 email = forms.EmailField(required=False) def user_list(request): obj = UserInfo() # 创建了这个对象 return render(request, ‘user_list.html‘, {‘obj‘: obj}) # 然后把对象传给html
html调用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/user_list/" method="post"> <p>用户:{{ obj.user }}</p> <p>密码:{{ obj.pwd }}</p> <p>端口:{{ obj.port }}</p> <p>主机:{{ obj.host }}</p> <p>邮箱:{{ obj.email }}</p> <input type="submit" value="submit" /> </form> </body> </html>
把我们的对象穿进去,html在引用的时候直接obj.host就可以自动生成html标签,然后看下html显示:
二、简单的form表单验证用户输入的内容
def user_list(request): obj = UserInfo() # 创建了这个对象 if request.method == ‘POST‘: # 获取用户输入一句话就搞定 user_input_obj = UserInfo(request.POST) ‘‘‘ 咱们把post过来的数据当参数传给UserInfo咱们定义的这个类,UserInfo会自动会去你提交的数据 email/host/port/mobile 自动的封装到user_input_obj里,封装到这个对象里我们就可以判断输入是否合法 ‘‘‘ print user_input_obj.is_valid() # return render(request,‘user_list.html‘,{‘obj‘:obj}) # 然后把对象传给html
当我们输入不合法的时候,(在创建类设置的需求)为空、或者不是email格式的时候!
这样在后端我们是不是就有一套验证的机制?就可以通过is_valid()来判断用户输入是否合法!如果不合法就把返回信息发送过去,如果合法获取数据操作即可!
捕获错误信息并返回
from django import forms class UserInfo(forms.Form): email = forms.EmailField(required=True) #required是否可以为空,如果为False说明可以为空 host = forms.CharField() #如果required不写默认为Ture port = forms.CharField() mobile = forms.CharField() def user_list(request): obj = UserInfo() #创建了这个对象 if request.method == ‘POST‘: #获取用户输入一句话就搞定 user_input_obj = UserInfo(request.POST) ‘‘‘ 咱们把post过来的数据当参数传给UserInfo咱们定义的这个类,UserInfo会自动会去你提交的数据 email/host/port/mobile 自动的封装到user_input_obj里,封装到这个对象里我们就可以判断输入是否合法 ‘‘‘ if user_input_obj.is_valid(): #判断用户输入是否合法 data = user_input_obj.clean() #获取用户输入 print data else: #如果发生错误,捕捉错误 error_msg = user_input_obj.errors print error_msg #打印一下然后看下他的类型 ‘‘‘ <ul class="errorlist"> <li>mobile<ul class="errorlist"><li>This field is required. </li></ul></li> <li>host<ul class="errorlist"><li>This field is required.</li></ul></li> <li>port<ul class="errorlist"><li>This field is required.</li></ul></li> </ul> ‘‘‘ #然后把错误信息返回 return render(request,‘user_list.html‘,{‘obj‘:obj,‘errors‘:error_msg,})#然后把对象传给html,在把错误信息传递过去 return render(request,‘user_list.html‘,{‘obj‘:obj,})#然后把对象传给html
html标签,使用error输出
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/user_list/" method="post"> <p>用户:{{ obj.user }}<span>{{ errors.user }}</span></p> <p>密码:{{ obj.pwd }}<span>{{ errors.pwd }}</span></p> <p>端口:{{ obj.port }}<span>{{ errors.port }}</span></p> <p>主机:{{ obj.host }}<span>{{ errors.host }}</span></p> <p>邮箱:{{ obj.email }}<span>{{ errors.email }}</span></p> <input type="submit" value="submit" /> </form> </body> </html>
3、form表单定制化
3.1、自定义报错内容
在form里有一个参数:error_messages 在他这里就可以定义报错内容
class UserInfo(forms.Form): email = forms.EmailField(required=True,error_messages={‘required‘:u‘邮箱不能为空‘}) # required是否可以为空,如果为False说明可以为空 host = forms.CharField(error_messages={‘required‘:u‘主机不能为空‘}) # 如果required不写默认为Ture port = forms.CharField(error_messages={‘required‘:u‘端口不能为空‘}) mobile = forms.CharField(error_messages={‘required‘:u‘手机不能为空‘})
3.2、我想给form表单添加一个属性
class UserInfo(forms.Form): email = forms.EmailField(required=True,error_messages={‘required‘:u‘邮箱不能为空‘}) # required是否可以为空,如果为False说明可以为空 host = forms.CharField(error_messages={‘required‘:u‘主机不能为空‘}) # 如果required不写默认为Ture port = forms.CharField(error_messages={‘required‘:u‘端口不能为空‘}) mobile = forms.CharField(error_messages={‘required‘:u‘手机不能为空‘}, widget=forms.TextInput(attrs={‘class‘:‘form-control‘,‘placeholder‘:u‘手机号码‘}) # 这里默认是TextInput,标签 )
3.3、在给他增加一个备注
class UserInfo(forms.Form): email = forms.EmailField(required=True,error_messages={‘required‘:u‘邮箱不能为空‘}) #required是否可以为空,如果为False说明可以为空 host = forms.CharField(error_messages={‘required‘:u‘主机不能为空‘}) #如果required不写默认为Ture port = forms.CharField(error_messages={‘required‘:u‘端口不能为空‘}) mobile = forms.CharField(error_messages={‘required‘:u‘手机不能为空‘}, widget=forms.TextInput(attrs={‘class‘:‘form-control‘,‘placeholder‘:u‘手机号码‘}) #这里默认是TextInput,标签 ) # 新增一个备注(textarea) memo = forms.CharField(required=False, widget=forms.Textarea(attrs={‘class‘:‘form-control‘,‘placeholder‘:u‘备注‘}) )
html代码
<form action="/user_list/" method="post"> <p>主机:{{ obj.host }}<span>{{ errors.host }}</span></p> <p>端口:{{ obj.port }}<span>{{ errors.port }}</span></p> <p>邮箱:{{ obj.email }}<span>{{ errors.email }}</span></p> <p>手机:{{ obj.mobile }}<span>{{ errors.mobile }}</span></p> <p>备注:{{ obj.memo }}<span>{{ errors.memo }}</span></p> <input type="submit" value="submit"/> </form>
4、自定义正则表达式增加判断规则
import re from django import forms from django.core.exceptions import ValidationError #自定义方法 def mobile_validate(value): mobile_re = re.compile(r‘^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$‘) #正则匹配 if not mobile_re.match(value): raise ValidationError(‘手机号码格式错误‘) #如果没有匹配到主动触发一个错误 class UserInfo(forms.Form): email = forms.EmailField(required=True,error_messages={‘required‘:u‘邮箱不能为空‘}) #required是否可以为空,如果为False说明可以为空 host = forms.CharField(error_messages={‘required‘:u‘主机不能为空‘}) #如果required不写默认为Ture port = forms.CharField(error_messages={‘required‘:u‘端口不能为空‘}) # 默认mobile里有一个默认为空的机制,我们在原有的参数里增加怎们自定义的方法 mobile = forms.CharField(validators=[mobile_validate,],# 应用咱们自己定义的规则 error_messages={‘required‘:u‘手机不能为空‘}, widget=forms.TextInput(attrs={‘class‘:‘form-control‘,‘placeholder‘:u‘手机号码‘}) # 这里默认是TextInput,标签 ) # 新增一个备注(textarea) memo = forms.CharField(required=False, widget=forms.Textarea(attrs={‘class‘:‘form-control‘,‘placeholder‘:u‘备注‘}) )
如果为空的话会提示,不能为空如果格式不对的话会提示手机号码格式错误
5、生成select标签
class UserInfo(forms.Form): user_type_choice = ( (0, u‘普通用户‘), (1, u‘高级用户‘),) user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,attrs={‘class‘:‘form-control‘}))
html内
<form action="/user_list/" method="post"> <p>用户类型:{{ obj.user_type }}<span>{{ errors.user_type }}</span></p> <p>主机:{{ obj.host }}<span>{{ errors.host }}</span></p> <p>端口:{{ obj.port }}<span>{{ errors.port }}</span></p> <p>邮箱:{{ obj.email }}<span>{{ errors.email }}</span></p> <p>手机:{{ obj.mobile }}<span>{{ errors.mobile }}</span></p> <p>备注:{{ obj.memo }}<span>{{ errors.memo }}</span></p> <input type="submit" value="submit"/> </form>
6、关于后端验证
这个后端验证是必须要有验证机制的,前端可以不写但是后端必须要写!前端的JS是可以被禁用掉到。
6、Django form漂亮的显示错误信息
设置显示error的样式
error_msg = user_input_obj.errors.as_data()#这里原来什么都没写,默认是ul的样式,默认是as_ul(),如果我们写成as_data()返回的就是一个原生的字符串 #还有一个as_json
实例:
import re from django import forms from django.core.exceptions import ValidationError # 自定义方法 def mobile_validate(value): mobile_re = re.compile(r‘^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$‘) # 正则匹配 if not mobile_re.match(value): raise ValidationError(‘手机号码格式错误‘) # 如果没有匹配到主动出发一个错误 class UserInfo(forms.Form): user_type_choice = ( (0, u‘普通用户‘), (1, u‘高级用户‘),) user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,attrs={‘class‘:‘form-control‘})) email = forms.EmailField(required=True,error_messages={‘required‘:u‘邮箱不能为空‘}) # required是否可以为空,如果为False说明可以为空 host = forms.CharField(error_messages={‘required‘:u‘主机不能为空‘}) # 如果required不写默认为Ture port = forms.CharField(error_messages={‘required‘:u‘端口不能为空‘}) # 默认mobile里有一个默认为空的机制,我们在原有的参数里增加怎们自定义的方法 mobile = forms.CharField(validators=[mobile_validate,],# 应用咱们自己定义的规则 error_messages={‘required‘:u‘手机不能为空‘}, widget=forms.TextInput(attrs={‘class‘:‘form-control‘,‘placeholder‘:u‘手机号码‘}) # 这里默认是TextInput,标签 ) # 新增一个备注 memo = forms.CharField(required=False, widget=forms.Textarea(attrs={‘class‘:‘form-control‘,‘placeholder‘:u‘备注‘})) def user_list(request): obj = UserInfo() #创建了这个对象 if request.method == ‘POST‘: #获取用户输入一句话就搞定 user_input_obj = UserInfo(request.POST) if user_input_obj.is_valid(): #判断用户输入是否合法 data = user_input_obj.clean() #获取用户输入 print data else: #如果发生错误,捕捉错误 error_msg = user_input_obj.errors.as_data()#这里原来什么都没写,默认是ul的样式,默认是as_ul(),如果我们写成as_data()返回的就是一个原生的字符串 #还有一个as_json print error_msg #打印一下然后看下他的类型 #然后把错误信息返回 return render(request,‘user_list.html‘,{‘obj‘:obj,‘errors‘:error_msg,})#然后把对象传给html,在把错误信息传递过去 return render(request,‘user_list.html‘,{‘obj‘:obj,})#然后把对象传给html
看下他的实际是什么内容:
{‘mobile‘: [ValidationError([u‘\u624b\u673a\u4e0d\u80fd\u4e3a\u7a7a‘])], ‘host‘: [ValidationError([u‘\u4e3b\u673a\u4e0d\u80fd\u4e3a\u7a7a‘])], ‘email‘: [ValidationError([u‘\u90ae\u7bb1\u4e0d\u80fd\u4e3a\u7a7a‘])], ‘port‘: [ValidationError([u‘\u7aef\u53e3\u4e0d\u80fd\u4e3a\u7a7a‘])]}
所以我们自定义一个模板语言对其进行修饰:
然后在html中调用
{% load cmdb_tag %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Shuai</title> </head> <body> <form action="/user_list/" method="post"> <p>用户类型:{{ obj.user_type }}<span>{% error_message errors.user_type %}</span></p> <p>主机:{{ obj.host }}<span>{% error_message errors.host %}</span></p> <p>端口:{{ obj.port }}<span>{% error_message errors.port %}</span></p> <p>邮箱:{{ obj.email }}<span>{% error_message errors.email %}</span></p> <p>手机:{{ obj.mobile }}<span>{% error_message errors.mobile %}</span></p> <p>备注:{{ obj.memo }}<span>{% error_message errors.memo %}</span></p> <input type="submit" value="submit"/> </form> </body> </html>
显示效果如下:
因为模板语言不支持用索引的方式取值,所以我们通过自定义simp_tag来进行取值
持续更新
以上是关于Python进阶篇二Pygame的结构的主要内容,如果未能解决你的问题,请参考以下文章