Skip to content

Instantly share code, notes, and snippets.

@coolbutuseless
Created August 13, 2018 13:07
Show Gist options
  • Save coolbutuseless/0028ab1e64603c9667bb857706ac0ff5 to your computer and use it in GitHub Desktop.
Save coolbutuseless/0028ab1e64603c9667bb857706ac0ff5 to your computer and use it in GitHub Desktop.
gganimate sprites
library(tidyverse)
library(raster)
library(gganimate)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Not going to directly link in to script to avoid hitting server
# https://www.spriters-resource.com/resources/sheets/12/12593.png
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sprite_sheet <- png::readPNG("12593.png")
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Set up the extraction parameters
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Nframes <- 16 # number of frames to extract
width <- 28 # width of a frame
sprite_frames <- list() # storage for the extracted frames
# Not equal sized frames in the sprite sheet. Need to compensate for each frame
offset <- c(3, 4, 6, 7, 7, 6, 5, 5, 6, 6, 7, 7, 7, 6, 7, 8)
# Manually extract each frame
for (i in seq(Nframes)) {
sprite_frames[[i]] <- sprite_sheet[13:40, (width*(i-1)) + (1:width) + offset[i], 1:3]
}
# Test plot
plot(as.raster(sprite_frames[[15]]), interpolate=FALSE)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function to convert a sprite frame to a data.frame
# and remove any background pixels i.e. #82ABE7
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sprite_frame_to_df <- function(frame) {
plot_df <- data_frame(
fill = as.vector(as.raster(frame)),
x = rep(1:width, width),
y = rep(width:1, each=width)
) %>%
filter(fill != '#82ABE7')
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Convert all sprite frames to sprite data.frames
# and set the 'idx' column to the frame number
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sprite_dfs <- sprite_frames %>%
map(sprite_frame_to_df) %>%
imap(~mutate(.x, idx=.y))
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Work out the spirte colours for scale_fill_manual
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fill_manual_values <- unique(sprite_dfs[[1]]$fill)
fill_manual_values <- setNames(fill_manual_values, fill_manual_values)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Stack all the sprites into a mega data.frame
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mega_df <- dplyr::bind_rows(sprite_dfs)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Create the basic ggplot object
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
p <- ggplot(mega_df, aes(x, y, fill=fill)) +
geom_tile(width=0.9, height=0.9) +
coord_equal(xlim=c(1, width), ylim=c(1, width)) +
scale_fill_manual(values = fill_manual_values) +
theme_bw() +
theme(legend.position = 'none')
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Facet by time
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
p +
facet_wrap(~idx)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Facet by time with gganimate
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
panim <- p +
transition_manual(idx, seq_along(sprite_frames)) +
labs(title = "gganimate bubble bobble")
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Create and save animation
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gganimate::animate(panim, fps=8, width=400, height=400)
# gganimate::anim_save("bubble_bobble.gif")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment