Yeah, let's take a break today from our normally scheduled programming chat to consider some design stuff today. I did have some trickiness making my new shooting mechanic work better, but that mostly has to do with the fact that I can't remember what I named stuff. Either way, now the Fortress type enemies no longer use a rectangle to keep track of stuff. Instead they use that sweet code I wrote to calculate bullet trajectories. Most of if anyway, since it can also calculate absolute distances.
Which gets me to my point (pretty quick today). Now Fortress enemies shoot at the player if they are nearby, which is what the document said that it should. More specifically it shoots at the closest player. The $64,000 question though, is if a player moves out of that range, should the Flying Fortress enemies still shoot at them? On this, I am torn. As always, let's do a series of thought experiments to see what happens.
Let's first assume that they do not shoot at a player who is no longer near them. This is how the game is currently set up. In this case they will fly on through and only attack if you are near them. Avoid their initial shots and they move along. Nothing too bad really. Provided that multiple people are playing, I can see this enemy type putting a shitload of fire on the screen, since it will move cleanly along the screen and attack players 1 at a time. This would also allow the bomb carrier to be more or less safe, even in single player.
Now on the other hand let's assume that the Fortress kept targeting a player even though they left the firing area. This has the cute ability to have a Fortress long ball a player from across the screen. Add to that the weird gift that slightly rounds off the angles a little (leaving open zones where they can't actually shoot) and the addition of the bullets makes for some serious crazy.
But now that I think about it, here are the problems I'm finding:
1) The Bomb mechanic would not jive with this mechanic anymore, especially in single player. The bullets don't just exist in a vacuum, but instead live in an ecosystem of all kinds of hideous destructive things. The addition of a Dive Bomber to a mix with Fortresses shooting would probably cost the lives of digital Zeppelin crew.
2) It seems less fun. While I know that knowing whether something will be "fun" or not is pretty subjective, the proof being in the pudding so to speak, this strikes me as annoying and contrary to the gameplay. I'll explain.. If the game was designed to be a slower affair with more thinking and the possibility of setting up a win-less situation, then having the long firing would be okay. As it is, if a single player were to get just a little too close to a Flying Fortress they would be harassed until the lil' bastard finally left the screen. Being afraid to move the player around strikes me as less fun.
So there we go then. The issue is handled. Now I got some color to that list.
-Speaking of the list there are some things I'm not ready to share yet. The thing I want to talk about is that odd (?) next to Multiplayer. The thing is, for all intents and purposes the multiplayer works. Every enemy is designed for it, and every game system can theoretically handle it. Hypothetically I could have a hundred players...although that would be stupid. No, the big reason for the colored in question mark, is that I only have the 1 XBox controller for my PC. I get the impression there will be a lot of testing on the XBox when I launch on XNA.
Thursday, March 31, 2011
Wednesday, March 30, 2011
Hard Cast
As weird as it may sound, all of that somewhat esoteric math that I previously talked about was somewhat tricky to actually implement. First I had the issue of looking around for the command that let's me figure out the square root of something (an important bit of the Pythagorean Principal), and then I ran into the real problem. You see, most computer languages have lots and lots of different ways to say the same fuggin thing. Let's explore the menagerie, shall we?
The classic one is an Integer. These little brutes only deal with whole solid numbers. These are the ones most people think about when the term "number" is thrown about. In computer land they take up a reasonable about of space since they have a pretty wide range of numbers. These are what I tend to use the most since I can use some math and get really good mileage out of them.
The first oddity is something called a Bool. These particular beasties can only ever be a 1 or a 0, but take up so little space that they are almost free. These will usually have a special property where the 1 and 0 will be magically translated into True and False. It also works both ways, so you can create a Bool that is equal to one of those like this : Bool Number = True;
Next up is a sweet baby called a Float. The "floating" part of these numbers refers to the "Floating Point" decimal place. These are how we get tiny little fractions like 2.0012. In terms of what I was doing, these kinds of numbers are needed for things like a square root calculation to work. They take up way more space than an Integer though, since the computer has to constantly keep track of the damned decimal point and do all the extra math to make sure it always ends up in more or less the right place.
Finally we have the freakish and rare monster known as the Double. Here the name refers to the space itself. It "Double" the amount used by an Integer. This extra space gives them crazy range in terms of what kinds of numbers that you want to think about. Like, if you were going to build a program that counted up stars, then you're going to want to use a Double. I almost never use this, since there is almost nothing that I've ever had to code that needs numbers that huge.
"But why!? Why assault us with this nonsense?" Well, there's a reason for that. The issue that I was having tonight is that Int 1, Bool 1, Float 1.0 and Double 1 are not the same gods damned number. Basically I did all of my math using a Float, since I really could use those sweet decimal places to make sure that the square roots worked. When the math was figured out I fed the answers into the waiting, gaping maw of the function that makes enemy bullets.
Then the program had an error. It kept saying (and here come the titles) that I didn't "Cast" the number correctly. The thing is that even though we know what the number is, the computer doesn't. That "1" is stored in tables of 1's and 0's. So the Integer 1 may look like this : 00001, but the double of the same thing has 63 zeroes instead. The computer, regardless of how much memory it has or how fast the processor may be, is actually a stupid beast. So, what kept me busy for my specified coding time today was trying to make the system convert the numbers.
What I finally found was that I could take almost any similar values and explicitly tell them to do something. So this works : Int Number = (int) FloatNumber;
I know, a "Float Number" does in fact sound like a premium mattress. Anyhow, once I discovered that particular bit of something, the program compiled and those flying fortress enemies proceeded to shoot the shite out of me. They tracked me, the math worked, the bullets streamed out like targeted laser win. The whole system still works for crap, but at least the math worked. No fiddling, no rewriting. Once the casting was worked out, the math proved to be correct from the start. So in spite of all of that, it was a good day for development.
The classic one is an Integer. These little brutes only deal with whole solid numbers. These are the ones most people think about when the term "number" is thrown about. In computer land they take up a reasonable about of space since they have a pretty wide range of numbers. These are what I tend to use the most since I can use some math and get really good mileage out of them.
The first oddity is something called a Bool. These particular beasties can only ever be a 1 or a 0, but take up so little space that they are almost free. These will usually have a special property where the 1 and 0 will be magically translated into True and False. It also works both ways, so you can create a Bool that is equal to one of those like this : Bool Number = True;
Next up is a sweet baby called a Float. The "floating" part of these numbers refers to the "Floating Point" decimal place. These are how we get tiny little fractions like 2.0012. In terms of what I was doing, these kinds of numbers are needed for things like a square root calculation to work. They take up way more space than an Integer though, since the computer has to constantly keep track of the damned decimal point and do all the extra math to make sure it always ends up in more or less the right place.
Finally we have the freakish and rare monster known as the Double. Here the name refers to the space itself. It "Double" the amount used by an Integer. This extra space gives them crazy range in terms of what kinds of numbers that you want to think about. Like, if you were going to build a program that counted up stars, then you're going to want to use a Double. I almost never use this, since there is almost nothing that I've ever had to code that needs numbers that huge.
"But why!? Why assault us with this nonsense?" Well, there's a reason for that. The issue that I was having tonight is that Int 1, Bool 1, Float 1.0 and Double 1 are not the same gods damned number. Basically I did all of my math using a Float, since I really could use those sweet decimal places to make sure that the square roots worked. When the math was figured out I fed the answers into the waiting, gaping maw of the function that makes enemy bullets.
Then the program had an error. It kept saying (and here come the titles) that I didn't "Cast" the number correctly. The thing is that even though we know what the number is, the computer doesn't. That "1" is stored in tables of 1's and 0's. So the Integer 1 may look like this : 00001, but the double of the same thing has 63 zeroes instead. The computer, regardless of how much memory it has or how fast the processor may be, is actually a stupid beast. So, what kept me busy for my specified coding time today was trying to make the system convert the numbers.
What I finally found was that I could take almost any similar values and explicitly tell them to do something. So this works : Int Number = (int) FloatNumber;
I know, a "Float Number" does in fact sound like a premium mattress. Anyhow, once I discovered that particular bit of something, the program compiled and those flying fortress enemies proceeded to shoot the shite out of me. They tracked me, the math worked, the bullets streamed out like targeted laser win. The whole system still works for crap, but at least the math worked. No fiddling, no rewriting. Once the casting was worked out, the math proved to be correct from the start. So in spite of all of that, it was a good day for development.
Saturday, March 26, 2011
Chasing Butterflies
I've been busy recently. Not really doing much other than this new project that I've been assigned. Since the nature of the project is somewhat hush with a little more hush involved, I'm not exactly sure what or how much I can talk about it. So, I'll not mention the why, or the how right now (although it is would make a pretty excellent entry if I could) but I think I can go into the what.
Basically, I had to create some programs that do very explicit things. One of those things was to create a function that could shuffle up a standard deck of cards. One of the way that you could do that would be to use the "Random" function that almost every programming language anywhere has. These "Random" functions will usually seed their numbers with something like the milliseconds on the system clock. The problem with that is that languages are fast, really really fast. So if you were to have the system make "random" numbers with the "Random" function using the system clock, the numbers would probably look like this : 1,1,1,2,2,3,3,3,4,5,6,6,6,7,7,7...which is why I keep using the little ""'s around the word "Random."
No, to really get the things really properly shuffled I had to think of something else and it came to me while I was playing Magic. Oh, yeah, that game. So I was shuffling up and thinking. You see, in the system cards would be stored in a table with 52 cells in it. My Magic deck had around 40, but the principal is still the same. Visualize shuffling cards for a moment, but really slow. What you're doing is splitting them into piles and the adding them to each other by alternating the cards. So if you had 6 cards you would split them in half like this :
1,2,3 and 4,5,6
When you shuffle them you should then get this as the new order:
4,1,5,2,6,3
This looks more random, but since we know what we started with then all we really did was create a new pattern. We could probably express this new pattern with an equation, which doesn't really strike me as truly randomized.
I know, I know, why not just shuffle more times? Well, that's the thing. I looked up shuffling and that particular kind of shuffle returns itself to the original setting in n shuffles where n is the number of cards in the deck. That means that every single variation of that deck could be expressed and calculated in advance.
So I got to thinking, "What if," I asked myself, "I didn't just do 2 piles? What if I broke the deck into quarters and shuffled those together?" This led me to my solution, which was to do exactly that, and the use the "Random" generator to select which decks to mix together. Since the decks that were actually shuffled together would change every time I did it, and then do that a random number of times the results that I finally got were truly random. The odds of getting the exact same distribution of cards using this method is 52 to the 52nd power. Considering that there are only 10 to the 23rd power stars in the universe that's a damn lot of randomly selected variations.
With that out of the way I then had to use that to create a small program that plays . The specifics didn't take all too long, but I found that going back into Blitz Basic after playing with some of the awesome sauce that C# can do is terribly disorientating. Question like, "What do you mean I can't feed an entire table into a function?" came up, considering that much of the Paper Engine is based on doing exactly that. Also the WaitKey() command in Blitz does less than dick when you are working with the command line, so I had to create a graphics program to display my fuggin' text.
Long story short, it works now. I even got the tricky bit involving a soft <message redacted> to work correctly, and the variable nature of <message redacted> to work as well using a system of counters that keep track of things for the different players. I may eventually post my sweet <message redacted> program somewhere to show my coding prowess, but I think that the fine people at <message redacted...Hard> may think that I am sharing some kind of secret process to my legions of readers (Ha!).
-We should return to our regularly scheduled nonsense soon, once I get this hotness to its rightful place in the universe.
-The titles have almost nothing to do with the content today. Oh, there is so a reason that I call them that, other than the one I'm not about to share (state secrets, MIBs, a secret briefcase and all). Actually the Wife had picked up on of those butterfly habitats and we are watching the butterflies go through their adorable life processes. As of today they are coming out and looking all, butterfly-ish. Except for one of them anyway who came out with a weird wing. We call him Lucky, on account of his lucky wing. Oh, and he flies like a drunk. It's adorable, and I get the impression that we're going to end up keeping him.
Gotta catch 'em all.
Basically, I had to create some programs that do very explicit things. One of those things was to create a function that could shuffle up a standard deck of cards. One of the way that you could do that would be to use the "Random" function that almost every programming language anywhere has. These "Random" functions will usually seed their numbers with something like the milliseconds on the system clock. The problem with that is that languages are fast, really really fast. So if you were to have the system make "random" numbers with the "Random" function using the system clock, the numbers would probably look like this : 1,1,1,2,2,3,3,3,4,5,6,6,6,7,7,7...which is why I keep using the little ""'s around the word "Random."
No, to really get the things really properly shuffled I had to think of something else and it came to me while I was playing Magic. Oh, yeah, that game. So I was shuffling up and thinking. You see, in the system cards would be stored in a table with 52 cells in it. My Magic deck had around 40, but the principal is still the same. Visualize shuffling cards for a moment, but really slow. What you're doing is splitting them into piles and the adding them to each other by alternating the cards. So if you had 6 cards you would split them in half like this :
1,2,3 and 4,5,6
When you shuffle them you should then get this as the new order:
4,1,5,2,6,3
This looks more random, but since we know what we started with then all we really did was create a new pattern. We could probably express this new pattern with an equation, which doesn't really strike me as truly randomized.
I know, I know, why not just shuffle more times? Well, that's the thing. I looked up shuffling and that particular kind of shuffle returns itself to the original setting in n shuffles where n is the number of cards in the deck. That means that every single variation of that deck could be expressed and calculated in advance.
So I got to thinking, "What if," I asked myself, "I didn't just do 2 piles? What if I broke the deck into quarters and shuffled those together?" This led me to my solution, which was to do exactly that, and the use the "Random" generator to select which decks to mix together. Since the decks that were actually shuffled together would change every time I did it, and then do that a random number of times the results that I finally got were truly random. The odds of getting the exact same distribution of cards using this method is 52 to the 52nd power. Considering that there are only 10 to the 23rd power stars in the universe that's a damn lot of randomly selected variations.
With that out of the way I then had to use that to create a small program that plays
Long story short, it works now. I even got the tricky bit involving a soft <message redacted> to work correctly, and the variable nature of <message redacted> to work as well using a system of counters that keep track of things for the different players. I may eventually post my sweet <message redacted> program somewhere to show my coding prowess, but I think that the fine people at <message redacted...Hard> may think that I am sharing some kind of secret process to my legions of readers (Ha!).
-We should return to our regularly scheduled nonsense soon, once I get this hotness to its rightful place in the universe.
-The titles have almost nothing to do with the content today. Oh, there is so a reason that I call them that, other than the one I'm not about to share (state secrets, MIBs, a secret briefcase and all). Actually the Wife had picked up on of those butterfly habitats and we are watching the butterflies go through their adorable life processes. As of today they are coming out and looking all, butterfly-ish. Except for one of them anyway who came out with a weird wing. We call him Lucky, on account of his lucky wing. Oh, and he flies like a drunk. It's adorable, and I get the impression that we're going to end up keeping him.
Gotta catch 'em all.
Monday, March 21, 2011
Target Acquired
If you were pondering what I'm pondering (other than wondering if, provided the shrimp was giant enough, you could ride it) then target locking has been on your mind. Well, maybe if you were in the process of creating a shooter wherein no fewer (but not exactly more) than 2 different enemies shot at you the same way.
You see, on a basic level both the flying fortresses and the ground turrets use the same kind of shooting. First, they're pretty harmless and mosey nice along the screen. They don't even move terribly quickly. But if you get too close they'll lock right on like a, um, lock and shoot bullets at you. Until something else has the bright idea to get in range of their furious bullet shaped wrath.
This behaviour is supposed to encourage a long range solution when you're playing single player. Both enemies can take a bunch of hits before exploding into a joyous ball of fire and also smoke, so lining up quality shots from as far as you can is a good idea. In multiplayer those same enemies' tendency to throw hate at a particular player should allow the other player's to draw it their way through clever flying and a high risk kind of constitution.
Which gets us to the two competing ideas for this. On the one hand I can use a somewhat basic shooting mechanic that will shoot along the 8 axes (the plural of "axis" although pronounced "Ackszeese"). This has the great ability to simplify the shooting for the entire game since then every kind of bullet will travel in these lines. A well versed player will be able to understand the firing "lanes" and use them to some effect. Which could be great if I wanted to make a game based on thinking. Paper Zeppelin is supposed to be a little hectic.
On the other hand I could use an equation to calculate out the vector of the bullet. This would add the kind of chaos that I kind of like, although actually takes more thinking from me. I believe I'll try that one out, just to see if I can make it work correctly. If I hate it, I can always do the easier thing instead.
-Wows, "use an equation to calculate out the vector" sounds a little complicated, so I'll explain what "vector" means. In this case, the "vector" is the distance traveled. In 2D space (although you can also use a vector in 3D space) it is the difference in the X and Y position since the last time we checked. So if the movement vector is 2,1, it means that whatever it is has moved 2 units of whatever along the X axis and 1 unit of whatsit along the Y.
In 3D is where we get weird stuff. So if you've ever wondered what the hells the people in Star Trek are talking about when they say that something is at 81,17,26, well know you sort of know.
Oddly, I've worked out the maths involved for calculating these things in advance. It works like this. Say we have 2 objects, and one of those objects is shooting at the other. We know that object 3 is 2 units to the left of object 2 and 4 whatsit units above them. Using some quick math that looks like this (a^2 + b^2 = c^2) to figure out that the long side, the distance is between the 2 objects is 5.
Knowing the distance we also know how fast the bullets are supposed to go. Let's say that they go 2 whatevers every second. 5 / 2 gives us 2-1/2, so the bullets should arrive at where they are supposed to go in 2-1/2 seconds. Then, we divide the x and y distances (3 and 4 remember) by how many seconds (2-1/2) to see how far along the x and y axes the bullet is supposed to go. So in this case it's (4 / 2-1/2) and (3 / 2-1/2) or 1.6 and 1.2.
After all of that math, the vector for those bullets will be 1.6,1.2. Thankfully the computer is really good at math. Really good.
So what does that have to do with Paper Zeppelin? Well, if a Turret is going to shoot at a player it knows where the player is and it also knows where it is and it should know how fast bullets are supposed to go. I can plug all of that information to create a bullet that goes the correct speed in any damn direction I can think of, and I can think of a lot of damn directions.
-Slightly off topic, yes, that was a short um, crash course in Trigonometry. Oddly, I never thought much of it when I learned it originally, and honestly forgotten most of it. If you've ever thought that you won't need this, you're probably right. Forgetting it, then recreating the equations from scratch, it much harder than remembering in the first place though. So really, it's not that you'll never need it, it's that once you know it you have to discover something to do with it. I do indie games, and I need it constantly.
So, the more you know, I guess. (cue jingle)
You see, on a basic level both the flying fortresses and the ground turrets use the same kind of shooting. First, they're pretty harmless and mosey nice along the screen. They don't even move terribly quickly. But if you get too close they'll lock right on like a, um, lock and shoot bullets at you. Until something else has the bright idea to get in range of their furious bullet shaped wrath.
This behaviour is supposed to encourage a long range solution when you're playing single player. Both enemies can take a bunch of hits before exploding into a joyous ball of fire and also smoke, so lining up quality shots from as far as you can is a good idea. In multiplayer those same enemies' tendency to throw hate at a particular player should allow the other player's to draw it their way through clever flying and a high risk kind of constitution.
Which gets us to the two competing ideas for this. On the one hand I can use a somewhat basic shooting mechanic that will shoot along the 8 axes (the plural of "axis" although pronounced "Ackszeese"). This has the great ability to simplify the shooting for the entire game since then every kind of bullet will travel in these lines. A well versed player will be able to understand the firing "lanes" and use them to some effect. Which could be great if I wanted to make a game based on thinking. Paper Zeppelin is supposed to be a little hectic.
On the other hand I could use an equation to calculate out the vector of the bullet. This would add the kind of chaos that I kind of like, although actually takes more thinking from me. I believe I'll try that one out, just to see if I can make it work correctly. If I hate it, I can always do the easier thing instead.
-Wows, "use an equation to calculate out the vector" sounds a little complicated, so I'll explain what "vector" means. In this case, the "vector" is the distance traveled. In 2D space (although you can also use a vector in 3D space) it is the difference in the X and Y position since the last time we checked. So if the movement vector is 2,1, it means that whatever it is has moved 2 units of whatever along the X axis and 1 unit of whatsit along the Y.
In 3D is where we get weird stuff. So if you've ever wondered what the hells the people in Star Trek are talking about when they say that something is at 81,17,26, well know you sort of know.
Oddly, I've worked out the maths involved for calculating these things in advance. It works like this. Say we have 2 objects, and one of those objects is shooting at the other. We know that object 3 is 2 units to the left of object 2 and 4 whatsit units above them. Using some quick math that looks like this (a^2 + b^2 = c^2) to figure out that the long side, the distance is between the 2 objects is 5.
Knowing the distance we also know how fast the bullets are supposed to go. Let's say that they go 2 whatevers every second. 5 / 2 gives us 2-1/2, so the bullets should arrive at where they are supposed to go in 2-1/2 seconds. Then, we divide the x and y distances (3 and 4 remember) by how many seconds (2-1/2) to see how far along the x and y axes the bullet is supposed to go. So in this case it's (4 / 2-1/2) and (3 / 2-1/2) or 1.6 and 1.2.
After all of that math, the vector for those bullets will be 1.6,1.2. Thankfully the computer is really good at math. Really good.
So what does that have to do with Paper Zeppelin? Well, if a Turret is going to shoot at a player it knows where the player is and it also knows where it is and it should know how fast bullets are supposed to go. I can plug all of that information to create a bullet that goes the correct speed in any damn direction I can think of, and I can think of a lot of damn directions.
-Slightly off topic, yes, that was a short um, crash course in Trigonometry. Oddly, I never thought much of it when I learned it originally, and honestly forgotten most of it. If you've ever thought that you won't need this, you're probably right. Forgetting it, then recreating the equations from scratch, it much harder than remembering in the first place though. So really, it's not that you'll never need it, it's that once you know it you have to discover something to do with it. I do indie games, and I need it constantly.
So, the more you know, I guess. (cue jingle)
Saturday, March 19, 2011
Crashing With The Possibility of Burning
So now the fighters are all done. Yesterday they had the problem of shooting which I call, not altogether affectionately, the Bullet Hose. Basically the little dudes want to shoot every single cycle the game goes through, which means that their little guns shoot 60 times...per second. It looks like a laser almost. A stupid, broken laser. The problem that I had is similar to the one I had with the players, since they too needed a way to keep track of timing. The issue was that all of the things in the whole game really only have 1 spare variable that I built into them. Each type of thing uses it differently. So the dive bombers use it to keep track of how they fly, and the crashing enemies use it as a timer until they explode. The fighter planes use it to track which player they are chasing after.
Which meant that they couldn't also use that variable for their timer.
Or so I thought. C languages like C, C++ and C# have an adorable little bit of math built into them. It looks like this : "%". In this case it's not a percent sign, but a funny way to divide. Like we remember from 2nd grade, most numbers don't divide well, and usually they will have either fractions left over, or remainders. The "%" sign divides and tells you what the remainder is. So 104 % 10 = 4.
So for fighters, and probably the flying fortress enemies and ground turrets, they have a timer that's built into the 10's place for the misc field. It works really quite well. While I was there I use that same internal clock to make them a little less vicious by making them have a slight delay before they do much of anything. So now they aren't the super hunters that they were before and are challenging without being unfair. I'll call that a positive.
Since I was finishing off the fighters I also went ahead and added their dead crashing version. So I went in and made a Class for them and made a placeholder fireball for them. Then I realized that they don't need their own class. Going back a little bit, I explained how I can summon up a constructor to make a class. Since making an instance (a new robot that follows the class code) has a whole lot of crap in it I found it was easier to just make a function that I fed the stuff I care about. So I could do this : MakeChicken(red)
It would then be a red Chicken that followed all of the code in the Chicken part of the code. Well, Crashing enemies aren't really that complicated. They don't move much and it's not as if every type does something different. I mean, the design says that they burn differently, but that's really just a simple number. So instead of having an entire class devoted to each possible type of crashing enemy, I could update my SpawnCrasher() function to make any kind I want. So now when I make one I tell it what kind of thing the enemy was, and it loads the correct animation and gives it the right number for how flammable it is. It's pretty awesome really.
Finally, things now bump into the ground. I discovered that certain enemies (namely the dive bombers) are really stupid and will crash into anything, killing them instantly. So either a) I can add code to make them less stupid or b) I can just design levels around them. I think I'll end up doing that. It is kind of cute to make fighters try to track me into things though. I know that I could make them smarter, but really, if I want to create tunnels in the levels, the ground based enemies are a smarter choice anyway. It's what Gradius III did, so I'm okay with it.
Which meant that they couldn't also use that variable for their timer.
Or so I thought. C languages like C, C++ and C# have an adorable little bit of math built into them. It looks like this : "%". In this case it's not a percent sign, but a funny way to divide. Like we remember from 2nd grade, most numbers don't divide well, and usually they will have either fractions left over, or remainders. The "%" sign divides and tells you what the remainder is. So 104 % 10 = 4.
So for fighters, and probably the flying fortress enemies and ground turrets, they have a timer that's built into the 10's place for the misc field. It works really quite well. While I was there I use that same internal clock to make them a little less vicious by making them have a slight delay before they do much of anything. So now they aren't the super hunters that they were before and are challenging without being unfair. I'll call that a positive.
Since I was finishing off the fighters I also went ahead and added their dead crashing version. So I went in and made a Class for them and made a placeholder fireball for them. Then I realized that they don't need their own class. Going back a little bit, I explained how I can summon up a constructor to make a class. Since making an instance (a new robot that follows the class code) has a whole lot of crap in it I found it was easier to just make a function that I fed the stuff I care about. So I could do this : MakeChicken(red)
It would then be a red Chicken that followed all of the code in the Chicken part of the code. Well, Crashing enemies aren't really that complicated. They don't move much and it's not as if every type does something different. I mean, the design says that they burn differently, but that's really just a simple number. So instead of having an entire class devoted to each possible type of crashing enemy, I could update my SpawnCrasher() function to make any kind I want. So now when I make one I tell it what kind of thing the enemy was, and it loads the correct animation and gives it the right number for how flammable it is. It's pretty awesome really.
Finally, things now bump into the ground. I discovered that certain enemies (namely the dive bombers) are really stupid and will crash into anything, killing them instantly. So either a) I can add code to make them less stupid or b) I can just design levels around them. I think I'll end up doing that. It is kind of cute to make fighters try to track me into things though. I know that I could make them smarter, but really, if I want to create tunnels in the levels, the ground based enemies are a smarter choice anyway. It's what Gradius III did, so I'm okay with it.
Thursday, March 17, 2011
Can't Fight the Fever
Eventually, the titles and how I open these things will get better. Or they'll start off even worse than they already do, almost like I do this crap on purpose. I mean, it's not like I'm writing an essay here, so the format can go right out the window.
I'll get to the title in a minute. It's what the next piece of coding is. In the meantime I went ahead and played with the other site: StarFrogGames.com for a little bit. Eventually all this nonsense will be posted there, since it will at least look professional. The thing is, writing on this site is incredibly easy, and so is posting other information. The "actual" site though, everything is a pain in the ass. I figured out how to post a diary-esque entry today, but for some reason the formatting for the words goes right off the end and under the borders on the side. It's pretty stupid. Now, I know that somewhere there is a table that is too big, but it's buried in the assets and web code that I can hardly navigate, and certainly can't search. Eventually I'll find it and fix it, but until then I have stuff to do.
Which bring us to the titles. Today, I'm going to create a fighter plane enemy. If you check out the Design Document it needs to do a couple of things. First, it needs to fly. Second, it needs to select a player and move towards them. Third, it needs to rotate as it flies. Most difficult, it needs to fire bullets at the player if the player is in front of them, or diagonally in front of them if it is moving up or down.
So most of that crap the Dive Bomber already does and can be copied almost wholesale. The select a player option will need tweaking, but I think if I have it check for a player based on proximity to the front of the screen it will work pretty well. For 2 players, they'll probably change position pretty frequently and for more the players on the front are probably there playing a kind of defense for the team. Or I can also randomly select a player. I may add both given time to create a kind of uncertainty with the mechanic, which would be good in this case.
For the firing solution, I think that I'll project a rectangle in front of the Fighter and then check to see if the selected player is in said rectangle. For diagonals, I might be able to create a quick loop that creates stepped blocks and checks those. We'll find out I guess.
-Sometimes, just sometimes you didn't think of something and it turns out it may have sucked anyway. I'm currently (or recently since I'm writing this now) adding the stuff that makes the Fighters work right. So I made little bits that make them rotate when they are flying and they accelerate and so on so it's like they are flying and it's really cool. I even got them to shoot at me, and here's what I discovered:
As they are, they are kind of difficult.
You see, they track the player pretty well so it's actually quite hard to avoid the little brutes. Worse, they shoot at you if you are level with them. This makes them actually tricky to shoot down since you'll shoot and they'll shoot. You'll move to avoid their shots and they'll do the same in pursuit of you..
Anyway, with all of that they are also (according to the design) supposed to be able to shoot at you while they move provided you are on a diagonal with them. I've decided that they already have ample opportunity to shoot the bloody, streaky 'S' out of you and they don't need another.
I'm thinking about having some kind of timer or something so that they have a delay before they move, if only to make shooting them down a little easier.
Failing that, since they ignore the non-targeted player I may leave them as is to encourage teamwork. If I do that I'll make them spawn as different colors so you know which one is going after who. Yeah, I think I like that. I'll try that...later.
I'll get to the title in a minute. It's what the next piece of coding is. In the meantime I went ahead and played with the other site: StarFrogGames.com for a little bit. Eventually all this nonsense will be posted there, since it will at least look professional. The thing is, writing on this site is incredibly easy, and so is posting other information. The "actual" site though, everything is a pain in the ass. I figured out how to post a diary-esque entry today, but for some reason the formatting for the words goes right off the end and under the borders on the side. It's pretty stupid. Now, I know that somewhere there is a table that is too big, but it's buried in the assets and web code that I can hardly navigate, and certainly can't search. Eventually I'll find it and fix it, but until then I have stuff to do.
Which bring us to the titles. Today, I'm going to create a fighter plane enemy. If you check out the Design Document it needs to do a couple of things. First, it needs to fly. Second, it needs to select a player and move towards them. Third, it needs to rotate as it flies. Most difficult, it needs to fire bullets at the player if the player is in front of them, or diagonally in front of them if it is moving up or down.
So most of that crap the Dive Bomber already does and can be copied almost wholesale. The select a player option will need tweaking, but I think if I have it check for a player based on proximity to the front of the screen it will work pretty well. For 2 players, they'll probably change position pretty frequently and for more the players on the front are probably there playing a kind of defense for the team. Or I can also randomly select a player. I may add both given time to create a kind of uncertainty with the mechanic, which would be good in this case.
For the firing solution, I think that I'll project a rectangle in front of the Fighter and then check to see if the selected player is in said rectangle. For diagonals, I might be able to create a quick loop that creates stepped blocks and checks those. We'll find out I guess.
-Sometimes, just sometimes you didn't think of something and it turns out it may have sucked anyway. I'm currently (or recently since I'm writing this now) adding the stuff that makes the Fighters work right. So I made little bits that make them rotate when they are flying and they accelerate and so on so it's like they are flying and it's really cool. I even got them to shoot at me, and here's what I discovered:
As they are, they are kind of difficult.
You see, they track the player pretty well so it's actually quite hard to avoid the little brutes. Worse, they shoot at you if you are level with them. This makes them actually tricky to shoot down since you'll shoot and they'll shoot. You'll move to avoid their shots and they'll do the same in pursuit of you..
Anyway, with all of that they are also (according to the design) supposed to be able to shoot at you while they move provided you are on a diagonal with them. I've decided that they already have ample opportunity to shoot the bloody, streaky 'S' out of you and they don't need another.
I'm thinking about having some kind of timer or something so that they have a delay before they move, if only to make shooting them down a little easier.
Failing that, since they ignore the non-targeted player I may leave them as is to encourage teamwork. If I do that I'll make them spawn as different colors so you know which one is going after who. Yeah, I think I like that. I'll try that...later.
Wednesday, March 16, 2011
Return to Sender
Damn it feels good to be working again. It seems that not only has my time away from this finally come to an end, but my time as a social pariah has also. It's been a pretty good week really. Good to be here writing this, about this. If I had a horse to ride, I would be riding quite high, both from posture and because I figure the horse would be trojan sized, albeit without all the little Greek dudes hiding inside.
I'm clearly getting off track. My posts seem to be less focused when I'm in a really good mood. When I'm depressed or furious they seem to have more of a point, so I'll get to the stuff I did. Like the last post said, I went ahead and finished off the ground. It works now like it should and you can bump into it and so on. When I originally set it up I accidentally made all the ground act like a bullet, so enemies would crash into it. It was actually a nice representation of how it will eventually work. In the meantime I made all of the ground part of a different List.
With that finished I began to set up the system that could create different kinds of ground. Basically I wanted a border that would visually mark the boundary of the play areas. In other words I wanted it to be easy for a player to know where they could and couldn't fly. If you look at almost all side scrolling platforming games the outsides of places you can stand are a different color. If you look here : http://www.videogamecritic.net/images/nes/super_mario_bros__3.jpg you'll see that the floor does this. It represents a boundary that you cannot pass. The hills behind though you can pass through, so while they have outlines they are not as distinct as the one on the floor.
Anyway, when I coded the ground for Paper Zeppelin I wrote up a long winded function that checked to see what kind of tiles were around the ground that I was making, then created a ground piece with the appropriate number of sides and rotation. So now that works, which is far better than the alternative really. I did have a problem with the rotation though. The computer thought it would be a good idea to not rotate the squares correctly. So for every 90 degrees of rotation (as opposed to every 98 degrees of boy band) it would lose a couple of those degrees. These small changes make the tiles not line up quite right, which left gaps. The technical term for how it looked is "Ass." To fix that, there are now 2 different pictures for each ground piece that is rotated and when I make them, the system picks one based on the rotation that the system figured that each one should have based on what kinds of ground is around them. It's much better now.
With that done I made slanted ground work too. I did have a short conversation with myself regarding this type of ground. On the one hand it would make the game much better to look at, since in the final art the "slanted" ground will be represented as rolling hills and knolls (as in the grassy kind, not the other kind). On the other hand, it does make the ground functions work a little harder. Plus they need their own collision system. I decided that having both a corner piece and a hill would help facilitate enemy placement and level design. Basically, I could easily place enemies on the flat pieces much easier.
So the first thing I did was update the ground spawning function to also make slanted ground. Considering the rest of the ground spawning function already worked, it was quite easy. Then I created a collision system that used multiple rectangles to approximate collision with them. The problem is that collision only functions with rectangles. A slanted hill thingy doesn't fit into anything even resembling a rectangle, which kind of sucks. So I made a trio of rectangles that fit inside the slanted hill thingy, and it works well enough. So now that crap is all oranged.
-Right then. Something that is important to know if you're reading this is all about a List. A List is how C# and the Paper Engine keep track of objects. Basically, it's a set of things, and the type of List tells you what kind of things you are tracking. So for example, I have a Sprite List called groundList that is a list of all the ground that has been created so far. When I want to update it, I tell the system to go through everything in that list, find the Update() function in their robot code, and do what it says. Unlike in The Thief's Tale, I don't have explicit names for every little thing, so I can do stuff to the groups.
The reason that I keep adding new lists instead of just having everything on the same list of objects, is so I can make them interact in different ways. So I can create a nested code piece that says, "let's get everything on the ground list and see if any of them are touching anything in the enemy list and the bullet list." So in the example above, I had added all the ground to the bullet list. However, I also tell the computer to kill any enemy that is touching anything in the bullet list. Since ground was acting as an incredibly slow moving bullet, the enemies bit it when they touched.
I hope that clarifies.
-Alrighty, finally I can get to the titles. I discovered a new way to do something really awesome. It's called the Return function. Basically, a return function can act as a kind of variable. Let's say that we had a function that multiplied 2 numbers together like this :
Public Int MultiplicationIsFun(int X, int Y){
int Z = X * Y;
return Z;
}
This would send a value back. I can also create it to see if the number is odd, even or any other maths I can think of. What's really cool about it is that I can use the whole function in place of the variable that I really need. So I can do this math for example :
2 * MultiplicationIsFun(5,7);
Of I can nest them like this bit of crazyness:
X = MultiplicationIsFun(MultiplicationIsFun(10,5),MultiplicationIsFun(7,MultiplicationIsFun(6,2)
..which would look like this if written normally:
X = (10*5) * (7 * (6*2))
So what? Well, I discovered after this that I can substitute anything that can be returned. So I can fetch a list, or a color or even a player. An example of such is the controller input. It checks to see what a specific controller is doing. It's pretty swell, but the code is stupid because it looks like this : GetGamePad.One
That's right. It fuggin says "One." That means I can't do anything with it normally. However, I can Return that whole thing with a return function. So what I did was, instead of saying GetGamePad.One, I told it to GetControl(player). The GetControl() function then figures out which player I want (since "player" is a variable I can modify) and send back the right bit of code.
Say I wanted to know what player number 4 was doing. I would ask for GetControl(4) and it would send back up the stream GetGamePad.Four.
Again, one could ask why anybody should give two shites, but here's the really cute thing though, as of yesterday, all of the players are on their own list and all of the players has a controller that works. I can add any number of players when I want them and they should function correctly. In effect, the skeleton for multiplayer Paper Zeppelin is constructed.
-Today, the plan is to finish off the addition of the multiplayer bits. Mostly old stuff that still assumes that there is only one player in the house. Then I have to add an HP value to everything. One of those old bits is the gun timer. It tracks a distinct value for timing so bullets happen as a certain rate. The alternative (which is what is now happening) is a bullet hose that creates a laser of bullet bills (the placeholder sprite - it seemed appropriate). The problem with that is that I do not have enough variables in my classes to keep track of that number and the player's HP, so I need to add that value to everything. C# hates it if everything doesn't match.
Although this addition will allow me to correctly code the enemies in the design document that have more than a single hit point. I also figured that I could create ground that was destructible this way. Not full scale mind you, but a little could spice up the levels a bit. Or I'll hate it to death. Possibly that.
-Gods, a boy band reference. What is happening to me?
I'm clearly getting off track. My posts seem to be less focused when I'm in a really good mood. When I'm depressed or furious they seem to have more of a point, so I'll get to the stuff I did. Like the last post said, I went ahead and finished off the ground. It works now like it should and you can bump into it and so on. When I originally set it up I accidentally made all the ground act like a bullet, so enemies would crash into it. It was actually a nice representation of how it will eventually work. In the meantime I made all of the ground part of a different List.
With that finished I began to set up the system that could create different kinds of ground. Basically I wanted a border that would visually mark the boundary of the play areas. In other words I wanted it to be easy for a player to know where they could and couldn't fly. If you look at almost all side scrolling platforming games the outsides of places you can stand are a different color. If you look here : http://www.videogamecritic.net/images/nes/super_mario_bros__3.jpg you'll see that the floor does this. It represents a boundary that you cannot pass. The hills behind though you can pass through, so while they have outlines they are not as distinct as the one on the floor.
Anyway, when I coded the ground for Paper Zeppelin I wrote up a long winded function that checked to see what kind of tiles were around the ground that I was making, then created a ground piece with the appropriate number of sides and rotation. So now that works, which is far better than the alternative really. I did have a problem with the rotation though. The computer thought it would be a good idea to not rotate the squares correctly. So for every 90 degrees of rotation (as opposed to every 98 degrees of boy band) it would lose a couple of those degrees. These small changes make the tiles not line up quite right, which left gaps. The technical term for how it looked is "Ass." To fix that, there are now 2 different pictures for each ground piece that is rotated and when I make them, the system picks one based on the rotation that the system figured that each one should have based on what kinds of ground is around them. It's much better now.
With that done I made slanted ground work too. I did have a short conversation with myself regarding this type of ground. On the one hand it would make the game much better to look at, since in the final art the "slanted" ground will be represented as rolling hills and knolls (as in the grassy kind, not the other kind). On the other hand, it does make the ground functions work a little harder. Plus they need their own collision system. I decided that having both a corner piece and a hill would help facilitate enemy placement and level design. Basically, I could easily place enemies on the flat pieces much easier.
So the first thing I did was update the ground spawning function to also make slanted ground. Considering the rest of the ground spawning function already worked, it was quite easy. Then I created a collision system that used multiple rectangles to approximate collision with them. The problem is that collision only functions with rectangles. A slanted hill thingy doesn't fit into anything even resembling a rectangle, which kind of sucks. So I made a trio of rectangles that fit inside the slanted hill thingy, and it works well enough. So now that crap is all oranged.
-Right then. Something that is important to know if you're reading this is all about a List. A List is how C# and the Paper Engine keep track of objects. Basically, it's a set of things, and the type of List tells you what kind of things you are tracking. So for example, I have a Sprite List called groundList that is a list of all the ground that has been created so far. When I want to update it, I tell the system to go through everything in that list, find the Update() function in their robot code, and do what it says. Unlike in The Thief's Tale, I don't have explicit names for every little thing, so I can do stuff to the groups.
The reason that I keep adding new lists instead of just having everything on the same list of objects, is so I can make them interact in different ways. So I can create a nested code piece that says, "let's get everything on the ground list and see if any of them are touching anything in the enemy list and the bullet list." So in the example above, I had added all the ground to the bullet list. However, I also tell the computer to kill any enemy that is touching anything in the bullet list. Since ground was acting as an incredibly slow moving bullet, the enemies bit it when they touched.
I hope that clarifies.
-Alrighty, finally I can get to the titles. I discovered a new way to do something really awesome. It's called the Return function. Basically, a return function can act as a kind of variable. Let's say that we had a function that multiplied 2 numbers together like this :
Public Int MultiplicationIsFun(int X, int Y){
int Z = X * Y;
return Z;
}
This would send a value back. I can also create it to see if the number is odd, even or any other maths I can think of. What's really cool about it is that I can use the whole function in place of the variable that I really need. So I can do this math for example :
2 * MultiplicationIsFun(5,7);
Of I can nest them like this bit of crazyness:
X = MultiplicationIsFun(MultiplicationIsFun(10,5),MultiplicationIsFun(7,MultiplicationIsFun(6,2)
..which would look like this if written normally:
X = (10*5) * (7 * (6*2))
So what? Well, I discovered after this that I can substitute anything that can be returned. So I can fetch a list, or a color or even a player. An example of such is the controller input. It checks to see what a specific controller is doing. It's pretty swell, but the code is stupid because it looks like this : GetGamePad.One
That's right. It fuggin says "One." That means I can't do anything with it normally. However, I can Return that whole thing with a return function. So what I did was, instead of saying GetGamePad.One, I told it to GetControl(player). The GetControl() function then figures out which player I want (since "player" is a variable I can modify) and send back the right bit of code.
Say I wanted to know what player number 4 was doing. I would ask for GetControl(4) and it would send back up the stream GetGamePad.Four.
Again, one could ask why anybody should give two shites, but here's the really cute thing though, as of yesterday, all of the players are on their own list and all of the players has a controller that works. I can add any number of players when I want them and they should function correctly. In effect, the skeleton for multiplayer Paper Zeppelin is constructed.
-Today, the plan is to finish off the addition of the multiplayer bits. Mostly old stuff that still assumes that there is only one player in the house. Then I have to add an HP value to everything. One of those old bits is the gun timer. It tracks a distinct value for timing so bullets happen as a certain rate. The alternative (which is what is now happening) is a bullet hose that creates a laser of bullet bills (the placeholder sprite - it seemed appropriate). The problem with that is that I do not have enough variables in my classes to keep track of that number and the player's HP, so I need to add that value to everything. C# hates it if everything doesn't match.
Although this addition will allow me to correctly code the enemies in the design document that have more than a single hit point. I also figured that I could create ground that was destructible this way. Not full scale mind you, but a little could spice up the levels a bit. Or I'll hate it to death. Possibly that.
-Gods, a boy band reference. What is happening to me?
Tuesday, March 8, 2011
Collision Course
I got collision to work in Paper Zeppelin yesterday, and now when you crash your little dude into the ground it does something. It's kind of cute and it works like I thought it would. Also, I got ground to work, which brought up some interesting things. First of all, making the ground tiles 100 x 100 is way to damn big. I'm thinking that the resolution of PZ levels just got a lot higher. Second, and more importantly, it is really starting to look like a game now. I managed a kind of scrolling by making all the ground move to the left at a constant speed. Enemies move a faster speed, and it gives the impression that the world is scrolling smoothly by. TTT didn't have any scrolling, and this new hotness makes me a very happy panda.
But that's not really what this post is about. It occurred to me that this diary starts quite a bit after I had the initial insight into how collision systems in 2D could work in Thief, and I thought that now would be a good time to tell that story while also exploring the basic concepts of collision in a video game. So yeah, I'm going to get all talky.
Originally, way back in the proverbial day (I would say around diary entry number -25 or so) I had finally managed to get the little Zero character to animate and had worked out the basics for how the levels would be designed. I figured that if I made a series of rectangles, they could represent the level platforms.
For this, Blitz Basic had a cute function that allowed me to check if a sprite was touching a rectangle (technically if it was overlapping). So I threw considerable energy trying to get that to work, and it never did, not really. So it would let Zero stand on top of a rectangle, but it all fell straight to shit as soon as he touched another rectangle. There didn't seem to be a way to get multiple rectangles to work right. He would touch a rectangle and find himself placed on top of it no matter what. So I tried to create a conditional system that asked questions like, "Are you above the rectangle? Okay, are you to the left of it? The right? Underneath?" But then you would hit a corner and I would die a little inside.
Clearly, there was a way to do this. What I eventually came up with is to create a box of rectangles around the player. Then I could check to see if those rectangles were touching the rectangles in the level. Basically, Zero never touched them, but his invisible force field did. Since each rectangle only had a single condition that was either true or not, it became much easier to track the collision of those rectangles. It also allowed multiple things to touch at the same time, which is why in TTT you can run into a wall.
Other parts of Thief were designed to work with pixel collision. Basically with that you take two different pictures (usually with a mask color that the computer ignores) and see if any of the pixels in those pictures are overlapping. This system is how combat kept track of hitting. Again, since the easiest and most basic concept for collision is an on/off proposition, this kind is useful, but limited. Especially if you want to have any kind of static collision like touching a floor.
Getting it back to Paper Zeppelin, I created a function that checks to see if rectangles are overlapping. I plug in 8 variables, representing the X,Y,W and H of each rectangle and then check to see if any of the first set happens to be inside any of the second. Granted, if I have really odd shapes I may get a weird overlap where that isn't technically true (say a really wide but short and a really tall but thin set) but it works well enough for my purposes.
- Today the plan is to finish off the Collision system and add the rest of the ground pieces. The document says that different ground could reset the player in different directions, but now I'm just going have a standard collision set and make all the ground behave the same way. It seems like a better solution really. I am going to keep the different kinds of ground though, since it should be a simple addition and will make the levels look better.
The thinking is that I want a border on the ground that shows the actual boundary. But I really don't want to keep track of that when I'm putting the levels together. So I'm going to add a little to the ground creation function that checks to see what the area around the ground piece looks like. So a piece with ground on three sides will create ground that only has a border on the open side, while a piece that is open on all sides will have a full border.
Admittedly it's a bit of gold plating when the thing isn't even built yet, but since that's what the end product will entail, completely finishing that since I'm building it isn't too bad. Well, almost completely. From a prettiness standpoint I'm also going to build in a randomizer for the colors to create variations of greens. But I can actually wait for that.
But that's not really what this post is about. It occurred to me that this diary starts quite a bit after I had the initial insight into how collision systems in 2D could work in Thief, and I thought that now would be a good time to tell that story while also exploring the basic concepts of collision in a video game. So yeah, I'm going to get all talky.
Originally, way back in the proverbial day (I would say around diary entry number -25 or so) I had finally managed to get the little Zero character to animate and had worked out the basics for how the levels would be designed. I figured that if I made a series of rectangles, they could represent the level platforms.
For this, Blitz Basic had a cute function that allowed me to check if a sprite was touching a rectangle (technically if it was overlapping). So I threw considerable energy trying to get that to work, and it never did, not really. So it would let Zero stand on top of a rectangle, but it all fell straight to shit as soon as he touched another rectangle. There didn't seem to be a way to get multiple rectangles to work right. He would touch a rectangle and find himself placed on top of it no matter what. So I tried to create a conditional system that asked questions like, "Are you above the rectangle? Okay, are you to the left of it? The right? Underneath?" But then you would hit a corner and I would die a little inside.
Clearly, there was a way to do this. What I eventually came up with is to create a box of rectangles around the player. Then I could check to see if those rectangles were touching the rectangles in the level. Basically, Zero never touched them, but his invisible force field did. Since each rectangle only had a single condition that was either true or not, it became much easier to track the collision of those rectangles. It also allowed multiple things to touch at the same time, which is why in TTT you can run into a wall.
Other parts of Thief were designed to work with pixel collision. Basically with that you take two different pictures (usually with a mask color that the computer ignores) and see if any of the pixels in those pictures are overlapping. This system is how combat kept track of hitting. Again, since the easiest and most basic concept for collision is an on/off proposition, this kind is useful, but limited. Especially if you want to have any kind of static collision like touching a floor.
Getting it back to Paper Zeppelin, I created a function that checks to see if rectangles are overlapping. I plug in 8 variables, representing the X,Y,W and H of each rectangle and then check to see if any of the first set happens to be inside any of the second. Granted, if I have really odd shapes I may get a weird overlap where that isn't technically true (say a really wide but short and a really tall but thin set) but it works well enough for my purposes.
- Today the plan is to finish off the Collision system and add the rest of the ground pieces. The document says that different ground could reset the player in different directions, but now I'm just going have a standard collision set and make all the ground behave the same way. It seems like a better solution really. I am going to keep the different kinds of ground though, since it should be a simple addition and will make the levels look better.
The thinking is that I want a border on the ground that shows the actual boundary. But I really don't want to keep track of that when I'm putting the levels together. So I'm going to add a little to the ground creation function that checks to see what the area around the ground piece looks like. So a piece with ground on three sides will create ground that only has a border on the open side, while a piece that is open on all sides will have a full border.
Admittedly it's a bit of gold plating when the thing isn't even built yet, but since that's what the end product will entail, completely finishing that since I'm building it isn't too bad. Well, almost completely. From a prettiness standpoint I'm also going to build in a randomizer for the colors to create variations of greens. But I can actually wait for that.
Monday, March 7, 2011
PZ Like Sunday Morning
The Big List is together for Paper Zeppelin, and at first blush it seems like a lot. I've made the mistake before of saying something to the effect of, "No problem. I can get this done in like an hour," so I'm not going to let the size of the thing seem like it's not a big deal. There are a lot of things on that list that still need doing, but worse for me there are good number of things that I would need to figure out. To wit, the stuff that goes under the "Classes" section for programming is all pretty basic on a fundamental level. They are all sprites and work the same way within the confines of the structure that I've built already. So adding the Ground for example, shouldn't take to long. Making it work correctly, which also involved a rudimentary collision detection similar to the one employed in TTT is something else altogether. But that's just logic and math, and is do-able by the stretches of most imaginations.
Less so are the things on that list that I need to figure out still, like the String Import Routine, where I'll be able to import text into the PZ engine (I think I'll dub it "The Paper Engine") so I can build my levels using Excel. Otherwise I'm going to end up hard coding all of the levels, which I would rather not do.
The Game Types bit may also take a while, since A) I only have the one controller for my PC and B) I'll need to re-write some chunks of code that are already there.
Of course that doesn't include any of the art or anything, which will always take more time that I think it will.
The thing is, with certain caveats, nothing on this list is too terribly out there. There's nothing in it like there is on the designs that I've written up for The Star Frog EP that would take some kind of extensive programming mojo to be discovered. I can do pretty much everything with what I know, and hopefully will have something up and running and fun to play sooner rather than later, which is always a good thing.
- The plan yesterday was to finish off some stuff and add some options for drawing on the screen. So if we look at the new Big List, the Dive Bombers and their dead versions are finished. Well, more or less. The little bits of code that drive them works, but nothing has been finalized yet in terms of variables. The important thing though is that they work and you can shoot them, and they fall in a big ball of fire and can crash into each other. It's pretty cool.
-Also, I got rotation to work. It sounds really dumb, but it is important. Basically, there is only 1 function that draws stuff on the screen. So when I want to draw a bunch of things using C#, I tell the system to look at the list of sprites, and run the Draw() function. It works great. However, I realized when figuring out how the bloody ground was going to work, that I also need to keep track of some other variables like the rotation, and the color. However there was a bit of a problem, my master Draw() function didn't have variables for these things, and none of the Classes (like Dive Bombers, bullets or players) had to track those variables. So I added them...to everything. It could be worse though, since I could have added this way later to my dozen+ things that the Big List says I should.
-Except for color that is. Different things know what color they are supposed to be, but I can't make it work correctly. Basically, in C# you can draw something and add color to it. In PZ, players will all share the same sprite and animations, but will be colored differently. It's how they used to do it back in the proverbial day.
Using C# it looks like this : Color.White
...assuming that "white" is what you want the color to be (which is to say, don't add any color). So I thought that if I added a variable like this :
String tint = "white"
...then I could do this and it could work.
Color.tint
Except that it doesn't. I built a bit of code that sorta gets around it, but it's incredibly ugly and crazy limited. It does work well enough though, and there are too many things to do to spend time right now.
-Hmm, got a little technical at the end there.
Less so are the things on that list that I need to figure out still, like the String Import Routine, where I'll be able to import text into the PZ engine (I think I'll dub it "The Paper Engine") so I can build my levels using Excel. Otherwise I'm going to end up hard coding all of the levels, which I would rather not do.
The Game Types bit may also take a while, since A) I only have the one controller for my PC and B) I'll need to re-write some chunks of code that are already there.
Of course that doesn't include any of the art or anything, which will always take more time that I think it will.
The thing is, with certain caveats, nothing on this list is too terribly out there. There's nothing in it like there is on the designs that I've written up for The Star Frog EP that would take some kind of extensive programming mojo to be discovered. I can do pretty much everything with what I know, and hopefully will have something up and running and fun to play sooner rather than later, which is always a good thing.
- The plan yesterday was to finish off some stuff and add some options for drawing on the screen. So if we look at the new Big List, the Dive Bombers and their dead versions are finished. Well, more or less. The little bits of code that drive them works, but nothing has been finalized yet in terms of variables. The important thing though is that they work and you can shoot them, and they fall in a big ball of fire and can crash into each other. It's pretty cool.
-Also, I got rotation to work. It sounds really dumb, but it is important. Basically, there is only 1 function that draws stuff on the screen. So when I want to draw a bunch of things using C#, I tell the system to look at the list of sprites, and run the Draw() function. It works great. However, I realized when figuring out how the bloody ground was going to work, that I also need to keep track of some other variables like the rotation, and the color. However there was a bit of a problem, my master Draw() function didn't have variables for these things, and none of the Classes (like Dive Bombers, bullets or players) had to track those variables. So I added them...to everything. It could be worse though, since I could have added this way later to my dozen+ things that the Big List says I should.
-Except for color that is. Different things know what color they are supposed to be, but I can't make it work correctly. Basically, in C# you can draw something and add color to it. In PZ, players will all share the same sprite and animations, but will be colored differently. It's how they used to do it back in the proverbial day.
Using C# it looks like this : Color.White
...assuming that "white" is what you want the color to be (which is to say, don't add any color). So I thought that if I added a variable like this :
String tint = "white"
...then I could do this and it could work.
Color.tint
Except that it doesn't. I built a bit of code that sorta gets around it, but it's incredibly ugly and crazy limited. It does work well enough though, and there are too many things to do to spend time right now.
-Hmm, got a little technical at the end there.
Friday, March 4, 2011
Back in the Saddle
Damn it feels good to be back and working again. I had almost forgotten after so long how downright awesome it can be, on a minute to minute basis, to be in the process of putting together a video game. Even the extra surrounding crap takes on a weird kind of joy, since I know what's going to happen later. Never, let me put that again for emphasis:
NEVER...
...will I let myself think it's a good idea to not be making a bloody video game. When I got on and opened up the code, it took only a minute to remember how everything was put together, and how the C# is structured, and what I was working on last (turns out before I shut it down the level reading part worked, and I had worked out inheritance so that I could make crashing enemies work correctly). The code came quickly, easily, and before I knew what was going on, I had burned through my allotted hours and: updated the bullet speed so it doesn't suck, added the AI logic for the Dive Bomber Kamikaze enemies, make crashing enemies hit each other, and worked out how to make things rotate when I need them to. It was a very good bit of coding that I got done.
Today the plan is to finish off the AI logic for the Dive Bombers and add a color and rotation option to the basic drawing function. I could write a whole lot more right now, but I'd rather take the minutes bring Paper Zeppelin a little closer to the finish line.
NEVER...
...will I let myself think it's a good idea to not be making a bloody video game. When I got on and opened up the code, it took only a minute to remember how everything was put together, and how the C# is structured, and what I was working on last (turns out before I shut it down the level reading part worked, and I had worked out inheritance so that I could make crashing enemies work correctly). The code came quickly, easily, and before I knew what was going on, I had burned through my allotted hours and: updated the bullet speed so it doesn't suck, added the AI logic for the Dive Bomber Kamikaze enemies, make crashing enemies hit each other, and worked out how to make things rotate when I need them to. It was a very good bit of coding that I got done.
Today the plan is to finish off the AI logic for the Dive Bombers and add a color and rotation option to the basic drawing function. I could write a whole lot more right now, but I'd rather take the minutes bring Paper Zeppelin a little closer to the finish line.
Wednesday, March 2, 2011
The Wastes
Today is a funny kind of day. A sad kind of day really, but more because it's less funny in a "Ha Ha" sense and more funny in an off putting way with a kind of underlying anger at myself. It has to do with why this particular diary has so many missing entries. You see, I had thought that while I was without means I should also abstain from working on any of these things. It was a way to focus myself and to provide a kind of built in motivation. I had thought that it was a good idea, and although slow it was paying off.
Until yesterday that is. Yesterday the giant pause button, the Iron Lung metaphor that I've been using, became a liability. I was told that I lack "follow- through" because I was able to put all of this on hold. Further, that became one of the deciding factors. Liability.
Afterward, as I sat thinking about this new paradigm, this new way of considering everything, I was struck by how much time I had wasted. Almost a year now, a bloody year has come and almost gone, and all I had to show for it was a couple of updates and a lot of articles read. I thought for just a moment, what if? What if I had continued instead of setting myself on a kind of intellectual and creative exile? Where would I be now? How would things be better? How many projects like Paper Zeppelin would I have finished? How much more advanced would my coding have become?
But the real question quickly became, why am I doing this to myself? If nothing else, every day I could have had something new to show for the day I spent.
So I'm throwing it off. When the very act that I thought would help was beginning to actively hinder me, then there is no reason to continue to use it.
To that end, let's consider the good bits that we can find. Yes, it did motivate me because I rightly would do nothing but code all day and make my games given an option. It did provide a carrot, but too far removed to provide a real fire. So here's the plan as I continue. Every day in the morning, I do what I need to do. No procrastinating and none of the other things that I could be doing. Then in the afternoon, provided that I did what I had set out to do that day, I'll get back to work.
A new paradigm. A new plan. A new start.
I know what it takes to start again...
Until yesterday that is. Yesterday the giant pause button, the Iron Lung metaphor that I've been using, became a liability. I was told that I lack "follow- through" because I was able to put all of this on hold. Further, that became one of the deciding factors. Liability.
Afterward, as I sat thinking about this new paradigm, this new way of considering everything, I was struck by how much time I had wasted. Almost a year now, a bloody year has come and almost gone, and all I had to show for it was a couple of updates and a lot of articles read. I thought for just a moment, what if? What if I had continued instead of setting myself on a kind of intellectual and creative exile? Where would I be now? How would things be better? How many projects like Paper Zeppelin would I have finished? How much more advanced would my coding have become?
But the real question quickly became, why am I doing this to myself? If nothing else, every day I could have had something new to show for the day I spent.
So I'm throwing it off. When the very act that I thought would help was beginning to actively hinder me, then there is no reason to continue to use it.
To that end, let's consider the good bits that we can find. Yes, it did motivate me because I rightly would do nothing but code all day and make my games given an option. It did provide a carrot, but too far removed to provide a real fire. So here's the plan as I continue. Every day in the morning, I do what I need to do. No procrastinating and none of the other things that I could be doing. Then in the afternoon, provided that I did what I had set out to do that day, I'll get back to work.
A new paradigm. A new plan. A new start.
I know what it takes to start again...
Tuesday, March 1, 2011
The Lost Weekend
It's been a while since I typed anything onto these pages. I spent a part of yesterday re-reading chunks of my own diary, and the writing seemed foreign somehow. The jokes funny again because I had forgotten that I wrote them. It's been far too long.
In case you're curious (I say to all the un-people that read this), the thing is still very much hanging over me. But now I think I can talk about it, if only to have something to talk about. The long sabbatical from my writing, and my developments and my projects and my fuggin life, is directly related to my lack of employment. A widely known fact in that being an indie game designer, especially one that gives stuff away for free or for the almost free that XBLIG offers, isn't a way to become famous, or rich for that matter. In fact, it turns out it's almost impossible to feed one's self from the meager proceeds. So this thing that I adore so much, simply cannot love me back because it lacks the means to.
That means that I need to be employed for any of this to work. I need to devote 8 hours every day to somebody else's projects and somebody else's dreams, so that I can have the possibility of devoting 2 hours to my own.
What I begin to wonder about though, is if that very drive makes it difficult to continue. I wonder if a manager looks at all of this and simply assumes that is what I would do, given the chance. The honest truth of it is that, yes, I would. But I can't. The very fact of which depresses me, but being depressed about it doesn't make it any less of a fact.
I'll put it another way, like in a story that a friend of mine told me. He went to school and has a Master's Degree in Molecular Biology (which is quite difficult to say after the 3rd pint of Guinness) and finds that he is un-hirable. Any non-biology job that he applies for is turned down almost immediately. The reason is that, since he spent so much time and effort on being a Molecular Biologist, then clearly he is simply going to leave when an opportunity shows up. My design and programming and all of this are the same. The assumption is that I will leave when given the option to, in spite of the fact that I really just want a good place to be so that I can be my own patron.
It's maddening.
So when I go out to apply and do interviews and talk with people, in the back of my mind I'm always thinking, "I not just applying for this, but also to once again be the Lead Designer at Star Frog Games." Forget 401K or dental, that's the best benefit that I could ever want.
In case you're curious (I say to all the un-people that read this), the thing is still very much hanging over me. But now I think I can talk about it, if only to have something to talk about. The long sabbatical from my writing, and my developments and my projects and my fuggin life, is directly related to my lack of employment. A widely known fact in that being an indie game designer, especially one that gives stuff away for free or for the almost free that XBLIG offers, isn't a way to become famous, or rich for that matter. In fact, it turns out it's almost impossible to feed one's self from the meager proceeds. So this thing that I adore so much, simply cannot love me back because it lacks the means to.
That means that I need to be employed for any of this to work. I need to devote 8 hours every day to somebody else's projects and somebody else's dreams, so that I can have the possibility of devoting 2 hours to my own.
What I begin to wonder about though, is if that very drive makes it difficult to continue. I wonder if a manager looks at all of this and simply assumes that is what I would do, given the chance. The honest truth of it is that, yes, I would. But I can't. The very fact of which depresses me, but being depressed about it doesn't make it any less of a fact.
I'll put it another way, like in a story that a friend of mine told me. He went to school and has a Master's Degree in Molecular Biology (which is quite difficult to say after the 3rd pint of Guinness) and finds that he is un-hirable. Any non-biology job that he applies for is turned down almost immediately. The reason is that, since he spent so much time and effort on being a Molecular Biologist, then clearly he is simply going to leave when an opportunity shows up. My design and programming and all of this are the same. The assumption is that I will leave when given the option to, in spite of the fact that I really just want a good place to be so that I can be my own patron.
It's maddening.
So when I go out to apply and do interviews and talk with people, in the back of my mind I'm always thinking, "I not just applying for this, but also to once again be the Lead Designer at Star Frog Games." Forget 401K or dental, that's the best benefit that I could ever want.
Subscribe to:
Posts (Atom)