【发布时间】:2016-09-29 09:34:18
【问题描述】:
我有一个代表我的角色的精灵。这个精灵根据我的鼠标位置旋转每一帧,这反过来又使我的矩形根据鼠标的位置变得越来越小。
基本上我想要做的是让我的精灵 (Character) 不会进入精灵墙。现在,由于墙壁的矩形更大,所以实际图片看起来并且我的矩形根据我的鼠标位置不断增长和缩小,这让我不知道如何做出一个声明来阻止我的精灵以令人信服的方式移动到墙壁中.
我已经确定我的 ColideList 只是应该与之碰撞的块。我找到了Detecting collision of two sprites that can rotate,但它是在 Java 中的,我不需要检查两个旋转精灵之间的碰撞,而是一个和一堵墙。
我的 Character 类如下所示:
class Character(pygame.sprite.Sprite):
walking_frame = []
Max_Hp = 100
Current_HP = 100
Alive = True
X_Speed = 0
Y_Speed = 0
Loc_x = 370
Loc_y = 430
size = 15
Current_Weapon = Weapon()
Angle = 0
reloading = False
shot = False
LastFrame = 0
TimeBetweenFrames = 0.05
frame = 0
Walking = False
Blocked = 0
rel_path = "Sprite Images/All.png"
image_file = os.path.join(script_dir, rel_path)
sprite_sheet = SpriteSheet(image_file) #temp
image = sprite_sheet.get_image(0, 0, 48, 48) #Temp
image = pygame.transform.scale(image, (60, 60))
orgimage = image
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.walking_frame.append(self.image)
image = self.sprite_sheet.get_image(48, 0, 48, 48)
self.walking_frame.append(image)
image = self.sprite_sheet.get_image(96, 0, 48, 48)
self.walking_frame.append(image)
image = self.sprite_sheet.get_image(144, 0, 48, 48)
self.walking_frame.append(image)
image = self.sprite_sheet.get_image(0, 48, 48, 48)
self.walking_frame.append(image)
image = self.sprite_sheet.get_image(48, 48, 48, 48)
self.walking_frame.append(image)
image = self.sprite_sheet.get_image(96, 48, 48, 48)
self.walking_frame.append(image)
image = self.sprite_sheet.get_image(144, 48, 48, 48)
self.walking_frame.append(image)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = [self.Loc_x,self.Loc_y]
print "Shabat Shalom"
def Shoot(self):
if self.Alive:
if(self.reloading == False):
if(self.Current_Weapon.Clip_Ammo > 0):
bullet = Bullet(My_Man)
bullet_list.add(bullet)
self.Current_Weapon.Clip_Ammo -= 1
def move(self):
if self.Alive:
self.Animation()
self.Loc_x += self.X_Speed
self.Loc_y += self.Y_Speed
Wall_hit_List = pygame.sprite.spritecollide(My_Man, CollideList, False)
self.Blocked = 0
for wall in Wall_hit_List:
if self.rect.right <= wall.rect.left and self.rect.right >= wall.rect.right:
self.Blocked = 1 #right
self.X_Speed= 0
elif self.rect.left <= wall.rect.right and self.rect.left >= wall.rect.left:
self.Blocked = 3 #Left
self.X_Speed = 0
elif self.rect.top <= wall.rect.bottom and self.rect.top >= wall.rect.top:
self.Blocked = 2 #Up
self.Y_Speed = 0
elif self.rect.top >= wall.rect.bottom and self.rect.top <= wall.rect.top:
self.Blocked = 4 #Down
self.Y_Speed = 0
self.image = pygame.transform.rotate(self.orgimage, self.Angle)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = [self.Loc_x, self.Loc_y]
def Animation(self):
# #Character Walk Animation
if self.X_Speed != 0 or self.Y_Speed != 0:
if(self.Walking == False):
self.LastFrame = time.clock()
self.Walking = True
if (self.frame < len(self.walking_frame)):
self.image = self.walking_frame[self.frame]
self.image = pygame.transform.scale(self.image, (60, 60))
self.orgimage = self.image
self.frame += 1
else:
self.frame = 0
else:
if self.frame != 0:
self.frame = 0
self.image = self.walking_frame[self.frame]
self.image = pygame.transform.scale(self.image, (60, 60))
self.orgimage = self.image
if self.Walking and time.clock() - self.LastFrame > self.TimeBetweenFrames:
self.Walking = False
def CalAngle(self,X,Y):
angle = math.atan2(self.Loc_x - X, self.Loc_y - Y)
self.Angle = math.degrees(angle) + 180
我的 Wall 类如下所示:
class Wall(pygame.sprite.Sprite):
def __init__(self, PosX, PosY, image_file, ImageX,ImageY):
pygame.sprite.Sprite.__init__(self)
self.sprite_sheet = SpriteSheet(image_file)
self.image = self.sprite_sheet.get_image(ImageX, ImageY, 64, 64)
self.image = pygame.transform.scale(self.image, (32, 32))
self.image.set_colorkey(Black)
self.rect = self.image.get_rect()
self.rect.x = PosX
self.rect.y = PosY
我的 BuildWall 函数如下所示:
def BuildWall(NumberOfBlocks,TypeBlock,Direction,X,Y,Collide):
for i in range(NumberOfBlocks):
if Direction == 1:
wall = Wall(X + (i * 32), Y, spriteList, 0, TypeBlock)
wall_list.add(wall)
if Direction == 2:
wall = Wall(X - (i * 32), Y, spriteList, 0, TypeBlock)
wall_list.add(wall)
if Direction == 3:
wall = Wall(X, Y + (i * 32), spriteList, 0, TypeBlock)
wall_list.add(wall)
if Direction == 4:
wall = Wall(X, Y - (i * 32), spriteList, 0, TypeBlock)
wall_list.add(wall)
if(Collide):
CollideList.add(wall)
最后我的步行活动是这样的:
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE: #Press escape also leaves game
Game = False
elif event.key == pygame.K_w and My_Man.Blocked != 2:
My_Man.Y_Speed = -3
elif event.key == pygame.K_s and My_Man.Blocked != 4:
My_Man.Y_Speed = 3
elif event.key == pygame.K_a and My_Man.Blocked != 3:
My_Man.X_Speed = -3
elif event.key == pygame.K_d and My_Man.Blocked != 1:
My_Man.X_Speed = 3
elif event.key == pygame.K_r and (My_Man.reloading == False):
lastReloadTime = time.clock()
My_Man.reloading = True
if (My_Man.Current_Weapon.Name == "Pistol"):
My_Man.Current_Weapon.Clip_Ammo = My_Man.Current_Weapon.Max_Clip_Ammo
else:
My_Man.Current_Weapon.Clip_Ammo, My_Man.Current_Weapon.Max_Ammo = Reload(My_Man.Current_Weapon.Max_Ammo,My_Man.Current_Weapon.Clip_Ammo,My_Man.Current_Weapon.Max_Clip_Ammo)
elif event.type == pygame.KEYUP:
if event.key == pygame.K_w:
My_Man.Y_Speed = 0
elif event.key == pygame.K_s:
My_Man.Y_Speed = 0
elif event.key == pygame.K_a:
My_Man.X_Speed = 0
elif event.key == pygame.K_d:
My_Man.X_Speed = 0
【问题讨论】:
-
我曾经遇到过类似的问题,并决定不旋转播放器精灵,而是为不同的朝向设置 8 张不同的图像。不确定这是否适用于您的游戏,但它可能是一个很好的最后解决方案。
-
@CharltonLane 我真的希望它能够跟随光标,这样我就可以以最直接的方式向光标射击。我决定,如果 StackOverFlow 不能帮助我,我可能会忽略墙壁并使其成为一个开放区域。但我还是有信心的
标签: python python-2.7 pygame sprite