我目前正在开展一个小项目。我期待创建一个基本的RPG来习惯Python 2.7.1中的类。我正在使用Pygame。我目前编写了一个基于点击的移动系统,并以玩家精灵为中心(固定在显示屏的中心)。希望模仿暗黑破坏神II系统。
可以在此WeTransfer链接中找到运行该程序的所有文件: Program Files
运动基础知识: 在主循环的每次迭代中,我运行下面的get_offset(字符,事件)函数,如果检测到MOUSEBUTTONDOWN事件,那么只有这样才能为我提供ax和y偏移量以及达到该函数所需的一些“步骤”。 destination(点击时鼠标位置下的地图区域)。
在每个循环中重复x和y偏移,直到玩家再次点击或“步数”下降到0,在这种情况下,偏移设置为0(玩家停止)。
get_offset函数如下:
def get_offset(character,event):
if event.type == MOUSEBUTTONDOWN:
print 'reset'
m_pos = pygame.mouse.get_pos() #mouse position tracker
variables.player_dest_pos = m_pos
speed = character.speed #player's speed
xp = (variables.screenWIDTH/2)
yp = (variables.screenHEIGHT/2)
#print xp,yp
xm = m_pos[0]-10 #adds offset to center player
ym = m_pos[1]-5
dx= xm-xp
dy= float(ym-yp)
dist = (dx**2+dy**2)**0.5 #get lenght to travel
#sets number of steps/loops needed to reach destination
steps = dist/speed #float
steps = int(dist)/speed #int
#calculates angle and sets quadrant
if dx == 0 or dy == 0:
angle_rad = 0
if dx == 0 and ym > yp:
xoffset = 0
yoffset = -speed
elif dx == 0 and ym < yp:
xoffset = 0
yoffset = speed
elif dy == 0 and xm > xp:
xoffset = 0
yoffset = -speed
elif dy == 0 and xm < xp:
xoffset = 0
yoffset = speed
else:
xoffset, yoffset = 0,0
elif xm > xp and ym > yp:
angle_rad = np.arctan((abs(dy)/abs(dx)))
xoffset = -np.cos(angle_rad)*speed
yoffset = -np.sin(angle_rad)*speed
elif xm < xp and ym > yp:
angle_rad = np.arctan((abs(dx)/abs(dy)))
xoffset = -np.cos(angle_rad)*speed
yoffset = -np.sin(angle_rad)*speed
elif xm < xp and ym < yp:
angle_rad = np.arctan((abs(dy)/abs(dx)))
xoffset = np.cos(angle_rad)*speed
yoffset = np.sin(angle_rad)*speed
else:# xm > xp and ym < yp:
angle_rad = np.arctan((abs(dx)/abs(dy)))
xoffset = -np.sin(angle_rad)*speed
yoffset = np.cos(angle_rad)*speed
#sets the values to global accessible in the 'variables' module
variables.xoffset = xoffset
variables.yoffset = yoffset
variables.offset_time = steps
然后我创建了一个具有以下移动方法的敌人精灵:
def move(self,event):#,mouse_pos, screen, background
if event.type == MOUSEBUTTONDOWN:
self.dest = (random.randint(0,600),random.randint(0,480))
if self.dest[0] > self.rect[0]:
variables.screen.blit(variables.background, self.rect, self.rect) #erases players by bliting bg
variables.move_speed = self.speed
self.move_EW() #moves player
variables.screen.blit(self.image, self.rect) #draws player
if self.dest[0] < self.rect[0]:
variables.screen.blit(variables.background, self.rect, self.rect) #erases players by bliting bg
variables.move_speed = -self.speed
self.move_EW() #moves player
variables.screen.blit(self.image, self.rect) #draws player
if self.dest[1] < self.rect[1]:
variables.screen.blit(variables.background, self.rect, self.rect) #erases players by bliting bg
variables.move_speed = -self.speed
self.move_NS() #moves player
variables.screen.blit(self.image, self.rect) #draws player
if self.dest[1] > self.rect[1]:
variables.screen.blit(variables.background, self.rect, self.rect) #erases players by bliting bg
variables.move_speed = self.speed
self.move_NS() #moves player
variables.screen.blit(self.image, self.rect) #draws player
def move_NS(self):
self.rect = self.rect.move(0, variables.move_speed)
if self.rect.top < 0:
self.rect.bottom = 480
if self.rect.bottom > 480:
self.rect.top = 0
# Check for Collisions
for obstacle in variables.building_list:
if pygame.sprite.collide_rect(self, obstacle):
#print 'collide'
self.rect = self.rect.move(0, -(variables.move_speed))
def move_EW(self):
self.rect = self.rect.move(variables.move_speed , 0)
if self.rect.right > 600:
self.rect.left = 0
if self.rect.left < 0:
self.rect.left = 600
# Check for Collisions
for obstacle in variables.building_list:
if pygame.sprite.collide_rect(self, obstacle):
#print 'collide'
self.rect = self.rect.move(-(variables.move_speed) , 0)
此精灵的移动基本上与其他任何东西无关。
然后我在group_offset(组,字符)函数中编码,该函数能够将get_offset偏移量添加到组中的任何精灵中,以使游戏中的任何精灵相对于玩家“移动”(因此适用)对于静态对象。)它还检查组中的任何元素是否使用局部变量test_rect与播放器冲突,如果发生冲突,则偏移量在两个方向上都设置为0。如果没有发生碰撞,则精灵移动偏移值。
def group_offset(group,character):
for sprite in group: #checks if sprite collide with character using test_rect
test_rect = Rect(sprite.rect)
if variables.offset_time > 0:
test_rect = test_rect.move(variables.xoffset,variables.yoffset)
if test_rect.colliderect(character.rect):
variables.xoffset, variables.yoffset = 0,0
#if no collision occurs moves the sprites in the group
if variables.xoffset != 0 and variables.yoffset != 0:
for sprite in group:
if variables.offset_time > 0:
sprite.rect = sprite.rect.move(variables.xoffset,variables.yoffset)
当我使用组偏移功能两次,一次用于我的建筑物,一次用于我的敌人时,我的问题就出现了。当我这样做时,我的英雄在看起来只有一个“步骤”之后停止移动。
第一次通话结束后一切正常,英雄一直移动到达目的地。
当我再次使用group_offset(variables.ennemi_list,hero)调用它时。 然后我的播放器在一步后停止。
我最初认为我的敌人精灵在检查与我的建筑物碰撞而不是我的玩家,但是正如你可以看到呼叫是与玩家(英雄)进行的,因此它应该只检测到碰撞并在我的时候停止运动玩家击中一个建筑物(从第一次通话开始)或敌人......
任何帮助都会有所帮助,因为我真的不知道为什么会发生这个错误。我试过评论很多东西,看起来问题似乎来自这行代码:group_offset(variables.ennemi_list,hero)。
这是我的带有游戏循环的main.py脚本:
导入pygame,sys,变量 来自pygame.locals import * 从类导入* 来自实例导入* 来自函数import *
#game loop
while True:
variables.screen.fill((0,0,0)) #make background black for map edges
for event in pygame.event.get(): #setting up quit
if event.type == QUIT:
pygame.quit()
sys.exit()
get_offset(hero,event) # sets the movement offset for the iteration
for o in variables.char_list:
if isinstance(o, Character): #moves characters
o.move(event)
if isinstance(o, Ennemi): #performs attack when enemmi is clicked and in contact
if pygame.sprite.collide_rect(o,hero) == True:
hero.attack(sword,o)
group_offset(variables.building_list,hero) #new building position using offset
scroll_map.offset() #offsets grass background map
variables.screen.blit(scroll_map.image, scroll_map.rect) # blits the grass map to new pos
variables.building_list.draw(variables.screen) #blits the buildings to new pos
variables.screen.blit(hero.image, hero.rect) #blits hero to screen center
#group_offset(variables.ennemi_list,hero)
for o in variables.ennemi_list:
variables.screen.blit(o.image, o.rect)
pygame.display.update()
pygame.time.delay(10)
variables.offset_time -= 1 #removes on step from the offset counter to keep track of when
#offset needs to be reset to 0, i.e. position is reached