0

I am trying to:

  1. draw a circle onto my window
  2. let it move AND rotate at the same time to simulate a rolling ball.

Appreciate anyone's solutions! Attached below is my code.

import pygame

#create win
W, H = 700, 700
win = pygame.display.set_mode((W, H))
pygame.display.set_caption("Rotating Ball Simul")

#color lib
BG = (20,20,20)
BLUE = (0,0,255)

#draw circle
ballX, ballY = 0, 0
ballW = 20
ballH = ballW

ball = pygame.draw.circle(win, BLUE, (ballX, ballY), ballW, 1)

def redraw_window():
  win.fill(BG)
  win.blit(ball, (ballX, ballY))
  pygame.display.update()

def main():
  
  run = True
  while run:
    for event in pygame.event.get():
      if event.type == pygame.QUIT:
        run = False

    redraw_window()

if __name__ == '__main__':
  main()
mojishi
  • 13
  • 3
  • 2
    How do you want to let visibly rotate a uniformly colored circle? It'x when of a circle's characteristics that a rotated circle is always exactly the same as the unrotated version. You should have an image to rotate. – The_spider May 18 '22 at 11:41

1 Answers1

0

A circle always looks the same when you rotate it. You must use a sphere image to see the rotation. Read about How do I rotate an image around its center using PyGame? and move the ball image and change the rotation of the image depending on the movement. The angle of rotation depends on the movement and the diameter of the ball:

angle -= (self.x - prev_x) / self.diameter * 180 / math.pi
self.image = pygame.transform.rotate(self.original_image, self.angle)
self.rect = self.image.get_rect(center = self.rect.center)

Minimal example:

repl.it/@Rabbid76/PyGame-FollowInGrid

import os
import math
import pygame

class MarbelSprite(pygame.sprite.Sprite):
    def __init__(self, x, ground, diameter, velocity, filename):
        pygame.sprite.Sprite.__init__(self)
        try:
            self.image = pygame.transform.smoothscale(pygame.image.load(filename).convert_alpha(), (diameter, diameter))
        except:     
            self.image = pygame.Surface((diameter, diameter), pygame.SRCALPHA)
            pygame.draw.circle(self.image, (255, 128, 0), (diameter // 2, diameter // 2), diameter // 2)
        self.original_image = self.image
        self.rect = self.image.get_rect(midbottom = (x, ground))
        self.diameter = diameter
        self.x = x
        self.velocity = velocity
        self.move_x = 0
        self.follow = None
        self.angle = 0
        
    def update(self, time, restriction):
        move_x = 0
        prev_x = self.x
        if self.move_x != 0:
            move_x = self.move_x * self.velocity * time
        elif self.follow:
            dx = self.follow.rect.centerx - self.x
            move_x = (-1 if dx < 0 else 1) * min(self.velocity * time, abs(dx))
        self.x += move_x
        self.x = max(restriction.left + self.diameter // 2, min(restriction.right - self.diameter // 2, self.x))
        self.rect.centerx = round(self.x)
        self.angle -= (self.x - prev_x) / self.diameter * 180 / math.pi
        self.image = pygame.transform.rotate(self.original_image, self.angle)
        self.rect = self.image.get_rect(center = self.rect.center)

pygame.init()
window = pygame.display.set_mode((500, 300))
clock = pygame.time.Clock()

ground_level = 220
object = MarbelSprite(window.get_rect().centerx, ground_level, 100, 0.4, 'BaskteBall.png')
follower = MarbelSprite(window.get_width() // 4, ground_level, 50, 0.2, 'TennisBall.png')
all_sprites = pygame.sprite.Group([object, follower])

run = True
while run:
    time = clock.tick(60)
    for events in pygame.event.get():
        if events.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()
    object.move_x = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]
    follower.follow = object
    all_sprites.update(time, window.get_rect())

    window.fill((32, 64, 224))
    pygame.draw.rect(window, (80, 64, 64), (0, ground_level, window.get_width(), window.get_height()-ground_level))
    all_sprites.draw(window)
    pygame.display.flip()

pygame.quit()
exit()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174