Uncategorized

A Complete Android Game

And here’s the source code:

package com.pdg.android.sandbox;

import java.util.Random;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class SandboxActivity extends Activity {
    private static final int INITIAL_GUESS_COUNT = 0;
	private static final int NUMBER_MAXIMUM = 100;
	private static final int NUMBER_MINIMUM = 1;
	private int guessCount;
	private Random random = new Random();
	private int number;

	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        startGame();
    }

    private void startGame() {
    	pickNumber();
    	setGuessCount(INITIAL_GUESS_COUNT);
    	setPrompt(getString(R.string.guess_my_number));
    	updateGuessStatus();
	}

	private void pickNumber() {
		setNumber(random.nextInt(NUMBER_MAXIMUM-NUMBER_MINIMUM+1)+NUMBER_MINIMUM);
	}

	private void setNumber(int theNumber) {
		number = theNumber;
	}

	private int getNumber(){
		return number;
	}

	private void updateGuessStatus() {
    	setGuessStatus(String.format(getString(R.string.guess_count_format), getGuessCount()));
	}

	private void setGuessStatus(String theGuessStatus) {
		TextView tv = (TextView)findViewById(R.id.guessCount);
		tv.setText(theGuessStatus);
	}

	private int getGuessCount() {
		return guessCount;
	}

	private void setGuessCount(int theGuessCount) {
		guessCount = theGuessCount;
	}

	private void setPrompt(String thePrompt) {
		TextView tv = (TextView)findViewById(R.id.prompt);
		tv.setText(thePrompt);
	}

	public void guessButtonPressed(View view){
		EditText et = (EditText)findViewById(R.id.currentGuess);
		int theGuess = Integer.parseInt(et.getText().toString());
		setGuessCount(getGuessCount()+1);
		updateGuessStatus();
		if(theGuessgetNumber()){
			setPrompt(getString(R.string.guess_too_high));
		}else{
			setPrompt(getString(R.string.guess_correct));
			setGuessCount(INITIAL_GUESS_COUNT);
			pickNumber();
		}
    }
}

Yes, it is the perennial classic “Guess My Number 1 to 100” game that just about everyone has written.

Why did I write this?

Mainly, I’m teaching myself the view based xml ui for android.

This is how I do it.

By writing an entirely too simplistic game.

But now I know how to put resources correctly into xml files, how to grab widgets by id, and how to set text values on TextViews.

Of course, the thing still blows up if you don’t put anything into the edit box and press “Guess!”, but that’s a feature!

Uncategorized

Java CTYR, Now in the browser…

I get it now.

I really, really get it now.

After figuring out the stuff in LWJGL to make it work in a browser and show a black rectangle, I finally figured out how get a Slick2D app to do the same thing.

And here it is.

So now, from exactly the same code base, I can generate both the stand alone runnable jar and the web browser app.

The deployment is different, but that’s fine.

I can do it.

Yay for me.

Uncategorized

Updating Minecraft Plugins

So, I updated my bukkit plugins recently.

And when I did, the users were jubilant, like the onlookers in a Tom Slick race.

And I noticed that there were some tickets associated with my plugins, some of which were submitted by me, some from others.

Neat! I’ve actually got people interested in the improvement of my software.

So, I start to address them, now that I have straightened out my Java workspaces thanks to Dropbox.

And I was cruising along, and made a few additions.

One of the most important parts any bukkit plugin is the command console processing.

Generally there is at least some sort of command that need to set configuration or otherwise check the status of the plugin.

In the one I am working on now, SpawnSurance, has to process a lot of config parameters.

And looking at the code, it was of the nature:

  • if there is one parameter
    • if the parameter is X
    • if the parameter is Y
    • if the parameter is Z
  • if there are two parameters
    • if the parameter is X
    • if the parameter is Y
    • if the parameter is Z
  • if there are three parameters
    • if the parameter is X
    • if the parameter is Y
    • if the parameter is Z

Which is obviously a mess to have to maintain and deal with, especially since added a new parameter that takes the rest of the parameters and concatenates them to add to a custom message.

So, after now acquiring quite a bit of Java experience, I know that I can use List<String>, copy my String[] of arguments over to it, and process through them in a more natural way.

  • if the first parameter is X
    • remove first parameter, then process with the processX method
  • if the first parameter is Y
    • remove first parameter, then process with the processY method
  • if the first parameter is Z
    • remove first parameter, then process with the processZ method

Which is way more maintainable.

But I got hoist on my own petard, and had a hard time finding out why or how I had done so.

I have had a bizarre fetish for not using magic numbers or strings.

