《我的第一本程式設計書》第八章 可以操作的程式,操作方塊

伊徵銀王發表於2020-01-18

第八章 可以操作的程式,操作方塊
(程式設計的“三大必備”:迴圈、區域性程式、命名儲存區)

1.程式是怎麼知道鍵盤被按下的?
因為程式只能操作儲存區,所以儲存區是唯一的選項。(其實就是記憶體)
又因為方塊畫素在“儲存區[50000]”-“儲存區[59999]”,所以只要改變方塊的“儲存區”數值就行。

2.通過裝置操縱儲存區(也就是規定了哪個儲存區編號,代替哪個按鍵,並且相關聯。)

儲存區編號      按鍵
50004           上
50005           下
50006           左
50007           右

次外,這些編號的儲存區,是不能在程式中進行操縱的,否則會報錯。

3.實現操作

儲存區[60000]->儲存區[50006]*999999    #左

即按下“左箭頭”時,“儲存區[50006]”就相當於變成了1。而乘以999999,也就是“儲存區[60000]->999999”
如果沒有按下“左箭頭”,則“儲存區[50006]”就相當於0。而乘以999999,也就是“儲存區[60000]->0”

4.無限迴圈

只要 0<1
    {略}

畢竟程式不能操作一次就結束,那樣就沒法玩了。

5.移動一個點 (首先讓一個畫素自動向下移動)

儲存區[0]->0
只要 儲存區[0]<100
    儲存區[60000+(儲存區[0]*100)]->999999
    儲存區[60000+(儲存區[0]*100)]->0
    儲存區[0]->儲存區[0]+1

6.點選“向下箭頭”,讓畫素點向下移動。

縱向位置->0
只要 0<1
    縱向位置->縱向位置+儲存區[50005]  #“儲存區[50005]”向下按鈕
    儲存區[60000+(縱向位置*100)]->999999
    儲存區[60000+(縱向位置*100)]->0

由於這樣的畫素點會一閃一閃的,所以使用“儲存區[55001]->1”關閉調控

儲存區[55001]->1     #就追加了這一條“關閉調控”
縱向位置->0
只要 0<1
    縱向位置->縱向位置+儲存區[50005]
    儲存區[60000+(縱向位置*100)]->999999
    儲存區[55000]->1
    儲存區[60000+(縱向位置*100)]->0

7.向其他方向移動

縱向位置,向上。

縱向位置->縱向位置-儲存區[50004]   #向上箭頭按鈕

縱向位置,向下。

縱向位置->縱向位置+儲存區[50005]   #向下箭頭按鈕

縱向位置,“向上”和“向下”。

縱向位置->縱向位置+儲存區[50005]-儲存區[50004]   

一個畫素點的上下移動!(但超出儲存區的顯示範圍會報錯)

儲存區[55001]->1
縱向位置->0    #先給縱向位置一個初始值
只要 0<1
    縱向位置->縱向位置+儲存區[50005]-儲存區[50004]    #關鍵在這一行
    儲存區[60000+(縱向位置*100)]->999999                   #由於上下畫素間隔是100
    儲存區[55000]->1
    儲存區[60000+(縱向位置*100)]->0

上下完成了,再追加左右也就容易了。

儲存區[55001]->1
縱向位置->0    #先定義一個縱向位置
橫向位置->0    #再定義一個橫向位置
只要 0<1
    縱向位置->縱向位置+儲存區[50005]-儲存區[50004]    #向下移動則+1,向上移動則-1
    橫向位置->橫向位置+儲存區[50007]-儲存區[50006]    #向右移動則+1,向左移動則-1
    儲存區[60000+(縱向位置*100)+橫向位置]->999999
    儲存區[55000]->1
    儲存區[60000+(縱向位置*100)+橫向位置]->0

8.移動方塊。(畫素點實現了移動,那就替換成方塊吧!)

儲存區[55001]->1
縱向位置->0
橫向位置->0
只要 0<1
    縱向位置->縱向位置+儲存區[50005]-儲存區[50004]
    橫向位置->橫向位置+儲存區[50007]-儲存區[50006]
    儲存區[3]->縱向位置     #儲存區[3]在方塊的區域性程式中
    儲存區[4]->橫向位置     #儲存區[4]也在方塊的區域性程式中
    儲存區[5]->999999
    方塊()             #呼叫區域性程式
    儲存區[55000]->1
    儲存區[5]->0
    方塊()

    #區域性程式
方塊() 是
    縱向次數->0
    只要 縱向次數<4
    橫向次數->0
    只要 橫向次數<4
        儲存區[60000+(儲存區[3]*500)+(儲存區[4]*5)+(縱向次數*100)+橫向次數]->儲存區[5]
        橫向次數->橫向次數+1
    縱向次數->縱向次數+1

基本上並沒有改變多少,無非是將“縱向位置”和“橫向位置”分別賦值給了“方塊()”這個區域性程式中的“儲存區[3]”和“儲存區[4]”,代表橫向位置和縱向位置的儲存區罷了。

