鱼C论坛

 找回密码
 立即注册
查看: 1838|回复: 5

[新人求助]pygame中以中心点进行旋转

[复制链接]
发表于 2022-3-23 22:18:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 zowen 于 2022-3-23 22:22 编辑

写了一个雷达的pygame,在做旋转效果的时候有一个扇形的图片要以图片中心点进行旋转(通过A和D控制旋转方向)
发现pygame.transform.rotate这个鬼东西是以一个看不到的点为中心旋转的,没办法,只好定义一个旋转前的中心坐标下x,y,在定义一个旋转后的中心坐标x1,y1,然后旋转完成求出差值(x-x1,y-y1),再把旋转后的图片移回   图片位置.move(x-x1,y-y1)
还是没有解决预期的两个问题
问题1:
怎么还是偏移
问题2:
像素丢失的厉害

#设置初始旋转角度变量
speed=0

#导入视场角图片(fov)
png_fov = pygame.image.load('png_fov.png').convert_alpha()
png_change_fov = png_fov

#获得视场角(fov),扫描区域(zoon)的位置矩形
where_fov = png_fov.get_rect()
where_change_fov = where_fov

#获得初始中心坐标
center = png_change_fov.get_rect().center
x, y = x1, y1 = center


#主程序DEMO循环
while True:
        for event in pygame.event.get():

            #开始旋转
            if event.key == K_a or event.key == K_d:

               
                 if event.key == K_a:
                    speed+=1
                    
                    png_change_fov = pygame.transform.rotate(png_change_fov, speed)

                 if event.key == K_d:
                    speed+=1
                    
                    png_change_fov = pygame.transform.rotate(png_change_fov, -speed)
               
                 where_change_fov = png_change_fov.get_rect()
               

                 center_temp = png_change_fov.get_rect().center
                 x1, y1 = center_temp

                 move_temp=(int(x-x1), int(y-y1))

               
                 where_change_fov = where_change_fov.move(move_temp)
                 where_change_fov = png_change_fov.get_rect()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-3-23 22:49:29 | 显示全部楼层
move_temp=(int(x-x1), int(y-y1))               
where_change_fov = where_change_fov.move(move_temp)

这段命令没发生想要的效果,图像坐标没有移动回去~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-3-23 23:09:49 | 显示全部楼层
搞懂了~~~~~
用print打印每次变化的get_rect()拿坐标值发现

这pygame.transform.rotate鬼程序,比如一个正方形旋转40°以后,原来的正方形获取的位置矩形(长宽都是正方形的边长)不会发生45°角度倾斜,只是产生了一个新的旋转45°的图片
新的图片获取一个新的位置矩形,还是水平的没有倾斜,新的矩形的长和宽不再是原来正方形的边长,而是原来对角线的长度
换句话说也就是多次旋转新的图形会无限扩大获得的矩形位置,造成了像素的不断放大丢失

暂时想到的办法是如果旋转的经度是1°的话,做360张图片,对应不同的角度直接更新图片上去

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-3-23 23:37:27 | 显示全部楼层
解决方案
#导入原始'精灵'
png_fov = pygame.image.load('png_fov.png').convert_alpha()
#定义旋转后的'精灵'
png_change_fov = png_fov
where_fov = where_change_fov=png_fov.get_rect()

#定义初始角度angle
angle=0

#计算每次按键后的角度值angle,每次按键旋转1°
angle+=1

#以原'精灵'rect作为初始,每次按键后直接旋转对应的角度,避免了像素丢失
png_change_fov = pygame.transform.rotate(png_fov, angle)

#计算中心点偏移center_temp
center=png_fov.get.rect().center       #原始精灵中心点坐标center
center_change=png_change_fov.get.rect().center   #旋转后精灵中心点坐标center
center_temp=center-center_change

#移动旋转后的'精灵'中心点返回原始'精灵'中心点
where_change_fov=pygame.move(center_temp)

#更新'精灵'
screen.blit(png_change_fov, (where_change_fov))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-3-24 02:20:35 | 显示全部楼层
还是失败~改不动了~写的又臭又长~回头把这个搞明白了 继续学习把zoon封装成类  fov封装成zoon的子类 ~估计代码会好看很多吧

# demo.py
import pygame
import sys
#将pygame的所有常量名导入
from pygame.locals import *


#初始化 pygame
pygame.init()


#定义初始窗口大小,视场角旋转速度,背景颜色,移动位置
size = width, height = 720 , 480
bg = (0, 0, 0)



#设置旋转角度
angle_right = 0
angle_left = 0


#设置放大、缩小比率
ratio = 1.0


#创建demo指定大小的窗口、全屏状态
screen = pygame.display.set_mode(size, RESIZABLE)
fullscreen = not FULLSCREEN


#创建窗口标题
pygame.display.set_caption('监测覆盖范围——DEMO——PURPLERIVER.CE')


#导入视场角图片(fov),导入扫描区域图片(zoon),电子地图(map)
png_fov = pygame.image.load('png_fov.png').convert_alpha()
png_change_fov = png_fov

png_zoon = pygame.image.load('png_zoon.png').convert_alpha()
png_change_zoon = png_zoon

png_map = pygame.image.load('png_map.png').convert_alpha()
png_map = pygame.transform.scale(png_map,(720, 480))


#获得视场角(fov),扫描区域(zoon)的位置矩形
where_fov = png_fov.get_rect()
where_change_fov = where_fov

center = where_change_fov.center

x, y = x1, y1 = center
print('初始中心点坐标'+str(center)+str(where_change_fov))


where_zoon = png_zoon.get_rect()
where_change_zoon = where_zoon

