物件導向的程式設計在遊戲開發中使用(五):基本計算器

遊資網發表於2019-08-19
物件導向的程式設計在遊戲開發中使用(五):基本計算器

我並不是遊戲開發的從業人員,甚至連軟體開發都不是,但至少我是程式設計師。
我認為,一個【物件導向】的理念在學習過程中的重要性遠大於對於程式碼本身含義的認識。 這一點可以在諸多書籍中得到論證,但很奇怪的一件事是,絕大部分的視訊入門教程和並沒有過多的強調這一點。

系列收藏夾:https:/cowlevel.net/collection/3476202

自此,我們對物件導向已經有了一個很全面的瞭解。但是我們寫程式碼的時候要怎麼做呢?

從這篇文章開始,我們將完成一個簡單的計算器,並且逐步新增他的功能。
我們會使用Godot引擎的gds程式語言,這個引擎同樣支援一種視覺化的編輯方法,給苦於學習程式語言又想製作一款遊戲的人有相當的幫助。

網路上有許多Godot的入門教程,我個人也有在考慮撰寫一些相應的內容
雖然我不是職業遊戲開發者,但是我希望進入這個領域的人從最開始程式設計就擁有良好的習慣,這也是本文的目的 如果未來有機會,我會從文件和程式設計的角度為大家介紹這個引擎,但並不能說是教學,因為對於這個引擎實際上的應用我也有許多不明白的地方。
至於選擇這個引擎的原因,本來我打算使用ruby來編寫這部分的程式碼,使得程式碼更加直觀。但是作為教學使用,會浪費大量的時間來解釋特性,而且畢竟是遊戲開發,使用遊戲引擎總是更好。

本內容的程式碼已經上傳至 碼雲

1 分析專案

計算器由什麼組成的,我們要按鈕,要一個螢幕,然後用一個核心邏輯來控制這一切

按鈕每次按下會“輕拍”一下核心邏輯,並遞給它一個數或者符號,

而螢幕定時詢問核心邏輯要顯示什麼。

除此之外,計算器的功能就是對數字進行計算,我們的核心邏輯在收到等於號後吧公式丟給負責計算的員工。

所以我們還需要公式類,數字類和計算類,但我們可能會在下篇文章在完成這部分的細節

2 介面

作為基本的互動,我們需要做個計算器。由按鈕和顯示構成
  1. func _process(delta):
  2.         text = BusiLogic.get_str()
  3. #每幀從核心邏輯更新字元
  4.         pass
複製程式碼

標籤每次更新(_process會被每幀呼叫)時會向核心邏輯查詢最新的字串並顯示
出於效率考慮,將顯示工具註冊給核心邏輯,由核心邏輯呼叫並更新文字更加優秀,但顯然管理這個標籤的重新整理並不是核心邏輯的工作,如果未來對這顯示內容需要進行擴充套件,需要顯示額外內容,這些內容可能由其他部分控制,會牽扯到核心邏輯已經完成程式碼的修改。

根據封裝的原則,我們不希望按鈕自身的資料受到可能的汙染,這對於一個計算器按鈕,可能不會有什麼問題,在更大部分的環境下,我們可能需要對輸入的資料進行驗證和隔離來保證錯誤的輸入不會使後續的工作受到困惑

另外,當我們新增按鈕的功能,我們可以不用改變按鈕的建立,而只是將新的功能定義在函式裡

  1. func bt_set_data(dat, is_num):
  2.         bt_dat = dat
  3.         bt_is_num = is_num
  4.         pass
複製程式碼

3 按鈕按下

在設計上,當按鈕按下後,我們會通知核心邏輯自己按下的按鈕

  1. func enPressed():
  2.         BusiLogic.buttonEnPress(bt_get_data())
  3.         pass
  4. func bt_get_data():
  5.         return {"dat": bt_dat, "is_num": bt_is_num}
  6.         pass
複製程式碼

由於對按鈕的使用時固定而且特殊的,並不需要額外的介面提供給雙方。

