What do 200 lines of code get you? Collision detection, managed movement with available easing functions, objects, pusher plates, advanced perspective rendering, animated tiles. The Million Tile Engine is not merely a fast culling solution. It brings powerful integrated features driven by simple function calls to bear.
–VIDEO–
http://www.youtube.com/watch?v=0ILi0haOYco
Want to move your player 3 pixels across the screen? That’s easy enough. How about 300 pixels over 1000ms using inOutQuad easing? A little harder, but easily doable. What if the layer is scaled by 1.2? Suddenly a pixel in your world is 1.2 pixels on the screen. Everything changes. Unless you’re using MTE.
mte.moveSprite(player, 3, 0)
Move the sprite 3 pixels to the right in relation to the world… whether those pixels match screen pixels 1 to 1, or 1 to 1.2, or 1 to 6. Three pixels in relation to the map, not the screen. Simple.
mte.moseSpriteTo{sprite = player, locX = player.locX + 1, locY = player.locY, time = 300, easing = “inOutQuad”}
You see where this is going. This single line will move the player 1 tile to the right, over the course of 300ms, using inOutQuad easing. And it is aware of the layer scale. All the headaches are taken care of (I use a lot of aspirin). Simple, powerful, and so very useful.
Drawing tiles is half the battle. Moving is the other half. Neither need concern you.
You may have noticed something nifty about the video, like how lower levels LOOK farther away, and higher levels LOOK closer. A cool 3D perspective effect. This required 0 lines of code, and it was all controlled using just one layer property per layer: Scale.
The map has multiple “floors.” Some call this a “sandwich.” This advanced functionality comes from one layer property: Level.
This map makes use of four separate tilesets. The Million Tile Engine will allow you to use as many different tilesets as your heart desires, on as many layers as your heart desires, so long as the tiles they contain are square. The different tilesets don’t even have to be the same number of tiles in width and height.
MTE contains thousands of lines of code.
And here’s the code on the user side c:
-- MTE "CASTLE DEMO" ----------------------------------------------------------
display.setStatusBar( display.HiddenStatusBar )
local mte = require "MTE.mte"
--LOAD MAP----------------------------------------
mte.loadMap("map/CastleDemo6")
mte.goto({ locX = 53, locY = 43, blockScale = 72})
--SETUP D-PAD-------------------------------------
local controlGroup = display.newGroup()
local DpadBack = display.newImageRect(controlGroup, "Dpad.png", 200, 200)
DpadBack.x = 120
DpadBack.y = display.viewableContentHeight - 120
local DpadUp = display.newRect(controlGroup, DpadBack.x - 37, DpadBack.y - 100, 75, 75)
local DpadDown = display.newRect(controlGroup, DpadBack.x - 37, DpadBack.y + 25, 75, 75)
local DpadLeft = display.newRect(controlGroup, DpadBack.x - 100, DpadBack.y - 37, 75, 75)
local DpadRight = display.newRect(controlGroup, DpadBack.x + 25, DpadBack.y - 37, 75, 75)
DpadBack:toFront()
--HIDE LEVELS-------------------------------------
local layerObjects = mte.getLayerObj()
local layers = mte.getLayers()
for i = 1, #layers, 1 do
if layers[i].properties.Level \> 2 then
layerObjects[i].isVisible = false
end
end
--PLAY MUSIC--------------------------------------
local bgm = audio.loadStream("Chardok.mp3")
audio.play(bgm, {loops = 0, fadein = 2000})
--CREATE PLAYER SPRITE----------------------------
local spriteSheet = graphics.newImageSheet("spriteSheetTall.png", {width = 32, height = 64, numFrames = 96})
local sequenceData = {
{name = "up", sheet = spriteSheet, frames = {85, 86}, time = 400, loopCount = 0},
{name = "down", sheet = spriteSheet, frames = {49, 50}, time = 400, loopCount = 0},
{name = "left", sheet = spriteSheet, frames = {61, 62}, time = 400, loopCount = 0},
{name = "right", sheet = spriteSheet, frames = {73, 74}, time = 400, loopCount = 0}
}
local player = display.newSprite(spriteSheet, sequenceData)
local setup = {
kind = "sprite",
layer = mte.getSpriteLayer(1),
locX = 53,
locY = 43,
levelWidth = 40,
levelHeight = 40,
}
mte.addSprite(player, setup)
mte.setCameraFocus(player)
--DETECT MOVEMENT---------------------------------
DpadUp.id = "up"
DpadDown.id = "down"
DpadLeft.id = "left"
DpadRight.id = "right"
local movement = nil
local function move( event )
if event.phase == "ended" or event.phase == "cancelled" then
movement = nil
elseif event.target.id then
movement = event.target.id
end
return true
end
--DETECT OBSTACLES--------------------------------
local obstacle = function(level, locX, locY)
local detect = mte.getTileProperties({level = level, locX = locX, locY = locY})
for i = 1, #detect, 1 do
if detect[i].properties then
if detect[i].properties.Solid then
detect = "stop"
player:pause()
return detect
end
end
end
end
local counter = 0
local toggle = 1
local moveTime = 260
local atlas = {}
atlas["left"] = { -1, 0 }
atlas["right"] = { 1, 0 }
atlas["up"] = { 0, -1 }
atlas["down"] = { 0, 1 }
local function gameLoop( event )
if not player.isMoving then
---------------------
--CHECK FOR OBJECTS--
local objects = mte.getObjectProperties({level = player.level, locX = player.locX, locY = player.locY})
if objects then
for key,value in pairs(objects[1].properties) do
if key == "change level" then
mte.changeSpriteLayer(player, mte.getSpriteLayer(tonumber(value)))
end
if key == "show level" then
local layerObjects = mte.getLayerObj()
local layers = mte.getLayers()
if value == "above" then
for i = 1, #layers, 1 do
if layers[i].properties.Level \> player.level then
layerObjects[i].isVisible = true
end
end
elseif value == "below" then
for i = 1, #layers, 1 do
if layers[i].properties.Level \< player.level then
layerObjects[i].isVisible = true
end
end
else
for i = 1, #layers, 1 do
if layers[i].properties.Level == tonumber(value) then
layerObjects[i].isVisible = true
end
end
end
end
if key == "hide level" then
local layerObjects = mte.getLayerObj()
local layers = mte.getLayers()
if value == "above" then
for i = 1, #layers, 1 do
if layers[i].properties.Level \> player.level then
layerObjects[i].isVisible = false
end
end
elseif value == "below" then
for i = 1, #layers, 1 do
if layers[i].properties.Level \< player.level then
layerObjects[i].isVisible = false
end
end
else
for i = 1, #layers, 1 do
if layers[i].properties.Level == tonumber(value) then
layerObjects[i].isVisible = false
end
end
end
end
local locX, locY, time = player.locX, player.locY, 300
if key == "move to locX" then
if value == "random" then
locX = player.locX + math.random(1, 3) - 2
else
locX = tonumber(value)
end
end
if key == "move to locY" then
if value == "random" then
locY = player.locY + math.random(1, 3) - 2
else
locY = tonumber(value)
end
end
if math.abs(locX - player.locX) \> 3 or math.abs(locY - player.locY) \> 3 then
time = 600
end
if locX ~= player.locX or locY ~= player.locY then
mte.moveSpriteTo({sprite = player, locX = locX, locY = locY, time = time, easing = "inOutQuad"})
end
end
end
-------------------------
--MOVE PLAYER CHARACTER--
if movement then
local xTile, yTile = player.locX + atlas[movement][1], player.locY + atlas[movement][2]
local result = obstacle( player.level, xTile, yTile )
if not result then
if player.sequence ~= movement then
player:setSequence( movement )
end
player:play()
mte.moveSpriteTo( { sprite = player, locX = xTile, locY = yTile, time = moveTime, easing = "linear" } )
end
else
player:pause()
end
end
mte.debug()
mte.update()
end
DpadUp:addEventListener("touch", move)
DpadDown:addEventListener("touch", move)
DpadLeft:addEventListener("touch", move)
DpadRight:addEventListener("touch", move)
Runtime:addEventListener("enterFrame", gameLoop)
Oh, and I’ve altered my release timeline. [import]uid: 99903 topic_id: 32457 reply_id: 144604[/import]