
-----------------------------------
Nathan4102
Thu Feb 27, 2014 10:40 pm

2D Physics in Game Development
-----------------------------------
Hey guys, I'm starting work on my ICS3UI summative, basically I'm planning on a 2D physics related game, I'd rather not give the specifics. It'll include vertical momentum, gravity changes (Direction and magnitude), inertia, you name it. Basically I need it looking as realistic as possible, which means not jumping at a constant 2m/s, or having your momentum shift from 2m/s up to 2m/s down in a tick when gravity changes.

This doesn't seem like too much, except I've never taken a physics course. I don't know how an instantaneous change of direction of gravity would affect a person in flight, I don't know how to calculate the path of a jumping person, I don't know any of that stuff. How do you guys suggest I learn all this stuff? Like sure I could look up a whole bunch of physics stuff and learn how to calculate this stuff using fancy formulas, but I feel like actually implementing it in a 2D game isn't that simple. I've looked up a bit on 2D game development, and 2D physics, but none of the stuff I've found has been too useful. Any suggestions?

Also, how should I control the rate at which the game progresses? Like in the past, I've had my main loop which calls on calculations and drawing functions etc, then waits x miliseconds, then does the loop again. This is alright except it'll run faster on a good computer, and slower on a slow old computer. Ideally, I'd like the computers processing power to determine the FPS, not the rate the game actually progresses. How would I go about doing this? Like take this turing program for example:

var x := 2.0;
for i : 1..1000
    for ii: 1..1000
        for iii : 1..1000
            x := (x * 2) / 2
        end for
    end for
    put(i);  
end for

This program will print numbers at different speeds on different computers. Ideally if the numbers were frames, it should skip numbers on slow computers, and print at a constant speed on fast computers(Or maybe even decimals). How would I go about doing this in a program?

Thanks!

-----------------------------------
Raknarg
Thu Feb 27, 2014 11:50 pm

RE:2D Physics in Game Development
-----------------------------------
For the physics part, don't make it too complicated. Here's a couple examples.

Here's a ball with "inertia". The actual momentum can be calculated if you have a variable to represent mass. My hope is that by now you know how to use classes, which is a much better method of doing this. Basically you have variables to represent your position and some to represent your velocity. To change direction, what you do is add or subtract to your velocity. If you're going right 5 m/s and you want to go left, you slow down by 1m/s every second or whatever. This will look more realistic. You'll slow down, then start going left, like in this example:


setscreen("offscreenonly")

type characterData :
    record
        x, y, vx, vy : real
        drawx, drawy : int
    end record
    
fcn newCharacter(initx, inity : real) : characterData
    var newc : characterData
    newc.x := initx
    newc.y := inity
    newc.vx := 0
    newc.vy := 0
    
    result newc
end newCharacter
    
var player : characterData := newCharacter(100, 100)
var key : array char of boolean

loop
    Input.KeyDown(key)
    if key(KEY_RIGHT_ARROW) then
        player.vx += 0.1
    end if
    if key(KEY_LEFT_ARROW) then
        player.vx -= 0.1
    end if
    if key(KEY_UP_ARROW) then
        player.vy += 0.1
    end if
    if key(KEY_DOWN_ARROW) then
        player.vy -= 0.1
    end if
    
    player.x += player.vx
    player.y += player.vy
    
    % This is essentially friction
    player.vx *= 0.98
    player.vy *= 0.98
    
    player.x := min(max(player.x, 0), maxx)
    player.y := min(max(player.y, 0), maxy)
    
    player.drawx := round(player.x)
    player.drawy := round(player.y)
    
    Draw.FillOval(player.drawx, player.drawy, 10, 10, 12)
    
    View.Update
    delay(5)
    cls
end loop


Pretty simple. If you want to do other physics with them, as long as you know the size and mass of them you should be able to do it. This is the basics. You can also do realistic jumping with gravity with a few small tweaks:


setscreen("offscreenonly")

% Add a gravity constant
const gravity := -0.1

type characterData :
    record
        x, y, vx, vy : real
        drawx, drawy : int
    end record
    
fcn newCharacter(initx, inity : real) : characterData
    var newc : characterData
    newc.x := initx
    newc.y := inity
    newc.vx := 0
    newc.vy := 0
    
    result newc
end newCharacter
    
var player : characterData := newCharacter(100, 0)
var key : array char of boolean

loop
    Input.KeyDown(key)
    if key(KEY_RIGHT_ARROW) then
        player.vx += 0.1
    end if
    if key(KEY_LEFT_ARROW) then
        player.vx -= 0.1
    end if
    %Essentially this is the only input change
    if key(KEY_UP_ARROW) and player.y 