Skip to content

Commit 6380f08

Browse files
authored
Add drawing, animation (#16)
* Add drawing capability (close #12) * First draft of frame and animate fns * Build out frame_pixels and gif_pixels * Improve comments, correct matrix inversion, reduce script count * Update DESCRIPTION, NEWS, README, add gifski to suggests * Add mario and pokemon datasets, update readme * Correct checks * Convert demo data matrices to integer type * Convert blue data to integer, remove integer requirement in edit_pixels * Use RStudio example in README * Update setup-r to v2 in GHA yamls * Update setup-r-dependencies to v2 in GHA yamls * Matrix must be integer for click_pixel
1 parent 70a38d5 commit 6380f08

31 files changed

+950
-178
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
^docs$
66
^pkgdown$
77
^\.github$
8+
^README\.Rmd$

.github/workflows/R-CMD-check.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ jobs:
3333

3434
- uses: r-lib/actions/setup-pandoc@v1
3535

36-
- uses: r-lib/actions/setup-r@v1
36+
- uses: r-lib/actions/setup-r@v2
3737
with:
3838
r-version: ${{ matrix.config.r }}
3939
http-user-agent: ${{ matrix.config.http-user-agent }}
4040
use-public-rspm: true
4141

42-
- uses: r-lib/actions/setup-r-dependencies@v1
42+
- uses: r-lib/actions/setup-r-dependencies@v2
4343
with:
4444
extra-packages: rcmdcheck
4545

.github/workflows/pkgdown.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ jobs:
1919

2020
- uses: r-lib/actions/setup-pandoc@v1
2121

22-
- uses: r-lib/actions/setup-r@v1
22+
- uses: r-lib/actions/setup-r@v2
2323
with:
2424
use-public-rspm: true
2525

26-
- uses: r-lib/actions/setup-r-dependencies@v1
26+
- uses: r-lib/actions/setup-r-dependencies@v2
2727
with:
2828
extra-packages: pkgdown
2929
needs: website

.github/workflows/test-coverage.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ jobs:
1717
steps:
1818
- uses: actions/checkout@v2
1919

20-
- uses: r-lib/actions/setup-r@v1
20+
- uses: r-lib/actions/setup-r@v2
2121
with:
2222
use-public-rspm: true
2323

24-
- uses: r-lib/actions/setup-r-dependencies@v1
24+
- uses: r-lib/actions/setup-r-dependencies@v2
2525
with:
2626
extra-packages: covr
2727

DESCRIPTION

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
Package: pixeltrix
2-
Title: Click Pixels and Get a Matrix
3-
Version: 0.1.0
2+
Title: Simple Interactive Sprite Creator
3+
Version: 0.1.1
44
Authors@R:
55
person("Matt", "Dray", , "mwdray@gmail.com", role = c("aut", "cre"))
6-
Description: A simple tool that lets you click ‘pixels’ interactively in a
7-
plot window and returns your final image as a matrix. Could be used to help
8-
create simple videogame sprites, for example.
6+
Description: A very simple tool that lets you click ‘pixels’ interactively in a
7+
plot window and returns your final image as a matrix. Provide multiple
8+
frames to create an animated gif.
99
License: MIT + file LICENSE
1010
URL: https://github.com/matt-dray/pixeltrix, https://matt-dray.github.io/pixeltrix
1111
BugReports: https://github.com/matt-dray/pixeltrix/issues
1212
Encoding: UTF-8
1313
Roxygen: list(markdown = TRUE)
1414
RoxygenNote: 7.1.2
1515
Suggests:
16+
gifski,
1617
testthat (>= 3.0.0)
1718
Config/testthat/edition: 3
19+
Depends:
20+
R (>= 2.10)
21+
LazyData: true

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Generated by roxygen2: do not edit by hand
22

33
export(click_pixels)
4+
export(draw_pixels)
45
export(edit_pixels)
6+
export(frame_pixels)
7+
export(gif_pixels)

NEWS.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
# pixeltrix 0.1.1
2+
3+
* Added `draw_pixels()` to plot the matrix with `image()` to the plotting window (#12).
4+
* Added `frame_pixels()` and `gif_pixels()` to capture successive 'frames' of an animation and write it to a gif (#13).
5+
* Suggested {gifski} for creating gifs (towards #15).
6+
* Provided to the user some instruction messages when they enter interactive mode.
7+
* Improved code commentary.
8+
* Added two matrix outputs as example datasets (Pokemon and Mario).
9+
110
# pixeltrix 0.1.0
211

312
* Added basic error tests.

R/click.R

Lines changed: 96 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,26 @@
2424
#'
2525
#' @export
2626
#'
27-
#' @examples \dontrun{click_pixels(3, 4, 4, TRUE)}
27+
#' @examples \dontrun{
28+
#' # Create a 16 x 16 pixel matrix with 3 possible states to cycle through
29+
#' click_pixels(n_rows = 16, n_cols = 16, n_states = 3, grid = TRUE)
30+
#' }
2831
click_pixels <- function(
29-
n_rows = 8L,
30-
n_cols = 16L,
32+
n_rows = 8L,
33+
n_cols = 16L,
3134
n_states = 2L,
32-
grid = TRUE
35+
grid = TRUE
3336
) {
3437

35-
if (!is.numeric(c(n_rows, n_cols, n_states))) {
36-
stop("Arguments 'n_rows', 'n_cols' and 'n_states' must be integer values.")
38+
if (!is.matrix(m) | !is.integer(m)) {
39+
stop(
40+
"Argument 'm' must be a matrix object composed of integers.",
41+
call. = FALSE
42+
)
3743
}
3844

3945
if (!is.logical(grid)) {
40-
stop("Argument 'grid' must be TRUE or FALSE.")
46+
stop("Argument 'grid' must be TRUE or FALSE.", call. = FALSE)
4147
}
4248

4349
n_rows <- as.integer(n_rows)
@@ -52,6 +58,89 @@ click_pixels <- function(
5258
.add_grid(m)
5359
}
5460

61+
message("Click squares in the plot window. Press <Esc> to end.")
62+
63+
.repeat_loop(m, n_states, grid)
64+
65+
}
66+
67+
#' Edit 'Pixels' in an Interactive Plot
68+
#'
69+
#' Opens an interactive plotting canvas with a grid of clickable squares
70+
#' ('pixels') that represent the cells of a matrix provided by the user,
71+
#' ideally the output from \code{\link{click_pixels}}.
72+
#'
73+
#' @param m A matrix of integers. The maximum value is assumed to be the number
74+
#' of pixel states desired. Override by supplying a 'n_states' value larger
75+
#' than the maximum in the matrix.
76+
#' @param n_states Integer. The number of states that a pixel can be. Click a
77+
#' pixel to cycle through the states. Numeric values are coerced to integer.
78+
#' See details.
79+
#' @param grid Logical. Should a boundary line be placed around the pixels to
80+
#' make them easier to differentiate? Defaults to TRUE.
81+
#'
82+
#' @details Click the pixels in the plotting window repeatedly to cycle through
83+
#' a number of 'states'. Successive clicks increase the state value by 1
84+
#' (wrapping back to 0, the default when the canvas is first plotted) and
85+
#' make the pixel darker grey in colour. Press the ESCAPE key to exit the
86+
#' mode and be returned a matrix that contains the state values of each
87+
#' pixel.
88+
#'
89+
#' @return A matrix.
90+
#'
91+
#' @export
92+
#'
93+
#' @examples \dontrun{
94+
#' # Create a 3 x 4 pixel matrix with 3 possible states to cycle through
95+
#' mat <- click_pixels(n_rows = 3, n_cols = 4, n_states = 3)
96+
#'
97+
#' # Update the original matrix, allow for an extra state
98+
#' mat_udpated <- edit_pixels(m = mat, n_states = 4)
99+
#' }
100+
edit_pixels <- function(m, n_states = NULL, grid = TRUE) {
101+
102+
if (!is.matrix(m) | !is.integer(m)) {
103+
stop(
104+
"Argument 'm' must be a matrix object composed of integers.",
105+
call. = FALSE
106+
)
107+
}
108+
109+
if (!is.null(n_states)) {
110+
if (!is.numeric(n_states)) {
111+
stop(
112+
"Argument 'n_states' must be an integer value or NULL.",
113+
call. = FALSE
114+
)
115+
}
116+
}
117+
118+
if (!is.null(n_states) && n_states < max(m + 1L)) {
119+
stop(
120+
"The number of states, 'n_states', can't be less than ",
121+
"the maximum value in the provided matrix, 'm'.",
122+
call. = FALSE
123+
)
124+
}
125+
126+
if (!is.logical(grid)) {
127+
stop("Argument 'grid' must be TRUE or FALSE.", call. = FALSE)
128+
}
129+
130+
if (is.null(n_states)) {
131+
n_states <- max(m) + 1L
132+
} else if (is.null(n_states)) {
133+
n_states <- as.integer(n_states)
134+
}
135+
136+
.plot_canvas(m, n_states)
137+
138+
if (grid) {
139+
.add_grid(m)
140+
}
141+
142+
message("Click squares in the plot window. Press <Esc> to end.")
143+
55144
.repeat_loop(m, n_states, grid)
56145

57146
}

R/data.R

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#' Example Sprite Matrix: Pokemon
2+
#'
3+
#' A matrix output from \code{\link{click_pixels}} that represents the pixels of
4+
#' a player sprite from Pokemon Blue.
5+
#'
6+
#' @examples \dontrun{
7+
#' # Plot the matrix as an image
8+
#' draw_pixels(
9+
#' m = pixeltrix::blue,
10+
#' colours = c("white", "#879afb", "gray20")
11+
#' )
12+
#' }
13+
#'
14+
#' @format A matrix with 16 rows and 14 columns, taking integers from 0 to 2.
15+
#'
16+
#' @source Hand-copied from Pokemon Blue (1996), The Pokemon Company.
17+
"blue"
18+
19+
#' Example Sprite Matrix: Mario
20+
#'
21+
#' A list of matrices output from \code{\link{frame_pixels}} that represent the
22+
#' pixels of the Mario sprite from Super Mario Bros. Each matrix is a step in
23+
#' the walk cycle.
24+
#'
25+
#' @examples \dontrun{
26+
#' # Write the list of matrices to a gif
27+
#' gif_pixels(
28+
#' frames = pixeltrix::mario,
29+
#' colours = c("white", "#FDA428", "#FC0D1B", "#A32B2E"),
30+
#' file = "mario.gif",
31+
#' delay = 0.15
32+
#' )
33+
#' }
34+
#'
35+
#' @format A list of matrices, each with 16 rows and 16 columns, taking integers
36+
#' from 0 to 2.
37+
#'
38+
#' @source Super Mario Bros (1983), Nintendo Entertainment System, Nintendo.
39+
"mario"

0 commit comments

Comments
 (0)