Pages

Saturday, August 25, 2012

11: 3-Hit Barrage

This time we actually give Tanner access to his full three hit combo, and let him swing to the left finally.

Explaining this part is going to be a little difficult, as my approach was much different than most other moments. See, the next two steps are fairly simple in theory, but I ran into problems every step of the way.

The easier issue to deal with is Tanner's inability to strike anything to his left. After duplicating and flipping Tanner's combo graphic to face the left, all you really have to do is add a bunch of OR statements to any if statement involving the attack graphic.

The more difficult issue is letting him perform swing 2 and 3. Just like with the directional issue, I had to add a bunch of OR statements for the 9th and 19th frame. The next step is a little more complicated, sorta.

Every time the player presses Z to reactivate the attack, the frame is reset to 0. We need an exception. There's a few we could use, but I just ended up with this:

Step Event:
if ((sprite_index == spr_tswingr) || (sprite_index == spr_tswingl))
{
     image_index += 1
}
else
{
     image_index = 0
}

And... that's about it. Every single part of this post was a mess of trial and error. I added some code, tested to see if it worked, and if it didn't, I fixed the typo or adjusted the logic. For the most part, you should definitely check out the .gml file and read the code.

A couple of pieces of advice I learned from this however:

   Be very careful with your parenthesis, especially when it comes to ANDs and ORs.

   Be careful mixing "!=" (NOT) with ANDs and ORs. The logic becomes fairly difficult to follow, and usually your code won't work.

Here's the .gml file:
     https://www.dropbox.com/s/4n0ewv0lyvfj9ni/11%203-Hit%20Barrage.gm81
Here's the .exe file:
     https://www.dropbox.com/s/ly8i6mo3vxjpi1l/11%203-Hit%20Barrage.exe

Friday, August 24, 2012

10b: Taking Swipes Return

