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/142637
def magnitude(v):
return math.sqrt(sum(v[i]*v[i] for i in range(len(v))))
def add(u, v):
return [ u[i]+v[i] for i in range(len(u)) ]
def sub(u, v):
return [ u[i]-v[i] for i in range(len(u)) ]
def dot(u, v):
return sum(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()
class Ball(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))
@property
def pos(self):
return self.x, self.y
# for drawing, we need the position as tuple of ints
# so lets create a helper property
@property
def int_pos(self):
return map(int, self.pos)
@property
def target(self):
return self.t_x, self.t_y
@property
def int_target(self):
return map(int, self.target)
def next_target(self):
self.set_target(self.pos)
self.set_target(next(self.path))
def set_target(self, pos):
self.t_x, self.t_y = pos
def update(self):
# if we won't move, don't calculate new vectors
if 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 points
if 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)
def draw(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]
while not 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"