Wednesday, December 21, 2011

Escapism

I am a gamer. I love being a gamer. I love being a nerd in general. I own it. I'm proud of it. But there is one thing I've never really understood: Escapism.

Now, let me clarify. I understand the concept. However, it's not something I've ever really done. I get into games, let them suck me into their world, but I do it because it's fun, not because I feel the need to escape reality. Reality has its own quirks and mysteries that are fun to figure out. I've never wanted a break from my life.

That has changed, today. When you realize that, no matter how hard you try, your own parents don't think of you as anything but worthless and inept, it's time to just forget reality for awhile, and delve into some other world. That is what today is about. So many other things I should be doing right now, but I really don't feel like it. This is not something I plan on making a habit of, but, for today, life is on hold. Fuck it all.

Thursday, December 15, 2011

For All That We Find New, Why Do We Crave the Old?

I love Skyrim. I really love Skyrim. It is one of the most amazing games of all time, and one of the best in the Elder Scrolls series. So, what has me excited? Is it that Bethesda has officially announced Skryrim DLC? Actually, no. It's this video. Well, more what the video is about. As awesome as Skyrim is, I'm excited for a Morrowind revamp. I haven't played seriously in a long time, and this is just the excuse I needed to pick it up again. It was my very first Elder Scrolls game, and it showed me just how awesome CRPGs could be. While Oblivion and especially Skyrim were and are good, even great, there are some things that Morrowind just did right that the others lost sight of. The shear number of equipment options, being able to wear clothes underneath your armor, and having 8 armor slots (9, if you used shields) to fill. While not a skill like it was in earlier titles, the ability to climb up mountains and such was something the newer engines didn't really allow for (though Skyrim is tons better about it than Oblivion was). Speechcraft was something you actually had to use, or it would never get useful. And there were more skills, one for every weapon type, as there should be, plus an entire armor category (medium armor) that simply doesn't exist in the newer games. Not to mention skills for unarmed and unarmored. Those are important skills! How can you play a Monk without them?!? Even a mage can be difficult without the unarmored skill!

I'm not saying I'm hanging up my Dovahkiin hat in favor of a Nerevarine style. I'll still be playing Skyrim. Quite a bit of Skyrim. Skyrim. Is. Amazing. But, so is Morrowind. And it's high time I visited Vvardenfell, again.

Program: Dice Bag

It's finally finished! Took a lot longer than it should have, and is messy as hell, but it's done. Now, let us analyze the code, shall we? First, the Class header. Basically, the top of and identification for this program.

