8 way-tile scroller (with reused sprites)

Hi,

could someone let me know how this performs on a device please?

Also I adapted the code from another site (http://love2d.org/wiki/Tutorial:Efficient_Tile-based_Scrolling) and i’m a bit unsure about the maths I’ve used

In this version I have to add a column and row in the map array to allow for my offscreen tiles at the bottom and right edge. so if your map is 100x100 you need to make it 101x101 and use the end row/columns just as dummy values as they are never actually seen. This may be an issue with my modulus and flooring calculations

also if there’s a more optimal to code it, please make any suggestions

regards
j

http://www.sendspace.com/file/k7e9vk

[blockcode]
require(“sprite”)

display.setStatusBar( display.HiddenStatusBar )

local map – stores tiledata
local mapWidth, mapHeight – width and height in tiles

local mapX, mapY – view x,y in tiles. can be a fractional value like 3.25.
local oldMapX, oldMapY

local tilesDisplayWidth, tilesDisplayHeight – number of tiles to show

local tilesetImage
local tileSize = 32 – size of tiles in pixels
local tilesetSprite

local moveX = 0
local moveY = 0
local moveAmount=8/tileSize – in tile units, so to move 1px at a time set moveAmount to 1/tileSize

local _floor = math.floor
local _max = math.max
local _min = math.min
local _rnd = math.random
local _fmod = math.fmod
local function setupMap()

– note for a 100x100 map i need a 1 tile border at the right and bottom,
– this is for my offscreen tiles used for scrolling.
– although maybe fixed maths will avoid having to add this?

mapWidth = 101
mapHeight = 101

local x,y

map = {}

for x=1,mapWidth do

map[x] = {}

for y=1,mapHeight do
– pick a random tile for now
map[x][y] = _rnd(100)
–map[x][y]=8

– edges of map
if(x==1 or y==1 or x==mapWidth-1 or y==mapHeight-1) then map[x][y]=4 end

– this boundary tile won’t be seen
– it’s the right and bottom edge used for scrolling
– you can check it by uncommenting the xScale, yScale
– at the end of this file
if(x==mapWidth or y==mapHeight) then map[x][y]=2 end

end
end
end

local function setupMapView()

mapX = 1
mapY = 1

tilesDisplayWidth = 11 --(10 * 32 = 320, plus 1 spare column)
tilesDisplayHeight = 16 --(15 * 32 = 480, plus 1 spare row)

end

local function setupTileset()

spritemap = display.newGroup()

spriteSheet = sprite.newSpriteSheet(“tileset.png”, tileSize, tileSize)

spriteSet1 = sprite.newSpriteSet(spriteSheet, 1,100)

for x=1,tilesDisplayWidth,1 do
for y=1,tilesDisplayHeight,1 do

local tilesprite = sprite.newSprite( spriteSet1 )
tilesprite:setReferencePoint(display.TopLeftReferencePoint)
tilesprite.x = (x-1)*tileSize
tilesprite.y = (y-1)*tileSize
spritemap:insert(tilesprite)

end
end

end

local function updateTilesetBatch()

local i = 1

local fX = _floor(mapX)
local fY = _floor(mapY)

local f, x, y

for x=0, tilesDisplayWidth-1,1 do

for y=0, tilesDisplayHeight-1, 1 do

f = map[x+fX][y+fY]

spritemap[i].currentFrame = f

i = i + 1

end

end

end

– central function for moving the map
local function moveMap(dx, dy)

oldMapX = mapX
oldMapY = mapY

local needUpdate = false

if(dx~=0) then
mapX = _max(_min(mapX + dx, mapWidth - (tilesDisplayWidth-1)), 1)
spritemap.x = 0-((mapX * tileSize)%tileSize)
if(_floor(mapX) ~= _floor(oldMapX)) then needUpdate=true end
end

if(dy~=0) then
mapY = _max(_min(mapY + dy, mapHeight - (tilesDisplayHeight-1)), 1)
spritemap.y = 0-((mapY * tileSize)%tileSize)
if(_floor(mapY) ~= _floor(oldMapY)) then needUpdate=true end
end
if(needUpdate) then

updateTilesetBatch()

end

end
local function update(event)

– if move amount is set, move the map
if(moveX~=0 or moveY~=0) then
moveMap(moveX,moveY)
end

– if not moving (ie at edges) then set moveX,moveY
if(mapX==oldMapX) then moveX=0 end
if(mapY==oldMapY) then moveY=0 end

end

local function onTap(event)

moveX=0
moveY=0

– tap edges of screen to move
if(event.x < 100) then moveX=-moveAmount
elseif(event.x > 220) then moveX=moveAmount
end

if(event.y < 100) then moveY=-moveAmount
elseif(event.y > 380) then moveY=moveAmount
end

return true

end

local function load()

setupMap()
setupMapView()
setupTileset()
updateTilesetBatch()

collectgarbage(“collect”)
collectgarbage(“count”)

–spritemap.xScale =0.5
–spritemap.yScale=0.5

end

load()

Runtime:addEventListener(“enterFrame”,update)
Runtime:addEventListener(“tap”, onTap)

local fps = require(“fps”)
local performance = fps.PerformanceOutput.new();
performance.group.x, performance.group.y = display.contentWidth/2, 0;
performance.alpha = 0.6;

[/blockcode] [import]uid: 10744 topic_id: 4323 reply_id: 304323[/import]

(posted under wrong account! it’s me by the way)

for this to appear right on other device resolutions you’ll need to set scale=“zoomStretch”

whereas actually the render code should maybe allow viewing a larger viewport, (or be masked off consistently) and the move code should really adapt so that the scrolling is clamped etc to the correct end position when reaching the end of the map etc [import]uid: 6645 topic_id: 4323 reply_id: 13452[/import]

Stretching doesn’t seem to work and I think there’s a problem with your FPS counter. That aside, it looks to be running smoothly in the quarter of the screen on my iPhone 4. Seems to run a lot better than my own streamBurst tilemapper so far. I was having errors in compensating for end of data with my tables. I might combine them and see what happens. [import]uid: 11024 topic_id: 4323 reply_id: 13472[/import]

Alright, I used your updateTilesetBatch() to patch up my burst() function (now no longer getting the end of data errors). It seems it’s the same idea. For these tests, my FPS counter is different, I have independent height and width, and I’m controlling the map with the analog touch joystick which is frequently checked & updated. My app also uses dual enterFrame runtimes. 17x11 tiles, 60px width by 64px height blocks.

I get about 42-45fps during fast movement (Sonic).
At slow and typical movement speed though (say Mario) it’s around 52-57fps.

While swirling the joystick and trying to lag it up, it went down to 37-42fps but only lowest when hitting the edges, so I don’t know what that’s about, but it was uncommon. The lowest minimum was about 25fps and I didn’t even notice when it happened.

All in all, looking very good at regular to moderate speeds. At really slow speeds, it has some chop anomalies, probably due to the resetting of the block positions and sprites still being weird along transparent edges despite antialias being turned off.

Might need to work on the position resetting, but this shouldn’t be an issue if you’re tapping to move like in yours so there would be less updates happening. Your device performance should be much better than mine as I was working with bigger sprites and 960x640 resolution. [import]uid: 11024 topic_id: 4323 reply_id: 13479[/import]

i didnt specify scale=“zoomEven” or “zoomStretch” in config.lua

the “tap to move” was just to test it, it wouldnt be how movement happened in a game

thanks
j

[import]uid: 6645 topic_id: 4323 reply_id: 13483[/import]

[deleted repeat post] [import]uid: 6645 topic_id: 4323 reply_id: 13484[/import]