allow me to offer my optimization knowledge
while (t = @tile_sprites[col_num]) && (t[0].x/t[0].zoom_x <= -49*t[0].zoom_x || t[0].x/t[0].zoom_x >= -17*t[0].zoom_x) && @anti_hang < 100
this is killing you I bet (not the only thing but a major contributor)
remember it gets run as is every loop. that means t[0] calls t.[](0) and has to resolve the object 6 times every loop. if you bound t[0] to a local name that would provide some speed up.
if you can do the same with the object's .zoom_x and .x properties instead of resolving them off the object with a call every time that might help too.
also you do the same division (t[0].x/t[0].zoom_x) twice, doing it once and binding it to a local name might help (that might need some testing I'm not familiar with the overhead of integer division vs name binding)
next, .zoom_x is a float yes? then your dividing an int by a float. in a typed and compiled language this wouldn't be an issue as the compiler would automatically optimize but in ruby we're doing this all at run time and as an int/float operation is technically impossible for the CPU ruby first has to coerce the int to a float, at run-time, every time it happens. same thign applies for all mathematical operations between floats and ints
lastly the
(t = @tile_sprites[col_num]) &&
while clever in that it is a clean way to set up for the while call, you introduce the somewhat unnecessary testing condition that @tile_sprites[col_num] exists every loop. if you've written everything correctly this condition should NEVER be false and if it can be then something else has gone wrong and you should look into that
all this in mind the line should probably be written as
t = @tile_sprites[col_num]
txf = t.x.to_f
tzoom_x = t.zoom_x
tratio = txf/tzoom_x
while (tratio <= -49.0*tzoom_x || tratio >= -17.0*tzoom_x) && @anti_hang < 100
#rest of loop code
#...
#...
col_num = @corner_index
t = @tile_sprites[col_num]
txf = t.x.to_f
tzoom_x = t.zoom_x
tratio = txf/tzoom_x
end #end of while
(($resolution.width + 64)*($resolution.height + 64)).floor / 1024
is there really a float in there that makes the .floor call necessary? in fact if you want an integer result it might be faster to force everything to integer first, there is a reason computers measure power in FLOPS, integer operations are insignificant vs floating point ones. that applies everywhere you end up using floats. drop to integers as soon as you can provided you wont lose needed precision.
Less optimization and more questioning implementation
@tile_sprites[j] && @tile_sprites[j].each_index do |i|
I'm unsure if the objective is to only loop if @tile_sprites[j] exists or if your trying to get a union or intersection of the arrays to loop over. only the former makes sense and I'm unsure of the performance of using an if statement over taking advantage of the way ruby only processes the statement after the && if the first returned a truthy value.
then I question the necessity of once again checking to ensure existence. if the condition really can happen then something else is wrong. and again, it's just one more operation in a loop that adds run time if you don't need it.
summery:
avoid all floating point operations you can.
avoid repeated calls or operations
avoid unnecessary name resolution
avoid implicit coercion at run-time
if you need to do constant checking for existence of an object INSIDE A LOOP then something is wrong elsewhere.
of course you probably should not take my word for all this. do your own tests.
don't take this as a smack down of your skills in any way. everyone has their coding style and ruby is a language where there are 100 ways to do something. it's just not always the fastest. it's taken me years and college classes to learn how to optimize
I'll leave with one final word. never prematurely optimize. only optimize if you NEED to and have profiles to prove that a method or function is eating a significant amount of time.