用python3从零开始开发一款烧脑射击游戏#2

上回说到用pygame绘制一个静止的小方块,今天将会实现通过鼠标或者键盘来控制小方块的移动

在这之前,首先我们需要考虑一个问题:
我们怎样才会认为一个物体在运动?风动,幡动还是仁者心动?

小方块在屏幕上的相对位置发生了变化,那就代表它移动了

与连续的现实世界不同的是,计算机内部的世界是离散化的,我们其实并没有真的去移动初始的小方块
而是在屏幕上不断的擦去旧的小方块,画出新位置上的小方块,玩家看起来就像它在移动一样

因此移动的实现逻辑就得到了:
在每一帧中擦去上一帧画的小方块
获取小方块当前的位置,并在这个位置画一个新的小方块

只要帧数足够多(超过视觉暂留的需求),就实现了小方块的“连续移动”

下面我们定义一个小方块的类

class Robot(object):
    def __init__(self:
        self.x = 120
        self.y = 350
        
    def Move(self):
        self.x+=1
        self.y+=1
        pygame.draw.rect(screen,color1,Rect(self.x,self.y,20,20))

小方块的初始为止在(120,350),每调用一次Move,坐标就会修改,如果绘制出新的矩形,就实现了移动
我们用这个类创建一个对象
robot = Robot()

然后开始绘制屏幕

while True:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    screen.fill(color)#用背景色刷掉前一帧的所有图形
    robot.Move()#绘制新的位置
    pygame.display.flip()

这样小方块就动起来辣

再来看怎么发出移动指令来控制移动行为

1.先看通过键盘的方向键来控制移动
pygame支持键盘事件,当按键按下的时候响应KEYDOWN事件,按键弹起的时候响应KEYDOWN事件
不过我不打算直接通过键盘事件来驱动移动行为,而采用一种更简便的方法:
在每帧更新方块位置时,获取当前被按下的键盘按键,然后对坐标做对应的修改:

key_press = pygame.key.get_pressed()
if(key_press[K_LEFT]):
    self.x -= 1
elif (key_press[K_RIGHT]):
    self.x += 1
elif (key_press[K_UP]):
    self.y -= 1
elif (key_press[K_DOWN]):
    self.y += 1

完整代码可以从这里获取

2.然后是鼠标控制。(鼠标控制要复杂一点,需要根据鼠标的点击维护好移动指令的状态)
这里我们将模拟实现鼠标移动操作最多的rts游戏(星际争霸与war3)中最基础的几个鼠标操作:
a.左键框选选中目标(可以同时选中框内的多个目标)
b.有选择单位时,右键点击移动位置,则选中的单位将会向目标点移动(持续移动,直到到达目标点为止,中间不需要其他命令)
c.左键单击空地,将会取消单位选中的状态

20190122_173911.gif

pygame支持一些鼠标事件,他们包括MOUSEMOTION,MOUSEBUTTONUP,MOUSEBUTTONDOWN
我们可以在事件轮训中判断当前是否发生鼠标事件

for event in pygame.event.get():
    if event.type == MOUSEBUTTONDOWN:
        #逻辑处理

由于我们是在帧触发时处理移动指令,我们需要自己记录鼠标的位置和点击状态(一组全局变量)

mouse_state = 0#0空闲,1左键按下,2右键按下
mouse_begin = [0,0]#鼠标按下时的起始位置
mouse_end = [0,0]#鼠标的当前位置
move_tar = [0,0]#鼠标右键选择的移动目标
move_click = False#是否有未处理的右键目标
check_select = False#是否需要检测框选目标

通过鼠标的按键信息,更新维护对应的状态变量:

pressed_array = pygame.mouse.get_pressed()
for index in range(len(pressed_array)):#判断鼠标按的是左中右的哪个键
    if pressed_array[index]:
        if index == 0:
            mouse_state = 1
            check_select = True
        elif index == 2:
            mouse_state = 2
if mouse_state > 0 :
    mouse_begin = pygame.mouse.get_pos()#获取鼠标的箭头位置

有了这些信息后,我们就可以改造一下方块类,让它根据鼠标选择的位置来进行移动

class Robot(object):
    def __init__(self,clo,ms):
        self.dir = [0,0]
        self.x = 120
        self.y = 350
        self.isselect = False#是否被框选中
        self.color = clo#区分颜色
        self.move_speed = ms#移动速度
        self.tar =[0,0]#移动目标
    
    def Move(self):
        if check_select:#检测是否在左键拉出的框内
            minx = min(mouse_begin[0],mouse_end[0])
            maxx = max(mouse_begin[0],mouse_end[0])
            miny = min(mouse_begin[1],mouse_end[1])
            maxy = max(mouse_begin[1],mouse_end[1])
            if(self.x >=minx and self.x <= maxx and self.y >= miny and self.y <= maxy):
                self.isselect = True
            else:
                self.isselect = False

        if move_click:#有移动指令
            if self.isselect :
                self.tar = move_tar
                dx = self.tar[0]-self.x
                dy = self.tar[1]-self.y
                len=(dx*dx+dy*dy)**0.5
                if(len > 0):
                    dx /= len
                    dy /= len
                dx *= self.move_speed
                dy *= self.move_speed
                self.dir = [dx,dy]#计算移动向量
        
        if( self.dir[0] != 0 or self.dir[1] != 0):#移动向量非0,表示需要移动更新坐标
            dx = self.tar[0]-self.x
            dy = self.tar[1]-self.y
            len=(dx*dx+dy*dy)**0.5
            if(len < 10):
                self.x=self.tar[0]
                self.y=self.tar[1]
                self.dir = [0,0]
            self.x += self.dir[0]
            self.y += self.dir[1]
        
        if True == self.isselect :
            pygame.draw.rect(screen,color1,Rect(self.x,self.y,20,20))
        else:
            pygame.draw.rect(screen,self.color,Rect(self.x,self.y,20,20))

完整代码可以从这里获取

你可能感兴趣的:(用python3从零开始开发一款烧脑射击游戏#2)