| Tuesday, November 27, 2007 |
 In the Thick of Things |
Posted - 11/27/2007 10:22:11 AM | Work is progressing on The Dry White Harvest - which I am considering renaming "A Dry Harvest", just because it rolls of the tongue better and, well, salt isn't necessarily (or even usually) white.
I have roughed in the title screen and instructions panel, and am currently building out the inventory/management screen. I have also simplified the tech tree a bit. Originally I had three types of people: Villagers, Farmers and Miners. The ideas was, villagers all worked the mines in a rudimentary fashion, and some of the could specialize in mining or farming. On consideration that seemed a little too arbitrary and complicated, so now there are only villagers, which can be assigned at the beginning of each turn to either farm food or gather salt. Villagers are the "grunts" of the game.
All the rest of the People types are special cases which can be hired from outside, once the village is stable and profitable. There will always be villagers coming and going, based on how profitable and stable the village is.
Two pie-in-the-sky ideas: First, being able to save a game. Second, making the game in such a way that it can be expanded without having to significantly alter the game.
| |
| Wednesday, November 14, 2007 |
 4E6 - first prototype |
Posted - 11/14/2007 6:34:37 PM | 
Here is the first rudimentary prototype. Mousing over a button will highlight the dependencies (e.g. ancestors in the tech tree) of the subject of that button.
| |
| Sunday, November 11, 2007 |
 The Story is Coming Together |
Posted - 11/11/2007 8:34:33 PM | I have made significant progress on putting together content for my game. I did some more research and I think I have the basic tech tree complete. It includes villager types, income sources and possible technologies. I think I have kept the structure generic enough that I will be able to add to the tree without having to significantly alter the coding in the game.
My dream of having a completely XML-based data system for the game is rapidly fading. All of the pieces and parts need to fit together in ways which are specific enough that, to create a game engine general enough to make use of it, would take more time than I have to complete the game. So the data and the game engine will be closely tied together.
If the game is successful then I will go back and re-factor everything, but for right now, completion takes priority over elegance.
In other news, I recently came across a site which has 201 of Anton Chekhov's stories, translated into English and ordered by Russian publication date. I am fighting the urge to just drop everything and spend the next week reading. One idea which came out of this discovery, however, was this: Re-create one of the stories, or perhaps one of his plays, as an interactive fiction construct. How cool would that be, to play Uncle Vanya as a text adventure! It seems to me that this would be a true test of how well a story or play is understood: Turn it into a game. Forget literary theory: Translate it into an interactive medium.
| |
| Tuesday, November 6, 2007 |
 The Last Word On the Subject, For Now. |
Posted - 11/6/2007 9:49:05 PM | I posted one more iteration of the rotating height map. I cleaned up the code and optimized it, but it is still pretty processor-intensive.
And to think this whole past several days of mad coding began when I started playing around with using Perlin Noise as a way to "seed" the terrain in my 4e6 game with varying amounts of salt for harvesting and mining.
The ideas for my game continue to gel. In my head I have all of the technical problems worked out, and if I had a free week I could probably get the game to a playable state. The problem I am now running into is, how will I make the game enjoyable? Playable once is not a problem. It is also not much of a challenge or a goal. I want people to get in trouble at work because they spend so much time on my game.
| |
 Rotating isometric height map, round 1 |