如果未來,我們的核心邏輯內,有多個與按鈕地位相等的工具,這些程式碼會遭到大量的更改。會造成諸多不可預料的問題,我們可能會使用一個輸入輸出的介面類來完成這些交換,來保證按鈕對任何的輸入,和任何對核心業務的輸入都暢通無阻。

  1. func buttonEnPress(btn):
  2.         if btn["is_num"]:
  3.                 tNum*= 10
  4.                 tNum+= btn["dat"]
  5.                 math_str += str(btn["dat"])
  6.         else:
  7.                 math_arr.push_back(tNum)
  8.                 math_arr.push_back(btn["dat"])
  9.                 math_str += BT_TEXT[ btn["dat"] ]
  10.         pass
複製程式碼

4 計算功能

我們當下設計的計算器是簡單的加減計算器,輸入數字時螢幕顯示數字,輸入符號時會計算之前的結果,輸入等於號時顯示結果,其後輸入數字和符號將不會繼續前面的結果。

對於這種過程,我們在核心邏輯接收單個數字和符號的輸入,並將其轉化為正常的數字,以及對符號進行判斷。同時,我們需要在計算類設定三種互動,提供數字+符號,返回之前的結果,提供等於號返回結果並清空,提供清楚號清除內容。

我們在數學類中實現這些功能。

  1. func comp(form):
  2.         var tNum = 0
  3.         if symb == BusiLogic.BT["ADD"]:
  4.                 tNum = num1 + form[0]
  5.         elif symb == BusiLogic.BT["SUB"]:
  6.                 tNum = num1 - form[0]
  7.         else:
  8.                 print("ERR",form)
  9.                 tNum = 0
  10.         num1 = tNum
  11.         symb = form[1]
  12.         if symb == BusiLogic.BT["EQU"]:
  13.                 clear()
  14.         return tNum
  15.         pass
複製程式碼

這段程式符合我們所設計的計算流程,返回答案,如果是減號在返回答案之後清空。

但是等號與清空在數學運算中並不相等,顯然這段程式超出了管理範圍,在數學上等號運算理應會返回本來的數字,因此我們進行修改,將等號加入前面的判斷。

  1. elif symb == BusiLogic.BT["EQU"]:
  2.                 tNum = num1
複製程式碼

在核心業務層次上,我們會針對兩種情況進行清理,當我們按下C,或者在按下等號後輸入數字

  1. func buttonEnPress(btn):
  2.         if btn["is_num"]:
  3.                 if en_equ :
  4.                         math.clear()
  5.                         en_equ = false
  6.                 tNum*= 10
  7.                 tNum+= btn["dat"]
  8.                 math_str = str(tNum)
  9.         else:
  10.                 if btn["dat"] == BT["CLR"]:
  11.                         math.clear()
  12.                         math_str = "0"
  13.                 else :
  14.                         en_equ = false
  15.                         math_str = str(math.comp([tNum, btn["dat"]]))
  16.                         tNum = 0
  17.                         if btn["dat"] == BT["EQU"]: en_equ = true
  18.         pass
複製程式碼

自此,我們計算器的雛形已經完成了,我們繼承了原有的標籤和按鈕,把他們改造成了自己想要的樣子,並對他們需要的內容進行了簡單的封裝。

然後我們創造了核心邏輯類負責管理資料的走向,建立了計算類負責對數值進行計算,並且解決了等於號計算中的越權行為。

但是我們的計算方法並不適合複雜的,具有不同優先順序的同個公式整體運算,比如先乘除後加減的遵守。同樣,我們的數字也只支援系統預設的數字,我們或許需要對於分數或者複數的計算功能。

顯然在現有的程式碼中對這些功能進行擴充套件是十分災難性的,我們在後續內容將大幅度改寫程式碼,新增乘除運算,並規劃未來發展的方向,使得我們的程式可以更加輕易的擴充套件。

系列文章
物件導向的程式設計在遊戲開發中使用(一):類
物件導向的程式設計在遊戲開發中使用(二):方法
物件導向的程式設計在遊戲開發中使用(三):三大特性
物件導向的程式設計在遊戲開發中使用(四):五大原則

物件導向的程式設計在遊戲開發中使用(五):基本計算器

作者:Kingfeng
來源:奶牛關
原地址:https://cowlevel.net/article/2053433


相關文章