omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello β€” I'm @olemoritz on Twitter.


    [SOLVED] Scene Update for all gameobjects help

    Pythonista
    iphone6s oop game gameloop ipadair2
    3
    15
    4671
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • stephen
      stephen @mikael last edited by

      @mikael well 😢 i actually have not tried let me run a quick test.

      but to answer your question..

      yes im wanting to have a single loop that EVERY GameObject that gets created inherits.

      1 Reply Last reply Reply Quote 0
      • stephen
        stephen last edited by

        @mikael No Sir they do not automatically link. i even tried subclassing EffectsNode.

        mikael 1 Reply Last reply Reply Quote 0
        • mikael
          mikael @stephen last edited by mikael

          @stephen, can you please reiterate the design goal? Is it that you need to:

          a) explicitly control the order every game object gets updated in
          b) have global awake, stop methods affecting all objects
          c) all objects to have access to the same core configuration

          What do you exactly mean by ”need to have all objects have the same timing”?

          1 Reply Last reply Reply Quote 0
          • JonB
            JonB last edited by

            I was saying you simply have something like this

            def update(self):
               for node in self.children:
                    if hasattr(node, 'update') and callable(node.update):
                        node.update()
            

            You could actually do something like this via a class decorator

            def auto_update_children(cls):
               originalupdate  = cls.__dict__.get('update')  # Possibly None.
               def update(self):
                  for node in self.children:
                     if hasattr(node, 'update') and callable(node.update):
                        node.update()
                  #finally, if the class already had an update... call it. so you can define classes with an update method, it will update children, then call your specific code..
                  if callable(originalupdate):
                     originalupdate(self)
               setattr(cls, 'update',update)
               return cls
            
            @auto_update_children
            class Game(Scene):
               def update(self):
                   #do any specific game logic... children have all been update'd when this gets called
                   check_collsitions()
                   etc()
            #...
            
            

            Likewise, you could then use said decorator on different "layers" that manage their own game state and children.

            The other approach is that you don't have to literally call update on every object. You probably have classes of objects -- player, enemy, projectiles, powerups, whatever.
            Keep those as lists inside your scene, and then loop through the lists.
            The advantage of that is you can do things like check collisions of every enemy with player, or projectiles with player.

            def add_enemy(self):
                       enemy = EnemyNode(....)           # ... some code to add a random enemy... 
                       self.enemies.append(enemy)
                       self.add_child(enemy)
            def add_projectile(self, initial_position, initial_velocity):
                       projectile = Projectile(initial_position, initial_velocity)
                       self.projectiles.append(projectile)
                       self.add_child(projectile)
            def update(self):
               for enemy in self.enemies:
                     enemy.update()
               player.update()
               for projectile in self.projectiles:
                     projectile.update()
                     if projectile.bbox.intersects(player.bbox):
                        #kill player,  ...
            

            So, you don't have to have a separate named object for everything in your scene, you have categories of objects that get added so that they can start being updated.

            1 Reply Last reply Reply Quote 2
            • stephen
              stephen last edited by

              @mikael

              I would be happy to πŸ˜€

              ill draw out a mini-version.


              
              class Core:
              	def __init__(self, *args, **kwargs):
              		self.awake()
              		
              		self.w, self.h=get_screen_size()
              		self.screenScale=get_screen_scale()
              		...and so on...
              		
              		self.start()
              		
              	def awake(self):
              		pass # exec before any attrs are set
              	
              	def start(self):
              		pass # exec afer attrs but before returned
              	
              	def update(self):
              		pass # needs to update from here for all gameobjects
              
              class GameObject(Core):
              	def __init__(self, id=None *args, **kwargs):
              		Core.__init__(self, *args, **kwargs)
              		self.id=id
              		
              class Actor(GameObject):
              	def __init__(self, isHostile=False, speed=30,
              					id=None, *args, **kwargs):
              		GameObject.__init__(self, id=id, *args, **kwargs)
              		self.isHostile=isHostile
              		self.speed=speed
              		self.position=(0,0)
              		
              class Deer(Actor):
              	def __init__(self, loot=[], isHostile=False, speed=50,
              					 id=100, *args, **kwargs):
              		Actor.__init__(self, isHostile=isHostile, speed=speed,
              						id=id, *args, **kwargs)
              		self.loot_inventory=loot
              		self.spawn_location=None
              		self.health_points=None
              		
              	def awake(self):
              		self.spawn_location=(456, 987)
              		
              	def start(self):
              		self.health_points=100
              		
              	def update(self):
              		self.position=(...)
              		
              

              ###In the example

              • Core holds the initial awake(), start() and update() methods
                • awake() is called before any base Attributes are set.
                • start() is called after all base attributes are set but before Instance is returned
                • update() needs to provide loop for All Subclasses of Core.. so all GameObjects.
              • now we work our way down to Deer() where we use the exec timing methods to set everything as needed.

              I know i can just drop ref to every object in the Scene subclass but im trying to find a way to do this implicitly at Core() or before..

              ive tried A handfull of approches including metaclass and nothing seems to do this other than manually placing hundreds+objects in the update() of Scene subclass.

              I will be more than happy to give any information to help, been on this solo project for nearly a year now and im at a stand still till i get this resolved.

              1 Reply Last reply Reply Quote 1
              • stephen
                stephen last edited by stephen

                @JonB

                Now thats what im talking bout!

                i believe i shale give a combination of entity goups and Cls decorater..

                Thank you!
                i will be sure to post wether this solves my issue!

                1 Reply Last reply Reply Quote 0
                • JonB
                  JonB last edited by

                  Rereading your question ... I guess maybe I read more into your question than you originally wanted...

                  class GameLoop(Scene):
                      def __init__(self):
                           self.go_list = [];
                      def add_gameobject(self, go):
                           self.go_list.append(go)
                           self.add_child(go)
                      def remove_gameobject(self,go):
                           #... remove from go_list and remove_child
                      def setup(self):
                           for i in range(40):
                              self.add_gameobject( GameObject() )
                      def update(self):
                           for go in self.go_list:
                               go.update()
                  

                  Doesn't something like this accomplish what you are after, without a lot of muss & fuss?

                  Now, I think you could accomplish various types of physics behaviours using decorators -- for instance, you could have a projectile decorator which simply takes current velocity and adjusts position. Then, you could have a affected_by_gravity decorator which adjusts velocity in each time step by g*dt in y. A bouncy decorator that looks for collisions and then inverts velocity, etc. Each decorator would have the form

                  def affected_by_gravity(cls):
                      originalupdate = cls.__dict__.get('update)
                      def update(self, dt):
                            self.velocity[1] = self.parent.gravity * dt
                            if callable(originalupdate):
                                originalupdate(self,dt)
                      setattr(cls,'update',update)
                      return cls
                  

                  then you could have

                  @affected_by_gravity
                  @projectile_physics
                  @bouncy
                  class Ball(ShapeNode):
                      def __init__(self):
                           pass
                  
                  mikael 1 Reply Last reply Reply Quote 1
                  • stephen
                    stephen last edited by stephen

                    i feel you first example hold the solution but i do know i will be looking into these decorators more. ive always went around them cuz thry feel uncomfortable. i normaly only programmed in .net on platforms like unity and unreal.

                    1 Reply Last reply Reply Quote 0
                    • mikael
                      mikael @JonB last edited by

                      @JonB, agree on the first half of your post. Thanks for taking the time to make examples.

                      Regarding bullet physics and all that, would seem like recreating SpriteKit.

                      1 Reply Last reply Reply Quote 1
                      • stephen
                        stephen last edited by

                        @JonB @mikael

                        Thank you!! i REALLY appreciate the effort! πŸ‘πŸ»πŸ‘πŸ»

                        this community has always got me in the right direction. hopefully this rpg will be play-test ready in roughly 6-8 months (im doing everything alone art, story, coding... so bare with me lol) and as it moves along ill try to post updates and functional "builds" that way you all can throw some input in. when it is fully completed i plan to host it on app store but i will be providing copies for group of you that have been aiding me along the way with python. i never thought i would be able to do this level of coding on a mobile device. lol thank you again and again @omz amazing work on Pythonista!

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post
                        Powered by NodeBB Forums | Contributors