public class DiceBag extends JFrame implements ActionListener {

The important part is the "public class DiceBag." That names the program, and tells the computer that everything within that bracket at the end of the line and its partner at the bottom of the code belongs to the DiceBag program. The rest of the line is for implementing a GUI (Graphical User Interface) and allowing the program to recognize when you've clicked a button. Next, we look at the Main method. The Main is an essential part of any non-applet Java program. It's where the program goes to start everything. This is what Dice Bag's Main method looks like:

public static void main(String[] args) {
        JFrame dB = new DiceBag();
        dB.setVisible(true);
    }

Not much to look at, is it? Especially for being so important. Basically, all it's saying is to call on the DiceBag method to create a new window, then display that window. So, how is this messy? Well, let's look at the DiceBag method.

public DiceBag() {
        setTitle("Dice Bag");
        setSize(250,250);
        setLocation(500,200);
        setLayout(new GridLayout(7,4));   
        setDefaultCloseOperation(EXIT_ON_CLOSE);
               
        Label plus = new Label("+");
        Label plus2 = new Label("+");
        Label plus3 = new Label("+");
        Label plus4 = new Label("+");
        Label plus5 = new Label("+");
        Label plus6 = new Label("+");
        Label plus7 = new Label("+");
       
        d4.addActionListener(this);
        d6.addActionListener(this);
        d8.addActionListener(this);
        d10.addActionListener(this);
        d12.addActionListener(this);
        d20.addActionListener(this);
        d100.addActionListener(this);
       
        add(nD4);
        add(d4);
        add(plus);
        add(p4);
       
        add(nD6);
        add(d6);
        add(plus2);
        add(p6);
       
        add(nD8);
        add(d8);
        add(plus3);
        add(p8);
       
        add(nD10);
        add(d10);
        add(plus4);
        add(p10);
       
        add(nD12);
        add(d12);
        add(plus5);
        add(p12);
       
        add(nD20);
        add(d20);
        add(plus6);
        add(p20);
       
        add(nD100);
        add(d100);
        add(plus7);
        add(p100);
    }

This type of method is known as a constructor, and is the only type of method allowed to share the same name as the Class it is contained in. A Class is Java's word for a program. Well, that's not entirely accurate. A Class is an object that can be use by a program, but every program is, itself, a Class. It's complicated, I know, but don't think on it too hard. That bit's not real important to grasp. Look at the first block of lines. The first line tells the program to display its name in the top bar of the window it creates. the next two lines set the dimensions of the window, and its position on your screen. The fourth line tells it what layout to use when we start adding components, and the final line tells it to shut down the program when you click on the close button in the top bar. All the other lines? All they do is create and place the various buttons and text fields that the program uses.

Once all this is set up, the Main makes it all visible, and it looks like this:
It ain't much, especially for the volume of code it took to create it, but it works for what we need.
Before we go on, I want to note something here. For those of you familiar with programming, you'll probably have realized this, but for those of you who aren't I wanted to let you know. Every Button, Text Field, and Label I used to create this window was declared within the Class brackets, but outside any Method brackets. The significance of this is that, because of that, they are World variables. Meaning they can be accessed and manipulated by any Method within the Class. Local variables, ones declared and defined within a Method, can only be accessed and manipulated by the Method they were created in. So all those components already existed before the Constructor Method was called, but they were not defined until after it was finished. Code blocks 2 and 3 of the constructor defined them. The remaining blocks placed them onto the window.

Okay, now we have a pretty window with buttons and fields, but now what? The constructor didn't call on another method. The program has stopped. Well, remember the first thing we looked at? The Class header said it extends JFrame, which is what it used to create the window in the first place, and implements ActionListener. ActionListener is a handy little thing that "listens" for any action taken by the user. Like, say, clicking on a button. Any program that uses ActionListener must have a Method called "actionPerformed." That Method in Dice Bag looks like this:

public void actionPerformed(ActionEvent arg0) {
        Object b = arg0.getSource();

            if (b == d4){
                nD4 = runCheckN(nD4);
                p4 = runCheckP(p4);
                rollDice(Integer.parseInt(nD4.getText()), Integer.parseInt(p4.getText()), 4);
            }

            if (b == d6){
                nD6 = runCheckN(nD6);
                p6 = runCheckP(p6);
                rollDice(Integer.parseInt(nD6.getText()), Integer.parseInt(p6.getText()), 6);
            }
       
            if (b == d8){
                nD8 = runCheckN(nD8);
                p8 = runCheckP(p8);
                rollDice(Integer.parseInt(nD8.getText()), Integer.parseInt(p8.getText()), 8);
            }
       
            if (b == d10){
                nD10 = runCheckN(nD10);
                p10 = runCheckP(p10);
                rollDice(Integer.parseInt(nD10.getText()), Integer.parseInt(p10.getText()), 10);
            }
       
            if (b == d12){
                nD12 = runCheckN(nD12);
                p12 = runCheckP(p12);
                rollDice(Integer.parseInt(nD12.getText()), Integer.parseInt(p12.getText()), 12);
            }
       
            if (b == d20){
                nD20 = runCheckN(nD20);
                p20 = runCheckP(p20);
                rollDice(Integer.parseInt(nD20.getText()), Integer.parseInt(p20.getText()), 20);
            }
       
            if (b == d100){
                nD100 = runCheckN(nD100);
                p100 = runCheckP(p100);
                rollDice(Integer.parseInt(nD100.getText()), Integer.parseInt(p100.getText()), 100);
            }
    }

Whenever you click one something in the window created by the Constructor Method, it runs this Method. This Method then runs a series of If Statements to see if what you clicked on is supposed to do anything. In this case, if you didn't click on one of the seven buttons, the program ignores the click. However, if you did click on a button, it figures out which button you clicked, and take the appropriate action. In the case of Dice Bag, the actions performed for each button are nearly identical. The only difference is the Text Fields being referenced, and the size of the virtual die or dice being rolled. So, let's look at the Methods that are called, in the order they are called.

The first line of every If Statement says "nD# = runCheckN(nD#);". This tells the program to take the Text Field that was placed before the button clicked, and change the value contained in it according to the instructions in the runCheckN Method. The runCheckN Method is largely a test for a valid value, and will only change an invalid value.

private TextField runCheckN(TextField n) {
        try{
            int test = Integer.parseInt(n.getText());
        }
        catch (NumberFormatException ex){
            n.setText("1");
        }
       
        return n;
    }

First thing to notice is that, up until now, every Method has begun with either "public/private methodName," or "public/private void methodName." That's because the Methods we've looked at up to this point haven't returned any values. This one does. It returns a TextField object. Also, when called, it requires that a TextField object be given to it for evaluation. Dice Bag always gives it the TextField object it is checking and potentially changing the value of. Now, this Method uses the Try/Catch statements that are used in Java to prevent a program from crashing if a critical error occurs. Within the Try brackets, I told the computer to attempt to turn the contents of the TextField into and "int." An int, which is short for integer, is one of the most basic variables a Java program can use. However, a TextField contains a String, which is a string of characters produced by a keyboard. As such, a TextField object can contain a value equal to anything you can type on your keyboard. There are ways of turning them all into numbers, which is what is required in order for them to fit within an int variable, but that's not exactly what we want. We want to make sure that the user has typed in a number into the TextField object to begin with. To this end, we create a new, local int variable called "test," and try to put the contents of the TextField into it. If the user typed in a number, then this works fine, and the Method completes without really doing anything. However, if the user left the field blank, or put anything but a number into it, it creates an error that the program doesn't know how to deal with. Normally, this results in the program simply shutting down. However, because it happened inside the Try Statement, it instead passes it to the Catch Statement.

The first part of the Catch Statement says "(NumberFormatException ex)," meaning it is looking for a specific kind of error. Any other errors will not be caught, and will result in the program crashing. However, there are no other errors that can occur at this point, so it works fine. When one of these errors is passed to it, it carries out the instructions inside of its brackets. In this case, it merely changes the value contained within the TextField object from an invalid value to the number 1. Because the TextField object originally passed to this Method represented the number of dice to be rolled, an invalid value results in only one die of the appropriate size being rolled.

Whether the value is changed or not, the TextField object is then returned, and the original nD# Text Field is changed to the value of "n".

The next Method called is nearly identical to the one we just looked at. However, it deals with the other TextField object in the row of the button clicked, p#, which represents the bonus (or penalty) applied to the roll.

private TextField runCheckP(TextField p) {
        try{
            int test = Integer.parseInt(p.getText());
        }
        catch (NumberFormatException ex){
            p.setText("0");
        }
       
        return p;
    }

Method runCheckP does exactly the same thing as runCheckN, except it changes the value, if there is an error, to 0. By default, no bonuses or penalties will be applied to the roll.

This brings us to the last line of all those If Statements: "rollDice(Integer.parseInt(nD#.getText()), Integer.parseInt(p#.getText()), #);." This line calls the rollDice Method, passing to it the contents of the TextField objects, after converting them into int values, as well as the number of sides of the die type being rolled. The Method is as follows:

private void rollDice(int tN, int tP, int d) {
        int t = 0;
        Random die = new Random();
        String result = "(";
       
        for (int i=0; i < tN; i++){
            int roll = 1 + die.nextInt(d);
           
            if (i == 0){
                result = result + roll;
            }
            else {
                result = result + " + " + roll;
            }
           
            t = t + roll;
        }
       
        t = t + tP;
       
        result = result + " ) + " + tP + " = " + t;
       
        JFrame displayResult = new DiceBag(result);
        displayResult.setVisible(true);
    }

First thing it does is create a new int variable called "t." This variable will be our total after everything is added up. The next line creates a random number generator that will act as our dice. The third line creates a String type variable to allow us to print the result onto the screen. Then we move on to a For Loop. Wonderful things. They create an internal int variable that starts at whatever value you want, checks it against a certain condition, then incrementally increases or decreases the value of the internal variable. This repeats until the condition is no longer met. In this case, the internal variable starts at 0, and increases until it is no longer less than the number dice we're rolling. Once it equals the number of dice, the loop breaks, and the program continues. The If/Else statement within the For Loop makes sure that the "+" isn't added to the front of the first die roll, but is added to each subsequent roll. To make this clearer, if we wanted to roll 3 4-sided dice, with no bonuses or penalties, and we got results of 3, 2, and 4, then the program would display a result of "(3 + 2 + 4) + 0 = 9." Without the for loop, either we'd have to do away with the plus signs all together, or we'd end up with a plus sign in front of the 3. Neither is what we want. Outside of the If/Else Statement, but still inside the For Loop, the variable "t" is being added to each time, adding the roll to the current total.

Once the For Loop breaks, the Method finishes making the String that it will use to display the results. Then, it gets interesting. The Method calls a Constructor, but not the same Constructor the Main Method called, despite having the same name. See, this time, the Method passes the result String to the constructor. This simple difference tells the computer to run a completely different Constructor. This one, in fact:

public DiceBag(String r){
        add(resultField);
        resultField.setText(r);
        setSize(500,100);
        setLocation(600,400);
    }

This Constructor creates a new window, placing in it a pre-declared Label, and setting the text in the Label to the result String. Then it sets the size and position on the screen before displaying the result. The only problem I can see with this, and I'm not sure it's an actual problem, is that there is no line that tells it to actually close when you click on the close button. It will set the window to invisible, but it might be still using memory. Also, every time you click on a button in the main window, it might be creating an entirely new window, instead of just editing the existing window. By the time a good night of gaming has gone by, your computer's memory might be cluttered with hundreds of invisible result windows. However, adding that functionality as I did with the main window might shut down the entire program, not just that window. It's something I will experiment with in future versions of the program, but, for now, this works.

So, there it is. My dice bag program. If anyone reading this has suggestions for better way to program the same results, please, by all means let me know. I do read the comments on this blog. Not that there are many, yet, but I do. Also, I've already figured out that, instead of declaring 7 Labels, and setting them all to say "+", I can instead create them on the spot. Less lines that way. Until next time!

Tuesday, December 13, 2011

Letteretize

So, I learned a  new word at work, today. Letteretize. It's like "alphabetize", except you only worry about the first letter. The rest of the letters don't matter. That is what we must do to overstock we send back to the warehouse; letteretize them.


I had to be at work at 7:00 this morning. That's after working the closing shift last night. And I am not a morning person. Not one bit. Yet, this is the second week in a row that I have been scheduled to work an extra early shift. I hope this doesn't become a trend. I might kill someone if this keeps up.

On the bright side, it doesn't seem to have negatively impacted my sense of humor. I was talking with a co-worker today about Skyrim, and she was telling me how she couldn't help but take all the random food items she could find. She said she had two barrels in her house; a food barrel and a non-food barrel. "In the non-food barrel, I put in Bear Claws and things," she said.

I replied, "Oh! For a minute there, I thought you were going to say you put in things like ale, mead, and whiskey."

"No, I avoid that stuff," she said.

"Aww. Shame, would have been funny," I replied, then changed into my best redneck accent, "Yeah, that thar's my food barrel. And that un over there? It's my *food* barrel. It's what I eat when I get thirsty! Goes down like a Flame Atronach . . . . Those hairs never did grow back."

Yeah. That's how my mind works. Especially while tired.

Oh, well. The weekend's over, and my three day block of work, work, work is done. The rest of the afternoon (it's just a little before 2:00 PM as of this writing), and the two whole days after it are mine. Gonna finish up that Dice Bag program, get some Toldara stuff worked on, and, of course, get in a bit of Skyrim. For now, though, it's time for a nap. I'm tired.