I put everything into a class called Constants, and there are a large number of public final static String X = “something”; and public final static Integer Y = 0; and so on.

Which is a good idea, but here’s where I went awry.

All of my constant integers were Integer, not int.

So, when I had my List<String>, I was passing Constants.argCountZero (an Integer) into the remove function.

There are two remove functions for List<String>. One takes an int, the other takes an Object.

Integer is an Object.

So called theArgList.remove(Constants.argCountZero) DID NOTHING!

BECAUSE IT IS AN Integer, NOT AN int!

Of course, this took me about an hour to determine.

Sigh.

Uncategorized

Adventures in Java

In the end, I don’t want much as a developer.

I want a canvas that I can draw images and text on.

I want the ability to play a sound, and the ability to set the volume of that sound.

I want to be able to respond to keyboard and mouse input.

And I want to be able to set a timer that periodically does something.

And that’s all I want to do.

Also, I’m impatient, and I don’t want to take the time to learn a new tool or API or method of deploying something.

However, at the same time, I want a decent tool for debugging, and a simply way of deploying.

Eclipse, I must say, is a decent tool for writing and debugging code.

Even though the various Java platforms resist anything being easy.

I have played with Slick2D, playn, LWJGL, and Android development.

Playn seems like too much of a black art for me to want to try to use it.  It had me downloading all sort of nonsense like maven and git and the gwt.

I didn’t mind the android SDK. I was able to get going with OpenGL on it.

The main issue for me was that it took a really long time for the emulator to start up, so android development work would take me quite a long time.

So, I like LWJGL and Slick2D.

And, because I have now taken the time to learn how to structure my Java projects into different packages, I can create my game in such a way where there is very little platform specific code separated from the game code and renderer.

Both the web platform and desktop platform can share a renderer, and the android gets its own renderer, but the underlying logic winds up the same.

Everything else is configuration.

So, a common library of useful classes is one package.

One package is the abstract game logic.

One package is a platform specific renderer.

One package is the overall wrapper for the platform.

(In the case of the Android, the renderer/platform shell can be the same package).

And I feel like I’m “architecting”.

But at the same time, I’ve gone back to basics.

Rather than write most of a usable game prototype, I made HelloLWJGL.

It works in eclipse.

I made HelloLWJGLApplet.

It also works in eclipse.

Next, make HelloLWJGL work as a runnable jar downloadable to Windows, Mac, and Linux.

Next, make HelloLWJGLApplet work in a web page that I upload to my Dropbox account.

And I LEAVE THESE THINGS AS PATTERNS SO THAT I CAN REFER BACK TO THEM AND NOT HAVE TO STRUGGLE SO MUCH.

So I’ve learned the language.

I’ve learned the tool.

I’ve learned the platform.

Now it is time to do some damage.

Uncategorized

Stop Resisting!

First, I am no longer resisting the grid.  I embrace the warm comfortableness of the grid.

And, moreover, I re-embrace ASCII graphics as the One True Way of doing things.

And, even more, I embrace QR codes, and their potential uses for game creation.

And, as usual, John Hattan is to blame.

Well, not directly.  Really this person is to blame.

So, taking a brief break from Yax (which more about later), I’m making a Minoquar version in Java.

I decided to use an ASCII grid because I already have one working from the version of JetLag I’ve been working on.

I acquired a very nice Java QR Encoder from here.

As a result, I learned some things about QR.

I have a suspicious that this accidental knowledge will one day be useful for a legitimate purpose at my day job.

But until then, MAEK GAEMS!

The most important thing is that I can take ANY TEXTUAL DATA and make a QR code with it.  There’s a limit on the number of characters, but I’ll burn that bridge when I come to it.

Also, because of the rules of Minoquar, there needs to be a “alignment square” in the lower right.

This square does not appear on all QR codes.

It also appears multiple times on larger QR codes.

Generally it appears on QR codes with a length of at least 18 characters (but not always… I think there is some sort of run-length encoding going on in QR).

So, for the nonce, I’m going to go with a set of about 20 “canned” pieces of text, plus the ability to enter in your own text.

Later (and likely as much work as the basic game itself) comes things like scanning existing QR codes and so on.

A few musings about Minoquar.

So, the link above talks about the rules of Minoquar.  Having read them and pondering them, I have come up with some of the following thoughts and potential problems (listed here primarily as notes to myself):

First, the player gets to choose initial position, and that initial position is going to be near to one of the three tools the player can use to complete the game.

The items are sword, cloak, and key. The sword allows tunneling through multiple black squares, the cloak allows crossing the minotaurs tracks, and the key teleports you to safety when the treasure has been obtained.

