class Basketball(Item):
- def __init__(self, world, plane_node, count, cb_inst, curr_bottom, repos):
- super().__init__(world, plane_node, count, cb_inst, curr_bottom, repos, 'assets/gltf/basketball/basketball.gltf', .4)
+ def __init__(self, world, plane_node, count, cb_inst, curr_bottom, repos, mass=1, pos=(0, 0, 0), r=0, count=0):
+ super().__init__(world, plane_node, count, cb_inst, curr_bottom, repos, 'assets/gltf/basketball/basketball.gltf', .4, mass=mass, pos=pos, r=r, count=count)
def _set_shape(self):
self.node.add_shape(BulletSphereShape(1))
class Box(Item):
- def __init__(self, world, plane_node, count, cb_inst, curr_bottom, repos):
- super().__init__(world, plane_node, count, cb_inst, curr_bottom, repos, 'assets/gltf/box/box.gltf')
+ def __init__(self, world, plane_node, count, cb_inst, curr_bottom, repos, mass=1, pos=(0, 0, 0), r=0, count=0):
+ super().__init__(world, plane_node, count, cb_inst, curr_bottom, repos, 'assets/gltf/box/box.gltf', mass=mass, pos=pos, r=r, count=count)
def _set_shape(self):
self.node.add_shape(BulletBoxShape((.5, .5, .5)))
class Domino(Item):
- def __init__(self, world, plane_node, count, cb_inst, curr_bottom, repos):
- super().__init__(world, plane_node, count, cb_inst, curr_bottom, repos, 'assets/gltf/domino/domino.gltf')
+ def __init__(self, world, plane_node, cb_inst, curr_bottom, repos, mass=1, pos=(0, 0, 0), r=0, count=0):
+ super().__init__(world, plane_node, cb_inst, curr_bottom, repos, 'assets/gltf/domino/domino.gltf', mass=mass, pos=pos, r=r, count=count)
def _set_shape(self):
class Item:
- def __init__(self, world, plane_node, count, cb_inst, curr_bottom, scene_repos, model_path, model_scale=1, exp_num_contacts=1):
+ def __init__(self, world, plane_node, cb_inst, curr_bottom, scene_repos, model_path, model_scale=1, exp_num_contacts=1, mass=1, pos=(0, 0, 0), r=0, count=0):
self._world = world
self._plane_node = plane_node
self._count = count
self._overlapping = False
self._first_command = True
self.repos_done = False
+ self._mass = mass
+ self._pos = pos
+ self._r = r
self._exp_num_contacts = exp_num_contacts
self._curr_bottom = curr_bottom
self._scene_repos = scene_repos
self._model_path = model_path
self._commands = []
self._command_idx = -1
- self.node = BulletGhostNode(self.__class__.__name__)
+ if count:
+ self.node = BulletGhostNode(self.__class__.__name__)
+ else:
+ self.node = BulletRigidBodyNode(self.__class__.__name__)
self._set_shape()
self._np = render.attach_new_node(self.node)
- world.attach_ghost(self.node)
+ if count:
+ world.attach_ghost(self.node)
+ else:
+ world.attach_rigid_body(self.node)
self._model = loader.load_model(model_path)
set_srgb(self._model)
self._model.flatten_light()
self._model.reparent_to(self._np)
- self._set_outline_model()
self._np.set_scale(model_scale)
- set_srgb(self._outline_model)
- self._model.hide(BitMask32(0x01))
- self._outline_model.hide(BitMask32(0x01))
+ if count:
+ self._set_outline_model()
+ set_srgb(self._outline_model)
+ self._model.hide(BitMask32(0x01))
+ self._outline_model.hide(BitMask32(0x01))
self._start_drag_pos = None
self._prev_rot_info = None
self._last_nonoverlapping_pos = None
self._last_nonoverlapping_rot = None
- self._instantiated = False
+ self._instantiated = not count
+ self.interactable = count
self._box_tsk = taskMgr.add(self.on_frame, 'on_frame')
- self._repos()
+ if count:
+ self._repos()
+ else:
+ self._np.set_pos(pos)
+ self._np.set_r(r)
def _set_shape(self):
pass
if not self._instantiated:
return
self._world.remove_rigid_body(self.node)
- self.node.set_mass(1)
+ self.node.set_mass(self._mass)
self._world.attach_rigid_body(self.node)
def on_click_l(self, pos):
self._txt.destroy()
self._count -= 1
if self._count:
- item = self.__class__(self._world, self._plane_node, self._count, self._cb_inst, self._curr_bottom, self._scene_repos) # pylint: disable=no-value-for-parameter
+ item = self.__class__(self._world, self._plane_node, self._cb_inst, self._curr_bottom, self._scene_repos, count=self._count, mass=self._mass, pos=self._pos, r=self._r) # pylint: disable=no-value-for-parameter
self._cb_inst(item)
self._scene_repos()
self._outline_model.set_color_scale(.4, .4, .4, 1)
def on_mouse_on(self):
- if not self._paused:
+ if not self._paused and self.interactable:
self._outline_model.show()
def on_mouse_off(self):
if self._start_drag_pos or self._prev_rot_info: return
- self._outline_model.hide()
+ if self.interactable:
+ self._outline_model.hide()
def on_mouse_move(self, pos):
if self._start_drag_pos:
self._paused = True
self._model.set_transparency(True)
self._model.set_alpha_scale(.3)
- if not self._txt.is_empty():
+ if hasattr(self, '_txt') and not self._txt.is_empty():
self._txt.set_alpha_scale(.3)
def restore_state(self):
self._paused = False
self._model.set_alpha_scale(1)
- if not self._txt.is_empty():
+ if hasattr(self, '_txt') and not self._txt.is_empty():
self._txt.set_alpha_scale(1)
def destroy(self):
self._np.remove_node()
taskMgr.remove(self._box_tsk)
- self._txt.destroy()
+ if hasattr(self, '_txt'):
+ self._txt.destroy()
if not self._instantiated:
self._world.remove_ghost(self.node)
else:
class Shelf(Item):
- def __init__(self, world, plane_node, count, cb_inst, curr_bottom, repos):
- super().__init__(world, plane_node, count, cb_inst, curr_bottom, repos, 'assets/gltf/shelf/shelf.gltf')
+ def __init__(self, world, plane_node, cb_inst, curr_bottom, repos, mass=1, pos=(0, 0, 0), r=0, count=0):
+ super().__init__(world, plane_node, cb_inst, curr_bottom, repos, 'assets/gltf/shelf/shelf.gltf', mass=mass, pos=pos, r=r, count=count)
def _set_shape(self):
self.node.add_shape(BulletBoxShape((1, .5, .05)))
class TeeterTooter(Item):
- def __init__(self, world, plane_node, count, cb_inst, curr_bottom, repos):
- super().__init__(world, plane_node, count, cb_inst, curr_bottom, repos, 'assets/gltf/teeter_tooter/teeter_tooter.gltf', exp_num_contacts=2)
+ def __init__(self, world, plane_node, count, cb_inst, curr_bottom, repos, mass=1, pos=(0, 0, 0), r=0, count=0):
+ super().__init__(world, plane_node, count, cb_inst, curr_bottom, repos, 'assets/gltf/teeter_tooter/teeter_tooter.gltf', exp_num_contacts=2, mass=1, pos=(0, 0, 0), r=0, count=0)
def _set_shape(self):
self.node.add_shape(
def reset(self):
[itm.destroy() for itm in self.items]
- self.items = [Box(self._world, self._mouse_plane_node, 3, self.cb_inst, self.current_bottom, self.repos)]
- self.items += [Shelf(self._world, self._mouse_plane_node, 3, self.cb_inst, self.current_bottom, self.repos)]
- self.items += [Domino(self._world, self._mouse_plane_node, 3, self.cb_inst, self.current_bottom, self.repos)]
- self.items += [Basketball(self._world, self._mouse_plane_node, 3, self.cb_inst, self.current_bottom, self.repos)]
- self.items += [TeeterTooter(self._world, self._mouse_plane_node, 3, self.cb_inst, self.current_bottom, self.repos)]
+ self.items = []
+ #self.items += [Box(self._world, self._mouse_plane_node, self.cb_inst, self.current_bottom, self.repos, count=3)]
+ #self.items += [Shelf(self._world, self._mouse_plane_node, self.cb_inst, self.current_bottom, self.repos, count=3)]
+ self.items += [Shelf(self._world, self._mouse_plane_node, self.cb_inst, self.current_bottom, self.repos, mass=0, pos=(-1.2, 0, 1), r=10)]
+ self.items += [Shelf(self._world, self._mouse_plane_node, self.cb_inst, self.current_bottom, self.repos, mass=0, pos=(1.2, 0, 1), r=-10)]
+ self.items += [Domino(self._world, self._mouse_plane_node, self.cb_inst, self.current_bottom, self.repos, count=3)]
+ #self.items += [Basketball(self._world, self._mouse_plane_node, self.cb_inst, self.current_bottom, self.repos, count=3)]
+ #self.items += [TeeterTooter(self._world, self._mouse_plane_node, self.cb_inst, self.current_bottom, self.repos, count=3)]
self._commands = []
self._command_idx = 0
if hit.get_node() == self._mouse_plane_node:
pos = hit.get_hit_pos()
for hit in self._get_hits():
- for item in [i for i in self.items if hit.get_node() == i.node]:
+ for item in [i for i in self.items if hit.get_node() == i.node and i.interactable]:
if not self._item_active:
self._item_active = item
getattr(item, method)(pos)
* issues
* todo
-** first level (domino + shelf)
+** ending condition
** script for creating a screenshot of the level
** second level (box + shelf)
** level menu