
-----------------------------------
mirhagk
Tue Dec 15, 2009 3:01 pm

Code optimization
-----------------------------------
There are four things a programmer needs to do to make a good game. 

1. Come up with a good idea and plan out the game.

2. Write the code for the game

3. Make the program idiot-proof (remember how dumb people are)

4. Make the amazing game as effecient as possible


Today I'm going to talk about the fourth item, because it seems to be the biggest problem for most programmers.

I have created a simple program to demonstrate many of the ways to optimize your code. The program is commented in case you don't understand it but you really should because it's very basic


var x, y : int %the position of the character
x := maxx div 2
y := maxy div 2
var keys : array char of boolean %keyboard input
var t := Time.Elapsed %keep track of the time
var tlast := t %the time last frame
var fps : real %keep track of the Frames Per Second
colourback (black) %set the background to black
colour (white) %and the font colour to white
cls
loop
    Input.KeyDown (keys) %get keyboard state
    t := Time.Elapsed - tlast
    if t = 0 then %to prevent a division by 0 we say if less
        fps := 1000          %than 1 second has passed then it's 1000fps
    else
        fps := 1000 / (t) %fps equals 1 second divided by the time it took to run the last frame
    end if
    tlast := Time.Elapsed
    Text.Locate (1, 1)
    put fps
    if keys (KEY_UP_ARROW) then %very simple movement
        y += 1
    elsif keys (KEY_DOWN_ARROW) then
        y -= 1
    end if
    if keys (KEY_RIGHT_ARROW) then
        x += 1
    elsif keys (KEY_LEFT_ARROW) then
        x -= 1
    end if
    for X : 1 .. maxx by 10
        for Y : 1 .. maxy by 10
            drawfillstar (X, Y, X - 5, Y - 5, yellow) %draws stars for the background
        end for
    end for
    drawfilloval (x, y, 3, 3, brightred) %draw the character
    delay (10)
    cls %clears the screen
end loop


obviously not a very useful game lol but it's just as an example. So first of all, probably one of the most common problems is "the flickering".

Well the first problem with that is where the cls is. Right now it clears the screen then does a bunch of code, then draws the stuff. It flickers much less when it does the code, then clears the screen right before it draws it.

However that really doesn't make much difference because you can just use View.Update and offscreenonly 
    if keys (KEY_UP_ARROW) then %time relative movement
        y += 1 * (t) / 10
    elsif keys (KEY_DOWN_ARROW) then
        y -= 1 * (t) / 10
    end if
    if keys (KEY_RIGHT_ARROW) then
        x += 1 * (t) / 10
    elsif keys (KEY_LEFT_ARROW) then
        x -= 1 * (t) / 10
    end if

of course for this to work x and y must be real (change from int to real at top) and must be rounded when drawn like so:

drawfilloval (round (x), round (y), 3, 3, brightred) %draw the character


In this example you won't notice the difference right away other than a smoother movement but if you take the drawfillstar command out you will notice he moves at the same speed as he did before.



And last but now least, closing your program. It's not a good thing if you have to keep clicking the 'X' at the top right corner to keep stopping your program. You should have an exit when statement in your main loop. For this one we'll use

var screen:=Window.Open("offscreenonly")

this works the same way View.Set (or setscreen) except you now have the window in a variable and can use the following

Window.Close(scree)

if you put that at the end of your code(after end loop) then it will stop the program and close it when you press the Escape key.


There are of course many, MANY other ways to improve your code, these are just a few of the simplest ones that can be used in most programs.

If you post your code I can help you modify your code to make it run faster.

Btw the final code is:


var screen := Window.Open ("offscreenonly") %opens a new window
var x, y : real %the position of the character
x := maxx div 2
y := maxy div 2
var keys : array char of boolean %keyboard input
var t := Time.Elapsed %keep track of the time
var tlast := t %the time last frame
var fps : real %keep track of the Frames Per Second
colourback (black) %set the background to black
colour (white) %and the font colour to white
cls
loop
    Input.KeyDown (keys) %get keyboard state
    t := Time.Elapsed - tlast
    if t = 0 then %to prevent a division by 0 we say if less
        fps := 1000          %than 1 second has passed then it's 1000fps
    else
        fps := 1000 / (t) %fps equals 1 second divided by the time it took to run the last frame
    end if
    tlast := Time.Elapsed
    Text.Locate (1, 1)
    put fps %puts the frames per second
    if keys (KEY_UP_ARROW) then %time relative movement
        y += 1 * (t) / 10
    elsif keys (KEY_DOWN_ARROW) then
        y -= 1 * (t) / 10
    end if
    if keys (KEY_RIGHT_ARROW) then
        x += 1 * (t) / 10
    elsif keys (KEY_LEFT_ARROW) then
        x -= 1 * (t) / 10
    end if
    for X : 1 .. maxx by 10
        for Y : 1 .. maxy - 10 by 10
            drawfillstar (X, Y, X - 5, Y - 5, yellow) %draws stars for the background
        end for
    end for
    drawfilloval (round (x), round (y), 3, 3, brightred) %draw the character
    View.Update %updates the screen
    cls %clears the screen
    exit when keys (KEY_ESC) %exits when you press escape
end loop
Window.Close (screen) %closes the window


-----------------------------------
DemonWasp
Tue Dec 15, 2009 4:15 pm

RE:Code optimization
-----------------------------------
First, your FPS-detection code is incorrect (if t 20 then
                fps -= 10
            elsif fps > 1 then
                fps -= 1
            else
                exit
            end if
        end if
    end if
    told := Time.Elapsed
    %drawfilloval (round (x), round (y), 15, 15, white)
    cls
    x += xv * (1000 / fps) / 2
    y += yv * (1000 / fps) / 2
    Text.Locate (1, 1)
    put fps
    if maxframe then
        put "Currenty running as fast as it can"
        put "Press any key to switch to 200 fps" ..
    else
        put "Currently running at the above rate"
        put "If you can notice a lag please let me know"
        put "Press any key to decrease the refresh rate"
    end if
    drawfilloval (round (x), round (y), 15, 15, col)
    View.Update
    if x > maxx then
        xv := -1
        collided := true
    elsif x < 0 then
        xv := 1
        collided := true
    end if
    if y > maxy then
        yv := -1
        collided := true
    elsif y < 0 then
        yv := 1
        collided := true
    end if
    if collided then
        col := Rand.Int (0, 5)
        case col of
            label 0 :
                col := brightred
            label 1 :
                col := brightblue
            label 2 :
                col := brightpurple
            label 3 :
                col := 42
            label 4 :
                col := yellow
            label 5 :
                col := brightgreen
        end case
        collided := false
    end if
end loop
put "Thank you for using Nathan's frame rate test. Please go to www.compsci" ..
put ".ca and find the code optimization thread under turing>turing tutorials"
put "Please let me post and let me know what speed you noticed it lagging at"
put "(if you haven't yet please try this a couple of times so you can get " ..
put "an accurate answer"
View.Update
Input.Pause
Window.Close (win)


okay and is there a way to get the ip address with turing? I guess it only returns the local ip address
