math.randomseed( os.time() ) -- unfuck luas base-1 bullshit function iarray(a) local n = 0 local s = #a if a[0] ~= nil then n = -1 end return function() n = n + 1 if n <= s then return n, a[n] end return nil,nil end end --[[ create a ready-to-go tiled background for VisionaireStudio V5 tilewidth: the width (or height if moving vertical) of a single background tile tick: the time that passes between calls to the move-function aBasetiles: array of basetile-animations (round robin) (every odd tile) aAlt1: alternatives for even tiles (round robin) aAlt2: special alternative for even tiles (round robin) chance2: the chance (0...1) that an even tile will be a special one. NYI / todo: vertical movement, movement ltr ]]-- QP_createTiledBackground = function(tilewidth, tick, aBasetiles, aAlt1, aAlt2, chance2) ret = {} ret.scWidth = game.CurrentScene.Sprite:getSize().x ret.numTiles = math.ceil(ret.scWidth / tilewidth) ret.odd = 0 ret.tilewidth = tilewidth ret.chance2 = chance2 * 100 ret.isInit = false ret.tick = tick ret.tiles = {} ret.ordering = {} local pos = 0 for _,t in iarray(aBasetiles) do ret.tiles[pos] = t pos = pos + 1 end ret.numBases = pos for _,t in iarray(aAlt1) do ret.tiles[pos] = t pos = pos + 1 end ret.startAlt2 = pos ret.numAlt1 = pos - ret.numBases for _,t in iarray(aAlt2) do ret.tiles[pos] = t pos = pos + 1 end ret.numAlt2 = pos - ret.numBases - ret.numAlt1 -- move all animation-tiles outside the viewport ret.initBackground = function(self) if (self.isInit) then return end self.isInit = true self.offset = 0 for _,t in iarray(self.tiles) do local ani = getObject("Animations["..t.."]") startAnimation(ani) ActiveAnimations[t].AnimationCurrentPosition = {x = self.scWidth, y = 0} end end -- check if a tile is already used in the ordering, skipping it ret.findTile = function(self, tile) for _,t in iarray(self.ordering) do if (t == tile) then return _ end end return -1 end -- return an appropiate tile from given range or nil if none available ret.getNextTile = function(self, start, stop) local pos = start while (pos < stop) do local tile = self.tiles[pos] if (self:findTile(tile) == -1) then return tile end pos = pos + 1 end return nil end -- move all tiles one index down, filling nils with new ones ret.orderBackground = function(self) local pos, off = 0,1 if (self.ordering[0] ~= nil) then ActiveAnimations[self.ordering[0]].AnimationCurrentPosition = {x = self.scWidth, y = 0} end while (pos <= self.numTiles) do self.ordering[pos] = self.ordering[off] if (self.ordering[pos] == nil) then if (pos % 2 == self.odd) then -- odd tiles get basetile self.ordering[pos] = self:getNextTile(0, self.numBases) else -- even tiles get one of the alternatives if (self.chance2 >= math.random(0,100)) then self.ordering[pos] = self:getNextTile(self.startAlt2,#(self.tiles)+1) else self.ordering[pos] = self:getNextTile(self.numBases, self.startAlt2) end end end off = off + 1 if (self.ordering[pos] ~= nil) then pos = pos + 1 end -- reasonable way out if to few tiles given if (off - pos > 5) then break end end end ret.moveBackground = function(self) self:initBackground() self:orderBackground() local pos = 0 for _,t in iarray(self.ordering) do ActiveAnimations[t].AnimationCurrentPosition = {x = self.tilewidth * pos, y = 0} ActiveAnimations[t]:to(self.tick, { VAnimationCurrentPosition = {x = self.tilewidth * (pos - 1), y = 0} }) pos = pos + 1 end self.odd = 1 - self.odd end return ret end --[[ Example Usage: scUW = QP_createTiledBackground(913, 300, {"tunnel0a","tunnel0b"}, {"tunnel1a","tunnel1b"}, {"tunnel2"}, 0.3) call from scene: 1. scUW.moveBackground() 2. wait 300 3. goto 1 ]]--