One thing I neglected to mention in the last post was the bugs that crept up on me. When i originally worked on the last blog post, I actually wrote it all out before even trying it. Not the smartest thing to do, no, but since what I was doing would work in theory (and wasn't too complicated), I figured it was worth a shot. Fortunately it worked, but not without a lot of bugs. What you ended up seeing me typing was a fully working version, but I actually had several problems along the way. I figure I should go over them now, since debugging is a very important skill to learn.

The biggest problem early on is the alarm event. Originally the code read like this:

End Step:

if (sprite_index == spr_tswingr)
{
     if (image_index == 4)
     {
          image_speed = 0
          lightable = 1
          alarm[0] = 8
     }
}

This originally caused me trouble. Why? Because in the current code, the alarm is reset to 8 every frame as long as Tanner is on his 4th slashing frame, leaving him stuck there. That's why I finally touched it up to:

End Step:

if (sprite_index == spr_tswingr)
{
     if (image_index == 4)
     {
          image_speed = 0
          lightable = 1
          if (alarm < 0)
          {
               alarm[0] = 8
          }
     }
}

With this if statement added, the alarm won't constantly reset itself. Unfortunately, this also means that we have to make sure the alarm is turned off before it reaches this bit of code.

Next off is a small detail, but one I forgot early on.


Step Event:
if (keyboard_check_pressed(z) && lightable == 1)
{
     runable = 0
     jumpable = 0
     lightable = 0
     sprite_index = spr_tswingr
     image_index = 0
     image_speed = (1/2)
}

Early on when repeating the attack animation, I noticed that he wouldn't actually change frames because I never bothered to type in image_index = 0.

That's about it for now. I just thought I'd address the issue, since the last post I ignored all the bugs I ran into.


Thursday, August 23, 2012

10: Taking Swipes

I'm back!

Now that we've given our hero the ability to move about, it's time to move onto the real fun stuff, swinging his sword. Don't laugh please...

No laughing permitted. You can however, chuckle or snicker.

From this point on, I honestly don't know what I'm doing. I've read enough guides on how to make a platformer I could do so without too much hassle. From this point forward, all bets are off, and I'll be trying whatever I can think of. This again stresses what this blog is really supposed to be about: expressing the mindset of a programmer, particularly from a beginner.

As before with movement, the first thing to do is add the sprites into Game Maker. It can be especially troublesome since the sword's width means you have to really extend the sprite's boundaries, which can make adjusting the sprite rather frustrating.


Unlike running and jumping, we need to add the animation first. Now that we have the graphics loaded, we should be able to make our hero slash by typing something like:

Step Event:
if keyboard_check_pressed(z)
{
     sprite_index = spr_tswingr
}

Or not. This code will do absolutely nothing. The problem here is that no matter what, our character's sprite changes based on his movement. Everything we've done so far has been done assuming that running and jumping is the only thing our character can do. From this point forward we have to use variables to set up what your character can and cannot do, and what actions he is performing.

The way I originally did this was through a universal variable called state. Depending on what number it was set to would define what action the character was in the middle of. For example: 1 would mean the player could move, 2 would mean the player was performing a light attack, 3 would mean the player was performing a strong attack, 4 would mean the player was taking damage and so on. The problem with this method was that it was either too general or each state had to be made so specific it became tedious.

Instead we're going to use a series of variables to determine what the player is allowed to do. This means we can controls things a lot closer, and change things on the fly as well. Instead of me rambling on about this though, let's actually try it out.

First let's add the variables:

Create Event:
runable = 1
jumpable = 1
lightable = 1             //able to perform light attack
gravable = 1             //if 0, deactivates gravity for player (for aerial attacks perhaps)

Next, we have to add these new conditions to our original code. We could add new if statements around everything, but it'll look really messy and could be trouble. Fortunately, there's a much easier solution, AND. By adding and/&& inbetween conditional statements, both have to be true in order to work.


From this point on, we can turn the player's controls on or off whenever we want. For instance, now when we add in our sword slash:

Step Event:
if (keyboard_check_pressed(z) && lightable == 1)
{
     runable = 0
     jumpable = 0
     lightable = 0
     sprite_index = spr_tswingr
     image_index = 0
     image_speed = (1/2)
}

...it negates our player's ability to move, jump, or activate the attack swing once more.

Can't... move...

Unfortunately this just causes the poor character to be stuck in his idle animation, since he cannot move and the End Step still changes his sprite despite the restrictions. Perhaps we should fix this.


Now our hero finally can slash that stupid sword of his, and he will continually slash it until his arm falls off. He's stuck in a loop because we haven't actually added anything to stop him from swinging, and perhaps more importantly, let him move once more. This is where things can get a bit dicey, so I'll try and lay it out as plainly as possible.

Again, no laughing, but perhaps a chortle.
It's a very badly flowing flow chart, but this is laying out exactly how I want the character to perform his 3-hit combo. Try playing any 2 games with simple 3-hit combos and you'll find they all have different rules and nuances. To the player, these minor elements aren't really thought about in any kind of intense detail, but to programmers like you and me spreading everything out not only allows us better control over how our game is played, but makes translating ideas to code much easier.

For now, I just want to work with the very first sword swing animation. Let's go to our End Step, shall we?

End Step:
if (sprite_index == spr_tswingr)
{
     if (image_index == 4)
     {
          image_speed = 0
          lightable = 1
          if (alarm < 0)
          {
               alarm[0] = 8
          }
     }
}

Now Tanner stops swinging at the last frame of his sword swing. You may have noticed I used two if statements instead of just &&. I did this solely because I will be adding more conditional statements later, and it just seemed easier to bunch them altogether underneath one if statement, but that is for later. For now, we should actually write some code for that alarm, or else Tanner is now stuck awkwardly holding his blade to the side. Add an event for Alarm 0 and add:

Alarm 0:
if (sprite_index == spr_tswingr) && (image_index ==4)
{
     alarm[0] = -1
     runable = 1
     jumpable = 1
     movable = 1
     lightable = 1
}

As you can see, the if statements are starting to get much more specific, but that isn't necessarily a bad thing. The ifs are actually unnecessary, but it's good to be careful now instead of having to fix everything later.

As a final touch, now that we are using an alarm, we should turn it off whenever we start a new attack to prevent it from stopping the character mid-swing, so let's add one final bit:

Step Event:
if (keyboard_check_pressed(z)) && (lightable == 1)
{
     runable = 0
     jumpable = 0
     lightable = 0
     alarm[0] = -1
     sprite_index = spr_tswingr
     image_index = 0
     image_speed = (1/2)
}

As a little thing to note, alarms are a very useful feature of Game Maker. You can simulate your own fairly easily, but they actually gave them some nice functionality. They always stop at 0, and setting them to any negative number turns them off immediately. The only annoying part to me is that in order to use them you have to actually create an alarm Event for them to function, instead of just working automatically and allowing you to use a simple if statement.

Next, we add more to the combo, and try to get Tanner to swing to the left.

Here's the .gml file:
     https://www.dropbox.com/s/pyyn63er0e14spd/10%20Taking%20Swipes.gm81
Here's the .exe:
     https://www.dropbox.com/s/g9elezj611gblnk/10%20Taking%20Swipes.exe