move_x_fov, move_y_fov = where_change_fov.center
move_x_zoon, move_y_zoon = where_change_zoon.center





#主程序DEMO循环
while True:
      
    #定义退出事件(点击关闭或按下ESC键)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.KEYDOWN:
            #定义退出按键
            if event.key == K_ESCAPE:
                sys.exit()

            if event.key == K_RIGHT:
                move_x_fov += 20
                move_y_fov += 0
                move_x_zoon += 20
                move_y_zoon += 0
               

            if event.key == K_LEFT:
                move_x_fov -= 20
                move_y_fov -= 0
                move_x_zoon -= 20
                move_y_zoon += 0
              
               

            if event.key == K_UP:
                move_x_fov -= 0
                move_y_fov -= 20
                move_x_zoon -= 0
                move_y_zoon -= 20
               

            if event.key == K_DOWN:
                move_x_fov += 0
                move_y_fov += 20
                move_x_zoon += 0
                move_y_zoon += 20
              

            where_change_fov.center = (int(move_x_fov), int(move_y_fov ))
            where_change_zoon.center = (int(move_x_zoon), int(move_y_zoon))

            #print('位移后定位'+str(move_x_fov))
            


            
            #定义全屏按键
            if event.key == K_F11:
                fullscreen = not fullscreen
                if fullscreen:
                    screen = pygame.display.set_mode((1920, 1080), FULLSCREEN | HWSURFACE)
                    png_map = pygame.transform.scale(png_map,(int(1920), int(1080)))
                else:
                    screen = pygame.display.set_mode(size)


            #放大、缩小监测范围(“=”放大,“-”缩小,“空格”恢复原尺寸,left right up down 控制左右上下移动)
            if event.key == K_EQUALS or event.key == K_MINUS:
                if event.key == K_EQUALS:
                    ratio += 0.1

                if event.key == K_MINUS:
                    ratio -= 0.1                          
                    
                #变换后的监控范围像素值
                png_change_fov = pygame.transform.smoothscale(png_fov, (int(where_fov.width * ratio), int(where_fov.height * ratio)))
                png_change_zoon = pygame.transform.smoothscale(png_zoon, (int(where_zoon.width * ratio), int(where_zoon.height * ratio)))

                #获取最新的位置
                where_change_fov = png_change_fov.get_rect()
                where_change_zoon = png_change_zoon.get_rect()

                #定义视图中心点
                where_change_fov.center = move_x_fov, move_y_fov
                where_change_zoon.center = move_x_zoon, move_y_zoon

              

               



        
            #开始旋转
            if event.key == K_a or event.key == K_d:               
               
               
                if event.key == K_a:
                    

                    print('旋转前定位'+str(where_change_fov))
                    angle_left += 15                                      
                    png_angle_fov = pygame.transform.rotate(png_change_fov, (angle_left))
                    where_angle_fov = png_angle_fov.get_rect()
                          
                    center_change=where_angle_fov.center   #旋转后精灵中心点坐标center
                    center_temp=[int(x-x1), int(y-y1)]                    
                    where_change_fov=where_angle_fov.move(center_temp)   #移动旋转后的'精灵'中心点返回原始'精灵'中心点
                    print('旋转后定位'+str(where_change_fov))
                    

                if event.key == K_d:
                    
                    
                    print('旋转前定位'+str(where_change_fov.center))
                    angle_right -= 15                                    
                    png_angle_fov = pygame.transform.rotate(png_change_fov, (angle_right))
                    where_angle_fov = png_angle_fov.get_rect()

                    center_change=where_angle_fov.center   #旋转后精灵中心点坐标center
                    center_temp=[int(x-x1), int(y-y1)]                    
                    where_change_fov=where_angle_fov.move(center_temp)   #移动旋转后的'精灵'中心点返回原始'精灵'中心点                                                                                       
                    print('旋转后定位'+str(where_change_fov.center))

               
               


                #where_angle_fov = png_angle_fov.get_rect()
                #where_angle_fov.center = int(move_x_fov), int(move_y_fov )

                #where_change_fov.center = where_angle_fov.center
                #center_change = where_change_fov.center
                #x1, y1 = center_change

                #center_temp=[int(x-x1), int(y-y1)]               
                #where_change_fov = where_change_fov.move(center_temp)
               
                        

            
                     
        


        #定义调整窗口大小事件
        if event.type == VIDEORESIZE:
            size = event.size
            width, height = size
            screen = pygame.display.set_mode(size, RESIZABLE)
            png_map = pygame.transform.scale(png_map,(int(width), int(height)))
            

            #if event.type == pygame.VIDEORESIZE:
                #screen = pygame.display.set_mode((1920, 1080), FULLSCREEN | HWSURFACE)
               



    #填充背景
    screen.fill(bg)

    #更新图像(fov、zoon、map)区域
    screen.blit(png_map,(0,0))
    screen.blit(png_change_zoon, (where_change_zoon))
    screen.blit(png_change_fov, (where_change_fov))

    #screen.blit(png_map, (0, 0))

    #blit_alpha(png_zoon, png_fov, where_zoon, where_fov, 100)
   

    #更新界面
    pygame.display.flip()

    #动作延迟
    pygame.time.delay(10)
            











         

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-3 04:14:56 | 显示全部楼层
image = pygame.image.load('image.png').convert_alpha()
position = image.get_rect(center=(200, 200))
angle = angle_temp = 0

while True:
    angle_temp += 15
    angle = angle_temp
    image_temp = pygame.transform.rotate(image, angle)
    image_temp = image.get_rec(center = position.center)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-6 22:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表