viernes, 17 de febrero de 2012

The View: Problems and solutions - Or not!

Problems
U mad?

The theory and basic implementation of the view is fine and dandy - or you would think so. But like all great software, the initial, clean algorithm never takes more than 10% of the code. The other 90% is graceful spaghetti code in an attempt to fix bugs and impossible exceptions without breaking much else. We will now focus on this 90% of program.

Transparency
Let's use the last image to show what's wrong as of now with our display:


Namely, the pink has to go. It's background color, not useful at all; if anything, it blocks the different maps that are on the back.

We could adjust it so that every blank panel was not to be written, but that only solves half of the problem: pretty much every boxel that has some actual content in it also has some parts that have to have 0 alpha.

------------------------
EXTRA INFO: ALPHA CHANNEL.
We talk about alpha or about alpha channel when we refer to an images' opacity property; in other words, how transparent it is, or how much of the picture that's behind it can we see through. The following image makes the alpha fall from 1 to 0 as the y coordinate progresses:

-----------------------

We went through several approaches in order to solve this issue.

Sequential Pixel-by-Pixel Check
This one was by far the most obvious and the easiest to implement on that current structure. Only a pixel-by pixel check was required for the view to do; if it was that pink color, don't paint it - otherwise, go ahead.

This seems simple enough to program, and simple enough to understand, and it worked - No bugs whatsoever. However a tiny new problem arose that forced us to take a different view on the subject.

Such was the problem:



0 frames per second on a Core 2 Duo MacBook Pro is NOT a good sign.

Threaded Pixel-by-Pixel Check
Same solution, but with a grid of Graphics2D, each one in an implemented Runnable for every boxel that came in.


------------------------
EXTRA INFO: THREADS
This one is interesting so take a look. A thread is an execution logic that allows us to make different operations at the same time while being independent of each other. Therefore, we could be painting a red pixel and adding 3 and 2 at the same time.

The threads are the units that allow us to do such parallel execution.

Normally one processor is not capable of calculating anything but sequentially; however the graphics' card, which consists of a bunch of little processors that can make the simplest operations (just enough to display the graphics) can BE used for threading.

------------------------



Since we only had to initialize every thread once and start it sequentially but without waiting for the earlier one to finish, this would have helped the performance of the View.



You might have noticed it's the same video as before. This is my sarcastic way of expressing the performance did not go as better as expected (in reality I was tearing my hair off at this point, along with David's if he ever came too close).

Pre-alpha loading
On the verge of destructing rage, I decided to pre-check every pixel of every texture for alpha and save it in a huge matrix (0 for opaque, 1 for invisible). This was done on the controller.

It took more time than it should, and while I was working on it I quickly realized this helped little with our problem; it was not the checking for transparency itself but the fact that we had to go pixel by pixel what affected the performance.

PNG alpha channel
As you may or may not know, PNG files do have a feature that allows storage of alpha, which works wonders on our issue.

So your totally justified question would be, "why was that not your first option?". Well, it was, and it failed. And then they suggested the same thing again. And I reluctantly retried it. And it worked. Java works in mysterious ways indeed.

Flickering
Of course, after one problem goes down, another one pops up, such is the way of the programmer. A really basic issue which I did not take into account was the flickering, or 2D clipping.

------------------------
EXTRA INFO: CLIPPING
This is a very basic problem that happens upon designing a graphics engine. Basically, it comes from these premises:

  • You paint an object drawn on your screen. It can be anything: an image, a polygon, a circle, a line...
  • You paint another object of the same nature on your screen. Such object happens to be in the same position, partially or fully, as the former.
  • Computer: which one should I paint? Is one in front of the other? Are they truly in the same space? As I have no directions about this, I can't give a correct or stable solution...
Of course the bad outcome takes many forms; in our case, since we want to repaint the screen constantly to keep track every time of what's going on in the game, it will flicker.



To one that only wants to paint once, they will probably experience that the latter layer is painted in front of the earlier.

