See my personal weblog
 Shaded Landscape, Experiment 1 |
Posted - 11/2/2008 8:22:03 PM | 
Click here to see the interactive version.
Source code here.
It took a little longer than I thought, and I am not entirely sure what specific thing I did which made things work right, but things are working right.
Now that I have the last graphic treatment in place I am going to take a few days away from this project and work on a couple of simple game ideas which came up when I was playing with the earlier Perlin Noise experiments.
| |
| Thursday, October 30, 2008 |
 Perlin Ants |
Posted - 10/30/2008 9:29:47 AM | 

I took a short break from working on the game engine to play around with a mash-up of Perlin Noise-based landscapes, and Langton's Ants.
Click here for the single color version.
Click here for the three color version.
In other news, I figured out how to apply simple shading to the landscape in the tile game, and I should be able to post something sometime this weekend.
| |
 Tile Game Engine Update: Where Am I? |
Posted - 10/27/2008 12:03:00 PM | 
Click here to play with the prototype.
This latest update includes an event which fires every time the player moves to a new tile on the world map. Right now it returns the x and y coordinates and the elevation (based on color) of the current tile. Using that information, I will be able to set up a random-ish encounters table which takes into account environment (e.g. elevation), and factors such as distance from civilization, latitude, and the like. But for right now the deciding factor will be elevation. The system will work something like this: Each creature in the creature library has, as two of its attributes, a minimum elevation and a maximum elevation. This ensures that critters will not appear in inappropriate places - nobody wants to fight a squid on top of a mountain. It just isn't done.
This is pulled from the design document:
<critter
name="Goblin"
id="goblin"
frequency=".05"
min_encounter_time=""
max_encounter_time=""
min_encounter_date=""
max_encounter_date=""
min_terrain=""
max_terrain=""
drops="a,b,c"
base_experience="10"
base_damage="1"
/>
There are attributes for time and date, which I am not currently using. If the particular game whcih I build with this engine requires it I can add times of the day and seasons, and adjust encounters accordingly. This will make things more complicated however; right now I am looking at a single variable - elevation - to sort out the encounter. Each additional factor doubles the amount of data to sort through before the fighting begins - Day or night? Spring or winter? Close to a city? In water or on land? Full moon? You get the idea.
In my 4E5 project (unfinished) I played around with having "sources" for different raw materials - salt, iron, wheat, and the like - the distance from which determined the likelihood of coming across a random deposit, and also helped set the buy/sell cost of the material while trading. This could also be determined by elevation, if I really want to go to town on the granularity of the game.
| |
 Another Week, Another Experiment |
Posted - 10/20/2008 10:07:17 PM | 
Click here to see the live version. (When will we be able to embed Flash movies in our posts?!?)
This is a quick update to the tile-based game engine experiments of months past. This update includes the procedural generation of individual tile textures. Each texture is the same, but I have colored them to reflect the colors of each pixel in the world view. After the initial tile is created, I clone it 256 times - one for each color in the color map - and overlay the Perlin noise with the solid color. Voila! 256 colored tiles.
All in all, I would call it a great success. The next step will be to modify the way I color the tiles in order to make them more vibrant. I am sure there is a way of doing so which will not be too processor intensive.
Right now, I think it looks just a bit like Ultima IV.
| |
| Thursday, October 16, 2008 |
 Gyruss Clone - Against the Horde |
Posted - 10/16/2008 8:08:05 AM | 
Click here to play with the prototype.
I have just updated the Gyruss clone to make it run more consistently across a wide variety of browser/platform combinations, and also to allow for more intense action if need be. I used this technique from 8-Bit Rocket, and in my linked prototype the game runs at a consistent ~30 frames per second. If you let it run for a minute, eventually there will be 100 enemies swirling around shooting at you. One caveat: I tried playing this on an old POS Mac OSX laptop, and it crashed the browser so severely that I had to give it the 3-finger salute to the the OS back.
I took a couple of weeks off of thinking about this thing to do some playing with various cellular automata experiments. The links to these are below:
Langtons's Ant
Langtons's Ant Hexagon pattern
Langtons's Ant 3d pattern
Random 2d cellular automata
Enjoy!
| |
| Friday, September 19, 2008 |
 Weekly Gyruss Clone Update |
