admin管理员组

文章数量:1122846

I tried to make this code execute code when the green cubes are clicked, and it worked:

from ursina import *

nav = [None, 0, 0]
"""nav[0] store the cubes hovered data so i can get information and change it (type(nav[0]) is entity)
nav[1] tells the player if it must move or not (0 and 1) 
nav[2] tells the program when it should reset nav (when the movement is over)(with 0 and 1)"""

# Configurable variables
movement_speed = 0.1  # Speed of movement when holding WASD
rotation_speed = 40   # Speed of rotation (degrees per frame)
camera_distance = 15  # Distance of the camera from the player
target_threshold = 0.5  # Distance threshold to stop moving when reaching the target
control_mode = 0  # 0 = Move with click, 1 = Move with WASD
"""this is the function that is called when a green cube is clicked and store the cubes data (like position) 
and tells the player when to start movement (with nav[1]):"""
def click():
    global nav
    nav = [
        (mouse.hovered_entity.x,#cube x
     mouse.hovered_entity.y + mouse.hovered_entity.scale[1] / 2,#cube y
      mouse.hovered_entity.z),#cube z
       1, #start or not 

        0]#reset nav to None when movment is over
"""I made a function that gets the player position (a_x,a_y) and
 block that is clicked(b_x ,b_y) and return the I and j vector that i** 2+j**2 =1 . 
 if the distance of player from block is less than 0.5 it will make nav [ 2] True so the player will stop: """
def normalize_direction_vector(x_a, y_a, x_b, y_b):
    global nav
    dx = x_b - x_a
    dy = y_b - y_a
    magnitude = math.sqrt(dx**2 + dy**2)
    try:
        i = dx / magnitude
        if magnitude < target_threshold:
            nav[2] = 1
    except:
        i = 0
        nav[2] = 1
    try:
        j = dy / magnitude
        if magnitude < target_threshold:
            nav[2] = 1
    except:
        j = 0
        nav[2] = 1
    return [i, j]
#u is the app(windows) and a is the player a white cube:
u = Ursina(fullscreen=1, development_mode=1)

a = Entity(model="cube", position=Vec3(0, 0, 0), scale=Vec3(1, 1, 1))
""" I made a 10*10 platform of green cubes 
which when they are clicked the player will move and their action is click()
and the problem is when they are clicked the function doesnt run:"""
for i in range(10):
    for j in range(10):
        block = Entity(model='cube',
         color=color.green,
          position=Vec3(i, -1, j),
           scale=Vec3(1, 1, 1),
            collider="box",
             on_click=click)#here is the problem

cam = camera

while True:
    if held_keys["escape"]:
        break
    """makes the cube that was hovered by the mouse green again so
    it won't remain black(because the mouse makes the hovered blocks black later in the code.
    I don't want them to remain black and become green again if mouse is not hovered) """
    try:
        hov.color = color.green
    except:#if hov is None 
        pass

    if control_mode:  # WASD Movement
        if held_keys["w"]:
            a.x += movement_speed
            a.z += movement_speed
        if held_keys["s"]:
            a.x -= movement_speed
            a.z -= movement_speed
        if held_keys["a"]:
            a.x -= movement_speed
            a.z += movement_speed
        if held_keys["d"]:
            a.x += movement_speed
            a.z -= movement_speed
    """makes the player move if hov[1] is true(the player must move)
     and make the player move (using line 16-35) .
     if hov[2] is true the nav list will reset and the player won't move anymore:"""
    if not control_mode and nav[1]:  # Click-to-move
        c = normalize_direction_vector(a.x, a.z, nav[0][0], nav[0][2])
        if nav[2]:#check if the plauer must stop
            nav = [None, 0, 0]
        else:
            a.x += c[0] * movement_speed
            a.z += c[1] * movement_speed
    """controls the camera and the players view with mouse"""
    a.look_at((mouse.x * 5 + a.x, 0, mouse.y * 5 + a.z,))
    cam.x = a.x - camera_distance
    cam.y = a.y + camera_distance
    cam.z = a.z - camera_distance
    cam.look_at((mouse.x * 5 + a.x, 0, mouse.y * 5 + a.z,))
    a.rotate(Vec3(0, rotation_speed, 0))
    """folowing line will make the hovered cubes with mouse black ."""
    try:
        hov = mouse.hovered_entity
        mouse.hovered_entity.color = color.black
    except:#if no hov cubes
        pass

    
    u.step()#update


But when I changed my code to be in a function, like this:

python
from ursina import *

def click():
        global nav
        nav = [(mouse.hovered_entity.x, mouse.hovered_entity.y + mouse.hovered_entity.scale[1] / 2, mouse.hovered_entity.z), 1, 0]


def runner():

    nav = [None, 0, 0]

    # Configurable variables
    movement_speed = 0.1  # Speed of movement when holding WASD
    rotation_speed = 40   # Speed of rotation (degrees per frame)
    camera_distance = 15  # Distance of the camera from the player
    target_threshold = 0.5  # Distance threshold to stop moving when reaching the target
    control_mode = 0  # 0 = Move with click, 1 = Move with WASD

   

    def normalize_direction_vector(x_a, y_a, x_b, y_b):
        global nav
        dx = x_b - x_a
        dy = y_b - y_a
        magnitude = math.sqrt(dx**2 + dy**2)
        try:
            i = dx / magnitude
            if magnitude < target_threshold:
                nav[2] = 1
        except:
            i = 0
            nav[2] = 1
        try:
            j = dy / magnitude
            if magnitude < target_threshold:
                nav[2] = 1
        except:
            j = 0
            nav[2] = 1
        return [i, j]

    u = Ursina(fullscreen=1, development_mode=1)

    a = Entity(model="cube", position=Vec3(0, 0, 0), scale=Vec3(1, 1, 1))
    for i in range(10):
        for j in range(10):
            block = Entity(model='cube', color=color.green, position=Vec3(i, -1, j), scale=Vec3(1, 1, 1), collider="box", on_click=click)

    cam = camera

    while True:
        if held_keys["escape"]:
            break

        try:
            hov.color = color.green
        except:
            pass

        if control_mode:  # WASD Movement
            if held_keys["w"]:
                a.x += movement_speed
                a.z += movement_speed
            if held_keys["s"]:
                a.x -= movement_speed
                a.z -= movement_speed
            if held_keys["a"]:
                a.x -= movement_speed
                a.z += movement_speed
            if held_keys["d"]:
                a.x += movement_speed
                a.z -= movement_speed

        if not control_mode and nav[1]:  # Click-to-move
            c = normalize_direction_vector(a.x, a.z, nav[0][0], nav[0][2])
            if nav[2]:
                nav = [None, 0, 0]
            else:
                a.x += c[0] * movement_speed
                a.z += c[1] * movement_speed

        a.look_at((mouse.x * 5 + a.x, 0, mouse.y * 5 + a.z,))
        cam.x = a.x - camera_distance
        cam.y = a.y + camera_distance
        cam.z = a.z - camera_distance
        cam.look_at((mouse.x * 5 + a.x, 0, mouse.y * 5 + a.z,))

        try:
            hov = mouse.hovered_entity
            mouse.hovered_entity.color = color.black
        except:
            pass

        a.rotate(Vec3(0, rotation_speed, 0))
        u.step()
runner()

it does not work anymore.

Also, I do not want to change my code to do something like have the mainloop contained in a function, I want to keep it contained in a while loop.

本文标签: pythonwhy onclick action doesn39t work on ursinaStack Overflow