raining boxes

This was just a little experiment. I wanted some boxes to fall from the sky.

First I made an array of boxes above my head using a function called once. Each box had a random x and y value between -5 and 5. I then made a task that went one by one to each box in the array and lowered its Z value by a random number between 0 and 2. If a raindrop goes below the floor, I reset its Z back to above my head and give it a new random X and Y. So the rain never stops.

I’ve left in some of my debugging code.

I would like to add to the code such that a “shadow” appeared on the ground so that the player could have a clue and have enough time to move before the box hit him/her on the head. As the time increased, the number of boxes or speed would increase. Anyone have an idea for the shadow? It should appear when the box is X units above the ground.

Second question, I used

loader.loadModelCopy('Box1')

instead of:

loader.loadModel('Box1')

how much of an effect does that have?

        self.rain = []
        self.makingRainF()


        taskMgr.add(self.fallingBoxesT, "fallingBoxesT")
        
                
    def makingRainF(self):
        j =0
        for x in range(1,5):
            print "x =", x
            print            
            for y in range (1,5):
                self.raindrop = loader.loadModelCopy('Box1')
                print "y=", y
                print "j=", j
                xx = random.randint(-5,5)
                yy = random.randint(-5,5)
                print xx, yy
                self.raindrop.setPos(xx, yy ,30)
                self.rain.append(self.raindrop)
                self.rain[j].reparentTo(render)
                print self.rain[j].getPos()
                j+=1
            
    def fallingBoxesT (self, task):
        
        for a in range(len(self.rain)):
            m = random.randint(0, 2)
            print "m =", m
            self.rain[a].setZ(self.rain[a].getZ()-m)
            
            if self.rain[a].getZ() < -6:
                tt = random.randint(-9,9)
                self.rain[a].setPos(tt, tt ,30)
                self.rain[a].setZ(self.rain[a].getZ()+33)
       
        return Task.cont     

I’m not sure about the difference between loadModel and loadModelCopy, but as to the shadow, a simple suggestion might be a variation on the method presented in this thread. The only change that I’d suggest is scaling the shadow in the x- and y- planes according to the distance between the rain-drop and the surface that it’s going to strike like so:

given a maximum increase in shadow size, "max_inc", a height above the surface "h", and the maximum height above ground (i.e. the height at which they start, I presume), "max_h":

xy_scale = 1.0 + max_inc*h/max_h

shadow.setScale(xy_scale, xy_scale, 0)

You could also set the transparency along similar lines:

transparency = min_trans + (1.0-min_trans)*(1.0-h/max_h)

Of course, this would probably work rather less well for non-planar floors or your player avatar, unless it has a significant plane on its top in the latter case.

loadModelCopy is deprecated. Now it’s the default behavior of loadModel. If the model is already loaded, the future calls of loadModel will load it from ModelPool in RAM instead of hitting your disk again.

Don’t use loadModelCopy(), it’s deprecated. Use loadModel() instead. https://discourse.panda3d.org/viewtopic.php?t=4470

David