0

So im new to ursina and listen to a lot of youtube how to's and alot of github, doc for ursina, reddit, etc. before i got into it. well i decided to get into the actual coding part and pick this code and i wanted to see if there was a way for two or more classes to interact with each other for example collision, because i was kinda confuse on how you give attributes to the objects in the game like health, status etc. i tried using the getattr() but it didnt work. in ursina is interaction between classes different or is giving the attributes to objects different? heres the code:

from ursina import *


app = Ursina()

EditorCamera()


class Players():
     def __init__(self):
      super.__init__()

      self.player = Entity(model='cube', color=color.orange, collider='box', origin_y=-.5)


class Triggerbox():
    def __init__(self):
     super.__init__()
     self.trigger_box = Entity(model='wireframe_cube', color=color.gray, scale=2, collider='box', position=Vec3(1,0,2), origin_y=-.5)



def update():
    
    player.z += (held_keys['w'] - held_keys['s']) * time.dt * 6
    player.x += (held_keys['d'] - held_keys['a']) * time.dt * 6

    if player.intersects(trigger_box).hit:
        trigger_box.color = color.lime
        print('player is inside trigger box')
    else:
        trigger_box.color = color.gray

app.run()
  • it is much easier when you use the same names in different classes - i.e. `self.rect` instead of `self.player` and `self.trigger_box`. And later you can use `for`-loop to work with many objects and compare `rect` from one object with `rect` from other objects. – furas Aug 29 '22 at 05:48
  • you have mess in your code. You should first create instaces - i.e. `p = Players()` `t = Triggerbox()` and later use `p.player.intersect(t.trigger_box).hit`. And if you would use `self.rect` then it would be `p.rect.intersect(t.rect).hit` – furas Aug 29 '22 at 05:52
  • Isn’t rect apart of pygame and for sprites – loudmounth artist Aug 29 '22 at 06:25
  • Wht you mean compare ? – loudmounth artist Aug 29 '22 at 07:52
  • You're making classes for no reason here. – pokepetter Aug 29 '22 at 11:56
  • But how do you get the attributes , u need classes for attributes – loudmounth artist Aug 29 '22 at 12:23
  • I used name `rect` similar to PyGame but it doesn't matter - you can use any name. More important is to use the same name for the same attribute in different classes because it helps to make code simpler - it doesn't need `if/else` to check what class you use to compare values from different classes - ie. to compare if both elements are in the same place to check collision. – furas Aug 29 '22 at 19:12
  • you can keep attributes even in separated variables but using classes can be useful to make code cleaner. Problem is that you get code documentation and you add classses but you don't use it - ie. you use `player.x` like in documentation but it would need to create instance `p = Player()` and later use this instance `p.player.x`. BTW: if you want to use classes then documentation also show to use inheritance `class Player(Entity)` – furas Aug 29 '22 at 19:17
  • as for `health` - you don't need `getattr()`. First you have to create variable in `__init__` - with some value `self.health = 100`, and next you have to use instance `p = Player()` and you will have access `p.health`. That's all. It is the same as in any other classes. – furas Aug 29 '22 at 19:22
  • Is there really no way for interaction between classes in ursine and u hve to do that – loudmounth artist Aug 29 '22 at 19:54

1 Answers1

1

Problem 1: You've defined some classes, but never instantiate them.

Problem 2: The classes don't do anything. Even if you instantiated them correctly, you'd have to do something like player.player.intersects(trigger.trigger) which sounds unnecessarily complicated to me. A better approach if you need to extend an Entity with additional functionality, would be to make the class inherit from Entity:

class Player(Entity):
    def __init__(self, **kwargs):
        super().__init__(model='cube', color=color.orange, collider='box', origin_y=-.5)
        self.health_bar = Entity(parent=self, model='quad', color=color.red, scale_y=.1, y=1.2)
        self.max_health = 100
        self.health = self.max_health

        for key, value in kwargs.items():
            setattr(self, key, value)

    @property
    def health(self):
        return self._health

    @health.setter
    def health(self, value):
        print('set player health to:', value)
        self._health = value
        self.health_bar.scale_x = value / 100



player = Player()

def input(key):
    if key == '-':
        player.health -= 5

However, often you won't even need to do that. I this case you could simply not make classes at all. Here's working example:

from ursina import *


app = Ursina()

EditorCamera()

player = Entity(model='cube', color=color.orange, collider='box', origin_y=-.5)
trigger_box = Entity(model='wireframe_cube', color=color.gray, scale=2, collider='box', position=Vec3(1,0,0), origin_y=-.5)

def update():
    player.z += (held_keys['w'] - held_keys['s']) * time.dt * 6
    player.x += (held_keys['d'] - held_keys['a']) * time.dt * 6

    if player.intersects(trigger_box).hit:
        trigger_box.color = color.lime
        print('player is inside trigger box')
    else:
        trigger_box.color = color.gray

app.run()
pokepetter
  • 1,383
  • 5
  • 8