0

I want a randomized pair of shapes to appear on the screen when the game is run and this pair removed and replaced with another pair of shapes when the left shift or right shift button on the keyboard is pressed, using the Ursina Engine in Python. Currently, my code works but it always breaks down when the third pair of shapes appear on the screen. I don't know what exactly the problem is or how to solve it. Any help?

from ursina import *
import random 

#creates the instance of the game
app = Ursina()

#contains a list of the shapes
shape_a = [] #set a shapes on the right side
shape_b = [] #set b shapes on the left side


#Entities refer to shapes created that appear in pairs
#SET A
#Visibilities turned off for each entity
s1a = Entity(model = 'cube', color = color.orange, scale = (2,2), position = (-2.5,0,0), rotation = Vec3 (45,45,45), texture = 'white_cube')
s1a.visible  = False
s2a = Entity(model = 'cube', color = color.orange, scale = (2,2), position = (-2.5,0,0), rotation = Vec3 (45,-45,45), texture = 'white_cube')
s2a.visible  = False
s3a = Entity(model = 'sphere', color = color.orange, scale = (2,2), position = (-2.5,0,0), rotation = Vec3 (45,45,45), texture = 'white_cube')
s3a.visible  = False
s4a = Entity(model = 'quad', color = color.orange, scale = (2.5,2), position = (-2.5,0,0), rotation = Vec3 (45,-45,45), texture = 'white_cube')
s4a.visible  = False

#Appends each entity to the corresponding list
shape_a.append(s1a)
shape_a.append(s2a)
shape_a.append(s3a)
shape_a.append(s4a)


#Entities refer to shapes created that appear in pairs
#SET B
#Visibilities turned off for each entity
s1b = Entity(model = 'cube', color = color.orange, scale = (2,2), position = (2.5,0,0), rotation = Vec3 (45,45,45), texture = 'white_cube')
s1b.visible  = False
s2b = Entity(model = 'cube', color = color.orange, scale = (2.5,2), position = (2.5,0,0), rotation = Vec3 (45,-45,45), texture = 'white_cube')
s2b.visible  = False
s3b = Entity(model = 'quad', color = color.orange, scale = (2,2), position = (2.5,0,0), rotation = Vec3 (45,45,45), texture = 'white_cube')
s3b.visible  = False
s4b = Entity(model = 'sky_dome', color = color.orange, scale = (0.5,0.5), position = (2.5,0,0), rotation = Vec3 (45,-45,45), texture = 'white_cube')
s4b.visible  = False

#Appends each entity to the corresponding list
shape_b.append(s1b)
shape_b.append(s2b)
shape_b.append(s3b)
shape_b.append(s4b)


#Shows the first pair of shapes on the screen.
a = random.choice(shape_a)
a.visible = True

b = random.choice(shape_b)
b.visible = True

#Called to turn off the visibility of the current shapes
def Falsefunction ():
        #a = random.choice(shape_a)
        a.visible = False

        #b = random.choice(shape_b)
        b.visible = False


for i in range(1,20):
        def input(key):
            #receives input from the keyboard
                if key == "left shift" or key == "right shift":
                        Falsefunction()
                        #After the current pair of shapes disappear from the screen, the next lines of code causes another
                        #random pair of shapes to appear as long as the loop keeps running.
                        a = random.choice(shape_a)
                        a.visible = True

                        b = random.choice(shape_b)
                        b.visible = True 

app.run()

1 Answers1

0

The problem lies in some of the shapes not being accessed as expected, probably due to either a problem with what objects the Falsefunction method is changing (since it doesnt explicity get the both objects and return them its a bit hard to see what exact object it changes). The fact that it seems to happen after a few times indicates that it has to do with the random selection, so it seems to turn off some of the objects visible attributes in the lists properly, but for some it doesn't seem to work.

To find the exact problem you could for example try to print out the entire list visible status and see where the problem starts to happen.

As a simple workaround where it is more clear to see what exactly happens you could just turn off the visibility of all objects in both lists on each key input, this way no error can happen.

Then you also don't even need the selection objects a and b. What you simply do is randomly pick an object from the list and set its attribute directly. Then in each call of Falsefunction you just set all visible attributes in all objects to False. If you prefer the way to write it with a and b you can also just leave all that unchanged and only change the Falsefunction, the result will be the same.

Obviously if you have a very large number of objects this starts to get inefficient and it might be better to actually figure out the exact problem. For the small number of objects it won't make any difference performance-wise.

...

# Shows the first pair of shapes on the screen.
random.choice(shape_a).visible = True
random.choice(shape_b).visible = True


# Called to turn off the visibility of all shapes
def Falsefunction():
    for shape in shape_a + shape_b:
        shape.visible = False


def input(key):
    # receives input from the keyboard
    if key == "left shift" or key == "right shift":
        Falsefunction()

        # After the current pair of shapes disappear from the screen, the next lines of code causes another
        # random pair of shapes to appear as long as the loop keeps running.
        random.choice(shape_a).visible = True
        random.choice(shape_b).visible = True


app.run()
ewz93
  • 2,444
  • 1
  • 4
  • 12