9.避免過快的移動(爭取按一下就移動一次,而不是一直移動下去)

同樣以一個畫素為例,並向右移動

儲存區[55001]->1
橫向位置->0
之前按下了?->儲存區[50007]
只要 0<1
    現在按下了?->儲存區[50007]
    之前沒有按下?->1-之前按下了?
    移動的話為1->現在按下了?*之前沒有按下?
    橫向位置-> 橫向位置+移動的話為1
    之前按下了?->現在按下了?
    儲存區[60000+橫向位置]->999999
    儲存區[55000]->1
    儲存區[60000+橫向位置]->0

這裡涉及到一個式子
即“現在按下了?”和“之前沒有按下?”就移動。其餘情況都不移動。

通過表格就是

現在按下了?    之前沒有按下?    結果  
0               0               0  
0               1               0   
1               0               1  
1               1               0

而想通過計算生成結果,就需要加減乘除。但從上述表格來看,加減乘除都不行,但換個方式,就馬上能行了!也就是將“之前沒有按下?”用1去減。
即 (1-之前沒有按下?)*現在按下了?

現在按下了?   1-之前沒有按下?          結果  
0        *      (1-0)     =          0  
0        *      (1-1)     =          0   
1        *      (1-0)     =          1  
1        *      (1-1)     =          0

(繼續感嘆,自己就想不到啊!)
然後將這部分追加到“橫向位置”和“縱向位置”,就能實現“按一下”或“按住”就移動一格的效果。

橫向位置->橫向位置+(現在按下了?*(1-之前按下了?))#這是向右移動1
橫向位置->橫向位置-(現在按下了?*(1-之前按下了?))#這是向左移動1
縱向位置->縱向位置+(現在按下了?*(1-之前按下了?))#這是向下移動1
縱向位置->縱向位置-(現在按下了?*(1-之前按下了?))#這是向上移動1

當然,還需要與各個操作的儲存區進行匹配!

10.完整的上下左右移動

儲存區[55001]->1
縱向位置->0
橫向位置->0
之前按下了上?->儲存區[50004]
之前按下了下?->儲存區[50005]
之前按下了左?->儲存區[50006]
之前按下了右?->儲存區[50007]
只要 0<1
    現在按下了上?->儲存區[50004]
    現在按下了下?->儲存區[50005]
    現在按下了左?->儲存區[50006]
    現在按下了右?->儲存區[50007]
    向上移動的話為1->現在按下了上?*(1-之前按下了上?)
    向下移動的話為1->現在按下了下?*(1-之前按下了下?)
    向左移動的話為1->現在按下了左?*(1-之前按下了左?)
    向右移動的話為1->現在按下了右?*(1-之前按下了右?)
    縱向位置->縱向位置+向下移動的話為1-向上移動的話為1
    橫向位置->橫向位置+向右移動的話為1-向左移動的話為1
    之前按下了上?->現在按下了上?
    之前按下了下?->現在按下了下?
    之前按下了左?->現在按下了左?
    之前按下了右?->現在按下了右?
    儲存區[60000+(縱向位置*100)+橫向位置]->999999
    儲存區[55000]->1
    儲存區[60000+(縱向位置*100)+橫向位置]->0

先定義“橫向”和“縱向”
再定義“之前的上下左右”是否按下,由“儲存區”驗證
然後是無盡迴圈
再定義“現在的上下左右”是否按下,由“儲存區”驗證
再計算公式“現在的上下左右*(1-之前的上下左右)”,確定是1還是0
再追加在“橫向”和“縱向”裡
再把“現在的上下左右”替換掉“之前的上下左右”
最後放進“顯示的儲存區”裡。

修改的短一點(其實就是減少了命名的字數)

儲存區[55001]->1
縱->0
橫->0
前上->儲存區[50004]
前下->儲存區[50005]
前左->儲存區[50006]
前右->儲存區[50007]
只要 0<1
    現上->儲存區[50004]
    現下->儲存區[50005]
    現左->儲存區[50006]
    現右->儲存區[50007]
    上->現上*(1-前上)
    下->現下*(1-前下)
    左->現左*(1-前左)
    右->現右*(1-前右)
    縱->縱+下-上
    橫->橫+右-左
    前上->現上
    前下->現下
    前左->現左
    前右->現右
    儲存區[60000+(縱*100)+橫]->999999
    儲存區[55000]->1
    儲存區[60000+(縱*100)+橫]->0

再換成英文字母

儲存區[55001]->1
y->0
x->0
ou->儲存區[50004]
od->儲存區[50005]
ol->儲存區[50006]
or->儲存區[50007]
只要 0<1
    nu->儲存區[50004]
    nd->儲存區[50005]
    nl->儲存區[50006]
    nr->儲存區[50007]
    y->y+(nd*(1-od)-nu*(1-ou))
    x->x+(nr*(1-or)-nl*(1-ol))
    ou->nu
    od->nd
    ol->nl
    or->nr
    儲存區[60000+(y*100)+x]->999999
    儲存區[55000]->1
    儲存區[60000+(y*100)+x]->0

