[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/pacmacs 94c3a3cc1e 191/472: Merge branch 'master' into boa
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/pacmacs 94c3a3cc1e 191/472: Merge branch 'master' into board-refactoring-105 |
Date: |
Thu, 6 Jan 2022 21:59:23 -0500 (EST) |
branch: elpa/pacmacs
commit 94c3a3cc1ead8a8a71dd03dc9d02c03b71f70e5b
Merge: 7601c1ae5c fe40eb20c7
Author: rexim <reximkut@gmail.com>
Commit: rexim <reximkut@gmail.com>
Merge branch 'master' into board-refactoring-105
Conflicts:
pacmacs.el
---
.gitignore | 3 +-
.travis.yml | 2 +
Cask | 7 +-
README.md | 49 ++++++-
maps/game-over.txt | 20 ++-
maps/map01.txt | 17 ++-
maps/map02.txt | 20 ++-
maps/map03.txt | 14 +-
maps/map04.txt | 13 +-
maps/map05.txt | 19 ++-
maps/map06.txt | 14 +-
pacmacs-anim.el | 8 +-
pacmacs-board.el | 2 +-
pacmacs-image.el | 5 +-
pacmacs-render.el | 3 +-
pacmacs-score.el | 100 ++++++++++++++
pacmacs-utils.el | 20 ++-
pacmacs.el | 251 +++++++++++++++++++++--------------
sprites/Red-Ghost-Win.json | 27 ++++
sprites/Red-Ghost-Win.xpm | 49 +++++++
sprites/src/Ghost.ase | Bin 1918 -> 2144 bytes
test-data/file-with-hello-string.txt | 1 +
test/pacmacs-anim-test.el | 5 +
test/pacmacs-image-test.el | 7 +-
test/pacmacs-utils-test.el | 10 ++
tools/compile.el | 17 +++
26 files changed, 514 insertions(+), 169 deletions(-)
diff --git a/.gitignore b/.gitignore
index c26aaf4216..07981c7a56 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
.cask/
-dist/
\ No newline at end of file
+dist/
+*.elc
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 1abcb9b596..bd89b63611 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,6 +15,8 @@ env:
- EVM_EMACS=emacs-24.4-bin
- EVM_EMACS=emacs-24.5-bin
script:
+ - emacs --script ./tools/compile.el
+ - cask clean-elc
- cask exec ert-runner
notifications:
email:
diff --git a/Cask b/Cask
index 11068714e4..9f5be6eb2f 100644
--- a/Cask
+++ b/Cask
@@ -3,9 +3,10 @@
(package-file "pacmacs.el")
-(files "*.el")
-
-(depends-on "dash")
+(files "*.el"
+ ("maps" "maps/*.txt")
+ ("sprites" "sprites/*.json")
+ ("sprites" "sprites/*.xpm"))
(development
(depends-on "el-mock")
diff --git a/README.md b/README.md
index 0e4a170807..973ab70c5f 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,70 @@
[![Build
Status](https://travis-ci.org/rexim/pacmacs.el.svg?branch=master)](https://travis-ci.org/rexim/pacmacs.el)
[![Coverage
Status](https://coveralls.io/repos/rexim/pacmacs.el/badge.svg?branch=master&service=github)](https://coveralls.io/github/rexim/pacmacs.el?branch=master)
+[![MELPA](http://melpa.org/packages/pacmacs-badge.svg)](http://melpa.org/#/pacmacs)
# Pacmacs #
Pacman for Emacs
+<p align="center">
+ <img
src="https://cloud.githubusercontent.com/assets/5211845/10491579/9ba466b2-72a7-11e5-982c-579ed6abe1a5.gif"
href="https://www.reddit.com/r/emacs/comments/3opb5k/pacmacs_a_pacman_variant_for_emacs/"/>
+</p>
+
+(thanks to [@kaushalmodi](https://github.com/kaushalmodi) for the animation)
+
## Requirements ##
- Emacs 24.3+
- Emacs should have displaying images support
- Emacs should have the [XPM](https://en.wikipedia.org/wiki/X_PixMap) image
format support
+## Installation ##
+
+Pacmacs available on [MELPA](http://melpa.org/). Add the following to
+your emacs config file somewhere (.emacs, init.el, whatever):
+
+```
+(require 'package)
+(add-to-list 'package-archives
+ '("melpa" . "https://melpa.org/packages/") t)
+```
+
+Then use `M-x package-install RET pacmacs RET` to install the game.
+
## Usage ##
+### Functions ###
+
+1. `M-x pacmacs-start RET` — start the game;
+2. `M-x pacmacs-score RET` — show the 10 best scores.
+
+### Controls ###
+
+Only available in the `*Pacman*` buffer.
+
+1. `<up>` — move Pacman up;
+2. `<down>` — move Pacman down;
+3. `<left>` — move Pacman left;
+4. `<right>` — move Pacman right;
+5. `q` — quit the game;
+6. `SPC` — pause the game.
+
+
+## Development ##
+
+Before developing the game please remove it from Emacs if it was
+installed before.
+
+I usually use the following workflow when I develop this game:
+
1. `$ git clone git://github.com/rexim/pacmacs.el.git && cd pacmacs.el`;
2. `M-x find-file RET /path/to/pacmacs.el/pacmacs.el RET`
3. `M-x eval-expression RET (add-to-list 'load-path default-directory) RET`;
4. `M-x eval-buffer RET`;
-5. `M-x pacmacs-start RET`.
+5. `M-x pacmacs-start RET`;
+6. `M-x pacmacs-quit RET`;
+7. Change something in the source code;
+8. Go to the step 4.
## Unit Tests ##
diff --git a/maps/game-over.txt b/maps/game-over.txt
index 7d005bd7d1..f28cdbb21f 100644
--- a/maps/game-over.txt
+++ b/maps/game-over.txt
@@ -1,13 +1,9 @@
-####
-# # ### ##### ##
-# # # # # # #
-# ## ### # # # ##
-# # # # # # # #
-#### # # # # # ##
+### ### ##### ###
+# # # # # # # #
+# # ### # # # ##
+### # # # # # ##
-####
-# # # # ## ###
-# # # # # # #
-# # # ## ## ####
-# # # # # # #
-#### ### ## # #
+### # # ### ###
+# # # # # # # #
+# # # # ## ####
+### # ## # #
diff --git a/maps/map01.txt b/maps/map01.txt
index 674169eee4..bee14b9a8d 100644
--- a/maps/map01.txt
+++ b/maps/map01.txt
@@ -1,7 +1,10 @@
-#########
-#.......#####
-#. . #
-#.g## . ##
-#. ## . o#
-#.......####
-#########
+##########
+#o. ##
+ ######
+ ####
+#### ###..
+ # #. #
+## #.##
+ # #..#
+...#.....#
+##########
diff --git a/maps/map02.txt b/maps/map02.txt
index fe3db346f1..5631b824ea 100644
--- a/maps/map02.txt
+++ b/maps/map02.txt
@@ -1,12 +1,8 @@
-#### ####
-#. .#
-# ## ## #
-# #
-# ## ## #
-# #
-# ## ## #
- o
-# ## ## #
-# #
-#g #
-#### ####
+##############
+#...#...#....#
+#.#.#.#.#..#.#
+#o#.#.#.#..#.#
+# #.#.#.#..#.#
+# #.#.#.#..#.#
+#g#...#....#.#
+##############
diff --git a/maps/map03.txt b/maps/map03.txt
index 8935913fad..1f1b8e95e0 100644
--- a/maps/map03.txt
+++ b/maps/map03.txt
@@ -1,7 +1,7 @@
-######
-# .#
-# ## #
-# ## #
-# ## #
-# o #
-######
+##########
+#o.......#
+#........#
+#........#
+#........#
+#.......g#
+##########
diff --git a/maps/map04.txt b/maps/map04.txt
index 70d8183d9d..d03e9a952d 100644
--- a/maps/map04.txt
+++ b/maps/map04.txt
@@ -1,3 +1,10 @@
-#######
-. o .
-#######
+############
+#o . g#
+##### ######
+#..........#
+#..........#
+#..........#
+#..........#
+#..........#
+#..........#
+############
diff --git a/maps/map05.txt b/maps/map05.txt
index a045f8d51e..73ad0a000b 100644
--- a/maps/map05.txt
+++ b/maps/map05.txt
@@ -1,7 +1,12 @@
-##########
-#o.......#
-#. #
-#. #
-#. #
-#. g#
-##########
+#### ####
+#. . .#
+# ## ## #
+# ..... #
+# ## ## #
+# ..... #
+# ## ## #
+ o
+# ## ## #
+#. . . .#
+#g . #
+#### ####
diff --git a/maps/map06.txt b/maps/map06.txt
index 4b60914044..4bec64ec94 100644
--- a/maps/map06.txt
+++ b/maps/map06.txt
@@ -1,3 +1,11 @@
-############
-#o . g#
-############
+###########
+#.. ... ..#
+### ### # #
+ ...
+#.# ### #.#
+#.# .o. #.#
+#.# ### #.#
+ ...
+# # ### ###
+#.. ... .g#
+###########
diff --git a/pacmacs-anim.el b/pacmacs-anim.el
index e33f7dcf83..7a3d6684cd 100644
--- a/pacmacs-anim.el
+++ b/pacmacs-anim.el
@@ -1,4 +1,4 @@
-;;; pacmacs-anim.el --- Pacman for Emacs
+;;; pacmacs-anim.el --- Pacman for Emacs -*- lexical-binding: t -*-
;; Copyright (C) 2015 Codingteam
@@ -49,8 +49,10 @@
:duration duration))
(defun pacmacs-load-anim (animation-name)
- (let* ((aseprite-json-file (format "sprites/%s.json" animation-name))
- (sprite-sheet-file (format "sprites/%s.xpm" animation-name))
+ (let* ((aseprite-json-file (pacmacs--find-resource-file
+ (format "sprites/%s.json" animation-name)))
+ (sprite-sheet-file (pacmacs--find-resource-file
+ (format "sprites/%s.xpm" animation-name)))
(aseprite-json (json-read-file aseprite-json-file))
(aseprite-frames (cdr (assoc 'frames aseprite-json)))
(sprite-sheet (pacmacs-load-image sprite-sheet-file)))
diff --git a/pacmacs-board.el b/pacmacs-board.el
index a3deeaa812..6b6242aabf 100644
--- a/pacmacs-board.el
+++ b/pacmacs-board.el
@@ -1,4 +1,4 @@
-;;; pacmacs-board.el --- Pacman for Emacs
+;;; pacmacs-board.el --- Pacman for Emacs -*- lexical-binding: t -*-
;; Copyright (C) 2015 Codingteam
diff --git a/pacmacs-image.el b/pacmacs-image.el
index b2d3f69f08..25c30034a3 100644
--- a/pacmacs-image.el
+++ b/pacmacs-image.el
@@ -1,4 +1,4 @@
-;;; pacmacs-image.el --- Pacman for Emacs
+;;; pacmacs-image.el --- Pacman for Emacs -*- lexical-binding: t -*-
;; Copyright (C) 2015 Codingteam
@@ -33,8 +33,7 @@
;;; Code:
(defun pacmacs-load-image (filename)
- (create-image (concat default-directory filename)
- 'xpm nil :heuristic-mask t))
+ (create-image filename 'xpm nil :heuristic-mask t))
(defun pacmacs-insert-image (resource resource-vector)
(insert-image resource " " nil resource-vector))
diff --git a/pacmacs-render.el b/pacmacs-render.el
index 12c65638e1..c5966607ae 100644
--- a/pacmacs-render.el
+++ b/pacmacs-render.el
@@ -1,4 +1,4 @@
-;;; pacmacs-render.el --- Pacman for Emacs
+;;; pacmacs-render.el --- Pacman for Emacs -*- lexical-binding: t -*-
;; Copyright (C) 2015 Codingteam
@@ -34,6 +34,7 @@
(require 'pacmacs-image)
(require 'pacmacs-anim)
+(require 'pacmacs-board)
(defvar pacmacs--empty-cell nil)
(defvar pacmacs--life-icon nil)
diff --git a/pacmacs-score.el b/pacmacs-score.el
new file mode 100644
index 0000000000..64c6e25f3e
--- /dev/null
+++ b/pacmacs-score.el
@@ -0,0 +1,100 @@
+;;; pacmacs-score.el --- Pacman for Emacs -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015 Codingteam
+
+;; Author: Codingteam <codingteam@conference.jabber.ru>
+;; Maintainer: Alexey Kutepov <reximkut@gmail.com>
+;; URL: http://github.com/rexim/pacmacs.el
+
+;; Permission is hereby granted, free of charge, to any person
+;; obtaining a copy of this software and associated documentation
+;; files (the "Software"), to deal in the Software without
+;; restriction, including without limitation the rights to use, copy,
+;; modify, merge, publish, distribute, sublicense, and/or sell copies
+;; of the Software, and to permit persons to whom the Software is
+;; furnished to do so, subject to the following conditions:
+
+;; The above copyright notice and this permission notice shall be
+;; included in all copies or substantial portions of the Software.
+
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+;; SOFTWARE.
+
+;;; Commentary:
+
+;; Routines for working with score
+
+;;; Code:
+
+(require 'dash)
+(require 'dash-functional)
+
+(defconst pacmacs--score-file-name "~/.pacmacs-score")
+(defconst pacmacs--score-buffer-name "*Pacmacs Score*")
+
+(defun pacmacs-score ()
+ (interactive)
+ (switch-to-buffer-other-window pacmacs--score-buffer-name)
+ (text-mode)
+ (read-only-mode)
+ (with-current-buffer pacmacs--score-buffer-name
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (-> (pacmacs--read-score-table)
+ (pacmacs--sort-score-table)
+ (pacmacs--render-score-table)))))
+
+(defun pacmacs--read-score-table ()
+ (when (file-exists-p pacmacs--score-file-name)
+ (-> pacmacs--score-file-name
+ (pacmacs--file-content)
+ (read-from-string)
+ (car))))
+
+(defun pacmacs--write-score-table (score-table)
+ (with-temp-buffer
+ (-> score-table
+ (pp-to-string)
+ (insert))
+ (write-file pacmacs--score-file-name)))
+
+(defun pacmacs--sort-score-table (score-table)
+ (sort score-table
+ (-lambda ((_ . score1) (_ . score2))
+ (> score1 score2))))
+
+(defun pacmacs--render-score-table (score-table)
+ (let ((max-nickname-length
+ (--> (pacmacs--read-score-table)
+ (-map (-compose #'length #'car) it)
+ (apply #'max it))))
+ (insert "Best Scores:\n------------\n")
+ (-each score-table
+ (-lambda ((nickname . score))
+ (insert (format "%s%s %d\n"
+ nickname
+ (make-string (- max-nickname-length
+ (length nickname))
+ ?\s)
+ score))))))
+
+(defun pacmacs--add-entry-to-score-table (nickname score)
+ (->> (pacmacs--read-score-table)
+ (cons (cons nickname score))
+ (pacmacs--sort-score-table)
+ (-take 10)
+ (pacmacs--write-score-table)))
+
+(defun pacmacs--register-new-score (score)
+ (let ((nickname (read-from-minibuffer "Nickname: ")))
+ (pacmacs--add-entry-to-score-table nickname score)))
+
+(provide 'pacmacs-score)
+
+;;; pacmacs-score.el ends here
diff --git a/pacmacs-utils.el b/pacmacs-utils.el
index f8301b5b62..f4f603d9ac 100644
--- a/pacmacs-utils.el
+++ b/pacmacs-utils.el
@@ -1,4 +1,4 @@
-;;; pacmacs-utils.el --- Pacman for Emacs
+;;; pacmacs-utils.el --- Pacman for Emacs -*- lexical-binding: t -*-
;; Copyright (C) 2015 Codingteam
@@ -32,9 +32,13 @@
;;; Code:
+(require 'cl-lib)
+
+(defconst pacmacs--base (file-name-directory load-file-name))
+
(defmacro plist-bind (keys expr &rest body)
(declare (indent 2) (debug (sexp form &rest form)))
- (let ((expr-name (gensym)))
+ (let ((expr-name (cl-gensym)))
`(let* ((,expr-name ,expr)
,@(mapcar #'(lambda (key)
(cons (car key)
@@ -50,6 +54,9 @@ side-effects."
(plist-put plist property
(funcall transformer value))))
+(defun pacmacs--find-resource-file (filename)
+ (expand-file-name filename pacmacs--base))
+
(defun pacmacs--direction-vector (direction)
(let ((direction-table (list 'left (cons 0 -1)
'right (cons 0 1)
@@ -65,6 +72,15 @@ side-effects."
(cdr (assoc direction-vector
direction-table))))
+(defun pacmacs--file-content (filename)
+ (with-temp-buffer
+ (insert-file-contents filename)
+ (buffer-string)))
+
+(defun pacmacs--levelname-from-filename (filename)
+ (when (string-match "\\(map[0-9]+\\)\\.txt" filename)
+ (match-string 1 filename)))
+
(provide 'pacmacs-utils)
;;; pacmacs.el ends here
diff --git a/pacmacs.el b/pacmacs.el
index 0e0ee0388f..6c1afdbb80 100644
--- a/pacmacs.el
+++ b/pacmacs.el
@@ -1,4 +1,4 @@
-;;; pacmacs.el --- Pacman for Emacs
+;;; pacmacs.el --- Pacman for Emacs -*- lexical-binding: t -*-
;; Copyright (C) 2015 Codingteam
@@ -6,6 +6,7 @@
;; Maintainer: Alexey Kutepov <reximkut@gmail.com>
;; URL: http://github.com/rexim/pacmacs.el
;; Version: 0.0.1
+;; Package-Requires: ((dash "2.11.0") (dash-functional "1.2.0") (cl-lib "0.5")
(f "0.18.0"))
;; Permission is hereby granted, free of charge, to any person
;; obtaining a copy of this software and associated documentation
@@ -35,6 +36,7 @@
;;; Code:
+(require 'cl-lib)
(require 'dash)
(require 'pacmacs-anim)
@@ -42,6 +44,7 @@
(require 'pacmacs-image)
(require 'pacmacs-utils)
(require 'pacmacs-render)
+(require 'pacmacs-score)
(defconst pacmacs-buffer-name "*Pacmacs*")
(defconst pacmacs-tick-duration-ms 100)
@@ -56,21 +59,21 @@
(defvar pacmacs-player-state nil)
-(defvar pacmacs-ghosts nil)
+(defvar pacmacs--ghosts nil)
(defvar pacmacs-wall-cells nil)
(defvar pacmacs-pills nil)
(defvar pacmacs--render-buffer nil)
(defvar pacmacs--track-buffer nil)
-;;; play death prepare level-beaten
+(defvar pacmacs-play-pause nil)
+
+;;; play death prepare level-beaten game-over
(defvar pacmacs-game-state 'play)
(defvar pacmacs-lives 3)
-
-(defvar pacmacs-levels ["map01" "map02" "map03"
- "map04" "map05" "map06"])
+(defvar pacmacs-levels nil)
(defvar pacmacs-current-level 0)
(defvar pacmacs-waiting-counter 0)
@@ -81,10 +84,12 @@
(define-key pacmacs-mode-map (kbd "<left>") 'pacmacs-left)
(define-key pacmacs-mode-map (kbd "<right>") 'pacmacs-right)
(define-key pacmacs-mode-map (kbd "q") 'pacmacs-quit)
+ (define-key pacmacs-mode-map (kbd "SPC") 'pacmacs-pause)
(add-hook 'kill-buffer-hook 'pacmacs-destroy nil t)
(setq cursor-type nil)
(setq truncate-lines t))
+;;;###autoload
(defun pacmacs-start ()
(interactive)
(switch-to-buffer pacmacs-buffer-name)
@@ -92,7 +97,9 @@
(setq pacmacs-lives 3)
(setq pacmacs-score 0)
+ (setq pacmacs-levels (pacmacs--get-list-of-levels))
(setq pacmacs-current-level 0)
+
(pacmacs--load-current-level)
(pacmacs--switch-to-play-state)
@@ -130,6 +137,8 @@
:column column
:init-row row
:init-column column
+ :prev-row row
+ :prev-column column
:direction 'right
:current-animation (pacmacs-load-anim "Red-Ghost-Right")
:direction-animations (list 'left (pacmacs-load-anim "Red-Ghost-Left")
@@ -144,6 +153,8 @@
:column column
:init-row row
:init-column column
+ :prev-row row
+ :prev-column column
:direction 'right
:current-animation (pacmacs-load-anim "Pacman-Chomping-Right")
:direction-animations (list 'left (pacmacs-load-anim
"Pacman-Chomping-Left")
@@ -160,6 +171,13 @@
(plist-put game-object :row init-row)
(plist-put game-object :column init-column)))
+(defun pacmacs--step-back-object (game-object)
+ (plist-bind ((prev-row :prev-row)
+ (prev-column :prev-column))
+ game-object
+ (plist-put game-object :row prev-row)
+ (plist-put game-object :column prev-column)))
+
(defun pacmacs--kill-buffer-and-its-window (buffer-or-name)
(let ((buffer-window (get-buffer-window buffer-or-name)))
(if (and buffer-window
@@ -181,7 +199,7 @@
(defun pacmacs--ghost-at-p (row column)
(pacmacs--object-at-p pacmacs--render-buffer
row column
- pacmacs-ghosts))
+ pacmacs--ghosts))
(defun pacmacs-quit ()
(interactive)
@@ -197,13 +215,15 @@
(plist-put game-object :direction direction)
(plist-put game-object :current-animation (plist-get direction-animations
direction))))
-(defun pacmacs-step-object (game-object)
+(defun pacmacs--step-object (game-object)
(plist-bind ((row :row)
(column :column)
(direction :direction)
(speed-counter :speed-counter)
(speed :speed))
game-object
+ (plist-put game-object :prev-row row)
+ (plist-put game-object :prev-column column)
(if (zerop speed-counter)
(let* ((new-point (pacmacs--step-point pacmacs--render-buffer row
column direction))
(new-row (car new-point))
@@ -253,7 +273,7 @@
(column (cdr p))
(possible-ways (pacmacs--possible-ways row column))
(candidate-ways
- (remove-if #'pacmacs--filter-candidates possible-ways)))
+ (cl-remove-if #'pacmacs--filter-candidates possible-ways)))
(dolist (candidate-way candidate-ways)
(pacmacs--track-point candidate-way p))
(setq next-wave
@@ -269,28 +289,25 @@
(defun pacmacs-tick ()
(interactive)
- (with-current-buffer pacmacs-buffer-name
- (let ((inhibit-read-only t))
- (cond
- ((equal pacmacs-game-state 'play)
- (pacmacs-play-state-logic))
- ((equal pacmacs-game-state 'death)
- (pacmacs-death-state-logic))
- ((equal pacmacs-game-state 'prepare)
- (pacmacs-waiting-logic #'pacmacs--switch-to-play-state))
- ((equal pacmacs-game-state 'level-beaten)
- (pacmacs-waiting-logic #'(lambda ()
- (pacmacs--load-next-level)
- (pacmacs--switch-to-prepare-state)))))
+ (cond
+ ((equal pacmacs-game-state 'play)
+ (pacmacs-play-state-logic))
+ ((equal pacmacs-game-state 'death)
+ (pacmacs-death-state-logic))
+ ((equal pacmacs-game-state 'prepare)
+ (pacmacs-waiting-logic #'pacmacs--switch-to-play-state))
+ ((equal pacmacs-game-state 'level-beaten)
+ (pacmacs-waiting-logic #'(lambda ()
+ (pacmacs--load-next-level)
+ (pacmacs--switch-to-prepare-state)))))
- (erase-buffer)
- (pacmacs-render-state))))
+ (pacmacs-render-state))
(defun pacmacs--step-ghosts ()
- (dolist (ghost pacmacs-ghosts)
+ (dolist (ghost pacmacs--ghosts)
(pacmacs--track-object ghost)
- (pacmacs-step-object ghost)))
+ (pacmacs--step-object ghost)))
(defun pacmacs--detect-pill-collision ()
(plist-bind ((row :row)
@@ -299,13 +316,13 @@
(-when-let (pill (pacmacs--pill-at-p row column))
(setq pacmacs-score (+ pacmacs-score 10))
(setq pacmacs-pills
- (remove-if #'(lambda (pill)
- (plist-bind ((p-row :row)
- (p-column :column))
- pill
- (and (= row p-row)
- (= column p-column))))
- pacmacs-pills)))))
+ (cl-remove-if #'(lambda (pill)
+ (plist-bind ((p-row :row)
+ (p-column :column))
+ pill
+ (and (= row p-row)
+ (= column p-column))))
+ pacmacs-pills)))))
(defun pacmacs--ghost-collision-p ()
(plist-bind ((row :row)
@@ -314,24 +331,31 @@
(pacmacs--ghost-at-p row column)))
(defun pacmacs-play-state-logic ()
- (pacmacs--anim-object-next-frame pacmacs-player-state
pacmacs-tick-duration-ms)
- (pacmacs--anim-object-list-next-frame pacmacs-ghosts
pacmacs-tick-duration-ms)
- (pacmacs--anim-object-list-next-frame pacmacs-pills pacmacs-tick-duration-ms)
-
- (pacmacs--recalc-track-board)
- (if pacmacs-pills
- (if (pacmacs--ghost-collision-p)
- (pacmacs--switch-to-death-state)
- (pacmacs-step-object pacmacs-player-state)
- (pacmacs--detect-pill-collision)
- (if (pacmacs--ghost-collision-p)
- (pacmacs--switch-to-death-state)
- (pacmacs--step-ghosts)))
- (pacmacs--switch-to-level-beaten-state)))
+ (when (not pacmacs-play-pause)
+ (pacmacs--anim-object-next-frame pacmacs-player-state
pacmacs-tick-duration-ms)
+ (pacmacs--anim-object-list-next-frame pacmacs--ghosts
pacmacs-tick-duration-ms)
+ (pacmacs--anim-object-list-next-frame pacmacs-pills
pacmacs-tick-duration-ms)
+
+ (pacmacs--recalc-track-board)
+ (if pacmacs-pills
+ (progn
+ (pacmacs--step-object pacmacs-player-state)
+ (if (pacmacs--ghost-collision-p)
+ (progn (pacmacs--step-back-object pacmacs-player-state)
+ (pacmacs--switch-to-death-state))
+ (pacmacs--detect-pill-collision)
+ (pacmacs--step-ghosts)
+ (when (pacmacs--ghost-collision-p)
+ (dolist (ghost pacmacs--ghosts)
+ (pacmacs--step-back-object ghost))
+ (pacmacs--switch-to-death-state))))
+ (pacmacs--switch-to-level-beaten-state))))
(defun pacmacs-death-state-logic ()
(pacmacs--anim-object-next-frame pacmacs-player-state
pacmacs-tick-duration-ms)
+ (pacmacs--anim-object-list-next-frame pacmacs--ghosts
+ pacmacs-tick-duration-ms)
(when (= 0 (plist-get
(plist-get pacmacs-player-state
@@ -344,10 +368,8 @@
(defun pacmacs-waiting-logic (switcher)
(if (<= pacmacs-waiting-counter 0)
(funcall switcher)
- (decf pacmacs-waiting-counter
- pacmacs-tick-duration-ms)))
-
-
+ (cl-decf pacmacs-waiting-counter
+ pacmacs-tick-duration-ms)))
(defun pacmacs--put-object (anim-object)
(when anim-object
@@ -358,18 +380,23 @@
(defun pacmacs--switch-to-death-state ()
(setq pacmacs-game-state 'death)
- (decf pacmacs-lives)
+ (cl-decf pacmacs-lives)
(plist-put pacmacs-player-state :current-animation
- (pacmacs-load-anim "Pacman-Death")))
+ (pacmacs-load-anim "Pacman-Death"))
+ (dolist (ghost pacmacs--ghosts)
+ (plist-put ghost :current-animation
+ (pacmacs-load-anim "Red-Ghost-Win"))))
(defun pacmacs--switch-to-game-over-state ()
(setq pacmacs-game-state 'game-over)
- (pacmacs-load-map "game-over"))
+ (pacmacs-load-map "game-over")
+ (pacmacs--register-new-score pacmacs-score))
(defun pacmacs--switch-to-play-state ()
(setq pacmacs-game-state 'play)
+ (setq pacmacs-play-pause nil)
(pacmacs--reset-object-position pacmacs-player-state)
- (dolist (ghost pacmacs-ghosts)
+ (dolist (ghost pacmacs--ghosts)
(pacmacs--reset-object-position ghost))
(pacmacs--switch-direction pacmacs-player-state 'right))
@@ -382,63 +409,89 @@
(setq pacmacs-waiting-counter 1000))
(defun pacmacs-render-state ()
- (insert (format "Score: %d\n" pacmacs-score))
+ (with-current-buffer pacmacs-buffer-name
+ (let ((inhibit-read-only t))
+ (erase-buffer)
- (when pacmacs-debug-output
- (pacmacs--render-track-board pacmacs--track-buffer))
+ (insert (format "Score: %d\n\n" pacmacs-score))
- (pacmacs--fill-board pacmacs--render-buffer nil)
+ (when pacmacs-debug-output
+ (pacmacs--render-track-board pacmacs-track-board))
- (dolist (pill pacmacs-pills)
- (pacmacs--put-object pill))
+ (pacmacs--fill-board pacmacs--render-buffer nil)
- (dolist (ghost pacmacs-ghosts)
- (pacmacs--put-object ghost))
+ (dolist (pill pacmacs-pills)
+ (pacmacs--put-object pill))
- (pacmacs--put-object pacmacs-player-state)
-
- (dolist (wall pacmacs-wall-cells)
- (pacmacs--put-object wall))
-
- (plist-bind ((width :width)
- (height :height))
- pacmacs--render-buffer
- (dotimes (row height)
- (dotimes (column width)
- (let ((anim-object (pacmacs--cell-get pacmacs--render-buffer row
column)))
- (pacmacs--render-object anim-object)))
- (insert "\n")))
- (insert "\n")
- (dotimes (i pacmacs-lives)
- (pacmacs--render-life-icon)))
+ (dolist (ghost pacmacs--ghosts)
+ (pacmacs--put-object ghost))
+
+ (pacmacs--put-object pacmacs-player-state)
+
+ (dolist (wall pacmacs-wall-cells)
+ (pacmacs--put-object wall))
+
+ (plist-bind ((width :width)
+ (height :height))
+ pacmacs--render-buffer
+ (dotimes (row height)
+ (dotimes (column width)
+ (let ((anim-object (pacmacs--cell-get pacmacs--render-buffer row
column)))
+ (pacmacs--render-object anim-object)))
+ (insert "\n")))
+ (insert "\n")
+ (dotimes (i pacmacs-lives)
+ (ignore i)
+ (pacmacs--render-life-icon))
+
+ (when (equal pacmacs-game-state 'game-over)
+ (-> (pacmacs--read-score-table)
+ (pacmacs--sort-score-table)
+ (pacmacs--render-score-table)))
+ (goto-char 0))))
+
+(defun pacmacs--unpaused-play-state-p ()
+ (and (equal pacmacs-game-state 'play)
+ (not pacmacs-play-pause)))
(defun pacmacs-up ()
(interactive)
- (when (equal pacmacs-game-state 'play)
+ (when (pacmacs--unpaused-play-state-p)
(pacmacs--switch-direction pacmacs-player-state 'up)))
(defun pacmacs-down ()
(interactive)
- (when (equal pacmacs-game-state 'play)
+ (when (pacmacs--unpaused-play-state-p)
(pacmacs--switch-direction pacmacs-player-state 'down)))
(defun pacmacs-left ()
(interactive)
- (when (equal pacmacs-game-state 'play)
+ (when (pacmacs--unpaused-play-state-p)
(pacmacs--switch-direction pacmacs-player-state 'left)))
(defun pacmacs-right ()
(interactive)
- (when (equal pacmacs-game-state 'play)
+ (when (pacmacs--unpaused-play-state-p)
(pacmacs--switch-direction pacmacs-player-state 'right)))
-(defun pacmacs--file-content (filename)
- (with-temp-buffer
- (insert-file-contents filename)
- (buffer-string)))
+(defun pacmacs-pause ()
+ (interactive)
+ (when (equal pacmacs-game-state 'play)
+ (setq pacmacs-play-pause (not pacmacs-play-pause))))
+
+(defun pacmacs--get-list-of-levels ()
+ (->> (directory-files (pacmacs--find-resource-file "./maps/"))
+ (-map #'pacmacs--levelname-from-filename)
+ (-remove #'null)
+ (-sort #'string-lessp)
+ (apply #'vector)))
(defun pacmacs-load-map (map-name)
- (let* ((lines (split-string (pacmacs--file-content (format "maps/%s.txt"
map-name)) "\n" t))
+ (let* ((lines (split-string (->> map-name
+ (format "./maps/%s.txt")
+ (pacmacs--find-resource-file)
+ (pacmacs--file-content))
+ "\n" t))
(board-width (apply 'max (mapcar #'length lines)))
(board-height (length lines)))
(setq pacmacs-board-width board-width)
@@ -451,23 +504,23 @@
(setq pacmacs-wall-cells nil)
(setq pacmacs-pills nil)
- (setq pacmacs-ghosts nil)
+ (setq pacmacs--ghosts nil)
(setq pacmacs-player-state nil)
- (loop
+ (cl-loop
for line being the element of lines using (index row)
- do (loop for x being the element of line using (index column)
- do (cond ((char-equal x ?#)
- (add-to-list 'pacmacs-wall-cells
(pacmacs--make-wall-cell row column)))
+ do (cl-loop for x being the element of line using (index column)
+ do (cond ((char-equal x ?#)
+ (add-to-list 'pacmacs-wall-cells
(pacmacs--make-wall-cell row column)))
- ((char-equal x ?.)
- (add-to-list 'pacmacs-pills (pacmacs--make-pill row
column)))
+ ((char-equal x ?.)
+ (add-to-list 'pacmacs-pills (pacmacs--make-pill row
column)))
- ((char-equal x ?o)
- (setq pacmacs-player-state (pacmacs--make-player row
column)))
+ ((char-equal x ?o)
+ (setq pacmacs-player-state (pacmacs--make-player
row column)))
- ((char-equal x ?g)
- (add-to-list 'pacmacs-ghosts (pacmacs--make-ghost row
column))))))))
+ ((char-equal x ?g)
+ (add-to-list 'pacmacs--ghosts (pacmacs--make-ghost
row column))))))))
(provide 'pacmacs)
diff --git a/sprites/Red-Ghost-Win.json b/sprites/Red-Ghost-Win.json
new file mode 100644
index 0000000000..4086ba45a6
--- /dev/null
+++ b/sprites/Red-Ghost-Win.json
@@ -0,0 +1,27 @@
+{ "frames": {
+ "Ghost 0.ase": {
+ "frame": { "x": 0, "y": 0, "w": 40, "h": 40 },
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": { "x": 0, "y": 0, "w": 40, "h": 40 },
+ "sourceSize": { "w": 40, "h": 40 },
+ "duration": 200
+ },
+ "Ghost 1.ase": {
+ "frame": { "x": 40, "y": 0, "w": 40, "h": 40 },
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": { "x": 0, "y": 0, "w": 40, "h": 40 },
+ "sourceSize": { "w": 40, "h": 40 },
+ "duration": 200
+ }
+ },
+ "meta": {
+ "app": "http://www.aseprite.org/",
+ "version": "1.1.0-dev",
+ "image":
"/home/rexim/Programming/codingteam/pacmacs/sprites/Red-Ghost-Win.png",
+ "format": "RGBA8888",
+ "size": { "w": 80, "h": 40 },
+ "scale": "1"
+ }
+}
diff --git a/sprites/Red-Ghost-Win.xpm b/sprites/Red-Ghost-Win.xpm
new file mode 100644
index 0000000000..4079a28bb7
--- /dev/null
+++ b/sprites/Red-Ghost-Win.xpm
@@ -0,0 +1,49 @@
+/* XPM */
+static char *Red_Ghost_Win[] = {
+/* columns rows colors chars-per-pixel */
+"80 40 3 1 ",
+" c #AC3232",
+". c #CBDBFC",
+"X c None",
+/* pixels */
+"XXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXX",
+"XXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXX",
+"XXXXXXXXXX XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXX",
+"XXXXXXXXX XXXXXXXXXXXXXXXXXX
XXXXXXXXX",
+"XXXXXXX XXXXXXXXXXXXXX
XXXXXXX",
+"XXXXXX XXXXXXXXXXXX
XXXXXX",
+"XXXXX XXXXXXXXXX
XXXXX",
+"XXXX XXXXXXXX
XXXX",
+"XXXX XXXXXXXX
XXXX",
+"XXX XXXXXX
XXX",
+"XX XXXX
XX",
+"XX XXXX
XX",
+"X .. .. XX .. ..
X",
+"X .... .... XX .... ....
X",
+"X .. .. .. .. XX .. .. .. ..
X",
+" .. .. .. .. .. .. .. ..
",
+" .. .. .. .. .. .. .. ..
",
+"
",
+"
",
+"
",
+"
",
+"
",
+"
",
+"
",
+"
",
+"
",
+"
",
+"
",
+"
",
+"
",
+"
",
+"
",
+" XXX XXX XXXX
",
+" XXXXX XXXXX X XXXXXX X
",
+"X XXXXXXX XXXXXXX X XX XXXXXXXX XX
",
+"X XXXXXXX XXXXXXX X XXX XXXXXXXX XXX
",
+"X XXXXXXXXX XXXXXXXXX X XXXX XXXXXXXXXX XXXX
",
+"XX XXXXXXXXXXX XXXXXXXXXXX XX XXXXX XXXXXXXXXXXX XXXXX
",
+"XX XXXXXXXXXXX XXXXXXXXXXX XX XXXXXX XXXXXXXXXXXXXX XXXXXX
",
+"XXX XXXXXXXXXXXXX XXXXXXXXXXXXX XXX XXXXXXXX XXXXXXXXXXXXXXXX
XXXXXXXX "
+};
diff --git a/sprites/src/Ghost.ase b/sprites/src/Ghost.ase
index c17db360a0..151d81f4eb 100644
Binary files a/sprites/src/Ghost.ase and b/sprites/src/Ghost.ase differ
diff --git a/test-data/file-with-hello-string.txt
b/test-data/file-with-hello-string.txt
new file mode 100644
index 0000000000..ce01362503
--- /dev/null
+++ b/test-data/file-with-hello-string.txt
@@ -0,0 +1 @@
+hello
diff --git a/test/pacmacs-anim-test.el b/test/pacmacs-anim-test.el
index 4e08f0fdea..b4465ce23e 100644
--- a/test/pacmacs-anim-test.el
+++ b/test/pacmacs-anim-test.el
@@ -97,3 +97,8 @@
(mock (pacmacs-load-image *) => input-sprite-sheet)
(should (equal expected-output
(pacmacs-load-anim "foo"))))))
+
+(ert-deftest pacmacs--anim-object-list-next-frame-test ()
+ (with-mock
+ (mock (pacmacs--anim-object-next-frame 42 43) :times 5)
+ (pacmacs--anim-object-list-next-frame (make-list 5 42) 43)))
diff --git a/test/pacmacs-image-test.el b/test/pacmacs-image-test.el
index 6c78c9c124..a66a00d23c 100644
--- a/test/pacmacs-image-test.el
+++ b/test/pacmacs-image-test.el
@@ -1,8 +1,7 @@
(ert-deftest pacmacs-load-image-test ()
- (let ((default-directory "/khooy/"))
- (with-mock
- (mock (create-image "/khooy/pew" 'xpm nil :heuristic-mask t) => 42 :times
1)
- (should (= 42 (pacmacs-load-image "pew"))))))
+ (with-mock
+ (mock (create-image "pew" 'xpm nil :heuristic-mask t) => 42 :times 1)
+ (should (= 42 (pacmacs-load-image "pew")))))
(ert-deftest pacmacs-insert-image-test ()
(let ((resource "khooy")
diff --git a/test/pacmacs-utils-test.el b/test/pacmacs-utils-test.el
index 378045dce3..d323b4ff4c 100644
--- a/test/pacmacs-utils-test.el
+++ b/test/pacmacs-utils-test.el
@@ -5,3 +5,13 @@
(should (equal (list :foo 1
:bar 3)
plist))))
+
+(ert-deftest pacmacs--levelname-from-filename-test ()
+ (should (equal "map06" (pacmacs--levelname-from-filename "map06.txt")))
+ (should (not (pacmacs--levelname-from-filename "."))))
+
+(ert-deftest pacmacs--file-content-test ()
+ (with-mock
+ (should (equal "hello\n"
+ (pacmacs--file-content
+ "test-data/file-with-hello-string.txt")))))
diff --git a/tools/compile.el b/tools/compile.el
new file mode 100755
index 0000000000..62520fa090
--- /dev/null
+++ b/tools/compile.el
@@ -0,0 +1,17 @@
+(require 'cask "~/.cask/cask.el")
+
+(let ((bundle (cask-initialize default-directory)))
+ (require 'dash)
+ (require 'dash-functional)
+ (require 'f)
+ (require 'bytecomp)
+ (let* ((byte-compile-error-on-warn t)
+ (load-path (cons (cask-path bundle) (cask-load-path bundle))))
+ (when (->> (cask-files bundle)
+ (-filter (-lambda (path)
+ (and (f-file? path)
+ (f-ext? path "el"))))
+ (-map (-lambda (file)
+ (byte-compile-file file nil)))
+ (-any #'null))
+ (kill-emacs 1))))
- [nongnu] elpa/pacmacs 420dbec3e6 150/472: Register score on Game Over (#92), (continued)
- [nongnu] elpa/pacmacs 420dbec3e6 150/472: Register score on Game Over (#92), ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs 6f174d6239 156/472: Access resources in more general way (#95), ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs 330c69201f 160/472: Fix UTs, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs 131a070556 163/472: Merge pull request #110 from syohex/fix-package, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs bb622648e3 162/472: Add Package-Requires header for dependencies, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs 0c0aee723a 170/472: Fix regexp bug in pacmacs--levelname-from-filename, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs f28d928e89 177/472: Update README.md, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs 8b44939a29 179/472: Merge pull request #121 from kRITZCREEK/master, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs 368609060e 182/472: Add Win animation for Ghost. Close #90, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs 2c1881afdf 185/472: Compile the project on CI (#123), ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs 94c3a3cc1e 191/472: Merge branch 'master' into board-refactoring-105,
ELPA Syncer <=
- [nongnu] elpa/pacmacs b03ee65528 195/472: Merge branch 'board-refactoring-105'. Close #105, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs f84acb56ad 201/472: Double dash load-map function (#126), ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs e13b23bc34 206/472: Remove object-at-p predicate, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs 0c0f6c141c 210/472: Merge branch 'master' into integration-test-recorder-115, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs e64420ace4 209/472: Fix meta for Red-Ghost-Win animation, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs bfb089d1de 213/472: Exctract init code to a function (#115), ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs 09c0a15f40 217/472: Get pacmacs--object-at-p back (#122), ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs daca08b8b1 219/472: Add another it case (#122), ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs ed46a4b500 221/472: Add big pills sprites. Close #82, ELPA Syncer, 2022/01/06
- [nongnu] elpa/pacmacs ca32745bcb 224/472: Refactor char making duplicate code (#81), ELPA Syncer, 2022/01/06