Navigation

    Fuze Arena Logo
    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Popular
    • Users
    • Groups
    • Help
    • Discord

    Finding it hard to get enemies

    Help
    5
    27
    1675
    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.
    • Dave
      Dave Fuze Team @lawyerlounge last edited by Dave

      @lawyerlounge

      Absolutely happy to. There is a way I could provide a very "simple" example, without using states etc, but in my opinion it honestly ends up being far more complicated.

      Usually I begin with something like this:

      spritesheet = loadImage("filename")
      sprite = createSprite()
      setSpriteImage( sprite, spritesheet )
      
      // Now we create an array of animation data. Each element of this array is an array of two elements, the start tile and the end tile. 
      // Numbers are of course arbitrary.
      playerAnimationData = [
          [ 0, 6 ], // let's say this is the idle animation
          [ 7, 20 ], // this one could be an attack animation
          [ 21, 30 ] // this one could be jump
      ]
      
      // Now we make state variables to use as indexes into that animation array:
      idle = 0
      attack = 1
      jump = 2
      
      // Now the variable to store the current state
      state = idle
      
      // We will also **need** to keep track of the player's **old state**, in order to tell when we change animation.
      oldState = -1 // Making it -1 for now because we'll be setting it properly in the loop.
      
      // Lastly, a flag variable make sure that we only trigger the ``setSpriteAnimation()``` once
      animSwitch = false
      

      Okay, with that done, we can have something like the following in our main loop:

      loop
          clear()
          updateSprites()
          j = controls(0)
      
          // It's extremely useful to know which frame of animation you character is on, so let's make a local variable for that:    
          playerFrame = getSpriteAnimFrame( sprite )    
      
          // If A is pressed and the character was not previously in the jump state, enter jump state and set the animSwitch
          if j.a and oldState != jump then
              animSwitch = true
              state = jump
          endif
      
          // You might want your attack to only be possible if the player is not jumping, for instance:
          if j.x and oldState != attack and oldState != jump then
              animSwitch = true
              state = attack
          endif    
      
          // With the sprite's current animation frame known, we can also easily return to idle after certain animations:
          if state == attack and playerFrame >= playerAnimationData[state][1] then
              animSwitch = true
              state = idle
          endif
      
          // Notice that in our if statements, we simply need only change the state and turn the animation switch on. If we weren't using an array of animation data with a state machine,
          // we would have to do separate ```setSpriteAnimation()``` calls for each if statement. This ends up being quite cluttered and not so simple when you've got a large scale project.
          
          // However, with this way of doing things, we simply need this one if statement at the end. We check if the current state is != oldState and if our switch is on:
          if state != oldState and animSwitch then
              // playerAnimationData[ state ][0] contains the start tile for the current state, playerAnimationData[ state ][1] is the end tile
              setSpriteAnimation( sprite, playerAnimationData[ state ][0], playerAnimationData[ state ][1], 10 ) // 10 fps is arbitrary
              animSwitch = false // turn the switch off
          endif
          
          // Finally, we update the oldState variable to contain the current state at the end of the frame.
          oldState = state
          update()
      repeat
      

      I might be missing a couple of small details here as I didn't want to overload, but this is the method I'm using in the updated gothic Vania demo and it works nicely. It also grants you a lot of control over which states happen when.

      Actually, looking at this I'm not sure you actually need the animSwitch variable, since just knowing if the state is not equal to the old state might be enough. I would use it for good measure!

      I really hope this is what you were looking for. Please let me know if I can elaborate on anything at all.

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

        Thanks again for a great example. I noticed there was no use of drawSprites() in your loop. Is that possibly the reason I had issues with the animation not running?

        image = loadImage("filename")
        sprite = createSprite()
        setSpriteImage( sprite, image)
        
        startFrame = 0
        endFrame  = 10
        fps = 10
        
        Loop
              clear()
            
              setSpriteAnimation( sprite, startFrame, endFrame, fps)
        
              updateSprites()
              drawSprites()
        
              update()
        repeat
        

        I remember just trying to get the animation to work anywhere inside the loop (without any states or conditions) resulted in no movement at all. Is it because I was misusing some sort of update() command or drawSprites() command, and it kept redrawing the initial start frame and not allowing the animation to count up to 10 at 10 fps? I'm at work and away from my switch, but I believe I tried almost all combinations of including/excluding any update() draweSprites() and updateSprites() to no avail.

        Does that make sense though?

        pianofire 1 Reply Last reply Reply Quote 0
        • pianofire
          pianofire Fuze Team @lawyerlounge last edited by pianofire

          @lawyerlounge setSpriteAnimation() initializes the animation. If you call it in your game loop it will keep resetting it back to the beginning. The updateSprites() call is the one that will move the animation forward. drawSprites() will actually draw them into video memory and update() will render that to the screen.

          So this should work (let me know if it doesn't). You also need to set the sprite location using setSpriteLocation

          sprite = createSprite()
          setSpriteImage( sprite, image)
          setSpriteLocation(sprite, gwidth()/2, gheight()/2)
          startFrame = 0
          endFrame  = 10
          fps = 10
          setSpriteAnimation( sprite, startFrame, endFrame, fps)
          
          Loop
                clear()
              
          
                updateSprites()
                drawSprites()
          
                update()
          repeat
          
          1 Reply Last reply Reply Quote 0
          • Jonboy
            Jonboy Fuze Team last edited by

            Ha Waldron... "Finding it hard to get enemies".. I make new ones every day!

            Sorry.. can't be much more help than that at the moment. See what I mean.

            waldron 1 Reply Last reply Reply Quote 0
            • lawyerlounge
              lawyerlounge last edited by

              What is the main difference from Dave's example (2 posts up) and my example (which both at some point have the setSpriteAnimation() function inside of the main loop) that would cause his to work and mine not to.

              Other than having "if statements" (which basically change a variable called "state" which in turn changes the startFrame and endFrame vars for the arguments within setSpriteAnimation), and providing a check to see if the current state is not what it used to be, what causes the program in Dave's post to let the animation run from start to finish without constantly executing the beginning of the animation? (the problem you dissected within my example)

              Or is the method of checking if state != oldState required, because if you intend an animation to change throughout the main loop you need to find a way to only run it once at particular moments? And for any asset that doesn't need to change animations you would just use the setSpriteAnimation function before the main loop and set the visibility to false until needing to display?

              I think I've figured out the bare requirements for using sSA() in the loop... would this work?

              sprite = createSprite()
              setSpriteImage( sprite, image)
              setSpriteLocation(sprite, gwidth()/2, gheight()/2)
              startFrame = 0
              endFrame  = 10
              fps = 10
              
              animSwitch = true
              
              Loop
                    clear()
                   
                    currentFrame = getSpriteAnimFrame( sprite )
              
                    if animSwitch then
                          setSpriteAnimation( sprite, startFrame, endFrame, fps)
                          animSwitch = false
                    endif
              
                    if currentFrame >= endFrame then
                          animSwitch = true
                    endif
              
                    updateSprites()
                    drawSprites()
              
                    update()
              repeat
              

              P.S. thank you for all of the help teaching me something that must be simple for you guys!
              -MikeV

              pianofire 1 Reply Last reply Reply Quote 0
              • pianofire
                pianofire Fuze Team @lawyerlounge last edited by

                @lawyerlounge Not at all. That's what we are here for. Yes you only want to call setSpriteAnimation to change the current animation. The set animation will be repeated until a new one is set. If you want more control over the animation you can use setSpriteAnimFrame but you will have to control the speed yourself:

                https://fuzearena.com/help/view/setSpriteAnimFrame

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

                  Nice! so my example should display the animation on loop? (not at home yet to test it)

                  pianofire 1 Reply Last reply Reply Quote 0
                  • pianofire
                    pianofire Fuze Team @lawyerlounge last edited by

                    @lawyerlounge Well I haven't tried it but yes it looks like it should

                    1 Reply Last reply Reply Quote 0
                    • waldron
                      waldron F @Jonboy last edited by

                      @Jonboy haha i must be to nice

                      1 Reply Last reply Reply Quote 1
                      • Jonboy
                        Jonboy Fuze Team last edited by

                        ha, but not TOO nice. See, i did it again. Seriously, you should not invite me to comment :-)

                        1 Reply Last reply Reply Quote 1
                        • Dave
                          Dave Fuze Team last edited by

                          @lawyerlounge My bad! Completely forgot about perhaps the most important command, drawSprites(), in the example I gave.

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post