Posts Tagged ‘java’

A Complete Android Game

June 18, 2012

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!

Java CTYR, Now in the browser…

April 14, 2012

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.

Updating Minecraft Plugins

April 14, 2012

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.

Adventures in Java

April 12, 2012

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.

Minoquar! Update.

March 23, 2012

A quick progress video on Minoquar!

I’ve got the player moving, and the ability of the sword already coded in.

Now for minoquar movement and the cloak and key.

Stop Resisting!

March 22, 2012

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.

 

PDG Common: Configuration Class

March 6, 2012

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.

How to just trust @cokeandcode, and thus not be an idiot

March 3, 2012

I mentioned something like this before:

THE AUTHOR OF SLICK2D ALREADY THOUGHT OF ALMOST EVERYTHING FOR YOU. YOU DON’T HAVE TO WORRY ABOUT STUFF. SO DON’T. WORRY ABOUT STUFF.

After my various struggles with getting CTYR working on linux and mac, I did a brief pre-prototype of JetLag (which means: an application that has an ASCII grid that randomly changes once per frame)

And, just for a lark, went through the following procedure:

  1. export my common library (pdgcommon) into pdgcommon.jar
  2. export my game (jetlag) into jetlag.jar
  3. Fire up jarsplice
  4. add pdgcommon.jar and jetlag.jar
  5. also add slick.jar, lwjgl.jar, and the jogg and jorbis jar
  6. *IMPORTANT* add the natives-(operatingsystem).jar files
  7. DON’T BOTHER ADDING ANY NATIVES, THEY ARE IN THE JAR FILES FROM STEP 6
  8. Set the correct mainclass (in my case, com.pdg.jetlag.Program)
  9. make the fat jar
  10. Put it in my dropbox public folder
  11. download on linux and mac

What I had been doing before was adding the natives I downloaded from lwjgl. *FACEPALM*. I needed NOTHING outside of the slick/lib folder. IT WAS ALL JUST THERE ALL ALONG!

So now, a couple of links:

CTYR that works on windows, mac, and linux.

JetLag pre-prototype that also works on windows, mac, and linux.

And now some screenshots, in the spirit of the internet being the refrigerator upon which we affix all of our proud works with magnets.

Both working on the mac:

And CTYR working on ubuntu

And jetlag working on ubuntu

I have the fps counter working on the JetLag pre-prototype.

On my windows machine (not shown), I am getting 43 FPS.

On the mac machine, I am getting 44 FPS.

On the linux machine, I am getting 10 FPS, which isn’t bad for a Dell Inspiron B120.

In other events leading up to this iteration of JetLag:

I had a version I was doing last year in C#.

For this version, I decided to make a small PNG for each of the characters in each of the colors.

I generated these programmatically.

For the Java version, I decided to import them and make use of them.

4096 16x16px images are about 670K, which isn’t bad, but I don’t actually need them.

Slick2D has a nifty colorizing function that will take the white one and shade it whatever color I want.

It also has a way provided that I can use a single PNG and split it into a tilesest which I haven’t investigated.

For anyone’s perusal, I have the flash version of jetlag stripped down to its bare essentials (I was in a weird minimalist phase, and sucked most of the campy fun right out of jetlag) available.

Stuff I Need To Do

March 2, 2012

Writing this down in one spot, so that I can measure progress against it.

  1. Learn to make a stand-alone JAR for CTYR that works on my mac, and do it.
  2. Learn to make a stand-alone JAR for CTYR that works on my linux box, and do it.
  3. Learn to make an applet for CTYR that works on my windows machine, my mac, and my linux machine, and do it.
  4. Learn how to sign my JARs, and do it
  5. Learn how to make an Android version of CTYR that works on my phone, and do it.
  6. Learn how to get a free version of CTYR in the Android marketplace, and do it.
  7. Make JetLag, complete with ASCII graphics, JetLag theme, and all the lucky charms, for desktop windows/mac/linux and Android.

CTYR Design Document Overview

February 22, 2012

Anymore, I simply cannot work without some sort of up-front design work, even for something as simplistic as CTYR.

Like most of my games, I need some common components:

  • Configuration – Loads from xml, contains information mainly about the images, sounds, and other constants in the game.
  • Image Manager – Images are referenced by alias, which are mapped into the image configuration xml file, which yield an actual resource name.  They are loaded when needed, not all at game start.
  • Sound Manager – Sounds are referenced by alias, which are mapped into the image configuration xml file, which yield an actual resource name.  They are loaded when needed, not all at game start.
  • Constants – Also loaded from xml in the form of strings and integers.
  • Game State Machine – Taken care of by a Slick2D class.
  • Game States – Derived from a Slick2D class made to work with the state machine.

Next, the state machine:

  • Splash – Shows something like “another fine product of PlayDeez Games” for 5 seconds, keyboard or click will cancel it
  • Main Menu – Has buttons for instructions, rankings, logging in/out, options, mute/unmute
  • Instructions – Shows instructions for the game
  • Rankings – Shows rankings for the player’s session(if not logged in) or for the player account (if logged in)
  • Options – Controls for sound volume and muting
  • Log In – User name and password, logs the player in. It will also support getting logged in from the web page and passed into the applet, and the ability to save the login information in some form.
  • Pre-Game – Does a 1.2.3. count up at the commencement of each game
  • Game – Does the main game handling
  • Post-Game – Shows the final score, and links to new game, rankings.

And the appearance:

The main game field is square

The rhombus has an aspect of 2:1.

The area around the field is sufficient to show stats and buttons (stats on the top, buttons on the bottom), as well as a little border on the left and right.

In order to support communication between web page and application, I need to come up with a way to put the data into a payload.  I typically choose some form of JSON strings with base64 encoding and then an “encryption” method.

This will need to be supported on both the client and the server, so it needs to be written both in java and php.

I will naturally need some database tables.

Yes, this means I need a new user system.

Again.

Sigh.

I’d like to use some form of openid, ideally the google id at least.

That’s a research point.

Once I have some sort of user system in place, there is only one table that I actually need that stores the following information:

  • User id (however that winds up working)
  • Number of games played
  • Total score
  • Highest score

From this, the average score can be calculated (total score/games played).

This is, at least, for the “all time” rankings.

For the “last 30 days”, “last week” and “last day” part of the system, I need:

  • User id
  • When
  • Score