11.用方塊繪製(其實就是多追加了“儲存區[3]”和“儲存區[4]”的介面)

儲存區[55001]->1
縱->0
橫->0
前上->儲存區[50004]
前下->儲存區[50005]
前左->儲存區[50006]
前右->儲存區[50007]
只要 0<1
    現上->儲存區[50004]
    現下->儲存區[50005]
    現左->儲存區[50006]
    現右->儲存區[50007]
    上->現上*(1-前上)
    下->現下*(1-前下)
    左->現左*(1-前左)
    右->現右*(1-前右)
    縱->縱+下-上
    橫->橫+右-左
    前上->現上
    前下->現下
    前左->現左
    前右->現右
    儲存區[3]->縱
    儲存區[4]->橫
    儲存區[5]->999999
    方塊()
    儲存區[55000]->1
    儲存區[5]->0
    方塊()

方塊() 是
    縱向次數->0
    只要 縱向次數<4
    橫向次數->0
    只要 橫向次數<4
        儲存區[60000+(儲存區[3]*500)+(儲存區[4]*5)+橫向次數+(縱向次數*100)]->儲存區[5]
        橫向次數->橫向次數+1
    縱向次數->縱向次數+1

12.如果想讓方塊自動向下,只需要在“縱”上+1即可。(由於下落的速度過快,所以下一章會有)

儲存區[55001]->1
縱->0
橫->0
前上->儲存區[50004]
前下->儲存區[50005]
前左->儲存區[50006]
前右->儲存區[50007]
只要 0<1
    現上->儲存區[50004]
    現下->儲存區[50005]
    現左->儲存區[50006]
    現右->儲存區[50007]
    上->現上*(1-前上)
    下->現下*(1-前下)
    左->現左*(1-前左)
    右->現右*(1-前右)
    縱->縱+下-上+1         #這裡
    橫->橫+右-左
    {略}

13.將牆壁也放入後的完整程式碼

儲存區[55001]->1

繪製牆壁()
繪製底部()

縱->0
橫->5    #如果初始值是0,則會覆蓋掉左邊的牆壁。所以最少是1,最多是10
前上->儲存區[50004]
前下->儲存區[50005]
前左->儲存區[50006]
前右->儲存區[50007]
只要 0<1
    現上->儲存區[50004]
    現下->儲存區[50005]
    現左->儲存區[50006]
    現右->儲存區[50007]
    上->現上*(1-前上)
    下->現下*(1-前下)
    左->現左*(1-前左)
    右->現右*(1-前右)
    縱->縱+下-上
    橫->橫+右-左
    前上->現上
    前下->現下
    前左->現左
    前右->現右
    儲存區[3]->縱
    儲存區[4]->橫
    儲存區[5]->999999
    方塊()
    儲存區[55000]->1
    儲存區[5]->0
    方塊()

繪製牆壁() 是
    儲存區[5]->999999
    次數->0
    只要 次數<20
    儲存區[3]->次數
    儲存區[4]->0
    方塊()    #左
    儲存區[3]->次數
    儲存區[4]->11
    方塊()    #右
    次數->次數+1

繪製底部() 是
    儲存區[5]->999999
    次數->0
    只要 次數<10
    儲存區[3]->19
    儲存區[4]->1+次數
    方塊()
    次數->次數+1


方塊() 是
    縱向次數->0
    只要 縱向次數<4
    橫向次數->0
    只要 橫向次數<4
        儲存區[60000+(儲存區[3]*500)+(儲存區[4]*5)+橫向次數+(縱向次數*100)]->儲存區[5]
        橫向次數->橫向次數+1
    縱向次數->縱向次數+1

總結 i。從計算機的外部獲取資訊時還是使用儲存區。
(就是得先定義一下)

ii。判斷上下左右鍵是否被按下的方法
(就是按下了為1,沒按下為0)

iii。可以進行操作的程式是不會終止的程式,因此需要進行無限的迴圈。
(就是無限的迴圈操作)

iv。在一般人看來很簡單的邏輯,要讓計算機明白的話,需要進行相當程度的轉換才行。
(就是通過某種演算法進行計算。)

v。想得到需要的結果,就需要“創造”出算式
(就是創造出需要得出結果數的式子)

本章結尾的一段話:
將代入的數字替換為“操作”,得到的數字替換為“圖形”,算式替換為“程式”,就會變成“想要生成一個針對某一操作得到所需圖形的程式”。這正是編寫遊戲程式的精髓。程式就像是一個巨大的算式,“創造”它就是程式設計本身。

這句話挺有意思!而通過這一章的學習,也深刻感受到:我也就處於這個階段的程度啊!自己好弱。

相關文章