Я пытаюсь заставить свою программу определить расстояние между несколькими разными спрайтами и перейти к ближайшему, но она этого не делает, вместо этого она выбирает фиксированный, и все они перестают двигаться после того, как один из них съел спрайт вместо этого они следует пойти за новым ближайшим, если они все еще голодны.
if len(preys) > 0:
for wolf in Wolf_group:
for rabbits in Rabbit_group:
preysX,preysY=wolf.findClosestPrey(self,rabbit.x,rabbit.y)
movementx, movementy = Track(wolf.x, preysX, wolf.y, preysY)#how the predators move
wolf.move(movementx,movementy)#movementx, #movementy)
функция
def findClosestPrey(self,preyX,preyY):
tempdist=math.sqrt((self.x-preyX)**2 + (self.y-preyX)**2)
if tempDist<dist:
xpos=preyX
ypos=preyX
return xpos, ypos
Я не уверен, почему он это делает, так как все должно быть хорошо
полный код:
#simulates interactions of wild life
import math
import random
import pygame,sys
import random
import pdb
import time
from pygame.locals import *
pygame.init()#setsup pygame
screen = pygame.display.set_mode((1000,800))#setsup screen size
clock = pygame.time.Clock()#tells program how fast to update
timmer = 1#how long program has gone on for
#colours
grey=(60,60,60)
dark_grey=(20,20,20)
dark_blue=(0,0,160)
black=(0,0,0)
#classes-------------------------------------------------------------------
class Animal(pygame.sprite.Sprite):#main class
def __init__(self, image, x, y):
super().__init__()
self.x = x #min(max(0, self.x), screen_width)
self.y = x #min(max(0, self.y), screen_height)
self.image = image
self.rect = self.image.get_rect(center = (x, y))
self.Energy=10
def move(self, mx, my):#moves the sprite
self.x += mx
self.y += my
self.rect = self.image.get_rect(center = (self.x, self.y))#sets the image to the position
def is_collided_with(self, sprite):#is the eat function
return self.rect.colliderect(sprite.rect)
def checkEnergy(self):#checks the energy of an animal
EnergyVal=self.energy
return EnergyVal
def starve(self,sprite):# kills of sprite if energy hits bottom.
if self.energy<=0:
sprite.kill()
else:
self.energy-=1
print("starving")
self.starvetimmer=0
class Predator(Animal):#class for predators
def __init__(self,image, x, y):
super().__init__(image, x, y)
self.energy=9
self.starvetimmer=0
self.dist=1000
def reproduce(self):
if self.energy >= 15:
predator = Predator(self.image,600,600 )#elf.x, self.y)
all_sprites.add(predator)
Wolf_group.add(predator)
self.energy -= 6
def findClosestPrey(self,preyX,preyY):
tempdist=math.sqrt((self.x-preyX)**2 + (self.y-preyY)**2)
if tempdist<self.dist:
xpos=preyX
ypos=preyX
class Prey(Animal):
def __init__(self, image, x, y):
super().__init__(image, x, y)
self.energy=7
self.starvetimmer=0
self.dist=10000
def reproduce(self):
if self.energy >= 10:
prey = Prey(self.image,self.x-50,self.y+50 )#elf.x, self.y)
all_sprites.add(prey)
Rabbit_group.add(prey)
self.energy -= 6
return xpos, ypos
class Carrot(pygame.sprite.Sprite):#food for prey class
def __init__(self,image,x,y):
super().__init__()
self.x = x
self.y = y
self.image = image
self.rect = self.image.get_rect(center = (self.x, self.y))
def carrot_creation():
randomx=random.randint(0,9)
randomy=random.randint(0,9)
randomx=randomx*100
randomy=randomy*100
carrot=Carrot(carrot_image,(randomx,randomy))
all_sprites.add(carrot)
carrot_group.add(carrot)
# Functions--------------------------------------------------------------
def Track(AgressorX,DefenderX,AgressorY,DefenderY):#finds comapres X and Y, tells sprite how to move
if AgressorX > DefenderX:
XMovement=-1
elif AgressorX< DefenderX:
XMovement=1
else:
XMovement=0
if AgressorY > DefenderY:
YMovement=-1
elif AgressorY < DefenderY:
YMovement=1
else:
YMovement=0
return XMovement, YMovement
def leavingWindow(Xpos, Ypos):#boundry, keeps sprites in the window
if Xpos<=0:
return True
elif Xpos>=950:
return True
if Ypos<=0:
return True
elif Ypos>=750:
return True
def Boundry(Xpos, Ypos):
Xmovement = min(max(0, Xpos), 950)
ymovement = min(max(0, Ypos), 750)
return Xmovement, ymovement
def button(msg,x,y,width,height,inactiveColour,activecolour,action=None):#setup buttons
mouse = pygame.mouse.get_pos()#gets mouses position
click=pygame.mouse.get_pressed()#sees if the mouse is clicked
if x+width> mouse[0] > x and y+height> mouse[1] > y:
pygame.draw.rect(screen, activecolour,(x,y,width, height))
if click[0]==1 and action!=None:
if action= = "play":
main_game()
elif action= = "quit":
pygame.quit
quit()
elif action= = "pause":
paused()
else:
pygame.draw.rect(screen, inactiveColour,(x,y,width,height))
smallText = pygame.font.Font("freesansbold.ttf",16)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ( (x+(width/2)), (y+(height/2)) )
screen.blit(textSurf, textRect)
button("pause",450,450,100,50,grey,dark_grey,"play")
button("Quit",450,550,100,50,grey,dark_grey,"quit")
def text_objects(text, font):#sets up the text
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def paused():
largeText = pygame.font.SysFont("comicsansms",115)
TextSurf, TextRect = text_objects("Paused", largeText)
TextRect.center = ((1000/2),(800/2))
gameDisplay.blit(TextSurf, TextRect)
while pause:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
#gameDisplay.fill(white)
button("Continue",150,450,100,50,green,bright_green,unpause)
button("Quit",550,450,100,50,red,bright_red,quitgame)
pygame.display.update()
clock.tick(15)
#classes and sprites--------------------------------------------------------
#setup sprite groups
prey_image = pygame.image.load('Prey.png')
predator_image=pygame.image.load('Icon.png')
carrot_image=pygame.image.load("carrot.png")
all_sprites = pygame.sprite.Group()
carrot_group = pygame.sprite.Group()
Wolf_group= pygame.sprite.Group()
Wolf_group.add(Predator(predator_image,600,600))
Rabbit_group= pygame.sprite.Group()
#sets up multiple rabbits and carrots at start
for i in range(1, 3):
prey = Prey(prey_image, 100 * i, 700)
all_sprites.add(prey)
Rabbit_group.add(prey)
for i in range(0,3):#makes arndom carrots
randomx=random.randint(0,9)
randomy=random.randint(0,9)
randomx=randomx*100
randomy=randomy*100
carrot=Carrot(carrot_image,randomx,randomy)
all_sprites.add(carrot)
carrot_group.add(carrot)
all_sprites.add(carrot_group)
all_sprites.add(Wolf_group)
all_sprites.add(Rabbit_group)
#start of program
def main_game():
timmer = 1
running=True
while running:
clock.tick(60)
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
#buttons
#button("pause",650,30,100,50,grey,dark_grey,"play")
#button("Quit",750,30,100,50,grey,dark_grey,"quit")
carrots = carrot_group.sprites()
preys = Rabbit_group.sprites()
predators = Wolf_group.sprites()
if len(preys) > 0:
for wolf in Wolf_group:
for rabbits in Rabbit_group:
preysX,preysY=wolf.findClosestPrey(rabbits.x,rabbits.y)
movementx, movementy = Track(wolf.x, preysX, wolf.y, preysY)#how the predators move
wolf.move(movementx,movementy)#movementx, #movementy)
Leaving=leavingWindow(wolf.x,wolf.y)#keeps sprites in window
if Leaving == True:
movementx,movementy=Boundry(wolf.x,wolf.y)
wolf.x=movementx
wolf.y=movementy
if len(carrots) > 0:#the movement for prey
for rabbit in Rabbit_group:
for carrot in carrot_group:
## Energyval=rabbit.checkEnergy()
## if Energyval>=8:
movementx, movementy = Track(rabbit.x, carrot.x, rabbit.y, carrot.y)#how the prey move
rabbit.move(movementx, movementy)
Leaving=leavingWindow(rabbit.x,rabbit.y)#keeps sprites in window
if Leaving == True:
movementx,movementy=Boundry(rabbit.x,rabbit.y)
rabbit.x=movementx
rabbit.y=movementy
for carrot in carrots:#removes the carrots if they contact a rabbit
for rabbit in Rabbit_group:
if rabbit.is_collided_with(carrot):
print('works')
carrot.kill()
rabbit.dist=1000
rabbit.energy += 5#increases the rabbits energy
rabbit.reproduce()#reproduces once the
if rabbit.starvetimmer==120:#starves the animal over time
rabbit.starve(rabbit)
else:
rabbit.starvetimmer+=1
for wolf in Wolf_group:
for rabbit in Rabbit_group:
if rabbit.is_collided_with(wolf):
print("works 2")
wolf.dist=1000
rabbit.kill()
wolf.energy+=4#increases the rabbits energy
wolf.reproduce()
if wolf.starvetimmer==160:
wolf.starve(wolf)
else:
wolf.starvetimmer+=1
screen.fill((0,128,0))#background
all_sprites.draw(screen)#makes the sprites
pygame.display.update()#updates screen
timmer+=1
pygame.quit()
exit()
#main menu setup-----------------------------------------------------
def main_menu():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.fill(dark_blue)
largeText = pygame.font.SysFont("comicsansms",100)
TextSurf, TextRect = text_objects("Wildlife simulator", largeText)
TextRect.center = ((1000/2),(200))
screen.blit(TextSurf, TextRect)
button("Start",450,450,100,50,grey,dark_grey,"play")
button("Quit",450,550,100,50,grey,dark_grey,"quit")
pygame.display.update()
clock.tick(15)
play=True
#main loop
while play==True:
#main_menu()
main_game()
foo == True
является избыточным и не имеет смысла. Просто напишите foo
.
У тебя, кажется, ошибка? Вы уверены, что хотите использовать preyX
вместо preyY
в методе findClosestPrey
?
есть pygame.math.Vector2.distance_to
@Random, как насчет того, чтобы изменить его, чтобы каждый волк брал разные предметы?
@Flat_Pancake вы, вероятно, хотите, чтобы каждый волк шел к одному ближайшему к ним кролику. Не каждому кролику. Но я не знаю точно, как вы хотите, чтобы это работало, это ваша программа. Что касается поиска ближайшего, для каждого волка вам нужно будет получить расстояние до каждого кролика от каждого волка, затем выбрать кролика с наименьшим расстоянием до этого волка и переместить волка в это положение. Что касается того, как все это сделать, это зависит от вас, это потребует нескольких различных изменений. Мы не собираемся писать для вас правильную, полную версию, но мы можем ответить на ваши вопросы, если вы на чем-то застряли.
не ожидал, то, что вы дали (имея вещь в стиле списка), было тем, что я ожидал в ответ, так что спасибо
Ваш код не может работать, потому что метод findClosestPrey
ничего не возвращает:
def findClosestPrey(self,preyX,preyY): tempdist=math.sqrt((self.x-preyX)**2 + (self.y-preyY)**2) if tempdist<self.dist: xpos=preyX ypos=preyX
Вам нужно передать список или группу целей (спрайтов) в метод findClosestPrey
. Метод находит цель с самым близким расстоянием и возвращает ее позицию. Вернуть позицию самого объекта, если целей нет:
class Predator(Animal):
# [...]
def getDistanceTo(self, preyX, preyY):
return math.sqrt((self.x-preyX)**2 + (self.y-preyY)**2)
def findClosestPrey(self, targets):
if not targets:
return self.x, self.y
minDist = 1000000 # very large distance
for target in targets:
tempDist = self.getDistanceTo(target.x, target.y)
if tempDist < minDist:
targetX = target.x
targetY = target.y
return targetX, targetY
def main_game():
# [...]
while running:
# [...]
if len(preys) > 0:
for wolf in Wolf_group:
preysX, preysY = wolf.findClosestPrey(Rabbit_group)
movementx, movementy = Track(wolf.x, preysX, wolf.y, preysY)
wolf.move(movementx, movementy)
# [...]
Что такое
findClosestPrey
вdist
и где это определяется? Кроме того, неясно, зачем вам нужна эта функция, поскольку все, что она делает, это возвращает X и Y, которые вы передали. Окружающая логика также не ясна; вы не находите ближайшую добычу для каждого волка, вы буквально говорите каждому волку вWolf_group
идти за каждым кроликом вRabbit_group
. Итак, если каждому волку сказать сделать одно и то же, все они, вероятно, займут позицию самого последнего кролика в списке. Так же, как то, что вы описываете. Так что вообще непонятно, почему вы так написали.