非戰之罪

更新 發佈閱讀 6 分鐘

寫程式最怕碰到的,就是信心滿滿地寫好程式後,發現結果不如預期,而且完全看不出問題出在哪裡。這種慘況可以分成兩種:一種是程式很長、很複雜,想要把心機很重,躲在幽暗深處的臭蟲給抓出來,即使有功能強大的除錯工具,都不是件簡單的事;另一種是程式沒幾行,一切看起來都很清楚正常,臭蟲根本沒地方躲藏,可是結果就是不對。不管是哪一種,最讓人傻眼翻白眼的是,焚膏繼晷、殫精竭慮地奮戰多時,搞到開始懷疑人生之後,卻赫然發現,根本沒有臭蟲!根本就不是程式的問題!

寫好畫fractal tree的程式之後,邊看著turtle在螢幕上畫圖邊在想:應該把畫圖的過程做成動畫才對,看著一棵樹慢慢長出來,應該會比只看最後的完成圖有趣多了。可惜turtle並沒有支援把畫面存成動畫的功能,只能另外想辦法。

要把fractal tree的生長過程做成動畫,最簡單的方式,就是用螢幕錄影軟體直接錄下來。不過這樣做的話,檔案會挺大的,而且如果放在網頁裡頭,還要靠播放器才能看。比較好的方式,應該是做成GIF檔,既輕巧又好處理,使用方式也可以比較多樣化。至於顏色方面,雖然GIF支援的顏色不多,不過fractal tree的顏色就只有黑、綠、紅,不會有失真的問題。想要這麼做,就得把畫面一張一張的塞進GIF檔。所以最關鍵的問題是:怎樣把畫面一張一張地擷取下來?

嘿!turtle有支援畫面存檔的功能耶!剛看到時,心想這就好辦了,可省去很多功夫。可是再仔細一看,心裡涼了半截,居然只能存成ps檔。想要用PIL這個module來處理ps檔,還得額外裝Ghostscript。這可不是個好主意,電腦裝了一堆不常用的東西,就好像房子塞滿了不常用的雜物,搞到後來整個亂七八糟,想整理都無從整理起。所以能不裝就不裝,應該有其他辦法。

網路爬文的結果,可以用PIL的ImageGrab.grab().crop((x0, y0, x1, y1))把左上角和右下角分別是(x0, y0)及(x1, y1)這個長方形的畫面擷取下來。程式就簡單的幾行而已:

screen = turtle.Screen()
cv = turtle.getcanvas()
x0, y0 = cv.winfo_rootx(), cv.winfo_rooty()
x1, y1 = x0+screen.window_width(), y0+screen.window_height()
img = ImageGrab.grab().crop((x0, y0, x1, y1))

程式是夠簡單的了,可是……為什麼擷取下來的畫面不是原先想的區域?那個長方形明顯框錯了範圍,而且框到的turtle畫面的部分,還有透明的效果,居然看得到原本應該被蓋住的Spyder畫面。

天啊!這究竟是怎麼回事?程式就這麼幾行,到底是哪裡的問題?莫非是搞錯那幾個設定長方形範圍參數的意思了?一堆問號啊!

要解決這個問題,當然就是在網路上找資料。不過在網路上爬文時,最讓人頭大的一點是,一大堆名詞攪和在一起,有時實在是很難分辨到底所指為何。最主要的原因,是因為turtle使用tkinter來當作畫圖的介面,所以網路上的討論文章,有些會把這兩個東西混雜在一起討論。糟糕的是,因為要擷取螢幕畫面,所以就必須清楚知道畫面的座標位置。這時候,就又牽涉到相對座標和絕對座標的問題。既然牽涉到座標,那就得先搞清楚screen、widget、window、canvas這些是指什麼東西,而winfo_rootx()、winfo_rootx()、winfo_x()、winfo_y()傳回來的,又是哪個東西的哪個座標……

爬文了幾天,費盡千辛萬苦,橫看、豎看、左看、右看,不管怎麼看,都看不出為什麼那個長方形會框錯範圍。這時候,心裡開始浮現是不是要使出最終極那一招的想法。這招絕對有效,只是效率奇差無比,而且就只能用那麼一次,下次當狀況改變時,就得又花上不少時間重新再來。

