Bouncing An Image In A Polygonal Way With Pygame
Hey guys am new to pygame .I have to make a ball image ball.jpg to bounce in polygonal way.I have also an another ball image which is running in a square way.What i need is to add
Solution 1:
You'll need some vector math to do this.
Create a list of points that describe the path the object should move, then calculate a vector describing the direction from the current position to the target position. Then move the object by using that vector. Once you hit your target, aim for the next point to move.
Here's an example:
import pygame
import math
from itertools import cycle
# some simple vector helper functions, stolen from http://stackoverflow.com/a/4114962/142637defmagnitude(v):
return math.sqrt(sum(v[i]*v[i] for i inrange(len(v))))
defadd(u, v):
return [ u[i]+v[i] for i inrange(len(u)) ]
defsub(u, v):
return [ u[i]-v[i] for i inrange(len(u)) ]
defdot(u, v):
returnsum(u[i]*v[i] for i inrange(len(u)))
defnormalize(v):
vmag = magnitude(v)
return [ v[i]/vmag for i inrange(len(v)) ]
screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
classBall(object):
def__init__(self, path):
self.x, self.y = (0, 0)
self.speed = 2.5
self.color = (200, 200, 200)
self.path = cycle(path)
self.set_target(next(self.path))
@propertydefpos(self):
return self.x, self.y
# for drawing, we need the position as tuple of ints# so lets create a helper property @propertydefint_pos(self):
returnmap(int, self.pos)
@propertydeftarget(self):
return self.t_x, self.t_y
@propertydefint_target(self):
returnmap(int, self.target)
defnext_target(self):
self.set_target(self.pos)
self.set_target(next(self.path))
defset_target(self, pos):
self.t_x, self.t_y = pos
defupdate(self):
# if we won't move, don't calculate new vectorsif self.int_pos == self.int_target:
return self.next_target()
target_vector = sub(self.target, self.pos)
# a threshold to stop moving if the distance is to small.# it prevents a 'flickering' between two pointsif magnitude(target_vector) < 2:
return self.next_target()
# apply the balls's speed to the vector
move_vector = [c * self.speed for c in normalize(target_vector)]
# update position
self.x, self.y = add(self.pos, move_vector)
defdraw(self):
pygame.draw.circle(screen, self.color, self.int_pos, 4)
pygame.init()
quit = False
path = [(26, 43),
(105, 110),
(45, 225),
(145, 295),
(266, 211),
(178, 134),
(250, 56),
(147, 12)]
path2 = [(26, 43),
(105, 10),
(45, 125),
(150, 134),
(150, 26),
(107, 12)]
ball = Ball(path)
ball.speed = 1.9
ball2 = Ball(path2)
ball2.color = (200, 200, 0)
balls = [ball, ball2]
whilenot quit:
quit = pygame.event.get(pygame.QUIT)
pygame.event.poll()
map(Ball.update, balls)
screen.fill((0, 0, 0))
map(Ball.draw, balls)
pygame.display.flip()
clock.tick(60)
Here's an example without a custom class:
import pygame
import math
from itertools import cycle
# some simple vector helper functions, stolen from http://stackoverflow.com/a/4114962/142637
def magnitude(v):
return math.sqrt(sum(v[i]*v[i] for i in range(len(v))))
def sub(u, v):
return [ u[i]-v[i] for i in range(len(u)) ]
def normalize(v):
vmag = magnitude(v)
return [ v[i]/vmag for i in range(len(v)) ]
screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
pygame.init()
quit = False
path = [(26, 43),
(105, 110),
(45, 225),
(145, 295),
(266, 211),
(178, 134),
(250, 56),
(147, 12)]
path = cycle(path)
target = next(path)
ball = pygame.rect.Rect(target[0], target[1], 10, 10)
speed = 3.6
while not quit:
quit = pygame.event.get(pygame.QUIT)
pygame.event.poll()
if ball.topleft == target:
target = next(path)
target_vector = sub(target, ball.topleft)
if magnitude(target_vector) < 2:
target = next(path)
else:
move_vector = [c * speed for c in normalize(target_vector)]
ball.move_ip(move_vector)
screen.fill((0, 0, 0))
pygame.draw.rect(screen, pygame.color.Color('Grey'), ball)
pygame.display.flip()
clock.tick(60)
Post a Comment for "Bouncing An Image In A Polygonal Way With Pygame"