I'm kind of new to XNA (and games in general). I'm trying to make a young relative of mine (10yo) a simple fun game where he is the main character. I'm down to the wire (I have to get it to him by tomorrow and wont have time to work on it at all tomorrow, which means I have to finish it tonight). Everything was tight as it is (I'm kind of close to being finished, but not really). Everything was going pretty smoothly until a minute ago when I asked monsters and finished the level map data.
Here is a copy of what the map data looks like:
Its only 16x100. Basically, each color represents an object already specified in other parts of the game. I'm doing this for simplicity. Parsing the image itself happens nearly instantaneous so don't yell at me for doing it this way. The maps are pretty straight forward and don't need any real optimization.
Now, my first guess was, having this many monsters causes maaaaaaajor lag... (notice the 2 FPS).
- that's only half of the story -
Apparently, when I added the details for the upper half of the map image (It originally only had a couple of lines on it for testing) it causes a ton of the lag being involved.
So why does it cause so much lag?
Well, this is the embarrassing part. Because the player will be working on, there will be a lot of jumping involved. Because of this, I have to pan the 'camera' while he moves vertically. So, instead of the character moving, everything else actually moves. (All of the trusses, monsters, etc. move instead of the character). So basically, the character is locked vertically (he can move freely horizontally, however). The monsters cause a bit of lag but really, not anything noticeable unless both issues are combined.
Basically, the level is loaded into a multidimensional array. Then, whenever any vertical change occurs to the player (gravity or jumping), an offset equivalent to the amount I want it to appear that he is jumping is applied to EVERYTHING (this includes monsters and every block).
The game is made out of 64x64 sprites so there are a total of 10 ladder sprites visible in the screenshot above being moved every time the player moves.
Why I feel dumb...
First, I recognize the problem: To many sprites are being moved at the same time. Second, I recognize the solution: Only move sprites that are visible or vital (such as monsters). The problem is, I'm not sure how to only move the sprites that are visible. I tried dividing everything into vertical chunks of 10 and then check to see which ones are visible and only calculate those but things started getting out of hand! I don't want to ruin the game in the last hours I have working on it!
Oh, and did I mention? I've wired Lua in, I'm not even compiling the actual code! I'm scripting almost EVERYTHING!
So, it is my plea to you this day (the very last day of the year no less)! To help me find a quick (dirty if necessary!) solution to my problem!
If it helps, here is a copy of the level.lua
file I'm currently dealing with:
module(...,package.seeall)
local spriteTable={
{name="Blue Truss",color={r=0,g=148,b=255},position={x=0,y=0}};
{name="Red Truss",color={r=255,g=0,b=55},position={x=1,y=0}};
{name="Ladder",color={r=255,g=106,b=0},position={x=0,y=1}};
{name="Stone",color={r=0,g=0,b=0},position={x=1,y=1}};
{name="MonsterBox",color={r=188,g=75,b=0},position={x=0,y=3}};
}
currentLevel={map=nil,offset=0,toffset=0,cerrain={},spawn={x=14,y=96},character=nil}
local LEVELMAX=10
function getVisibleChunks()
local visible={}
Print(#currentLevel.map)
for _,v in ipairs(currentLevel.map) do
--CHECK TOP
local pos=base.HEIGHT-((#currentLevel.map-_*LEVELMAX)+1)*64-currentLevel.toffset
if pos>0 and pos<base.HEIGHT then
Print("CHUNK ".._.." IS VISIBLE!")
end
--CHECK BOTTOM
pos=base.HEIGHT-((#currentLevel.map-_*LEVELMAX)+1)*64-currentLevel.toffset+(LEVELMAX*64)
if pos>0 and pos<base.HEIGHT then
Print("CHUNK ".._.." IS VISIBLE!")
end
end
end
function play(level,callback)
currentLevel.map=loadLevel(level)
--getVisibleChunks()
me:AddSprite("levelback",0,0,base.WIDTH,base.HEIGHT,0,0,base.WIDTH,base.HEIGHT,1)
for _y=#currentLevel.map,1,-1 do
local top=currentLevel.map[_y]
for _x,obj in pairs(top) do
table.insert(currentLevel.cerrain,me:AddSprite("objects",(_x-1)*64,base.HEIGHT-(#currentLevel.map-_y+1)*64-currentLevel.toffset,64,64,obj.position.x*64,obj.position.y*64,64,64,2))
end
end
collision.loadTops(currentLevel.map)
ConnectEvent(base,"keydown",function(input)
character.sendInput({["direction"]=true,["key"]=input})
end)
ConnectEvent(base,"keyup",function(input)
character.sendInput({["direction"]=false,["key"]=input})
end)
ConnectEvent(base,"updated",function(t)
currentLevel.toffset=currentLevel.toffset-currentLevel.offset
for _,v in ipairs(currentLevel.cerrain) do
v:SetPosition(v.position.X,v.position.Y+currentLevel.offset)
end
currentLevel.offset=0
character.update(t)
monsters.update(t)
debugger.set("OFFSET: "..currentLevel.toffset)
end)
currentLevel.character=me:AddSprite("character",currentLevel.spawn.x*64,base.HEIGHT-(100-currentLevel.spawn.y)*64+29,64,99,128,0,64,99,5)
currentLevel.toffset=0
currentLevel.offset=0
character.set(currentLevel.character,currentLevel.character.position.x,currentLevel.character.position.y)
end
function loadLevel(level)
local imgmap=me:GetBitmapFromFile("maps\\"..level..".png")
local map={}
local cCount=0
for y=0,imgmap.Height-1 do
if cCount==0 then
table.insert(map,{})
end
cCount=cCount+1
local xLevel={}
for x=0,imgmap.Width-1 do
local fColor=imgmap:GetPixel(x,y)
local r=fColor.R
local g=fColor.G
local b=fColor.B
for _,v in ipairs(spriteTable) do
if (r==v.color.r) and (g==v.color.g) and (b==v.color.b) then
xLevel[x+1]={name=v.name,position=v.position}
end
end
end
--if cCount>=LEVELMAX then
-- cCount=0
--end
--map[#map][y+1]=xLevel
map[y+1]=xLevel
end
return map
end
Here are my edits:
So, the camera pan thing worked nearly perfectly! With some final tuneups, I'm not having any FPS drops at all!
Now, however, (as dumb as this sounds) I've got this issue here:
Is there a way to force some of these elements (such as the background image and the debug info) to stay instead of panning along with everything else?