Posted - 9/19/2008 11:43:48 PM | 
Click here to play.
Another week gone by, and a few updates have been made. Nothing too earth-shaking this time, just a graphic update: A rotating background. This was entirely too difficult to implement, or I was vastly over-thinking the problem. Probably the latter.
Because I am blitting several bitmaps together to draw the screen I needed to come up with a method to get the bitmap which comprises the background to rotate. In this instance, a simple background.rotation++ wouldn't work; I needed to do a little matrix math to rotate the actual bitmap data, rather than the bitmap which contained the bitmap data. And that caused its own issues; namely, that the original bitmap - which was simply a square with some Perlin noise applied - had subsequently been redrawn around polar coordinates, and then twisted, and expanded so that the resulting circle was as large as the diagonal of the original square, rather than the sides. And somewhere in there the origin point for the bitmap data became, well... not the center of the circle.
Obviously, I eventually got everything figured out.
But not before dealing with a couple of hours of this:

| |
| Monday, September 15, 2008 |
 More Spiral-ey Things |
Posted - 9/15/2008 11:23:31 AM | 
I just posted an update to the Gyruss clone. It includes one cosmetic change - the color palette of the background - and some experiments around how power-ups will work.
On the inside, I change how the shots move, to give them the ability to track around the center when fired at an angle. This also opened the possibility that enemies will be able to do the same thing.
I also spent a little while creating new graphics for the player ship, but almost immediately gave up in frustration, for two reasons: I am not a skilled artist, and I don't yet know what I want the overall theme of the game to be. And I felt depressed that it took me an hour and a half to come up with a BAD 48px x 24px sprite.
I have not yet done much work with optimizing the performance of the game. I will probably do something like this technique from 8-bit Rocket. Or even exactly like that. I just know that, when there are a couple of hundred shots floating around, things start to look kind of choppy.
There are a few more things I am going to work on before I add sound and significant graphics improvements:
- power-ups
- different enemy power, toughness, formation
- bosses
- indestructible objects
- start- and end- game screens
- etc...
Huh. Creating a simple game takes a long time at an hour of development time a week.
:
| |
| Wednesday, August 27, 2008 |
 An Iteration, A Combination |
