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.


    Help me find a way to make the lasers fire in a certain direction.

    Pythonista
    7
    66
    16997
    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.
    • ccc
      ccc last edited by

      random, turtle, and ui are imported but not used which slows down startup and uses more memory.

      A = Action() is created but not used which slows down startup and uses more memory.

      self.laserButton = SpriteNode('shp:Circle') is created twice which slows down startup, uses more memory, and makes it confusing which instance is being clicked on.

      Please reread and follow @JonB advise above.

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

        If you want help, you need to explain what the problem is, what you have tried. For instance you might start by saying "help, my lasers now don't even spawn in the right position" to which someone might ask (maybe even you), gee, did you remember to set the laser position when you spawned it?

        Or you might be wondering why the laser w only move when you are touching the button. In which case one could respond that you maybe didn't fix the indentation as previously mentioned. The act of typing out "for some reason my lasers only move when I am touching the fire button" might make you look at the code that moves your lasers, or look at the code that runs when the fire button is pressed.

        You might be wondering "hey, I updated the code to use direction, but all lasers seem to use the direction from when the button was pressed", which would allow someone to point out that if you want to use it in your laser update loop, it needs to be defined inside said loop (using the rotation of the looped laser object), or store it as an attribute of the laser object.

        I would encourage you to try to understand your own code before asking for help. Then you can be specific about what you tried, what debugging you added in to understand the program flow, or what you think should be happening vs what is actually happening.

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

          Whenever I press the shoot button, lasers fire down on the far left-hand side of the screen, and only go up. I am not getting any immediate errors, so I am investigating into the math.

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

            I think its due to the fact that I haven’t implemented your tips correctly however.

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

              I have assigned so the new_laser.rotation is = to the player rotation, this results in lasers popping on sides, not the right sides because I probably have to switch the math.pi equations around, but they are not moving.

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

                Move the for l in self.lasers loop to the proper indentation level. This should not be inside any of the touch handling code.

                You will then use the l.rotation to set the motion direction.

                Also, you will eventually need code that deletes lasers once they are off screen ( in that loop, check if laser.bbox is in self.bbox)

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

                  Um, sorry? I don’t really understand. I have properly indented the for l in self.lasers part, I don’t know how to add l.rotation to set motion direction.

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

                    Post your code. The last version you posted had the laser motion code INSIDE the touch handling code, which means the code would only execute when the fire button was being pressed.

                    1 Reply Last reply Reply Quote 0
                    • BurntRice
                      BurntRice last edited by ccc

                      from scene import *
                      import math
                      A = Action()
                      
                      
                      #Setting up background colour for the entire scene
                      class Game(Scene):
                          
                          def setup(self):
                              self.bg = SpriteNode('spc:BackgroundBlack')
                              self.lasers = []
                              
                              #Creating the player
                              self.Player = SpriteNode('shp:RoundRect')
                              self.Player.color = ("cyan")
                              self.Player.anchor_point = (0.5, 0.5)
                              self.Player.position = (512, 400)
                              self.Player.rotation = 0.0
                              self.add_child(self.Player)
                              
                              self.UpCrtl = SpriteNode('iow:arrow_up_b_32')
                              self.UpCrtl.x_scale = 3.5/1.0
                              self.UpCrtl.y_scale = 3.5/1.0
                              self.UpCrtl.alpha = 0.5
                              self.UpCrtl.position = (175, 295)
                              self.add_child(self.UpCrtl)
                              
                              self.DownCrtl = SpriteNode('iow:arrow_down_b_32')
                              self.DownCrtl.x_scale = 3.5/1.0
                              self.DownCrtl.y_scale = 3.5/1.0
                              self.DownCrtl.alpha = 0.5
                              self.DownCrtl.position = (175, 130)
                              self.add_child(self.DownCrtl)
                              
                              self.RightCrtl = SpriteNode('iow:arrow_right_b_32')
                              self.RightCrtl.x_scale = 3.5/1.0
                              self.RightCrtl.y_scale = 3.5/1.0
                              self.RightCrtl.alpha = 0.5
                              self.RightCrtl.position = (250, 212.5)
                              self.add_child(self.RightCrtl)
                              
                              self.LeftCrtl = SpriteNode('iow:arrow_left_b_32')
                              self.LeftCrtl.x_scale = 3.5/1.0
                              self.LeftCrtl.y_scale = 3.5/1.0
                              self.LeftCrtl.alpha = 0.5
                              self.LeftCrtl.position = (100, 212.5)
                              self.add_child(self.LeftCrtl)
                              
                              #The button for shooting
                              self.laserButton = SpriteNode('shp:Circle')
                              self.laserButton.color = ('gray')
                              self.laserButton.x_scale = 3/1
                              self.laserButton.y_scale = 3/1
                              self.add_child(self.laserButton)
                              self.laserButton.position = (1000, 212.5)
                              
                              #The score label
                              self.score_label = LabelNode(text='Score: 0')
                              self.score_label.anchor_point = (0, 0)
                              self.score_label.position = (10, 790)
                              self.score_label.font = ('Arial Rounded MT Bold', 30)
                              self.add_child(self.score_label)
                      
                          #Movement code.
                          def update(self):
                              for touch in self.touches.values():
                                  if touch.location in self.LeftCrtl.bbox:
                                      new_x = self.Player.position.x - 5
                                      self.Player.rotation = math.pi*3/2
                                      if new_x >= 0 and new_x <= 1100:
                                          self.Player.position = (new_x, self.Player.position.y)
                                          
                                  if touch.location in self.RightCrtl.bbox: 
                                      new_x = self.Player.position.x + 5
                                      self.Player.rotation = math.pi/2
                                      if new_x >= 0 and new_x <= 1100:
                                          self.Player.position = (new_x, self.Player.position.y)
                                  
                                  if touch.location in self.UpCrtl.bbox:
                                      new_y = self.Player.position.y + 5
                                      self.Player.rotation = 0.0
                                      if new_y >= 0 and new_y <= 800:
                                          self.Player.position = (self.Player.position.x, new_y)
                                      
                                  if touch.location in self.DownCrtl.bbox: 
                                      new_y = self.Player.position.y - 5
                                      self.Player.rotation = math.pi
                                      if new_y >= 0 and new_y <= 800:
                                          self.Player.position = (self.Player.position.x, new_y)
                                          
                                  if touch.location in self.laserButton.bbox:
                                      new_laser = SpriteNode('spc:LaserBlue6')
                                      new_laser.rotation = self.Player.rotation
                                      direction = Vector2(-math.sin(new_laser.rotation), math.cos(new_laser.rotation))
                                      self.add_child(new_laser)
                                      self.lasers.append(new_laser)
                                                  
                                  for l in self.lasers:
                                      l.position += direction*75
                      
                      
                      if __name__ == '__main__':
                          run(Game(), LANDSCAPE, show_fps=True)
                      
                      JonB 1 Reply Last reply Reply Quote 0
                      • ccc
                        ccc last edited by ccc

                        Can

                                    if touch.location in self.DownCrtl.bbox: 
                                        new_y = self.Player.position.y - 5
                                        self.Player.rotation = math.pi
                                        if new_y >= 0 and new_y <= 800:
                                            self.Player.position = (self.Player.position.x, new_y)
                        

                        be simplified to

                                    if touch.location in self.DownCrtl.bbox:
                                        self.Player.rotation = math.pi
                                        if 0 <= new_y <= 800:
                                            self.Player.position.y -= 5
                        
                        1 Reply Last reply Reply Quote 0
                        • JonB
                          JonB @BurntRice last edited by

                          @BurntRice okay, so

                          l.position += direction*75
                          

                          Let's think about this for a minute. Where have you defined direction? Remember, the goal here in the movement code is to figure out the direction for EACH laser that you are moving. So, you need to figure out the direction Vector2 based on each laser's rotation.

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

                            Perhaps

                                        for l in self.lasers:
                                            l.position += direction*75
                            

                            needs to be indented under the if touch.location in self.laserButton.bbox: block where direction is defined.

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

                              No. Trying the Socratic method to get him to think about his own code...

                              This would be simpler if the touch code and laser update code were their own functions, as they are completely independent. The fact that he shares a direction variable name is what is confusing him.

                              The touch code creates a laser. The laser created is spawned, and the code that sets the rotation and initial offset.

                              The code that moves the lasers is completely separate (one needn't have touch code at all to move laser objects). Lasers move even when buttons are not touched. So, how can you figure out what direction a given laser should travel?

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

                                I’ve made it so my laser shoots in the direction that I want it to, but, they are not moving. Once one laser pops up, the next one goes 75 pixels ahead, for ad infinitum. I don’t know if this is because of where I indented my direction value, but I don’t think so as that is mostly for rotation; nothing about moving forward etc.

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

                                  So you have code which is moving your laser, but it is only running once?

                                  Go back and look at all of your code to see if your indentation is correct. If you want laser movement code to run every update cycle, and it isn't, there must be some control code (if, for, with, while, etc ) that is preventing it from running.

                                  What will help you in this case is to break your update function into functions that you call, so that you can better follow the program flow. Once an indented section of code gets to be longer than a screenfull, that's a good indication that you might need a function.

                                  For instance, if each button had it's own method. Or, if all of your touch handling had it's own method. Then your update method would be easier for you to follow:

                                  def update (self):
                                     handleTouches(self)
                                     moveLasers(self)
                                     checkCollisions(self)
                                     spawnEnemies(self)
                                  
                                  1 Reply Last reply Reply Quote 0
                                  • BurntRice
                                    BurntRice last edited by ccc

                                    I have been looking for quite a bit, and I’m really blind, but I can’t find any indentation errors.

                                    from scene import *
                                    import math
                                    A = Action()
                                    
                                    
                                    #Setting up background colour for the entire scene
                                    class Game(Scene):
                                    
                                        def setup(self):
                                            self.bg = SpriteNode('spc:BackgroundBlack')
                                            self.lasers = []
                                    
                                            #Creating the player
                                            self.Player = SpriteNode('spc:Fire1')
                                            self.Player.color = ("cyan")
                                            self.Player.anchor_point = (0.5, 0.5)
                                            self.Player.x_scale = 2/1.0
                                            self.Player.y_scale = 1.5/1.0
                                            self.Player.position = (512, 400)
                                            self.Player.rotation = 0.0
                                            self.add_child(self.Player)
                                    
                                            self.UpCrtl = SpriteNode('iow:arrow_up_b_32')
                                            self.UpCrtl.x_scale = 3.5/1.0
                                            self.UpCrtl.y_scale = 3.5/1.0
                                            self.UpCrtl.alpha = 0.5
                                            self.UpCrtl.position = (175, 295)
                                            self.add_child(self.UpCrtl)
                                    
                                            self.DownCrtl = SpriteNode('iow:arrow_down_b_32')
                                            self.DownCrtl.x_scale = 3.5/1.0
                                            self.DownCrtl.y_scale = 3.5/1.0
                                            self.DownCrtl.alpha = 0.5
                                            self.DownCrtl.position = (175, 130)
                                            self.add_child(self.DownCrtl)
                                    
                                            self.RightCrtl = SpriteNode('iow:arrow_right_b_32')
                                            self.RightCrtl.x_scale = 3.5/1.0
                                            self.RightCrtl.y_scale = 3.5/1.0
                                            self.RightCrtl.alpha = 0.5
                                            self.RightCrtl.position = (250, 212.5)
                                            self.add_child(self.RightCrtl)
                                    
                                            self.LeftCrtl = SpriteNode('iow:arrow_left_b_32')
                                            self.LeftCrtl.x_scale = 3.5/1.0
                                            self.LeftCrtl.y_scale = 3.5/1.0
                                            self.LeftCrtl.alpha = 0.5
                                            self.LeftCrtl.position = (100, 212.5)
                                            self.add_child(self.LeftCrtl)
                                    
                                            #The button for shooting
                                            self.laserButton = SpriteNode('shp:Circle')
                                            self.laserButton.color = ('gray')
                                            self.laserButton.x_scale = 3/1
                                            self.laserButton.y_scale = 3/1
                                            self.add_child(self.laserButton)
                                            self.laserButton.position = (1000, 212.5)
                                    
                                            #The score label
                                            self.score_label = LabelNode(text='Score: 0')
                                            self.score_label.anchor_point = (0, 0)
                                            self.score_label.position = (10, 790)
                                            self.score_label.font = ('Arial Rounded MT Bold', 30)
                                            self.add_child(self.score_label)
                                    
                                        #Movement code.
                                        def update(self):
                                            for touch in self.touches.values():
                                                if touch.location in self.LeftCrtl.bbox:
                                                    new_x = self.Player.position.x - 5
                                                    self.Player.rotation = math.pi/2
                                                    if new_x >= 0 and new_x <= 1100:
                                                        self.Player.position = (new_x, self.Player.position.y)
                                    
                                                if touch.location in self.RightCrtl.bbox:
                                                    new_x = self.Player.position.x + 5
                                                    self.Player.rotation = math.pi*3/2
                                                    if new_x >= 0 and new_x <= 1100:
                                                        self.Player.position = (new_x, self.Player.position.y)
                                    
                                                if touch.location in self.UpCrtl.bbox:
                                                    new_y = self.Player.position.y + 5
                                                    self.Player.rotation = 0.0
                                                    if new_y >= 0 and new_y <= 800:
                                                        self.Player.position = (self.Player.position.x, new_y)
                                    
                                                if touch.location in self.DownCrtl.bbox:
                                                    new_y = self.Player.position.y - 5
                                                    self.Player.rotation = math.pi
                                                    if new_y >= 0 and new_y <= 800:
                                                        self.Player.position = (self.Player.position.x, new_y)
                                    
                                                if touch.location in self.laserButton.bbox:
                                                    new_laser = SpriteNode('shp:Circle')
                                                    new_laser.x_scale = 0.25/1.0
                                                    new_laser.y_scale = 0.25/1.0
                                                    new_laser.position = self.Player.position
                                                    new_laser.rotation = self.Player.rotation
                                                    direction = Vector2(-math.sin(new_laser.rotation), math.cos(new_laser.rotation))
                                                    self.add_child(new_laser)
                                                    self.lasers.append(new_laser)
                                                    for l in self.lasers:
                                                        l.position += direction*75
                                    
                                    
                                    if __name__ == '__main__':
                                        run(Game(), LANDSCAPE, show_fps=True)
                                    
                                    1 Reply Last reply Reply Quote 0
                                    • JonB
                                      JonB last edited by JonB

                                      Think about what should happen when you lifr your finger. Remember, update gets called 60 times per second.

                                      Do you want the existing lasers to keep moving? Or move only when your finger is down, and freeze when your finger is up.

                                      I would suggest rewriting your update function as follows, to make it easier for you to follow:

                                         def update(self):
                                            self.handle_button_presses()
                                            self.move_lasers()
                                      

                                      Your touch handling code then moves to one method, and other game logic moves to their own functions, and get called from update. For example, eventually you might be moving enemies or asteroids or the map. You might be spawning enemies at certain intervals, which would also be it's own method. Thus, you would create a spawn_enemies, and move_enemies methods, maybe a scroll_map if this is scroller type game, perhaps a check_collisions which checks if the player hit any obstacles or enemies, etc. You should be able to write your entire update method using dummy methods that sort of lay out what you need to work in, and can implement the methods one at a time, since they should all be mostly independent of each other, just depending on a common set of attributes or positions.

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

                                        I want my existing lasers to keep on moving. I have also implemented your idea of rewriting my update function.
                                        I really don’t know how to though. If I use a touch.began method, it runs once, but stays in it’s place.
                                        Am I forgetting to add something?

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

                                          Okay, let's try this again.

                                          If you want your laser to move, the movement code must be called EVERY time update is called. There should be no if statements around the for loop that moves the lasers.

                                          In your old code the laser loop was inside the if statement that checked for the laser button touch. That's why it doesn't move when your finger is up. You will need to update your loop because the direction variable that you use for moving the lasers must be define inside the loop, because it can be different for every laser. You'll need to grab the laser rotation for each laser to figure that out.

                                          Post your new updated 5 line update method. And post your update_laser_postions function or whatever you called it.

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

                                            def update(self):
                                            self.handle_button_presses()
                                            self.move_lasers()
                                            if random.random() < 0.01:
                                            self.spawn_item()

                                            def handle_button_presses(self):
                                                for touch in self.touches.values():
                                                    if touch.location in self.LeftCrtl.bbox:
                                                        new_x = self.Player.position.x - 5
                                                        self.Player.rotation = math.pi/2
                                                        if new_x >= 0 and new_x <= 1100:
                                                            self.Player.position = (new_x, self.Player.position.y)
                                            
                                                    if touch.location in self.RightCrtl.bbox:
                                                        new_x = self.Player.position.x + 5
                                                        self.Player.rotation = math.pi*3/2
                                                        if new_x >= 0 and new_x <= 1100:
                                                            self.Player.position = (new_x, self.Player.position.y)
                                            
                                                    if touch.location in self.UpCrtl.bbox:
                                                        new_y = self.Player.position.y + 5
                                                        self.Player.rotation = 0.0
                                                        if new_y >= 0 and new_y <= 800:
                                                            self.Player.position = (self.Player.position.x, new_y)
                                            
                                                    if touch.location in self.DownCrtl.bbox:
                                                        new_y = self.Player.position.y - 5
                                                        self.Player.rotation = math.pi
                                                        if new_y >= 0 and new_y <= 800:
                                                            self.Player.position = (self.Player.position.x, new_y)
                                            
                                            def move_lasers(self):
                                                for touch in self.touches.values():
                                                    if touch.location in self.laserButton.bbox:
                                                        new_laser = SpriteNode('shp:Circle')
                                                        new_laser.x_scale = 0.25/1.0
                                                        new_laser.y_scale = 0.25/1.0
                                                        new_laser.position = self.Player.position
                                                        new_laser.rotation = self.Player.rotation
                                                        direction = Vector2(-math.sin(new_laser.rotation), math.cos(new_laser.rotation))
                                                        self.add_child(new_laser)
                                                        self.lasers.append(new_laser)
                                                        for l in self.lasers:
                                                            l.position += direction*75
                                            
                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors