gpt4 book ai didi

python - 子弹看起来不像是从牙龈口中出来的 Pygame

转载 作者:行者123 更新时间:2023-12-04 09:13:24 25 4
gpt4 key购买 nike

enter image description here我有一个问题,我的子弹看起来不像是从我的枪里出来的,而是从玩家 body 里出来的 VIDEO正如你在视频中看到的,它在其他地方开枪,或者它的枪在左侧也是一样的,它向上射击很好,但向下射击很糟糕VIDEO
***我想说的是如何让我的枪在我的鼠标位置准确旋转***
我试着把我的枪调到 120,但结果是一切都对右侧有效,而不是左侧VIDEO正如你所看到的,它只是小故障


def draw(self,drawX,drawY):

self.rect.topleft = (drawX,drawY)

# the guns hitbox

# rotatiing the gun
dx = self.look_at_pos[0] - self.rect.centerx
dy = self.look_at_pos[1] - self.rect.centery

angle = (190/math.pi) * math.atan2(-dy, dx)

gun_size = self.image.get_size()
pivot = (8, gun_size[1]//2)


blitRotate(window, self.image, self.rect.center, pivot, angle)

if((angle > 90 or angle < -90) and self.gunDirection != "left"):
self.gunDirection = "left"
self.image = pygame.transform.flip(self.image, False, True)
if((angle < 90 and angle > -90) and self.gunDirection != "right"):
self.gunDirection = "right"
self.image = pygame.transform.flip(self.image, False, True)





我的全枪类
 
class handgun():
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.rect = pygame.Rect(x,y,height,width)


# LOL THESE IS THE HAND
self.shootsright = pygame.image.load("hands.png")
self.image = self.shootsright
self.rect = self.image.get_rect(center = (self.x, self.y))
self.look_at_pos = (self.x, self.y)

self.isLookingAtPlayer = False
self.look_at_pos = (x,y)




self.hitbox = (self.x + -18, self.y, 46,60)


self.gunDirection = "right"
def draw(self,drawX,drawY):

self.rect.topleft = (drawX,drawY)

# the guns hitbox

# rotatiing the gun
dx = self.look_at_pos[0] - self.rect.centerx
dy = self.look_at_pos[1] - self.rect.centery

angle = (120/math.pi) * math.atan2(-dy, dx)

gun_size = self.image.get_size()
pivot = (8, gun_size[1]//2)


blitRotate(window, self.image, self.rect.center, pivot, angle)

if((angle > 90 or angle < -90) and self.gunDirection != "left"):
self.gunDirection = "left"
self.image = pygame.transform.flip(self.image, False, True)
if((angle < 90 and angle > -90) and self.gunDirection != "right"):
self.gunDirection = "right"
self.image = pygame.transform.flip(self.image, False, True)




def lookAt( self, coordinate ):

self.look_at_pos = coordinate



white = (255,255,255)
handgun1 = handgun(300,300,10,10,white)




how my images are blitted





```def blitRotate(surf, image, pos, originPos, angle):

# calcaulate the axis aligned bounding box of the rotated image
w, h = image.get_size()
sin_a, cos_a = math.sin(math.radians(angle)), math.cos(math.radians(angle))
min_x, min_y = min([0, sin_a*h, cos_a*w, sin_a*h + cos_a*w]), max([0, sin_a*w, -cos_a*h, sin_a*w - cos_a*h])

# calculate the translation of the pivot
pivot = pygame.math.Vector2(originPos[0], -originPos[1])
pivot_rotate = pivot.rotate(angle)
pivot_move = pivot_rotate - pivot

# calculate the upper left origin of the rotated image
origin = (pos[0] - originPos[0] + min_x - pivot_move[0], pos[1] - originPos[1] - min_y + pivot_move[1])

# get a rotated image
rotated_image = pygame.transform.rotate(image, angle)

# rotate and blit the image
surf.blit(rotated_image, origin)

我想我想说的是我怎样才能让我的枪完全在我的鼠标位置旋转而没有任何问题
我的完整代码 script

最佳答案

一种方法是计算枪尖移动通过的弧的椭圆是什么,相对于它的 x,y协调。使用它来创建一个“Lookup Table
查找表,当由 0→360° 索引时,对于给定的角度,它给出一对偏移量以添加到“ ARM ”原点位置。添加在一起的这个新点是枪尖的坐标。例如,假设枪在 30°,我们访问 end_of_gun_lookup[ 30 ] ,并返回 ( 12, -6 ) ,对应于“ ARM ” Sprite 位置和枪尖之间的差异。
检查您的代码,角度似乎从大约 -120 开始至 120 .显然,我们不能对查找表使用负索引,因此我们只需将所有内容移动 120 ,所以 end_of_gun_lookup[ 0 ]用于角度 -120 , end_of_gun_lookup[ 1 ]用于角度 -119 , 等等。
所以现在当你去初始定位子弹时,它应该被创建在“ ARM ”位图 origin , 加 end_of_gun_lookup[ 120 + round( angle ) ]但!我们如何创建该查找表?
一种方法是在位图旋转时以编程方式“跟随”枪尖。一旦找到枪尖,立即将该位置存储在已知角度的查找表中。
为了找到枪的尖端,我修改了“ ARM ”位图,在枪的末端有一个亮绿色的​​像素块 (3x3)。这可以是位图中尚未使用的任何颜色,但我选择了绿色 ( 8, 255, 0 ) .
gun with Super-green pixel
然后我们创建函数,在每次旋转期间,费力地在旋转位图的每个像素中寻找绿色像素。这很慢,而不是您在游戏过程中想要做的事情。
rotating arm
这是那个功能。 end_of_gun_lookup是最终的查找表。首先我们用“无值”填充它 None对于每个可能的角度。

# Create empty look-up point for green-pixel offsets
SUPA_GREEN = ( 8, 255, 0 )
end_of_gun_lookup = [ None ] * 360
findGreenPixels()只要能够找到像素位置,函数就会填充这个全局列表:
def findGreenPixels( origin, image, rotation_angle ):
global end_of_gun_lookup

result = None
# Bitmap offset
origin_x, origin_y = origin
# find the Super Green pixel at the end of the gun.
# very slow, and inefficient
width = image.get_rect().width
height = image.get_rect().height
for y in range( height ):
for x in range( width ):
pixel_colour = image.get_at( ( x, y ) )
if ( pixel_colour == SUPA_GREEN ):
#print( "GREEN AT %d -> %d,%d" % ( rotation_angle, x, y ) )
result = ( round( origin_x - x ), round( origin_y - y ) )
# results go from -120 -> 120, so offset
# before storing the point.
# Distance is relative to bitmap orgin too
end_of_gun_lookup[ round( rotation_angle ) + 120 ] = ( result )
if ( result != None ):
break
if ( result != None ):
break
return result
它基本上遍历每个像素,寻找绿色。如果找到,则填充查找表。我使用了一个 3x3 的像素块,因为在图像旋转过程中,像素会被着色和模糊,并且一块像素可以更好地保持完全相同的颜色。
在程序结束时,我们转储查找表:
pygame.quit()

### PRINT THE LOOKUP TABLE
end_of_gun_lookup = fillLookupHoles( end_of_gun_lookup )
print( "end_of_gun_lookup = "+ str( end_of_gun_lookup ) )
在我的测试过程中,无论我移动鼠标有多慢,有时表格中都会出现未定义的位置。虽然我只管理过一次完美的 table 。无论如何,我添加了一些使用中点线算法来估计单个缺失值位置的代码。这清理了这些漏洞。显然你不能在表的末端生成点,这些点保持为 None .也许代码需要处理这些,也许它们永远不会发生。
这给了我这样的结果:

end_of_gun_lookup = [(108, 160), (109, 162), (110, 163), (111, 163), (111, 163), (112, 164), (111, 166), (113, 167), (114, 168), (114, 170), (115, 171), (116, 173), (116, 174), (118, 175), (118, 177), (120, 177), (120, 178), (121, 180), (122, 182), (124, 183), (125, 185), (95, 181), (126, 188), (129, 189), (130, 191), (130, 193), (133, 196), (103, 194), (104, 197), (137, 199), (107, 201), (106, 199), (137, 197), (105, 196), (104, 194), (101, 193), (101, 191), (101, 189), (130, 183), (99, 186), (99, 184), (99, 183), (97, 182), (98, 180), (98, 178), (95, 179), (96, 177), (96, 175), (94, 174), (95, 172), (94, 171), (94, 170), (94, 170), (93, 168), (94, 166), (95, 165), (95, 164), (95, 163), (95, 162), (94, 161), (94, 160), (95, 159), (95, 158), (96, 157), (97, 156), (98, 155), (98, 154), (98, 155), (98, 154), (98, 152), (101, 151), (101, 151), (101, 150), (102, 150), (102, 149), (104, 148), (105, 148), (106, 148), (107, 146), (108, 147), (109, 146), (110, 146), (110, 146), (112, 146), (114, 145), (115, 145), (117, 144), (117, 144), (119, 145), (119, 144), (122, 145), (123, 144), (126, 146), (126, 146), (128, 145), (129, 145), (131, 146), (134, 145), (134, 145), (136, 147), (138, 147), (140, 147), (142, 147), (144, 148), (144, 148), (148, 149), (149, 150), (151, 150), (153, 150), (154, 152), (158, 151), (159, 152), (161, 153), (163, 153), (166, 154), (169, 156), (170, 156), (172, 158), (175, 158), (177, 159), (179, 160), (178, 159), (176, 157), (174, 156), (173, 154), (171, 154), (169, 152), (168, 149), (164, 149), (163, 149), (163, 147), (161, 146), (160, 144), (159, 143), (155, 142), (154, 141), (154, 141), (154, 140), (151, 138), (151, 138), (148, 138), (146, 137), (145, 136), (144, 135), (144, 134), (143, 134), (142, 133), (139, 133), (140, 132), (138, 132), (137, 131), (136, 131), (135, 130), (134, 130), (133, 129), (133, 129), (132, 130), (130, 130), (130, 129), (129, 129), (129, 129), (128, 129), (127, 128), (128, 129), (126, 129), (126, 129), (125, 129), (125, 130), (124, 130), (124, 130), (123, 131), (124, 131), (124, 132), (123, 132), (122, 132), (122, 134), (122, 134), (123, 134), (122, 134), (122, 135), (122, 136), (122, 137), (123, 139), (122, 139), (122, 140), (123, 140), (123, 142), (123, 142), (123, 143), (124, 145), (124, 146), (124, 147), (125, 147), (125, 149), (126, 151), (126, 151), (127, 153), (128, 154), (129, 156), (129, 157), (129, 158), (130, 159), (130, 160), (132, 163), (133, 165), (134, 165), (135, 167), (136, 169), (105, 169), (137, 172), (107, 174), (137, 172), (103, 171), (103, 169), (102, 167), (131, 163), (98, 165), (99, 162), (96, 160), (96, 159), (93, 159), (93, 157), (93, 155), (93, 154), (91, 152), (89, 153), (89, 151), (89, 149), (87, 147), (86, 146), (85, 146), (84, 145), (85, 143), (84, 143), (82, 142), (83, 140), (82, 139), (83, 139), (82, 139), (82, 137), (82, 136), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]


所有这些 None s 最后可能不会发生。至少不是通过鼠标旋转。
所以一旦定义了这个查找表,就可以将其合并到代码中,并将生成的代码删除(或注释掉)。
编辑:
所以添加 end_of_gun_lookup的定义上一步生成的查找表到你的源。然后修改 blitRotate()使用它。
def blitRotate(surf, image, pos, originPos, angle):

...

# use lookup table to find the end-of gun at this angle
x_origin, y_origin = origin
x_offset, y_offset = end_of_gun_lookup[ round( angle ) + 120 ]
final_pos = ( x_origin + x_offset, y_origin + y_offset )

# rotate and blit the image
surf.blit( rotated_image, final_pos )
引用代码:(对 nug.png 使用上面的静态位图)
import pygame
import random
import math

# Window size
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
WINDOW_SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
DARK_BLUE = ( 3, 5, 54)


# Create empty look-up point for green-pixel offsets
SUPA_GREEN = ( 8, 255, 0 )
end_of_gun_lookup = [ None ] * 360

def midpoint( point_a, point_b ):
""" Use the midpoint-line formula to return the point between
point_a and point_b """
mid_x = round( ( point_a[0] + point_b[0] ) / 2 )
mid_y = round( ( point_a[1] + point_b[1] ) / 2 )
return ( mid_x, mid_y )

def fillLookupHoles( coord_list ):
""" Find any gaps in the lookup table, by finding the mid-point line
pixel between the two points, giving an estimated position """
for i in range( 1, len ( coord_list )-1 ): # we can't fix end-points, ignore first & last
before = coord_list[ i-1 ]
after = coord_list[ i+1 ]
if ( coord_list[ i ] == None and before != None and after != None ):
coord_list[ i ] = midpoint( before, after )
print( "Filled hole at angle %d" % ( i - 120 ) )
return coord_list

def findGreenPixels( origin, image, rotation_angle ):
global end_of_gun_lookup

result = None
# Bitmap offset
origin_x, origin_y = origin
# find the Super Green pixel at the end of the gun.
# very slow, and inefficient
width = image.get_rect().width
height = image.get_rect().height
for y in range( height ):
for x in range( width ):
pixel_colour = image.get_at( ( x, y ) )
if ( pixel_colour == SUPA_GREEN ):
#print( "GREEN AT %d -> %d,%d" % ( rotation_angle, x, y ) )
result = ( round( origin_x - x ), round( origin_y - y ) )
# results go from -120 -> 120, so offset
# before storing the point.
# Distance is relative to bitmap orgin too
end_of_gun_lookup[ round( rotation_angle ) + 120 ] = ( result )
if ( result != None ):
break
if ( result != None ):
break
return result



def blitRotate(surf, image, pos, originPos, angle):

# calcaulate the axis aligned bounding box of the rotated image
w, h = image.get_size()
sin_a, cos_a = math.sin(math.radians(angle)), math.cos(math.radians(angle))
min_x, min_y = min([0, sin_a*h, cos_a*w, sin_a*h + cos_a*w]), max([0, sin_a*w, -cos_a*h, sin_a*w - cos_a*h])

# calculate the translation of the pivot
pivot = pygame.math.Vector2(originPos[0], -originPos[1])
pivot_rotate = pivot.rotate(angle)
pivot_move = pivot_rotate - pivot

# calculate the upper left origin of the rotated image
origin = (pos[0] - originPos[0] + min_x - pivot_move[0], pos[1] - originPos[1] - min_y + pivot_move[1])

# get a rotated image
rotated_image = pygame.transform.rotate(image, angle)

end_of_gun_coord = findGreenPixels( origin, rotated_image, angle )

# rotate and blit the image
surf.blit(rotated_image, origin)




class handgun():
def __init__(self,x,y,height,width,color):
self.x = x
self.y = y
self.height = height
self.width = width
self.color = color
self.rect = pygame.Rect(x,y,height,width)

# LOL THESE IS THE HAND
self.shootsright = pygame.image.load("nug.png")
self.image = self.shootsright
self.rect = self.image.get_rect(center = (self.x, self.y))
self.look_at_pos = (self.x, self.y)

self.isLookingAtPlayer = False
self.look_at_pos = (x,y)
self.hitbox = (self.x + -18, self.y, 46,60)

self.gunDirection = "right"

def draw(self,drawX,drawY):
self.rect.topleft = (drawX,drawY)

# the guns hitbox
# rotatiing the gun
dx = self.look_at_pos[0] - self.rect.centerx
dy = self.look_at_pos[1] - self.rect.centery

angle = (120/math.pi) * math.atan2(-dy, dx)
gun_size = self.image.get_size()
pivot = (8, gun_size[1]//2)

blitRotate(window, self.image, self.rect.center, pivot, angle)

if((angle > 90 or angle < -90) and self.gunDirection != "left"):
self.gunDirection = "left"
self.image = pygame.transform.flip(self.image, False, True)
if((angle < 90 and angle > -90) and self.gunDirection != "right"):
self.gunDirection = "right"
self.image = pygame.transform.flip(self.image, False, True)

def lookAt( self, coordinate ):
self.look_at_pos = coordinate




white = (255,255,255)
handgun1 = handgun(300,300,10,10,white)




### initialisation
pygame.init()
pygame.mixer.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), WINDOW_SURFACE )
pygame.display.set_caption("Track Path of Green")


### Main Loop
clock = pygame.time.Clock()
done = False
while not done:

# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
elif ( event.type == pygame.MOUSEBUTTONUP ):
# On mouse-click
pass

handgun1.direction = "right"

# gun rotation
mousex, mousey = pygame.mouse.get_pos()
if not handgun1.isLookingAtPlayer:
handgun1.lookAt((mousex, mousey))


# Update the window, but not more than 60fps
window.fill( DARK_BLUE )
handgun1.draw( 200, 200 )
pygame.display.flip()

# Clamp FPS
clock.tick_busy_loop(60)

pygame.quit()

### PRINT THE LOOKUP TABLE
end_of_gun_lookup = fillLookupHoles( end_of_gun_lookup )
print( "end_of_gun_lookup = "+ str( end_of_gun_lookup ) )

关于python - 子弹看起来不像是从牙龈口中出来的 Pygame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63311312/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com