Note that there are some explanatory texts on larger screens.

plurals
  1. POSimple 2D gravity with pygame; Value Guidelines?
    text
    copied!<p>I am trying to simulate gravity in a simple 2D window using pygame. It's very simple stuff (a dot rising and falling again) and I understand the mechanics, i.e. speed as a vector and the y portion being consistently diminished by a value g representing gravity during each run through the mainloop and the subsequent update of the position of the dot. <br> <br> It's all working fine, but I am having trouble choosing the correct values to be inserted. It is all trial and error at the moment. <strong>Is there a good rule of thumb on how to determine which numbers to use, to achieve a semi-realistic looking trajectory?</strong></p> <p>I inserted a minimal example below, with the following values important to my question:</p> <pre><code>window = (640, 480) # pixels initial_speed = 20 # pixels per update along the y axis gravity = 0.4 # deduction on initial_speed per update </code></pre> <p>Now, why do these numbers happen to make the illusion work? I tried first to use formulae I learnt in physics class years and years ago, but, with or without unit conversions, the simulation was just not right. Most of the time, I didn't even see the ball, yet the above values, found through trial and error work.</p> <p>Thanks for all your help in advance. If you need more information, just post a comment and I will try to oblige.</p> <p>Here is the minimal example. Note the vector2D library was conveniently borrowed from the pygame website (<a href="http://www.pygame.org/wiki/2DVectorClass" rel="nofollow">follow this link</a>)</p> <pre><code>#!/usr/bin/env python import pygame from pygame.locals import * from vector2D import Vec2d pygame.init() GRAVITY = 0.4 class Dot(pygame.sprite.Sprite): def __init__(self, screen, img_file, init_position, init_direction, speed): pygame.sprite.Sprite.__init__(self) self.screen = screen self.speed = Vec2d(speed) self.base_image = pygame.image.load(img_file).convert_alpha() self.image = self.base_image # A vector specifying the Dot's position on the screen self.pos = Vec2d(init_position) # The direction is a normalized vector self.direction = Vec2d(init_direction).normalized() def blitme(self): """ Blit the Dot onto the screen that was provided in the constructor. """ self.screen.blit(self.image, self.pos) def update(self): self.speed.y -= GRAVITY displacement = Vec2d( self.direction.x * self.speed.x, self.direction.y * self.speed.y ) self.pos += displacement def main(): DIMENSION = SCREEN_WIDTH, SCREEN_HEIGHT = 640, 480 BG_COLOUR = 0,0,0 # Creating the screen window = screen = pygame.display.set_mode( (SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32) screen = pygame.display.get_surface() clock = pygame.time.Clock() dot = Dot(screen, "my/path/to/dot.jpg", (180, SCREEN_HEIGHT), (0, -1), (0, 20)) mainloop = True while mainloop: # Limit frame speed to 50 FPS time_passed = clock.tick(50) for event in pygame.event.get(): if event.type == pygame.QUIT: mainloop = False # Redraw the background screen.fill(BG_COLOUR) dot.update() dot.blitme() pygame.display.flip() if __name__ == '__main__': main() </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload