LoginLogin

How to put gravity

Root / Programming Questions / [.]

Z2BCodesCreated:
Can someone say me how to put gravity in a game pls?

You said "pls" because it's shorter than "please", so I'm going to say "No" because it's shorter than "Yes". If you want an answer that is actually useful, you'll have to post your code. Do you have a system for storing which sprites (or BG tiles) are for the ground vs which ones are actual objects that need gravity applied? Generally speaking, for each sprite that you want to apply gravity to, you'll decrease it's y-coordinate by some amount (something exponential if you want it to be realistic) and check for collision with the static terrain. If it's collided, do something to signify that it doesn't need gravity applied. We really do need your code.

snark snark snark. we need your code
The problem is more likely to be that they can't use what we give them just yet. There's probably not any code that we can work with.
Can someone say me how to put gravity in a game pls?
Click this if you know what you're doing:
Pure, Unfiltered Knowledge(basically what Chatter described) change the numbers until they feel good
WHILE TRUE
 <code>
 IF TOUCHINGGROUND THEN
  IF JUMP THEN
   YVEL = -10 `jump force
  ENDIF 
 ELSE
  INC YVEL, 2 `gravity
 ENDIF
 YVEL = YVEL * 0.87 `air resistance
 INC Y, YVEL
WEND
Click this if you don't:
THE GUIDE TO EVERYTHING This is a great tutorial for beginners, written by the very owner of this site. Skip ahead if you know something, don't if you don't. Some things to remember while using SmileBASIC:
  • Don't be afraid to experiment. There are three other 'slots' where you can write short programs to test things. You can run them by typing RUN <SLOT#> in DIRECT mode.
  • There's an incredibly useful help button in the top-right corner for when you're editing programs. Tapping it opens a command list. If your text cursor is on a command, it opens an explanation for that command.
  • What VSYNC does
  • Pressing Save/Load with Shift mode on makes saving/loading programs so much easier.
  • Use the right type of loop. Some loop examples

BED3CE8E (probably won't be up forever, get it while you can). Below is a sample program showing off gravity. Feel free to ask questions about parts you may not understand.
OPTION STRICT

'USED TO SHOW THE PATH OF FALLING/JUMPING
VAR MAX_POINTS = 50
VAR POINT_X[MAX_POINTS]
VAR POINT_Y[MAX_POINTS]
VAR POINT_COUNT = 0

'CONSTANTS
VAR GRAVITY = 9.8 'METERS PER SECOND
VAR PIXELS_PER_METER = 16
VAR MS_PER_SECOND = 1000
VAR MIN_TIME = 16 '1/60 SECOND
VAR BTN_DOWN = 0
VAR SCREEN_W = 400, SCREEN_H = 240
VAR SPRITE_W = 16, SPRITE_H = 16
VAR TILE_SIZE = 16
VAR BG_SKY = 639
VAR BG_GROUND = 610
VAR BG_W = SCREEN_W / TILE_SIZE 
VAR BG_H = SCREEN_H / TILE_SIZE
VAR CAT_ID = 856
VAR CAT_SPEED = 12 'METERS PER SECOND
VAR CAT_JUMP = -25 'JUMP POWER

'GLOBAL VARIABLES
VAR BTN 'BUTTON STATE
VAR CAT 'CAT SPRITE
VAR GAME_OVER = FALSE 'GAME LOOP EXIT FLAG
VAR MAY_JUMP = TRUE 'ALLOW JUMP
VAR I 'LOOP ITERATION
VAR X, Y, DX, DY, Y1, Y2 'POSITION
VAR T1, T2, DT 'TIME

SETUP_WORLD
SPCLR 'CLEAR ALL SPRITES
GENERATE_CAT OUT CAT, X, Y

T2 = MILLISEC 'SEED T2 FOR DELTA TIME CALC

WHILE GAME_OVER == FALSE
 'CALCULATE TIME BETWEEN FRAMES
 T1 = T2
 T2 = MILLISEC
 DT = MAX(MIN_TIME, T2 - T1)
 
 'RESET X SPEED
 DX = 0
 
 'READ BUTTON STATE
 BTN = BUTTON(BTN_DOWN)
 
 'HANDLE BUTTONS
 IF (BTN AND #LEFT) != 0 THEN
  DX = -1 * ((CAT_SPEED * DT * PIXELS_PER_METER) / MS_PER_SECOND)
 ENDIF
 
 IF (BTN AND #RIGHT) != 0 THEN
  DX = ((CAT_SPEED * DT * PIXELS_PER_METER) / MS_PER_SECOND)
 ENDIF
 
 IF (BTN AND #A) != 0 THEN
  IF DY == 0 AND MAY_JUMP THEN 'NOT FALLING OR JUMPING
   DY = CAT_JUMP
   MAY_JUMP = FALSE
  ENDIF
 ELSE
  MAY_JUMP = TRUE
 ENDIF
 
 IF (BTN AND #X) != 0 THEN
  GAME_OVER = TRUE
 ENDIF
 
 'UPDATE LOCATION
 X = MAX(0, MIN(SCREEN_W - SPRITE_W, X + DX))
 DY = DY + ((GRAVITY * DT * PIXELS_PER_METER) / MS_PER_SECOND)
 
 'DON'T WANT TO PASS THROUGH GROUND CHECK EACH PIXEL BECAUSE LAZY
 Y2 = MAX(0, MIN(SCREEN_H - SPRITE_H, Y + DY))
 IF DY >= 0 THEN
  FOR Y1 = Y TO Y2
   IF IS_ON_GROUND(X,Y1) THEN
    Y1 = Y1 - ((Y1 + 1) MOD TILE_SIZE)
    DY = 0
    BREAK
   ENDIF
  NEXT Y1
  Y = Y1
 ELSE
  Y = Y2
 ENDIF
 
 'UPDATE POINT TRAIL
 ADD_POINT X + SPRITE_W/2, Y + SPRITE_H / 2
 
 'UPDATE SCREEN
 'MOVE CAT
 SPOFS CAT, X, Y
 'DRAW POINT TRAIL
 GCLS
 FOR I = 0 TO POINT_COUNT - 2
  GLINE POINT_X[I], POINT_Y[I], POINT_X[I + 1], POINT_Y[I + 1], #WHITE
 NEXT I
 FOR I = 0 TO POINT_COUNT - 1
  GPSET POINT_X[I], POINT_Y[I], #BLACK
 NEXT I
 VSYNC
WEND
LOCATE 0, 1
PRINT "GOOD BYE"
COLOR #TWHITE, 0
END

DEF ADD_POINT X, Y
 VAR I
 
 IF POINT_COUNT < MAX_POINTS THEN
  POINT_X[POINT_COUNT] = X
  POINT_Y[POINT_COUNT] = Y
  POINT_COUNT = POINT_COUNT + 1
 ELSE
  FOR I = 0 TO MAX_POINTS - 2
   POINT_X[I] = POINT_X[I + 1]
   POINT_Y[I] = POINT_Y[I + 1]
  NEXT I
  POINT_X[MAX_POINTS - 1] = X
  POINT_Y[MAX_POINTS - 1] = Y
 ENDIF
END

DEF GENERATE_CAT OUT ID, X, Y
 SPSET CAT_ID OUT ID
 X = (SCREEN_W - SPRITE_W) / 2
 Y = 0
 SPOFS ID, X, Y
 SPSHOW ID
END

DEF IS_ON_GROUND(X, Y)
 VAR CELL_X = FLOOR((X + (SPRITE_W / 2)) / TILE_SIZE)
 VAR CELL_Y = FLOOR((Y + SPRITE_H + 1) / TILE_SIZE)
 VAR TILE = BGGET(0, CELL_X, CELL_Y)
 RETURN TILE == BG_GROUND
END

DEF SETUP_WORLD
 CLS
 GCLS
 GPRIO -255
 
 BGSCREEN 0, BG_W, BG_H
 BGFILL 0, 0, 0, BG_W - 1, BG_H - 2, BG_SKY
 BGFILL 0, 0, BG_H - 1, BG_W - 1, BG_H - 1, BG_GROUND
 BGFILL 0, BG_W / 2, BG_H / 2, (BG_W / 2) + 8, BG_H / 2, BG_GROUND
 
 LOCATE 0, 0
 COLOR #TWHITE, #TBLACK
 PRINT " JUMP    LEFT AND RIGHT    EXIT";
END