随机移动pygame

Random movement pygame

我正在尝试制作一个简单的生活模拟器,我需要 "cells" 在屏幕上几乎随机(有一些规则)移动。但问题是,过了一会儿,它们往往会聚集在屏幕的左上角。我试图改变很多东西,比如完全跳过规则并让它们完全随机移动,但它们仍然聚在一起。我的代码中有一些明显的问题吗?或者我应该完全不同地做这个动作吗?

删去无关部分的代码:

import sys, random, pygame
from pygame.locals import *
pygame.init()

WIDTH = 640 #game window width
HEIGHT = 480 #game window height
FPS = 60 #game's speeds
Pixsize = 2
screen = pygame.display.set_mode((WIDTH, HEIGHT)) #set the game window


class cell:
    def __init__(self):
        self.x = random.randrange(10, WIDTH-10) #x position
        self.y = random.randrange(10, HEIGHT-10) #y position
        self.speed = random.randrange(2,5) #cell speed
        self.move = [None, None] #realtive x and y coordinates to move to
        self.direction = None #movement direction

    def draw(self):
        pygame.draw.rect(screen, (255,255,255), (self.x,self.y,Pixsize,Pixsize),0) #draw the cell


    def wander(self):
        directions = {"S":((-1,2),(1,self.speed)),"SW":((-self.speed,-1),(1,self.speed)),"W":((-self.speed,-1),(-1,2)),"NW":((-self.speed,-1),(-self.speed,-1)),"N":((-1,2),(-self.speed,-1)),"NE":((1,self.speed),(-self.speed,-1)),"E":((1,self.speed),(-1,2)),"SE":((1,self.speed),(1,self.speed))} #((min x, max x)(min y, max y))
        directionsName = ("S","SW","W","NW","N","NE","E","SE") #possible directions
        if random.randrange(0,5) == 2: #move about once every 5 frames
            if self.direction == None: #if no direction is set, set a random one
                self.direction = random.choice(directionsName)
            else:
                a = directionsName.index(self.direction) #get the index of direction in directions list
                b = random.randrange(a-1,a+2) #set the direction to be the same, or one next to the current direction
                if b > len(directionsName)-1: #if direction index is outside the list, move back to the start
                    b = 0
                self.direction = directionsName[b]
            self.move[0] = random.randrange(directions[self.direction][0][0],directions[self.direction][0][1]) #change relative x to a random number between min x and max x
            self.move[1] = random.randrange(directions[self.direction][1][0],directions[self.direction][1][1]) #change relative y to a random number between min y and max y
        if self.x < 5 or self.x > WIDTH - 5 or self.y < 5 or self.y > HEIGHT - 5: #if cell is near the border of the screen, change direction
            if self.x < 5:
                self.direction = "E"
            elif self.x > WIDTH - 5:
                self.direction = "W"
            elif self.y < 5:
                self.direction = "S"
            elif self.y > HEIGHT - 5:
                self.direction = "N"
            self.move[0] = random.randrange(directions[self.direction][0][0],directions[self.direction][0][1]) #change relative x to a random number between min x and max x
            self.move[1] = random.randrange(directions[self.direction][1][0],directions[self.direction][1][1]) #change relative x to a random number between min x and max x
        if self.move[0] != None: #add the relative coordinates to the cells coordinates
            self.x += self.move[0]
            self.y += self.move[1]


cells = []
for i in range(200): #generate n cells
    Cell = cell()
    cells.append(Cell)


def mainloop():
    while True:
        for event in pygame.event.get():
            if event.type== QUIT: #if pressing the X, quit the progra
                pygame.quit() #stop pygame
                sys.exit() #stop the program
        screen.fill((0,0,0)) #clear the screen;
        for i in cells: #update all cells
            i.wander()
            i.draw()
        pygame.display.update() #update display
        pygame.time.Clock().tick(FPS) #limit FPS

mainloop()

许多随机数生成器倾向于选择较小的数字。您可能需要用其他一些微小的随机数来抵消随机值,或者研究更复杂的生成器。

我快速环顾四周,没有找到任何 "truly" 个随机生成器。

尝试将一个小数加到其他随机数上,看看会发生什么。

澄清一下我的意思:

#Instead of:

self.move[0] = random.randrange(directions[self.direction][0][0],directions[self.direction][0][1])
self.move[1] = random.randrange(directions[self.direction][1][0],directions[self.direction][1][1])

#Try something like:

smallOffset = random.random() #Random floating-point number between 0 and 1 ("Tiny number")

self.move[0] = random.randrange(directions[self.direction][0][0],directions[self.direction][0][1]) + smallOffset
self.move[1] = random.randrange(directions[self.direction][1][0],directions[self.direction][1][1]) + smallOffset

您可能需要调整 smallOffset 以限制它可以变得多大(因为它可以是一个几乎接近 1 的值,这已经不再小了)

您的单元格聚集到左上角的原因是 random.randrange()

randrange()部分处理范围,as per the pythonrange()函数。查看 range() 函数,range( A, B ) returns 列表 A -> B-1:

>>> for i in range( 1,10 ): print( i, end = ", " )
... 
1, 2, 3, 4, 5, 6, 7, 8, 9,

所以当您的代码执行 random.randrange(directions[self.direction][0][0],directions[self.direction][0][1]) 时,它排除了范围中的最后一项,它看起来是“SE”。因此,他们更有可能朝其他方向前进,经过数千次迭代后,将他们移至左上角。