All pastes #1064424 Raw Edit

bouncing ball

public python v1 · immutable
#1064424 ·published 2008-07-07 07:32 UTC
rendered paste body
#!/usr/bin/python import gtk, gobject, cairo, wnck, math class Ball:	def __init__ (self):		self.window = gtk.Window()		self.window.set_app_paintable(True)		self.window.set_border_width(80)		self.window.set_decorated(False)		self.alpha_screen_changed(self.window) 		self.window.set_events(gtk.gdk.ALL_EVENTS_MASK)		self.window.connect("button-press-event", self.button_press)		self.window.connect("expose-event", self.expose)		self.window.connect("focus-in-event", self.focus_in) 		self.moving = False					# true when the ball is in motion and is NOT being dragged		self.dragged = False				# true when the ball is being dragged by the user		self.x = 0							# x position		self.y = 0							# y position		self.width = 0						# width (used to check if we hit a wall)		self.height = 0						# height (used to check if we hit a wall)		self.vx = 0							# velocity along the x axis		self.vy = 0							# velocity along the y axis 		self.gravity = 1.5					# gravity		self.friction = 0.95				# friction along the bottom screen edge		self.motion_time = 10				# time in milliseconds for motion timeout		self.drag_time = 10					# time in milliseconds for drag timeout 		self.screen = wnck.screen_get_default()		self.max_x = self.screen.get_width()		self.max_y = self.screen.get_height() 		self.window.show_all() 	def move (self):		"""Timeout called when the ball is in motion."""		if not self.moving:			print "Returning False... Stop moving."			return False		if self.y < self.max_y:			self.vy += self.gravity		self.x += self.vx # calculate new x position		self.y += self.vy # calculate new y position		print self.vy,self.y+self.height, self.max_y		# right screen edge		if self.x + self.width > self.max_x:			self.vx *= -0.8			self.x = self.max_x - self.width		# left screen edge		elif self.x < 0:			self.vx *= -0.8			self.x = 0		# bottom screen edge		if self.y + self.height > self.max_y:			self.vy *= -0.8			self.y = self.max_y - self.height		# top screen edge		elif self.y < 0:			self.vy *= -0.8			self.y = 0		# if the x velocity is too small just make it 0		if abs(self.vx) < 1:			self.vx = 0		# if the y velocity is too small just make it 0		if abs(self.vy) < 1:			self.vy = 0		# if there's no movement in any direction stop moving		if self.y + self.height == self.max_y and self.vy == 0:			self.vx *= self.friction			if self.vx == 0:				self.moving = False # the timeout will automatically cancel itself		# finally, move		self.window.move(int(self.x), int(self.y)) # move to the new location		return True 	def update_speed (self):		"""Timeout called when the ball is being dragged."""		# handle change in x direction		pass 	# gtk handlers 	def button_press (self, widget, event):		print "button press event"		# drag the window		if event.button == 1:			self.moving = False # stop bouncing (the timeout will automatically cancel itself)			self.dragged = True			self.begin_x, self.begin_y = self.window.get_position()			self.begin_time_x = self.begin_time_y = gobject.get_current_time()			self.window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)			self.update_speed_timeout = gobject.timeout_add(self.drag_time, self.update_speed) 	def expose (self, widget, event):		print "expose event"		self.width = widget.allocation.width		self.height = widget.allocation.height 		ctx = widget.window.cairo_create() 		ctx.save()		ctx.set_source_rgba(1, 1, 1, 0)		ctx.set_operator (cairo.OPERATOR_SOURCE)		ctx.paint()		ctx.restore() 		ctx.save()		ctx.arc(self.width/2, self.height/2, min(self.height, self.width)/2, 0, 2*math.pi) 		#color = gtk.gdk.color_parse("red")			#ctx.set_source_rgba(color.red, color.green, color.blue, 0.8)		pattern = cairo.LinearGradient(0.0, 0.0, 0.0, self.height)		pattern.add_color_stop_rgb(1.0, 1.0, 1.0, 1.0)		pattern.add_color_stop_rgb(0.0, 0.0, 0.0, 0.0)		ctx.set_source(pattern)		ctx.fill()		ctx.restore 	def focus_in (self, widget, event):		"""Callback for focus event. This gets called when a drag ends."""		if self.dragged:			# set attributes			self.dragged = False			self.moving = True			# get the current time and position			now = gobject.get_current_time()			self.x, self.y = self.window.get_position()			# calculate the velocity along the x and y axis			self.vx = (self.x - self.begin_x) / ((now - self.begin_time_x) * 100)			self.vy = (self.y - self.begin_y) / ((now - self.begin_time_y) * 100)			# start the timeout function			self.move_timeout = gobject.timeout_add(self.motion_time, self.move) 	def alpha_screen_changed (self, widget, screen=None):		"""set colormap for window"""		if screen is None:			screen = widget.get_screen()		map = screen.get_rgba_colormap()		if map is None:			map = screen.get_rgb_colormap()		widget.set_colormap(map)if __name__ == "__main__":	app = Ball()	gtk.main()