Less lag in building game.

@Stevon8ter Your fine! Yours doesn’t really use a true grid system, and yeah, I know physic.bodies use acceleration, I was just comparing them in lag terms, not what they have in common. :slight_smile:

haha ok
but do you plan on adding multiple shapes and rotations? or just squares?

@Stevon8ter just squares

@Prynok ok well then i think the main toughness is the collision detection as we speak, most stuff should be less difficult, to still not that easy, but remeber you can use a vec3 to store which block is on that place (grass, dirt, …)

@Stevon8ter I made a small program that draws 500 rectangles on the screen, with no if statements or physic.bodies. and it runs slow also. So I’m now thinking the drawing is what is slowing it down.

I’m guessing a way to fix it would be using a system like backingmode(Retained)
Though the only problem would be the character moving, because backing mode shows what was last on the screen also.

@Prynok Change the rectangles to sprites.

EDIT: make an image of your objects and draw them as sprites.

EDIT: I drew 500 image sprites with a size of 100x100 at around 50 fps.

@dave1707 That doubled the fps, 30 with 1000 sprites on screen.

Also, when you draw objects, check if they’re on the screen. That can save some FPS.

@SkyTheCoder the map, or the camera doesn’t move, so I know everything is on the screen :wink:

@Prynok I’m not sure if this is exactly what your after, but maybe it will give you an idea. Try moving the guy thru the black areas. There are a few problems with this, but I’m going to bed. 1.) The guy can move diagonally, but shouldn’t be able to. 2.) The guy goes too far into the blocks before he stops.


displayMode(FULLSCREEN)

function setup()
    img=image(50,50)
    setContext(img)
    fill(255)
    rect(25,25,48,48)
    setContext()
    tab={}
    for x=1,22 do
        tab[x]={}
        for y=1,22 do
            tab[x][y]=math.random(0,1)
        end
    end
    x=300
    y=600
    xh=0
    yh=0            
end

function draw()
    background(40,40,50)
    for x=1,22 do
        for y=1,22 do
            if tab[x][y]==1 then
                sprite(img,x*25,y*25)
            end
        end
    end
    sprite("Platformer Art:Guy Standing",x,y,15)
end

function touched(t)
    if t.state==MOVING then
        x=x+t.deltaX
        y=y+t.deltaY
        xx=math.floor(x/25)
        yy=math.floor(y/25)
        if tab[xx][yy]==1 then
            x=xh
            y=yh
        end
        xh=x
        yh=y
    end
end

I know things have moved on to custom collision, but this thing I did a while back faced a similar problem:

http://twolivesleft.com/Codea/Talk/discussion/2077/drop-2000-squares-into-a-pile-at-30-fps#Item_3

Basically it’s got 2000 physics objects and I took 2 approaches to get performance.

  1. if a physics object doesn’t need to move, just be interacted with change it’s .type to STATIC, this massively reduces the processing load for physics.

  2. I draw the static objects to an offscreen image so I can just sprite that in rather than redrawing the individual objects every frame

@spacemonkey Could you explain the offscreen image, please? It sounds like that would help reduce the lag, also every physics.body besides the character is static.

So in my code you’ll see

setContext(bImg)
t:park()
setContext()

setContext means drawing happens to the image bImg, not the screen. Then the t:park() thing identifies stationary objects, makes them static and draws them onto bImg (note bImg is never cleared so it’s adding the new stopped ones).

The second setContext() without a paremeter reverts drawing to the screen.

Then in the main draw it has

sprite(bImg, w2, h2)

which copies the background image onto the screen before any other drawing. Then it draws the moving objects. This means all the parked objects in my case are not drawn every frame, it relies on them already being drawn to the background image.

A few questions, what does your Terrain:draw function do then? is t:park() a custom made function, or a pre-made one?

Thanks in advance .

Terrain is my own class I define in the code. t is an object of that class, so t:park() just calls the Terrain:park() method. None of this stuff is inbuilt, it’s stuff I wrote.

But the key is: for non moving stuff then ONLY ONCE do:

w2 = WIDTH / 2
    h2 = HEIGHT / 2
    bImg = image(WIDTH, HEIGHT)
setContext(bImg)

draw all your static stuff

then in draw() for your main app do

sprite(bImg, w2, h2)

draw all your dynamic stuff

And when I say do the non moving stuff once, that is each time it changes, which might be more often than once as it is in my case.

Huh, so basically you are making a picture of the scene, and just draw that instead of all the objects?

yes he is, tho you need to make sure to clear the image only when you delete an object, when placing an object, it doesn’t have to be cleared

How would that make it faster if your terrain:draw() is being called every frame?

Sorry not trying to be ignorant, just trying to wrap this around my head :slight_smile:

Terrain:draw() goes through all my objects, but it uses an if so it only actually draws objects where the physicsbody.type != STATIC. So it’s much quicker because it doesn’t draw all 2000 squares, it only draws the ones that are moving because the stationary ones will be in the background image.

@spacemonkey I just realized something about your project, it can run at 60 frames, but when a physic.bodies is touching another, it apparently slows down the Ipad quite a bit, I’m not sure if this is a bug, or the behavior of physic.bodies, but it is interesting.