Without the sword, the player may only tunnel through 1 black block, making the sword the most important tool.

Which means that choosing to start next to either of the other tools is silly.

Potential Problem #1: The sword is so powerful that is makes no sense to start elsewhere.

Potential Solution: Randomize the starting location of the player, or randomize the locations of the items and have them be unknown until they are in direct line of sight.

Second is the “leaving a path” issue. Both the hero and the minoquar leave a path like a lightcycle (but only in the white areas). The hero cannot cross his own path. The Minoquar cannot cross his own path. The Minoquar CAN cross the heros path, but cannot stay on it. The Hero CAN (with the cloak) cross the Minoquar’s path similarly.

The problem here is that a QR code is pretty tight as it is to move around.

Potential problem #2: the hero may never need to worry about the treasure, because this game is essentially lightcycles of tron with tunneling.

Potential solution: Either don’t have a path, or have a path fade away after a certain number of turns.

First step, though, is to do a faithful port of the rules as they currently exist, in order to see what the rule flaws are, so we’ll see how much of a real problem these things are before we go about fixing them.

About Yax

The game with the moving circles will similarly be on a grid and in ASCII graphics.

Why? Because it simplifies the design, and basically allows me to make it into an open-ended turn-based roguelike but with resource gathering and crafting.

Will there be QR codes?

Oh, most assuredly. QR codes can make wonderful caverns, dungeons, and above-ground ruins.

Will there be Yaks?

Certainly, the primary resource is yak hair and the things you can make with it. And it’s called “Yax”.

Will there be Lemurs?

Definitely. And they will be Mighty.

Does this project have a chance in hell of really going anywhere?

Prolly not.

 

Uncategorized

PDG Common: Configuration Class

This is one of those things that I wind up making for whatever game I happen to be working on, and when I’m smart, I make it once, put it into another assembly/package/other reusable unit, and make use of it evermore in whatever language/platform/ide I happen to be using.

It is a configuration class.

package com.pdg.common.managers;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.util.ResourceLoader;
import org.newdawn.slick.util.xml.XMLElement;
import org.newdawn.slick.util.xml.XMLElementList;
import org.newdawn.slick.util.xml.XMLParser;

import com.pdg.common.managers.names.TagNames;

public class Configuration {
	private Map managers = new HashMap();
	public Configuration(String ref) throws ConfigurationLoadException{
		if(!loadFromXml(ref)){
			throw new ConfigurationLoadException();
		}
	}
	@SuppressWarnings("unchecked")
	public  T get(String theName){
		try{
			return (T)managers.get(theName);//pesky unchecked warning... fix it one day
		} catch(ClassCastException e){
			return null;
		}
	}
	private boolean loadFromXml(String ref) {
		XMLParser parser = new XMLParser();
		try {
			InputStream stream = ResourceLoader.getResourceAsStream(ref);
			XMLElement root = parser.parse(ref,stream);
			XMLElementList children = root.getChildren();
			for(int index=0;index<children.size();++index){
				XMLElement child = children.get(index);
				String theType = child.getAttribute(TagNames.TYPE);
				LoadableFromXMLElement manager = (LoadableFromXMLElement)Class.forName(theType).newInstance();
				manager.loadFromXMLElement(child);
				managers.put(child.getName(), manager);
			}
			return true;
		} catch (SlickException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return false;
	}
}

And this works for however many managers I have to load.

For CTYR, I have the following managers:

<configuration>
	<image-manager type="com.pdg.common.managers.ImageManager">cfg/images.xml</image-manager>
	<sound-manager type="com.pdg.common.managers.SoundManager">cfg/sounds.xml</sound-manager>
	<widget-manager type="com.pdg.common.managers.WidgetManager">cfg/widgets.xml</widget-manager>
	<constant-manager type="com.pdg.common.managers.ConstantManager">cfg/constants.xml</constant-manager>
</configuration>

The “type” attribute conveniently tells me what class I need to load, and the contents of the tag tells me the file name.

I like to have different files for this, because things like images and sounds become rather large (as do constants), and so it gets quite hairy to have to manage the same file for everything.

When using an instance of Configuration, the line typically looks something like:

getConfiguration()<ConstantManager>get(ManagerNames.CONSTANT).<Integer>get(ConstantNames.DISPLAY_WIDTH);

Which gets rather lengthy, but this sort of flexibility comes at that cost.

I also wind up with a number of XXXXNames classes, for example ManagerNames and ConstantNames. These will have a number of string constants (or, in the case of Java, a bunch of public static final String lines). This is to centralize the use of magic strings.