最終極那一招,招式簡單但有效,就像神鵰俠侶中的傻姑,面對武功高強的赤練仙子李莫愁,就只一支火叉呆板毫無變化的刺、刺、刺,便讓李莫愁左支右絀,幾十手變化全被封死,最後落荒而逃。那招就是:手動調整。慢慢地試、慢慢地調,直到那個長方形能準確框住要擷取的區域為止。

這終極的一招,施展起來實在是無聊透頂,頗讓人躊躇要不要這麼做,所以就在網路上東逛逛、西逛逛,實在是下不了決心。突然間,「咦?!莫非……」

火速調整Windows的設定,然後執行程式。居然……成功了!

天啊!原來這一切都是Windows的設定搞的鬼,程式根本就沒問題。因為現在電腦螢幕的解析度都很高,所以Windows的字體會變得非常小。這麼小的字體,如果不調整一下,實在是在虐待眼睛,所以習慣把Windows的「變更文字、應用程式與其他項目的大小」調大。把這個設定值調回建議的100%之後,就可以準確地擷取到需要的範圍了。以前在錄製螢幕畫面時,也曾因為這個原因,錄好的畫面都被切掉一塊,花了不少時間才搞清楚原因。因為時日已久,早就忘了這麼回事,沒想到現在居然又被同樣的設定問題整了一次。還好這次在使出終極一招之前,靈光乍現,發現了問題所在,免去了浪費大把時間做無聊事之苦。

這一切的一切,都跟程式無關,是非戰之罪啊!

raw-image



