難解なストーリーと変にお洒落な雰囲気が何ともいえません。
このゲームはセリフが英語なので画面下に字幕が出るんですが、少し変わっています。
1. 文字の位置が微妙に動く。
2. 背景に陰影ができる。
3. 特定の文字の形が変化する。
といった謎の挙動。
少しだけ真似てみましょう。emacsで。
できた!駄作!
動作確認はなおざり。使い勝手もいまいち。
カレントバッファの内容をもぞもぞします。
参考にしたモノ
Emacsでドットエディターを作ってみた
上記の記事のdoteditor.elの関数を拝借して、
一定時間おきに画像を表現した16進数を毎回書き換えます。
パフォーマンスがアレ。
30日でできる! OS自作入門という本が手元にあったので
その中で使われてるフォントを改変して作ったデモ。
フォントの内容まで上げるのはアレかと思ったので、ザックリと使い方
コード中の font と adj にそれらしい値を読み込めば、動作します。
font は文字列のリストのリストです。文字列は、描画可能なhexを表しています。
文字コード?A番目には文字Aを描画するためのhexリストです。
例えば、(setq font (list (list hex-for-A0 hex-for-A1 hex-for-A2)
(listhex-for-B0 hex-for-B1 hex-for-B2)))
adj はn番目のhexの次に描画すべきインデックス。
例えば、(setq adj '((1 7 8)
略
(0 2 7 8 9)))
これだと、0番目の次に1番目か7番目か8番目のどれか。デモだとその中からランダムに動きます。
コード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(setq text nil) | |
(setq buff-name "k7script") | |
(setq timer nil) | |
(setq font nil) | |
(setq adj nil) | |
(load-file "path/to/file") | |
(defun k7:rand-walk (pos) | |
(let (neighbor) | |
(setq neighbor (nth pos adj)) | |
(nth (random (length neighbor)) neighbor))) | |
(defun k7:make-line (line) | |
(let (ret) | |
(setq ret "") | |
(while (car line) | |
(setq ret (concat ret (apply 'concat (mapcar 'car line)) "\n")) | |
(setq line (mapcar 'cdr line))) | |
ret)) | |
(defun k7:connect-lines (lines) | |
(let (ret) | |
(map nil '(lambda (line) | |
(setq ret (concat ret (k7:make-line line)))) | |
lines) | |
ret)) | |
(defun k7:update () | |
(setq text (mapcar '(lambda (line) | |
(mapcar '(lambda (c) | |
(list (first c) | |
(k7:rand-walk (car (last c))))) | |
line)) | |
text))) | |
(defun k7:make-chars () | |
(mapcar '(lambda (line) | |
(mapcar '(lambda (c) | |
(split-string (nth (car (last c)) (nth (first c) font)) "\n")) | |
line)) | |
text)) | |
(defun k7:make-script () | |
(k7:update) | |
(insert (format "%s" (k7:connect-lines (k7:make-chars)))) | |
(create-pbm-from-hex (point-min) (point-max))) | |
;; http://ynomura.dip.jp/archives/2010/12/emacs_1.html | |
;; http://ynomura.dip.jp/archives/misc/doteditor.el | |
(defun create-pbm-from-hex (start end) | |
"inserts PBM image data of hexified bitmap into the top of temporal buffer" | |
;; (interactive "r") | |
;; (when mark-active | |
(let ((pbm "") (width 0) (height 0)) | |
(while (< start end) | |
(let (ch1 ch2 n1 n2) ;n: decimal value of a hex char | |
(setq ch1 (char-after start)) ;ch1: hex char for first 4bit | |
(setq ch2 (or (char-after (+ start 1)) ?\0)) ;char-after eob is nil | |
(setq n1 (string-to-number (char-to-string ch1) 16)) | |
(cond ((or (> n1 0) (= ch1 ?0)) ;[1-9a-fA-F] or '0' | |
(setq n2 (string-to-number (char-to-string ch2) 16)) | |
(when (or (> n2 0) (= ch2 ?0)) | |
(setq start (+ 1 start))) | |
(setq pbm (concat pbm (format "%c" (logior (lsh n1 4) n2))))) | |
((= ch1 ?\n) | |
(if (= ch2 ?\n) nil (setq height (+ 1 height))) | |
)) | |
(setq start (+ 1 start)) | |
)) | |
(setq width (* 8 (/ (length pbm) height))) | |
;; (switch-to-buffer "tmp.pbm") | |
(goto-char 1) | |
(insert (format "P4 %d %d " width height) pbm)) | |
(if (functionp 'image-mode) (image-mode) nil) | |
);;) | |
(defun k7:start () | |
(interactive) | |
(let (lines max-len) | |
(setq text '()) | |
(setq lines (split-string (buffer-string) "\n")) | |
(setq max-len (apply 'max (mapcar 'length lines))) | |
(setq lines (mapcar '(lambda (line) | |
(while (< (length line) max-len) | |
(setq line (concat line " "))) | |
line) | |
lines)) | |
(setq text (mapcar '(lambda (line) | |
(mapcar '(lambda (c) | |
(list c 0)) | |
line)) | |
lines)) | |
(setq timer (run-with-timer 1 0.2 '(lambda () | |
(if (buffer-live-p (get-buffer buff-name)) | |
(kill-buffer buff-name)) | |
(switch-to-buffer buff-name) | |
(k7:make-script)))))) | |
;; (defun k7:stop () | |
;; (interactive) | |
;; (cancel-timer timer)) |
意外と見ていて楽しい。
でも、 run-with-idle-timer とかで入力が無い時に動かすような使い方しか思いつかない。
0 件のコメント :
コメントを投稿