如何在移动时将圆绘制到表面上并旋转?

发布于 2025-01-30 05:08:26 字数 711 浏览 1 评论 0原文

我正在尝试:

  1. 在我的窗户上画一个圆圈
  2. ,让它同时移动并旋转以模拟滚球。

感谢任何人的解决方案!下面是我的代码。

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()

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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一曲琵琶半遮面シ 2025-02-06 05:08:26

旋转时,一个圆总是看起来一样。您必须使用球体图像来查看旋转。阅读有关我如何旋转使用Pygame周围的图像?并移动球图像并根据运动的不同而更改图像的旋转。旋转角度取决于球的运动和直径:

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)

最小示例:

”“” 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()

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文