This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
exosceleton's profile picture

paintutils loadAnim/drawAnim

Started by exosceleton, 02 January 2017 - 05:39 PM
exosceleton #1
Posted 02 January 2017 - 06:39 PM
As some of you might know, you can create images, animations [and text(?)] in npaintpro. in the paintutils API they are two functions that can handle images:
paintutils.loadImage(imageFilePath) -- loads Image file to Image Table
paintutils.drawImage(imageTable,x,y) -- draws an Image using an Image Table
So, since npaintpro can make animations too I looked through the inter-webs to see if anyone made similar functions for animations. When I found none, I decided to make my own. So here you go people, Happy days.
loadAnim
paintutils.loadAnim = function(path)
  local frames = {}
  local frame = {}

  local colorMap = {
	[' '] = 0
	['0'] = colors.white,
	['1'] = colors.orange,
	['2'] = colors.magenta,
	['3'] = colors.lightBlue,
	['4'] = colors.yellow,
	['5'] = colors.lime,
	['6'] = colors.pink,
	['7'] = colors.gray,
	['8'] = colors.lightGray,
	['9'] = colors.cyan,
	['a'] = colors.purple,
	['b'] = colors.blue,
	['c'] = colors.brown,
	['d'] = colors.green,
	['e'] = colors.red,
	['f'] = colors.black
  }

  if not fs.exists(path) then
	error("file path invalid")
  end

  local l
  local tl = {}

  for l in io.lines(path) do
	l = f.readLine()
	if l == "~" or l == nil then
	  -- add frame to frames
	  table.insert(frames,frame)
	  frame = {}

	  if l == nil then -- eof
		break
	  end
	else
	   local pixel
	   for j=1,#l do
		 -- add char to line
		 pixel = colorMap[l:lower():sub(j,j)]
		table.insert(tl,pixel)
	 end

	 -- add line to frame
	 table.insert(frame,tl)
	 tl = {}
	end
  end

  return frames
end
drawAnim
paintutils.drawAnim = function(frames,x,y,delay,loop)
  x = x or 1
  y = y or 1
  delay = delay or .25
  loop = loop or false

  repeat
	for i,frame in pairs(frames) do -- iterate through frames
	  paintutils.drawImage(frame,x,y) -- draw frame
	  sleep(delay)
	end
  until not loop
end
Constructive feedback appreciated.
Edited on 02 February 2017 - 12:29 PM
Bomb Bloke #2
Posted 02 January 2017 - 11:58 PM
Great Glob of StuffInstead of this sort of thing:

local f = fs.open(path,"r")

local l

while true do
  l = f.readLine()
  .
  .
  .
end

f.close()

… it's faster and easier to use io.lines():

for l in io.lines(path)
  .
  .
  .
end

Storing the current terminal background colour in place of transparent pixels within your loaded images doesn't seem desirable. It looks like adding [' '] = 0 to your colorMap table should allow you to handle them normally.

#l executes faster (and is easier to type) than string.len(l). The likes of string.lower((string.sub(l,j,j))) can also be written as l:lower():sub(j,j), though I'm not sure you'd ever encounter upper-case characters there anyway.

This:

  while true do
        .
        .
        .
        if not loop then
          break
        end
  end

… could also be reduced by switching to a repeat loop:

repeat
  .
  .
  .
until not loop
Edited on 02 January 2017 - 11:04 PM
exosceleton #3
Posted 03 January 2017 - 03:12 PM
Thanks for the feedback. Fixed!
Edited on 03 January 2017 - 02:13 PM
ReBraLaCC #4
Posted 04 January 2017 - 06:24 AM
with drawAnim() just for shorter code and i dont know if it is faster but its easier because lua kinda does the if statement for you
x = x or 1
y = y or 1
delay = delay or 0.25
loop = loop or false
exosceleton #5
Posted 04 January 2017 - 04:06 PM
Fixed!