Posted - 11/4/2007 8:48:51 AM | 
Well, here it is.
Click the image to see it in action.
Click your browser's [REFRESH] button to see a new height map.
Be warned: Right now it is quite a processor hog; I still have work to do to optimize the performance. But at least, it works.
Complete source for this experiment is here:
package {
import flash.display.*;
import flash.geom.*;
import flash.events.*;
[SWF(backgroundColor="0x000000",width="480",height="480", frameRate="40")]
public class ThresholdTest extends Sprite {
private var bitmapData1:BitmapData;
private var bitmapData2:BitmapData;
private var displayBitmapData:BitmapData;
private var displayBitmap:Bitmap;
private var iterator:Number = 1;
private var w:Number;
private var h:Number;
private var dataLayers:Array;
private var displayMatrix:Matrix;
private var worldIterator:Number = 0;
public function ThresholdTest() {
addEventListener(Event.ENTER_FRAME,init);
}
private function init(e:Event):void {
if(!stage) return;
removeEventListener(Event.ENTER_FRAME,init);
stage.scaleMode = StageScaleMode.NO_SCALE;
w=250;
h=250;
displayBitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,true,0xff000000);
displayBitmap = new Bitmap(displayBitmapData);
addChild(displayBitmap);
bitmapData1 = new BitmapData(w,h,true,0xffffffff);
bitmapData1.perlinNoise(
Math.round(Math.random()*150)+150,
Math.round(Math.random()*150)+150,
Math.round(Math.random()*12),
Math.random()*100000,
true,
false,
Math.round(Math.random()*7),
true
);
dataLayers = [];
for(var i:Number = 0;i<256;i++) {
dataLayers[i] = new BitmapData(w,h,true,0x00000000);
}
displayMatrix = new Matrix();
addEventListener(Event.ENTER_FRAME,refreshBitmap);
}
private function rotateBitmap(e:Event):void {
displayBitmapData.lock();
displayBitmapData.fillRect(displayBitmapData.rect,0xff000000);
for(var i:Number = 0;i<dataLayers.length;i++) {
displayMatrix.identity();
displayMatrix.translate(-w/2,-h/2);
displayMatrix.rotate((Math.PI*2/360)*worldIterator);
displayMatrix.translate(
stage.stageWidth*.5,
stage.stageHeight*.75 - dataLayers[i].height/2-i
);
displayBitmapData.draw(dataLayers[i],displayMatrix);
}
displayBitmapData.unlock();
worldIterator++;
}
private function refreshBitmap(e:Event):void {
if(iterator==256) {
removeEventListener(Event.ENTER_FRAME,refreshBitmap);
addEventListener(Event.ENTER_FRAME,rotateBitmap);
return;
}
var t:String = "0x00" + ((iterator<16)?"0":"") + iterator.toString(16) + "0000";
var t2:String = "0xff"
+ ((iterator<16)?"0":"") + iterator.toString(16)
+ ((iterator<16)?"0":"") + iterator.toString(16)
+ ((iterator<16)?"0":"") + iterator.toString(16);
dataLayers[iterator].threshold(
bitmapData1,
bitmapData1.rect,
new Point(0,0),
">",
parseInt(t),
parseInt(t2),
0x00ff0000,
false
);
displayBitmapData.draw(dataLayers[iterator]);
iterator++;
}
}
}
| |
 Threshold: fill and wireframe |
Posted - 11/2/2007 5:29:20 PM | 
Wireframe height map

Filled Height Map
Click the images for animations. Source here:
package {
import flash.display.*;
import flash.geom.*;
import flash.events.*;
[SWF(backgroundColor="0x000000",width="480",height="480", frameRate="40")]
public class ThresholdTest extends Sprite {
private var bitmapData1:BitmapData;
private var bitmapData2:BitmapData;
private var display:Bitmap;
private var iterator:Number = 1;
private var w:Number;
private var h:Number;
public function ThresholdTest() {
addEventListener(Event.ENTER_FRAME,init);
}
private function init(e:Event):void {
if(!stage) return;
stage.scaleMode = StageScaleMode.NO_SCALE;
w = stage.stageWidth;
h = stage.stageHeight/2;
removeEventListener(Event.ENTER_FRAME,init);
bitmapData1 = new BitmapData(w,h,true,0xffffffff);
bitmapData1.perlinNoise(200,200,4,143534,true,true,7,true);
bitmapData2 = new BitmapData(w,h*2,true,0x00000000);
display = new Bitmap(bitmapData2);
addChild(display);
addEventListener(Event.ENTER_FRAME,refreshBitmap);
}
private function refreshBitmap(e:Event):void {
var t:String = "0x00" + ((iterator<16)?"0":"") + iterator.toString(16) + "0000";
var t2:String = "0xff"
+ ((iterator<16)?"0":"") + iterator.toString(16)
+ ((iterator<16)?"0":"") + iterator.toString(16)
+ ((iterator<16)?"0":"") + iterator.toString(16);
bitmapData2.threshold(
bitmapData1,
bitmapData1.rect,
new Point(0,h-iterator),
">",
parseInt(t),
parseInt(t2),
0x00ff0000,
false
);
iterator++;
if(iterator==256){
iterator=0;
bitmapData1.perlinNoise(
Math.round(Math.random()*150)+150,
Math.round(Math.random()*150)+150,
Math.round(Math.random()*12),
Math.random()*100000,
true,
false,
Math.round(Math.random()*7),
true
);
bitmapData2.fillRect(bitmapData2.rect,0xff000000);
}
}
}
}
| |
 Threshold and Perlin Noise |
