用python3從零開始開發(fā)一款燒腦射擊游戲#2

上回說到用pygame繪制一個靜止的小方塊,今天將會實現(xiàn)通過鼠標或者鍵盤來控制小方塊的移動

在這之前,首先我們需要考慮一個問題:
我們怎樣才會認為一個物體在運動?風動,幡動還是仁者心動?

小方塊在屏幕上的相對位置發(fā)生了變化,那就代表它移動了

與連續(xù)的現(xiàn)實世界不同的是,計算機內部的世界是離散化的,我們其實并沒有真的去移動初始的小方塊
而是在屏幕上不斷的擦去舊的小方塊,畫出新位置上的小方塊,玩家看起來就像它在移動一樣

因此移動的實現(xiàn)邏輯就得到了:
在每一幀中擦去上一幀畫的小方塊
獲取小方塊當前的位置,并在這個位置畫一個新的小方塊

只要幀數(shù)足夠多(超過視覺暫留的需求),就實現(xiàn)了小方塊的“連續(xù)移動”

下面我們定義一個小方塊的類

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,坐標就會修改,如果繪制出新的矩形,就實現(xiàn)了移動
我們用這個類創(chuàng)建一個對象
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()

這樣小方塊就動起來辣

再來看怎么發(fā)出移動指令來控制移動行為

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.然后是鼠標控制。(鼠標控制要復雜一點,需要根據(jù)鼠標的點擊維護好移動指令的狀態(tài))
這里我們將模擬實現(xiàn)鼠標移動操作最多的rts游戲(星際爭霸與war3)中最基礎的幾個鼠標操作:
a.左鍵框選選中目標(可以同時選中框內的多個目標)
b.有選擇單位時,右鍵點擊移動位置,則選中的單位將會向目標點移動(持續(xù)移動,直到到達目標點為止,中間不需要其他命令)
c.左鍵單擊空地,將會取消單位選中的狀態(tài)

20190122_173911.gif

pygame支持一些鼠標事件,他們包括MOUSEMOTION,MOUSEBUTTONUP,MOUSEBUTTONDOWN
我們可以在事件輪訓中判斷當前是否發(fā)生鼠標事件

for event in pygame.event.get():
    if event.type == MOUSEBUTTONDOWN:
        #邏輯處理

由于我們是在幀觸發(fā)時處理移動指令,我們需要自己記錄鼠標的位置和點擊狀態(tài)(一組全局變量)

mouse_state = 0#0空閑,1左鍵按下,2右鍵按下
mouse_begin = [0,0]#鼠標按下時的起始位置
mouse_end = [0,0]#鼠標的當前位置
move_tar = [0,0]#鼠標右鍵選擇的移動目標
move_click = False#是否有未處理的右鍵目標
check_select = False#是否需要檢測框選目標

通過鼠標的按鍵信息,更新維護對應的狀態(tài)變量:

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()#獲取鼠標的箭頭位置

有了這些信息后,我們就可以改造一下方塊類,讓它根據(jù)鼠標選擇的位置來進行移動

class Robot(object):
    def __init__(self,clo,ms):
        self.dir = [0,0]
        self.x = 120
        self.y = 350
        self.isselect = False#是否被框選中
        self.color = clo#區(qū)分顏色
        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))

完整代碼可以從這里獲取

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容