Tuesday 4 December 2007

A simple physics engine

Using a bit of Pygame stuff I learned from a very useful turorial, I've managed to write a basic physics engine demo with a ball bouncing around the screen. This afternoon I extended this further to include a feature that lets you actually pick the ball up with the mouse and then throw it across the screen - and it goes at a realistic speed as well! The maths behind this was actually fairly simple to work out, as the engine doesn't currently have fiddly things like air resistance implemented. It currently has proper gravity, realistic bouncing (it loses a proportion of its vertical speed with each bounce) and friction on the floor (which is admittedly a bit buggy at the moment). I intend to develop this further and possibly attempt to produce a small basketball minigame as a challenge. But for now, here's the source code to the physics engine for those of you who are interested:

##################################################
#
# PyGame physics engine test
# Copyright David Barker 2007
#
##################################################

import sys, pygame

def main():
____pygame.init()

____# Set up the window, the background colour and the timer
____size = width, height = 600, 600
____black = 0,0,0
____clock = pygame.time.Clock()

____# Set up the screen
____screen = pygame.display.set_mode(size)
____pygame.display.set_caption("ExeSoft 2D physics engine test -- Copyright David Barker 2007")

____# Ball object and physics
____ball = pygame.image.load("Ball.png")
____ballrect = ball.get_rect()
____velocity = [10, 10]
____colliding = 0
____dragging = 0
____mousemoves = []

____# The mainloop
____while 1:
________# Pause - to avoid insanely high framerates
________clock.tick(60)
________# Process events
________for event in pygame.event.get():
____________# Quit
____________if event.type == pygame.QUIT:
________________return
____________# If the user clicks on the ball, start dragging it and get the mouse's position on the ball so it drags that point
____________elif event.type == pygame.MOUSEBUTTONDOWN:
________________pos = event.pos
________________if pos[0]>ballrect.left and pos[0]
ballrect.top and pos[1]height and colliding == 0:
________________# Must be travelling down at a reasonable speed to bounce!
________________if velocity[1]>5:
____________________velocity[1] = -int((velocity[1]/4)*3)
____________________colliding = 1
____________________if velocity[0]>0:
________________________velocity[0] = velocity[0]-1
____________________elif velocity[0]<0:>0:
________________________velocity[0] = velocity[0]-1
____________________if velocity[0]<0:>width:
________________velocity[0] = -(velocity[0])

________screen.fill((0,0,0))
________screen.blit(ball, ballrect)
________pygame.display.update(ballrect)
________pygame.display.update(oldrect)

if __name__ == "__main__":
____main()


You may have noticed that it requires a file named "Ball.png" to use as the ball image; you will need to put an image by that name in the same place as the physics engine file in order for it to run. The one I used is on the left.

You will also need Python and Pygame installed; you can get these from www.python.org and www.pygame.org respectively.


Anyway, that's all for now; I'll attempt to develop the code further and will post it if I make any new progress.

1 comment:

  1. Hey David, sounds awesome. I couldn't wait to toy with your demo. Unfortunately, the code is horribly mangled by HTML, with spans all over the place. Good luck with your endeavours.

    Anon

    ReplyDelete