Posted - 11/2/2007 7:53:40 AM | 
Click the image to see a working example of BitmapData.Threshold and BitmapData.perlinNoise working together. The .swf in the example weighs in at a hefty 1794 bytes.
package {
import flash.display.*;
import flash.geom.*;
import flash.events.*;
[SWF(backgroundColor="0x000000",width="400",height="400", frameRate="40")]
public class ThresholdTest extends Sprite {
private var bitmapData1:BitmapData;
private var bitmapData2:BitmapData;
private var display:Bitmap;
private var debug:OutputWindow;
private var iterator:Number = 1;
private var w:Number;
private var h:Number;
public function ThresholdTest() {
addEventListener(Event.ENTER_FRAME,init);
}
private function init(e:Event):void {
if(!stage) return;
stage.scaleMode = StageScaleMode.NO_SCALE;
w = stage.stageWidth;
h = stage.stageHeight;
removeEventListener(Event.ENTER_FRAME,init);
bitmapData1 = new BitmapData(w,h,true,0xffffffff);
bitmapData1.perlinNoise(200,200,4,143534,true,true,7,true);
bitmapData2 = new BitmapData(w,h,true,0xff000000);
display = new Bitmap(bitmapData2);
addChild(display);
addEventListener(Event.ENTER_FRAME,refreshBitmap);
}
private function refreshBitmap(e:Event):void {
var t:String = "0x00" + ((iterator<16)?"0":"") + iterator.toString(16) + "0000";
var t2:String = "0xff"
+ ((iterator<16)?"0":"") + iterator.toString(16)
+ ((iterator<16)?"0":"") + iterator.toString(16)
+ ((iterator<16)?"0":"") + iterator.toString(16);
bitmapData2.threshold(
bitmapData1,
bitmapData1.rect,
new Point(0,0),
"==",
parseInt(t),
parseInt(t2),
0x00ff0000,
false
);
iterator++;
if(iterator==256){
iterator=0;
bitmapData1.perlinNoise(
200,
200,
8,
Math.random()*10000,
true,
false,
7,
true
);
}
}
}
}
| |
| Thursday, November 1, 2007 |
 Threshold Hell |
Posted - 11/1/2007 4:11:16 PM | So I think I finally figured it out.
package {
import flash.display.*;
import flash.geom.*;
import flash.events.*;
public class ThresholdTest extends Sprite {
private var bitmapData1:BitmapData;
private var bitmapData2:BitmapData;
private var display:Bitmap;
public function ThresholdTest() {
addEventListener(Event.ENTER_FRAME,init);
}
private function init(e:Event) {
if(!stage) return;
removeEventListener(Event.ENTER_FRAME,init);
bitmapData1 = new BitmapData(stage.stageWidth,stage.stageHeight,true,0xffffffff);
bitmapData2 = new BitmapData(stage.stageWidth,stage.stageHeight,true,0xff000000);
bitmapData1.perlinNoise(50,50,4,23423,true,true,7,true);
bitmapData2.threshold(
bitmapData1,
bitmapData1.rect,
new Point(0,0),
"==",
0x00800000,
ONLY ONE CHANNEL!!!!!!!!
0xffff0000,
0x00ff0000,
ONLY ONE CHANNEL!!!!!!!!!
false
source?
);
display = new Bitmap(bitmapData2);
addChild(display);
}
function updateBitmap():void {
}
}
}
I have been mucking around with getting threshold to work in AS3/Flash 9 for WEEKS!!! And I finally,
through much trial and error, got it all sorted out so now I can update my dynamic height map experiment to actually
work!
Argh!!!
| |
|
| S | M | T | W | T | F | S | | | | | | | 3 | | 5 | | 7 | 8 | 9 | 10 | | 12 | 13 | | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | | 28 | 29 | 30 | |
OPTIONS
Track this Journal
ARCHIVES
November, 2009
March, 2009
January, 2009
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
|