一、pygame中常用的数学函数
首先介绍两个角度和弧度转换的函数
math.degress()和math.radians()用法很简单,只要将数值传进去然后接受返回值就可以
math.cos(angle),math.sin(angle),这里的angle使用的是弧度表示的,因此需要先使用math.radians(),将角度换成弧度然后在传参
如果要获取当前时间,我们需要使用datetime模块
首先从datetime导入date和time
from datetime import datetime,date,time
使用datetime.body()函数可以获取当前的日期和事件
today = datetime.today()
print(today) 2019-03-29 17:42:55.960923
需要当前时间而不包含当前日期
time = datetime.today().time() print(time) 17:46:47.602774
Time有很多属性,Time.hour Time.minute Time.second Time.micresecond
二、pygame中加载位图,绘制位图
通常,游戏游戏中需要大量的位图,pygame中自带了一些类和函数可以帮组我们轻松的实现
1、加载位图
在pygame中可以使用pygame.image.load()函数来加载位图
space= pygame.image.load("spqce.png").convert_alpha() convert_alpha()方法会使用透明的方法绘制前景对象
2、绘制位图
surface对象有一个名为blit()的方法,它可以绘制位图
screen.blit(space,(0,0))
第一个参数;space 是加载完整的位图,第二个参数是绘制的起始坐
完整的程序如下:
import sys,pygame,math,random from pygame.locals import * pygame.init() screen = pygame.display.set_mode((800,600)) title = pygame.display.set_caption("星空") #创建字体 font = pygame.font.Font(None,18) #加载位图,convert_alpha:使前景对象透明 space = pygame.image.load("space.png").convert_alpha() while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() #获得键盘上所有按键的状态 keys = pygame.key.get_pressed() if keys[K_ESCAPE]: sys.exit() #绘制图位 screen.blit(space,(0,0)) pygame.display.update()
以上代码已经实现了星空背景图,下面的代码加载并绘制一个地球
#加载地球位图 planet2 = pygame.image.load("planet2.png").convert_alpha() #获取地球位图的宽和高 width,height = planet2.get_size() #在屏幕中间绘制地球 screen.blit(planet2,(400-width/2,300-height/2))
地球已经绘制完成以后,最后需要加载超人
#加载机器人 superman = pygame.image.load("military.png").convert_alpha() #绘制机器人 screen.blit(superman,(30,30))
机器人图像太大,需要缩小一些
此时需要用到的模块:pygame.transform 这个模块可以满足我们的需求,这个模块包含了比如缩放,翻转等一些非常有用的函数
pygame.transform.scale()这是一个快速缩放函数,可以快速缩放一个图像,但是如果你试过以后就会发现他并不是那么理想,像素看起来很密集,有点奇怪
幸好它有一个名为pygame,transform,smoothscale()的变体,这个函数通过复杂的计算产生比较平滑的图像,当然他的运行好使大于快速缩放函数
superman = pygame.transform.smoothscale(superman,(width//2,height//2))
考虑让超人绕着地球旋转
import sys,pygame,math,random from pygame.locals import * #定义一个类,方便实现图像的坐标 class Point(object): def __init__(self,x,y): self.__x = x self.__y = y def getx(self): return self.__x def setx(self,x): self.__x = x x = property(getx,setx) def gety(self): return self.__y def sety(self,y): self.__y = y y = property(gety,sety) #定义一个warp_angle(angle)函数,返回0~360之间的角度 def warp_angle(angle): return angle % 360 ''' radius是半径 angle是角度默认值 pos代表图像坐标 ''' radius = 250 angle = 0.0 pos = Point(0,0) old_pos = Point(0,0) pygame.init() screen = pygame.display.set_mode((800,600)) title = pygame.display.set_caption("星空") #创建字体 font = pygame.font.Font(None,18) #加载位图,convert_alpha:使前景对象透明 space = pygame.image.load("space.png").convert_alpha() #加载地球位图 planet = pygame.image.load("planet2.png").convert_alpha() #加载超人位图 superman = pygame.image.load("military.png").convert_alpha() #获取超人位图的宽和高 width,height = superman.get_size() #缩放机器人 superman = pygame.transform.smoothscale(superman,(width//2,height//2)) while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() #获得键盘上所有按键的状态 keys = pygame.key.get_pressed() if keys[K_ESCAPE]: sys.exit() # 绘制背景图位 screen.blit(space, (0, 0)) # 获取地球位图的宽和高 width, height = planet.get_size() # 在屏幕中间绘制地球 screen.blit(planet, (400 - width / 2, 300 - height / 2)) ''' |-- warp_angle是返回0~360的角度,而此代码是360度逐次减0.5度,来控制机器人移动的速度 |-- pos.x,pos.y:图像移动的正反坐标 |-- math.sin:返回弧度的正弦值,数值在-1,1之间 |-- math.cos:返回弧度的余弦值,数值在-1,1之间 |-- math.radians:角度转换成弧度,返回的是一个数值 ''' angle = warp_angle(angle - 0.5) #print("====",angle) pos.x = math.sin(math.radians(angle))*radius pos.y = math.cos(math.radians(angle))*radius #获取机器人的宽和高 width,height = superman.get_size() #绘制机器人,通过第二个参数的x,y轴移动来控制移动的正向还是反向 screen.blit(superman,(350+pos.x-width//2,250+pos.y-height//2)) pygame.display.update()
运行发现,超人可以绕着地球旋转,但是运动的比较僵硬,最好让自己也旋转起来,指向他移动的方向,以便让画面柔和一些
这里我们需要math.atan2()这个函数,它用于计算反正切函数,需要传递两个参数:delta_x,delta_y,
delta_x,delta_y表示两个坐标x,y之间的距离
工作流是这样的:先记录飞船的最近位置,然后使用当前位置和最近位置调用atan2函数,然后在给atan2函数的返回值加上180
我们还需要一个函数是pygame.trsnsform.rotate(),没错,它可以用来旋转位图,需要传两个参数:图像,图像旋转角度
import sys,pygame,math,random from pygame.locals import * #定义一个类,方便实现图像的坐标 class Point(object): def __init__(self,x,y): self.__x = x self.__y = y def getx(self): return self.__x def setx(self,x): self.__x = x x = property(getx,setx) def gety(self): return self.__y def sety(self,y): self.__y = y y = property(gety,sety) #定义一个warp_angle(angle)函数,返回0~360之间的角度 def warp_angle(angle): return angle % 360 ''' radius是半径 angle是角度默认值 pos代表图像坐标 ''' radius = 250 angle = 0.0 pos = Point(0,0) old_pos = Point(0,0) pygame.init() screen = pygame.display.set_mode((800,600)) title = pygame.display.set_caption("星空") #创建字体 font = pygame.font.Font(None,18) #加载位图,convert_alpha:使前景对象透明 space = pygame.image.load("space.png").convert_alpha() #加载地球位图 planet = pygame.image.load("planet2.png").convert_alpha() #加载超人位图 superman = pygame.image.load("military.png").convert_alpha() #获取超人位图的宽和高 width,height = superman.get_size() #缩放机器人 superman = pygame.transform.smoothscale(superman,(width//2,height//2)) while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() #获得键盘上所有按键的状态 keys = pygame.key.get_pressed() if keys[K_ESCAPE]: sys.exit() # 绘制背景图位 screen.blit(space, (0, 0)) # 获取地球位图的宽和高 width, height = planet.get_size() # 在屏幕中间绘制地球 screen.blit(planet, (400 - width / 2, 300 - height / 2)) ''' |-- warp_angle是返回0~360的角度,而此代码是360度逐次减0.5度,来控制机器人移动的速度 |-- pos.x,pos.y:图像移动的正反坐标 |-- math.sin:返回弧度的正弦值,数值在-1,1之间 |-- math.cos:返回弧度的余弦值,数值在-1,1之间 |-- math.radians:角度转换成弧度,返回的是一个数值 ''' angle = warp_angle(angle - 0.5) #print("====",angle) pos.x = math.sin(math.radians(angle))*radius pos.y = math.cos(math.radians(angle))*radius ''' |-- 旋转飞船 |-- delta_x,delta_y表示x,y轴之间的距离 |-- math.atan2()表示返回给定的 X 及 Y 坐标值的反正切值 |-- rangled表示图像旋转角度 |-- math.degrees():将弧度转换成角度 |-- pygame.transform.rotate():用来旋转位图,需要传入的两个参数:图像,角度 ''' delta_x = (pos.x - old_pos.x) delta_y = (pos.y - old_pos.y) rangle = math.atan2(delta_y,delta_x) rangled = warp_angle(-math.degrees(rangle)) superman_rotate = pygame.transform.rotate(superman,rangled) #获取飞船的宽和高 width,height = superman_rotate.get_size() #绘制飞船,通过第二个参数的x,y轴移动来控制移动的正向还是反向 screen.blit(superman_rotate,(300+pos.x-width//2,250+pos.y-height//2)) pygame.display.update()