Posted - 8/27/2008 10:14:02 PM | 
(click the image to play).
I suppose it was inevitable, but I combined the bitmap navigator functionality from the earlier experiments with the maze generator from a few days ago, and now I have an infinite variety of mazes which can be flown over. I haven't implemented wall/collision detection yet, but I should have it completed fairly soon. It won't be difficult; a simple color sniffer will give me pixel-level control over what is hitting what.
I also figured out how to add seeds to the maze generator, so now I can have the same mazes for everyone who plays, or each game session will now be able to be saved, without loading the game and discovering yourself in a new maze.
The code for the maze generator class is here:
package {
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Point;
public class MazeConstructor {
private var mazeBitmapData:BitmapData;
private var cellsX:Number;
private var cellsY:Number;
private var cellWidth:Number;
private var cellHeight:Number;
private var isRandom:Boolean = false;
private var seed:Number;
private var wallThickness:Number;
private var hasExits:Boolean;
private var maze:Array;
private var mx:Number = 0;
private var my:Number = 0;
private var nextCell:Number = 0;
private var d:Number = 0;
private var dx:Array = [ 0, 0, -1, 1 ];
private var dy:Array = [ -1, 1, 0, 0 ];
private var todo:Array = [];
private var todonum:Number = 0;
public function MazeConstructor() {}
public function initMaze($mazeBitmapData:BitmapData,$cellsX:Number,$cellsY:Number,$cellWidth:Number,$cellHeight:Number,$wallThickness:Number=1,$seed:Number=0,$hasExits:Boolean=false):void {
mazeBitmapData = $mazeBitmapData;
cellsX = $cellsX;
cellsY = $cellsY;
cellWidth = $cellWidth;
cellHeight = $cellHeight;
wallThickness = $wallThickness;
seed = $seed;
hasExits = $hasExits;
if(seed==0) isRandom = true;
createMaze();
}
private function createMaze():void {
mx = 0;
my = 0;
nextCell = 0;
d = 0;
dx = [ 0, 0, -1, 1 ];
dy = [ -1, 1, 0, 0 ];
todo = [];
todonum = 0;
maze = [];
for(mx = 0; mx < cellsX; mx++) {
maze[mx] = [];
for(my = 0; my < cellsY; my++) {
if(mx == 0 || mx == cellsX-1 || my == 0 || my == cellsY-1) {
maze[mx][my] = 32;
} else {
maze[mx][my] = 63;
}
}
}
if(isRandom==true) {
mx = (Math.floor(Math.random() * (cellsX-2)))+1;
my = (Math.floor(Math.random() * (cellsY-2)))+1;
} else {
mx = Math.floor(cellsX/2);
my = Math.floor(cellsY/2);
}
maze[mx][my] &= ~48;
for(d = 0; d < 4; d++) {
if((maze[mx + dx[d]][my + dy[d]] & 16) != 0) {
todo[todonum++] = ((mx + dx[d]) << 16) | (my + dy[d]);
maze[mx + dx[d]][my + dy[d]] &= ~16;
}
}
while(todonum > 0) {
if(isRandom==true) {
nextCell = (Math.floor(Math.random() * todonum));
} else {
seed++;
nextCell = seed % todonum;
}
mx = todo[nextCell] >> 16;
my = todo[nextCell] & 65535;
todo[nextCell] = todo[--todonum];
do{
if(isRandom==true) {
d = Math.floor(Math.random()*4);
} else {
seed++;
d = seed%4;
}
} while((maze[mx + dx[d]][my + dy[d]] & 32) != 0);
maze[mx][my] &= ~((1 << d) | 32);
maze[mx + dx[d]][my + dy[d]] &= ~(1 << (d ^ 1));
for(d = 0; d < 4; d++) {
if((maze[mx + dx[d]][my + dy[d]] & 16) != 0) {
todo[todonum++] = ((mx + dx[d]) << 16) | (my + dy[d]);
maze[mx + dx[d]][my + dy[d]] &= ~16;
}
}
}
if(hasExits==true) {
maze[1][1] &= ~1;
maze[cellsX-2][cellsY-2] &= ~2;
}
renderMaze();
}
private function renderMaze():void {
var i:int;
var j:int;
for(i = 1; i < cellsX-1; i++) {
for(j = 1; j < cellsY-1; j++) {
if((maze[i][j] & 1) != 0) {
mazeBitmapData.fillRect (new Rectangle(i * cellWidth, j * cellHeight, cellWidth+wallThickness, wallThickness),0xff000000);
}
if((maze[i][j] & 2) != 0) {
mazeBitmapData.fillRect(new Rectangle(i * cellWidth, j * cellHeight + cellHeight, cellWidth+wallThickness, wallThickness),0xff000000);
}
if((maze[i][j] & 4) != 0) {
mazeBitmapData.fillRect(new Rectangle(i * cellWidth, j * cellHeight, wallThickness, cellHeight+wallThickness),0xff000000);
}
if((maze[i][j] & 8) != 0) {
mazeBitmapData.fillRect(new Rectangle(i * cellWidth+cellWidth, j * cellHeight, wallThickness, cellHeight+wallThickness),0xff000000);
}
}
}
}
}
}
Looking at this, it occurred to me that it wouldn't be too difficult to modify this so that it can draw hex mazes. Really, it is just two more walls, and modify the positioning of the cells. The bitwise/boolean operators will work just as well, I think. But this is a project for when the weather is ugly, and the girlfriend is out of town.
Also: I discovered a port of Telengard (Windows) which has had me in a big ol' nostalgia kick for the past several days. It holds up surprisingly well for a game I first played on my Commodore 64, back in 1984.
| |
|
| S | M | T | W | T | F | S | | | | | | | 1 | | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | | | | | |
OPTIONS
Track this Journal
ARCHIVES
November, 2008
October, 2008
September, 2008
August, 2008
July, 2008
February, 2008
December, 2007
November, 2007
October, 2007
September, 2007
July, 2007
June, 2007
March, 2007
February, 2007
January, 2007
December, 2006
August, 2006
July, 2006
June, 2006
|