留言
avatar-img
留言分享你的想法!
avatar-img
ysf的沙龍
19會員
157內容數
寫點東西自娛娛人
ysf的沙龍的其他內容
2025/04/14
花了些時間,靜下心來,仔仔細細地研究了一番,總算把Python呼叫函數時引數的傳遞方式給徹底搞清楚了。
2025/04/14
花了些時間,靜下心來,仔仔細細地研究了一番,總算把Python呼叫函數時引數的傳遞方式給徹底搞清楚了。
2024/05/08
呼!折騰了好久,終於徹底搞清楚pygame的各個blend mode所用的計算式,到底是長啥樣子了。
2024/05/08
呼!折騰了好久,終於徹底搞清楚pygame的各個blend mode所用的計算式,到底是長啥樣子了。
2023/12/20
在寫《The Nature of Code閱讀心得筆記——使用Python實作》的[第四章]4.3節時,原書提到,在使用Java的ArrayList時,如果用迴圈一面走訪一面又移除其中的元素,那會有難以察覺的問題存在。寫個小程式測試的結果發現,Python的list也會有一樣的問題。
Thumbnail
2023/12/20
在寫《The Nature of Code閱讀心得筆記——使用Python實作》的[第四章]4.3節時,原書提到,在使用Java的ArrayList時,如果用迴圈一面走訪一面又移除其中的元素,那會有難以察覺的問題存在。寫個小程式測試的結果發現,Python的list也會有一樣的問題。
Thumbnail
看更多
你可能也想看
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
在完成一些简单的任务之后,我觉得ChatGPT可以帮我完成一些更为复杂,甚至于可能我并不是特别擅长的任务,而我想到了,也许,可以帮我写一个简单的游戏。 贪多嚼不烂的道理我还是明白的,于是,我给自己提前就设定了一个目标: 游戏可以运行实现简单的规则减少BUG的存在可以开始和结束 带着这四个最朴素
Thumbnail
在完成一些简单的任务之后,我觉得ChatGPT可以帮我完成一些更为复杂,甚至于可能我并不是特别擅长的任务,而我想到了,也许,可以帮我写一个简单的游戏。 贪多嚼不烂的道理我还是明白的,于是,我给自己提前就设定了一个目标: 游戏可以运行实现简单的规则减少BUG的存在可以开始和结束 带着这四个最朴素
Thumbnail
看來這應該是pygame的bug,而不是自己寫的程式有問題。為了進一步證實這個猜測,重寫了一個單純只畫出圓球的程式,除了畫出不同位置的圓球之外,沒有任何其他作用
Thumbnail
看來這應該是pygame的bug,而不是自己寫的程式有問題。為了進一步證實這個猜測,重寫了一個單純只畫出圓球的程式,除了畫出不同位置的圓球之外,沒有任何其他作用
Thumbnail
這款《控制》,一直是我期待已久的作品,倒不是因為多期待,而是因為拖很久⋯⋯
Thumbnail
這款《控制》,一直是我期待已久的作品,倒不是因為多期待,而是因為拖很久⋯⋯
Thumbnail
本作為像素風,最大特色是貪食蛇加彈幕遊戲,在Boss戰中,玩家須閃躲Boss的彈幕攻擊,並蒐集畫面上的資料,進行反擊,而主角的長度會因為攜帶的資料量而變長,增加閃躲的難度,玩法相當創新。
Thumbnail
本作為像素風,最大特色是貪食蛇加彈幕遊戲,在Boss戰中,玩家須閃躲Boss的彈幕攻擊,並蒐集畫面上的資料,進行反擊,而主角的長度會因為攜帶的資料量而變長,增加閃躲的難度,玩法相當創新。
Thumbnail
在那Nokia手機風靡全球的年代,因該有不少人玩過手機內建的貪吃蛇遊戲,記得當時年紀小在還是學生的那個年代就經常利用上電腦課的時候偷偷用我那隻好不容易打工購買的Nokia手機玩這款遊戲,玩到最後還利用電腦課的時間用BASIC寫出了一款簡易版的貪吃蛇遊戲。。。
Thumbnail
在那Nokia手機風靡全球的年代,因該有不少人玩過手機內建的貪吃蛇遊戲,記得當時年紀小在還是學生的那個年代就經常利用上電腦課的時候偷偷用我那隻好不容易打工購買的Nokia手機玩這款遊戲,玩到最後還利用電腦課的時間用BASIC寫出了一款簡易版的貪吃蛇遊戲。。。
Thumbnail
有些風景需要親自經歷後才能了解箇中滋味,這初衷,也可能讓您在20幾年後的今天,被現實打擊到身心疲憊時為了鼓舞自己大聲吶喊莫忘初衷後可以立即回憶起的經歷。 以上故事純屬虛構,如有雷同實屬巧合,以下開始本次教學。 依照慣例我們一樣先來看看完成後的的遊玩影片: A、提案企劃 一句話形容這個遊戲 遊戲類型
Thumbnail
有些風景需要親自經歷後才能了解箇中滋味,這初衷,也可能讓您在20幾年後的今天,被現實打擊到身心疲憊時為了鼓舞自己大聲吶喊莫忘初衷後可以立即回憶起的經歷。 以上故事純屬虛構,如有雷同實屬巧合,以下開始本次教學。 依照慣例我們一樣先來看看完成後的的遊玩影片: A、提案企劃 一句話形容這個遊戲 遊戲類型
Thumbnail
三張scratch積木程式圖示 大朋友小朋友都能參於 輕鬆完成經典貪食蛇遊戲!! 以學習為主要目標 完成了永不失敗的貪食蛇!! 內文提供SCRATCH連結可以回味一下貪食蛇遊戲
Thumbnail
三張scratch積木程式圖示 大朋友小朋友都能參於 輕鬆完成經典貪食蛇遊戲!! 以學習為主要目標 完成了永不失敗的貪食蛇!! 內文提供SCRATCH連結可以回味一下貪食蛇遊戲
Thumbnail
接下來我們會運用之前所學過的各種觀念,包括Turtle 模組、繼承等等,來製作這個大家都熟知的小遊戲-貪食蛇。完成品會長得像下圖這樣,包括可以設定難度(速度)、使用鍵盤的上、下、左、右鍵來移動貪食蛇的移動方向來吃到食物並加長蛇身、以及記分板等。
Thumbnail
接下來我們會運用之前所學過的各種觀念,包括Turtle 模組、繼承等等,來製作這個大家都熟知的小遊戲-貪食蛇。完成品會長得像下圖這樣,包括可以設定難度(速度)、使用鍵盤的上、下、左、右鍵來移動貪食蛇的移動方向來吃到食物並加長蛇身、以及記分板等。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News