------------------------

At the moment of writing these lines no solution has been found yet for the flickering, however as stated it is a very common problem and we already have a couple approaches in mind that we'll no doubt explain in later entries.

It's time to turn in as that's as many information as I can give for now. We'll keep working with the engine and start practicing with the mobs and physics, and we'll surely get back to you once we've got more to tell you.

Until then, out and over!

viernes, 13 de enero de 2012

WHAT WE HAVE: THE VIEW 

As stated, we originally planned to do everything from scratch. And I mean everything. So for the graphics' storing, we designed a simple heriarchy that would lead us from the pixel to the world network.

Originally:

  • Pixel: would store the RGB values;
  • Boxel: would store a matrix of pixels such as a texture (lame pun for voxel, I know, I know);
  • World: would store a matrix of boxels;
  • World_Table: would store all the worlds and their names for future references.



However we quickly learned that generating output from raw information like this is very complicated. Not only that, but there's already classes that do so more efficiently. 


Thus, we started using BufferedImage, a Java-integrated class that can quickly load and save external images, as well as have useful resources such the ability to edit the inside tiles (should that ever be necessary).

We also decided making a World an ordered list of Maps. Why? Well, that way we would have Background Maps, Ground maps and Foreground Maps. This is mainly aesthetic, but:

  • Background: What's in the back of the screen. Doesn't affect or hide anything. Looks pretty;
  • Ground: where everything stands and happens. This is the only "functional" map. The platforms with which you interact;
  • Foreground: What's in front of the ground. Aesthetic, but can hide the player (and enemies!) from the camera.

Once we have all that, well, let's move to the how-tos.

Loading textures

The million dollar question: where do we get a texture from? Answer: from an image. Duh. For reasons of space and image quality, therefore, we store the textures in a .png file.

When we talk about textures we really mean all the visual boxels that represent elements of the game, or sprites. Of course, somebody must first draw these sprites, manually. That's why one normally designs a pattern that's unambiguous to paint on (where do I draw? How many pixels wide is this supposed to be? Etcetera). The easiest way out is making a grid with background colors that you don't plan on using on the game to distinguish them from the real textures:



We are definitely not using that pink. Ever.

Making an algorithm that ignores the margins and only grabs the 400px inside was relatively easy; BufferedImage allows to grab a portion of itself with the getSubImage(int x_coord, int y_coord, int width, int length) method.


Loading the worlds

We've loaded the textures. We're supposed to keep them in matrixes inside Worlds. But, what texture goes in each slot? This is a thing the designers must decide when creating each map, making a world of their own. How? Why, with basic bitmap-mapping, of course!

---------------------------
EXTRA INFO: BITMAP-MAPPING
Though I call it this name, truth is this technique probably has another one, but I can't be bothered to search it (lazylity F-T-W!).

Bitmap-mapping is using an image so that every pixel of it represents one boxel, and the color that every pixel has is translated to a sprite in the game (through interpretation of the color). Example:


In this map, the black pixels represent dirt, or the first texture, whereas the white ones are air - technically speaking, no sprite whatsoever.
-------------------------


Painting the result
We've got the textures drawn (because we're awesome artists, that's why); we've got a good storage, a good interpret, and a world that makes sense with them. But those are all just assumptions! How to we make them graphic to check we're on the right track?


Making the screen display your game is possibly the most abstract part of them all. You're used to work with command lines and ASCII outputs - how are we going to get the wizard that lives inside the screen help us showing our pretty doodles?

Luckily Java also has a couple of classes that will help our way around graphical outputting. A JFrame, for example, is an easy way to open a window in which to paint. Just be wary of making it the right dimension.

BUT! JFrame won't paint itself; rather, JFrame is there to be painted on. So, what brush shall we use to paint on our window?

