Download Documentation API Reference Samples Asset Store Donate


Rubik's Cube
https://github.com/pokepetter/ursina/blob/master/samples/rubiks_cube.py


from ursina import * app = Ursina() cube_colors = [ color.pink, # right color.orange, # left color.white, # top color.yellow, # bottom color.azure, # back color.green, # front ] # make a model with a separate color on each face combine_parent = Entity(enabled=False) for i in range(3): dir = Vec3(0,0,0) dir[i] = 1 e = Entity(parent=combine_parent, model='plane', origin_y=-.5, texture='white_cube', color=cube_colors[i*2]) e.look_at(dir, 'up') e_flipped = Entity(parent=combine_parent, model='plane', origin_y=-.5, texture='white_cube', color=cube_colors[(i*2)+1]) e_flipped.look_at(-dir, 'up') combine_parent.combine() # place 3x3x3 cubes cubes = [] for x in range(3): for y in range(3): for z in range(3): e = Entity(model=copy(combine_parent.model), position=Vec3(x,y,z) - (Vec3(3,3,3)/3), texture='white_cube') cubes.append(e) # rotate a side when we click on it collider = Entity(model='cube', scale=3, collider='box', visible=False) def collider_input(key): if mouse.hovered_entity == collider: if key == 'left mouse down': rotate_side(mouse.normal, 1) elif key == 'right mouse down': rotate_side(mouse.normal, -1) collider.input = collider_input rotation_helper = Entity() def rotate_side(normal, direction=1, speed=1): if normal == Vec3(1,0,0): [setattr(e, 'world_parent', rotation_helper) for e in cubes if e.x > 0] rotation_helper.animate('rotation_x', 90 * direction, duration=.15*speed, curve=curve.linear, interrupt='finish') elif normal == Vec3(-1,0,0): [setattr(e, 'world_parent', rotation_helper) for e in cubes if e.x < 0] rotation_helper.animate('rotation_x', -90 * direction, duration=.15*speed, curve=curve.linear, interrupt='finish') elif normal == Vec3(0,1,0): [setattr(e, 'world_parent', rotation_helper) for e in cubes if e.y > 0] rotation_helper.animate('rotation_y', 90 * direction, duration=.15*speed, curve=curve.linear, interrupt='finish') elif normal == Vec3(0,-1,0): [setattr(e, 'world_parent', rotation_helper) for e in cubes if e.y < 0] rotation_helper.animate('rotation_y', -90 * direction, duration=.15*speed, curve=curve.linear, interrupt='finish') elif normal == Vec3(0,0,1): [setattr(e, 'world_parent', rotation_helper) for e in cubes if e.z > 0] rotation_helper.animate('rotation_z', -90 * direction, duration=.15*speed, curve=curve.linear, interrupt='finish') elif normal == Vec3(0,0,-1): [setattr(e, 'world_parent', rotation_helper) for e in cubes if e.z < 0] rotation_helper.animate('rotation_z', 90 * direction, duration=.15*speed, curve=curve.linear, interrupt='finish') invoke(reset_rotation_helper, delay=.2*speed) if speed: collider.ignore_input = True @after(.25*speed) def _(): collider.ignore_input = False check_for_win() def reset_rotation_helper(): [setattr(e, 'world_parent', scene) for e in cubes] rotation_helper.rotation = (0,0,0) win_text_entity = Text(y=.35, text='', color=color.green, origin=(0,0), scale=3) def check_for_win(): if {e.world_rotation for e in cubes} == {Vec3(0,0,0)}: win_text_entity.text = 'SOLVED!' win_text_entity.appear() else: win_text_entity.text = '' def randomize(): faces = (Vec3(1,0,0), Vec3(0,1,0), Vec3(0,0,1), Vec3(-1,0,0), Vec3(0,-1,0), Vec3(0,0,-1)) for i in range(20): rotate_side(normal=random.choice(faces), direction=random.choice((-1,1)), speed=0) randomize_button = Button(text='randomize', color=color.azure, position=(.7,-.4), on_click=randomize) randomize_button.fit_to_text() window.color = color._16 EditorCamera() app.run()