Thursday, December 8, 2011

Not As Good A Start As I'd Hoped

So, yeah. I don't remember it being this much work to create a simple dice bag program. GUI programming sucks. A lot. I've got the d4's to work, and from there it's just changing up the numbers for the rest, but I still need to add in the error catches. I'm done for now. When I get it finished, I will post up the code, and explain it. If you see a way I could have done it better, do let me know. I'm still not great at this. Lol!

It Begins

So, today, it begins. I am going to start seriously working on some of my myriad projects. Namely, the ones listed in yesterday's post. Today, I will be working on the programming projects I mentioned. They are the easiest and quickest to do . . . well, the quickest to do, anyway. So, yeah, don't be expecting me to start posting every day because of this. However, today will be another multi-post day. I will be updating my progress here. If you're legitimately uninterested in programming, I would ignore the rest of this post, and all the future ones today. However, if you just think it's too complicated, or too far above you, then stay awhile, and listen. You might be surprised at how simple it actually is.

For those who know what I'm talking about, I will be programming with Java. I like Java. It's multi-platform (Windows, Mac OS, Linux. Java don't give a shit. It does what it wants), and it has a lot of power. It's not C++, but it's still a really good language. My next several posts will be about the applications I'm making with it, and how I went about making it do what I wanted to do.

We will start with the simplest of simplicity. A dice bag app.

Wednesday, December 7, 2011

Twice In One Day!!! . . . Are You Feeling Okay?

A little nostalgic and disappointed in myself, actually. I have a problem. A big one. I'm lazy. More than that, I have about a half a bajillion projects that I need, and even want, to work on, but I can never get my head out of my ass (which is firmly planted in Skyrim at the moment) long enough to do any of it. Of course, that has been part of what all day today has been about. Catching up on things I've neglected, and maybe getting things back on track. Oh, and for the record, it's not Skyrim's fault. Skyrim has been making it difficult lately, but this was a problem loooooong before it got released.

I appologize to fans of my YouTube account (Galador5000), and to my dear friend, LawGambit. StarCraft II is still not in my immediate plans of seriously getting back into. That part is Skyrim's fault. Once Skyrim releases it's hold on me a bit more, I will start playing and streaming SCII again. For now, though . . . I just met and talked to a freaking dragon. Met and talked to a mother effing *DRAGON*. I'll be lost in Skyrim for a bit longer, I'm afraid.

That being said, I just got through catching up with my cousin's blog. It can be found at http://semiretiredgamer.blogspot.com/ if you're interested. It's mostly about his examinations of RPGs, as well as some of the work he's done/doing on some of them. One of the projects he's working on is a campaign world called Toldara. It's a world he's supposed to be making with me, but I've been so . . . I don't even know what I've been. I haven't put anywhere near the amount of work into it I should have. And that's going to change. Now. I have to update the races for Pathfinder, figure out some of the class ideas we had, and see how they'd best work within Paizo's system. Basically, anything and everything that has to do with the Pathfinder version of the rules. Also, wouldn't be nice if I came up with some more stuff as far as the world itself was concerned, since I'm supposed to be helping make it and all? So, yeah. Time to get up off my lazy ass (figuratively, of course, as I have to sit at a computer to do all of this), and get to work!

Another thing. I would really like to post more RP videos. People seemed to like the YouTube vids I posted of the failed DnD campaign, and I really had a lot of fun doing that. Of course, I need to fix my issues with video editing software, first. Get one that will chop large videos into smaller chunks without desyncing the video and audio tracks. That's a huge and annoying problem that I have no idea how to even begin to fix. Anyway, getting off track. If I were to post videos of an RPG again, I know the perfect game for it. Warhammer 40,000: Rogue Trader. I want to run that game so effing bad! The one RP group I have, though, already has three campaigns going at once, one of them I am already running, and I can't get my old group back together. We all have different schedules, now. Any two of us can find a day to get together, but the whole group, even for one night, would be a freakin' miracle, let alone getting together every week. So, yeah. While I think Rogue Trader would be absolutely perfect for my next broadcasted campaign, I unfortunately don't see it happening anytime soon. *sigh*

Oh, well. Enough of that. That's my battle plan. Work on Toldara. Work on an eventual Rogue Trader campaign. Beat Skyrim, and make lots of dragon armor. And program myself some helpful apps to better keep track of battles and initiative when I'm not using D20Pro. These are my immediate goals. I must finish one before moving on to another. So has the dragon decreed. So shall it be done!

Why, Hello There, Old Friend. It Has Been Some Time.

  Yes it has been a while, indeed. Partly because the list from last post got tedious, but I didn't want too move on without it. Which resulted in me not posting at all. So, yeah, dumping the list. Sorry if there was actually anyone interested in that.

   Actually, trying to catch up on a lot of things, today. My friend, LawGambit, and I, as we've both mentioned before, play StarCraft II. We've actually done some streaming, and I have yet to post all the videos. As I type this, I am searching for a good video editor to chop the files down to a reasonable size. Then off to YouTube they go. If you're interested, my YouTube account is Galador5000. As we've said before, we are Bronze league, so don't expect anything too spectacular.


Also, big surprise here, The Elder Scrolls V: Skyrim has consumed my life! I am but one of many who have had this thing take over their lives. Practically everyone at work plays it, too, which gives us quite a lot to talk about (not that we ever had trouble finding things to talk about). Wednesdays have turned into an interesting occurrence when I get them off, as I spend most of the day on Skyrim, and then head out to play D&D. It's the most awesome day of the week. Lol!

Well, unfortunately, this post was just to kind of get back into the groove. Plus, as I said, other things to catch up on, as well. For now, I leave you. However, I shall be posting more regularly, again.

Good day.