The answer is Graphics2D. A class specialized in painting two-dimensional shapes and Images on any place that has graphics to offer (as in, linking them like Graphics2D g2 = (Graphics2D) jFrame.getGraphics()- remember to downcast!). With this, we're showing the Graphics2D where can it paint. Once he acknowledges that, it's party time. Every boxel takes an initial coordinates and paints its 20x20px texture on it own, eventually making a whole map.

You may remember this on facebook - that was the work of what I've just explained:


Note that the shape of the dirt and the air (auxiliarly the pink-background color) match the map Image I showed earlier. The difference between textures were cause of testing with dynamic neighbor-sensitive texture changing - but that's still green, and a story for another day.


[ANOTHER ENTRY shall be up in a relatively small amount of time. It will depict the problems so far with the view implementation. It will aid in keeping the entries topic-ordered as well as short (or at least shorter. I know I'm a long writer, bite me).]

lunes, 9 de enero de 2012

"Cool Game" is the name!

For lack of a better title we have named our first game Cool Game. Because, you know, it's gonna be cool. And a game.


GENERAL

So what can you expect from this videogame? Well, these are the starting objectives we've come up with so far:
  • Coded in Java
  • 2D Gameplay & Graphics
  • Platformer side scroller
  • Entirely controlled by keyboard
  • Environment built box by box (not pixel by pixel).
  • Mobs are pixel precise
  • Different enemies mean varied
  • Various maps for each zone: forest, dungeon, village, lair...
  • Leveling & Skill through an EXP system.
  • Intuitive menu interfaces
  • Saving system
  • Classes, attributes, gold, items & equipment.
  • NPCs which gives place to:
    • Item trading system
    • Quest system
About the story, I must admit we haven't got any deep into. I have a basic idea of how it may go, but we're focusing on making the basic engines work. Nonetheless, here's some general info:
  • Magical medieval world
  • Classes / characters to choose from:
    • The barbarian
    • The magician
    • The archer
    • The priest
  • The 4 characters probably have a feeble backstory involving each other, and may be reflected in the gameplay.
  • Hero saves land from big bad dude. I think.



HOW?

So far we are making pretty much everything from scratch. Using OpenGL? Downloading the LWJGL? Forget all of that! We're hardcore.

We're using the MVC architecture pattern. As central as this may be classwise, as there's only one class to manage everything, we're thinking of implementing threads for every element for their calculations.

-----------------------
EXTRA INFO: THE MVC MODEL (Skip if you already know this.
For those unfamiliar with the term, here is a basic explanation. It structures your software (namely, your classes) in three different groups:

  • Model: classes that store the information of everything that is observed / used in the program.
    • Example: the hero belong in model, as it keeps their health and gold. They do not calculate the damage they take. They just keep the health.
  • View: classes in charge of generating screen output of the program
    • Example: The view will take care of getting the maps that are to be displayed and will paint them in a frame on the screen.
  • Controller: the big daddy. These classes will tell the View what to display, get the information from the Model and modify them if necessary.
    • Example: The controller will check if an Enemy attacked the Hero, if it hit him, how much it hurt, and if he's dead. He will also order the View to display every mob's action.



-----------------------


At the moment we have an UML planned and the classes are created, but we're missing the important part: the engines!

This is obviously the hardest part right now: without a graphics engine, or physics engine, etcetera, there's no videogame. We can worry about the NPCs and the RPG elements later. Right now we need to make this a side-scrolling platformer. And this is what we're doing: showing the platforms.



Next time, we'll show you what we've got so far. We'll talk about the graphics engine and how we paint and refresh the maps.


Out and over!

Introduction

Welcome everybody! If you've come across this blog then you probably already know what you're in for. This is the developers' blog we've created at Irony Games! As the name suggests, we work our hardest to create fun videogames that we can later release in various formats.

Our goal in this blog is not only to announce major updates on our projects, but also describing how we manage to solve problems and advance on implementation, so it may be useful to you as well.

Right now only me (Danny) and David are working in all of this, but I personally wish to expand Irony Games really soon!

Without further ado, let's dive right into our first game, shall we?