Outside of here at Blogger, I had a portfolio I had built up at Wordpress. Didn't realize the thing expired at the end of the year, so all the stuff I had put together is gone. Which really sucks. So now I've got to figure out what to do in terms of graphics related work.
But yeah, that sucks!
Back again to Blogger. Also tweaked some layout formatting here. This was originally setup on an XGA monitor, so when I went to a larger screen it was weird. A little fix here and there now that there's some more stuff in CSS3, but my CSS skills are as rusty as hell. But at least I got the background to center and overlay again like it was supposed to. It's "close-enough" for now, but I may do some more template fixing later.
Also I'm thinking of building one blog specifically for portfolio stuff. But here at Blogger, where it doesn't auto-expire if you don't really have the cash on hand. (Some say Wordpress is cheap, but when you're broke cheap isn't cheap enough.)
Thursday, January 14, 2016
Wednesday, June 25, 2014
Some Cycles nodes for neon.
Some Cycles nodes for a neat blue neon material with a few notes scribbled on. I used RGB curves node to control intensity over the surface from inside to outside, but a color ramp node with grayscale can likely do the same thing. That intensity falloff thing helps the glass part catch any glints and develop a few highlights from the neon itself. Hard to explain, other than messing around with settings and seeing how it works. I think it looks nice for what it is.
Friday, October 04, 2013
Some Blender stuff of all things
I haven't updated this blog in a while. But may as well post something useful this time around. So now for a video on how to make a wheel roll along a path in Blender regardless of what direction the path is going...
Thursday, August 23, 2012
A song about.... NO.
I also do audio stuff on occasion. This one is kind of pointless, but what the heck.
Oh and here's some of my other crap so you can feel even better about your musical talent (if you have any)...
Wednesday, August 22, 2012
The greeble monster makes no sense
Does anyone actually read this? Probably not. I don't see much in the way of feedback, and the typical basic stats I can see don't mean terribly much either.
Ah the mysteries of wi-fi router addresses scanned while bored.
I might post some satirical thing here in the future. Fun with home alchemy or something of that sort. Not that anyone would attempt such things if I made up a process of random things to mix together. Even the neigborhood trash douchbaggias wouldn't slip upon the advice of a random stranger. Herp-a-derp. That's it for the meantime.
Ah the mysteries of wi-fi router addresses scanned while bored.
I might post some satirical thing here in the future. Fun with home alchemy or something of that sort. Not that anyone would attempt such things if I made up a process of random things to mix together. Even the neigborhood trash douchbaggias wouldn't slip upon the advice of a random stranger. Herp-a-derp. That's it for the meantime.
Monday, February 27, 2012
A Camera is Watching You
I figure somebody at the park may chance upon this and read this after noticing the SSID from my wifi. Anyhow, take a look at the light posts on the streets around the park. At least one has a camera on the top of it. No, it's not the typical "bubble" cam or one of those blue light specials like you see in the seedier neighborhoods. But none the less, there's a camera up there. When you get a chance, wave "hi" to it. Go ahead and do it. It'll be funny!
Friday, August 05, 2011
Somebody mad?
YOU JELLY?
I don't know who's mad, but somebody felt inclined to egg my car. Even though it's 10 years old with scratches, it still must be too nice compared to theirs.
Maybe they heard I found work on the internet or something. I've been out of work for so long, why shouldn't I get some opportunities every now and then?
Don't worry though, you'll get yours in due time...
But on the business of work, I'm back to getting a 3D model done. Put in 4hrs last night, and will get more done today. Now that I'm keeping track of time on these things, they take longer than I thought. Seems most of the time goes into prep and then making decisions about where to place the edge loops or whether to commit to a smooth operation. Crazy, but whatever. It's all good.
I don't know who's mad, but somebody felt inclined to egg my car. Even though it's 10 years old with scratches, it still must be too nice compared to theirs.
Maybe they heard I found work on the internet or something. I've been out of work for so long, why shouldn't I get some opportunities every now and then?
Don't worry though, you'll get yours in due time...
But on the business of work, I'm back to getting a 3D model done. Put in 4hrs last night, and will get more done today. Now that I'm keeping track of time on these things, they take longer than I thought. Seems most of the time goes into prep and then making decisions about where to place the edge loops or whether to commit to a smooth operation. Crazy, but whatever. It's all good.
Sunday, February 13, 2011
Sound in Flash Player Broken?
Anyone know when or which update broke how event sounds play in Flash? I have some old stuff that used to work just fine, and now the sounds don't play correctly or not at all. I figure it had to be in one of the recent Adobe 10.x Flash player updates. This bug has to affect a lot of pages that have UIs or games made in older versions of the Flash authoring tool.
Surely I can't be the only person to notice this.
Surely I can't be the only person to notice this.
Friday, February 11, 2011
PMG Messiah:Studio - nice limited time offer
I figure there's a rare few that may read this blog, so I have some new news.
There's a pretty tight deal for a very limited time where you may be able to get a $1100 suite of graphics software for $40. Pretty much it's professional quality rigging and animation software that various studios use in their production pipeline.
Oh, and if $40 is still too much you can get the "light" $540 software for $10.
And here's the link:
http://projectmessiah.com/x6/shop.html
And for some reason if you don't see the green bar (which was hovering at 75% at the time of this post), you may be too late.
There's a pretty tight deal for a very limited time where you may be able to get a $1100 suite of graphics software for $40. Pretty much it's professional quality rigging and animation software that various studios use in their production pipeline.
Oh, and if $40 is still too much you can get the "light" $540 software for $10.
And here's the link:
http://projectmessiah.com/x6/shop.html
And for some reason if you don't see the green bar (which was hovering at 75% at the time of this post), you may be too late.
Saturday, September 18, 2010
Modeling A Preserve Jar
A Wings3D video tutorial, in case you missed it. Covers basic box modeling and UV mapping, as well as some of Wings3D vector operations. Dunno who reads this blog, but what the hey!
Quite a bit, isn't it? Hopefully something can be learned from it.
Quite a bit, isn't it? Hopefully something can be learned from it.
Saturday, July 24, 2010
Menus: Dropdown vs Pulldown explained
I was looking for some reference to clarify this issue on the web, and what do I see in the first couple hits on google? Bad information on the topic. It seems that a lot of sites say there is no difference between dropdown and pulldown menus. Guess what? THEY'RE WRONG!
Here's the difference:
Dropdown menu: When you click on the menu header to access the menu, the menu stays on the screen until a selection is made. Note that clicking outside the box also counts as a "selection".
Pulldown menu: You have to hold the mouse button down to access the menu. If you release the mouse button or drag off the menu, the menu goes away. In other words a PULLdown menu is a DRAGdown menu, but it is not a DROPdown menu!
A subtle difference I'm sure, but it's quite a big one in regards to UI workflow. Also note that a dropdown takes two mouse clicks. One to access the menu, and one to access the menu item. A pulldown (dragdown) only takes one click, but you must hold down the button as with a mouse drag operation.
Now is it clear? I hope so.
Here's the difference:
Dropdown menu: When you click on the menu header to access the menu, the menu stays on the screen until a selection is made. Note that clicking outside the box also counts as a "selection".
Pulldown menu: You have to hold the mouse button down to access the menu. If you release the mouse button or drag off the menu, the menu goes away. In other words a PULLdown menu is a DRAGdown menu, but it is not a DROPdown menu!
A subtle difference I'm sure, but it's quite a big one in regards to UI workflow. Also note that a dropdown takes two mouse clicks. One to access the menu, and one to access the menu item. A pulldown (dragdown) only takes one click, but you must hold down the button as with a mouse drag operation.
Now is it clear? I hope so.
Thursday, June 24, 2010
Cassius & Cassandra
Friday, June 11, 2010
Spacewar in under 100 lines?
I'm a little crazy, but I'm trying to code a clone of the ol' classic game "Spacewar" in under 100 lines in ActionScript 2. I did this before with code spread about on different movieclips and had a semi-playable game working. But now I'm trying something a little harder. This time I'm trying to keep all the actions together on the main timeline with the added challenge of trying to make better use of OOP conventions to better cover steps that repeat. So far I got it up to the point where it makes the bullets, but it doesn't quite shoot them. Hell, it's hard enough trying to figure out how I did it the first time around - being that I haven't done much in scripting for a long time. Anyhow... Here's the code:
// This is the section with the actual game.
// Create the Ship() constructor class.
function Ship(rot, xP, yP, player) {
this.rotation = rot;
this.xVelocity = 0;
this.yVelocity = 0;
this.hitPoints = 100;
this.player = player;
}
// Adding methods to Ship class.
Ship.prototype.applyThrust = function() {
trace("Applying thrust to "+this.player);
angleDeg = (this.rotation<0)*360+this.rotation;
angleRad = (angleDeg/180)*Math.PI;
this.xVelocity += (Math.sin(angleRad)*.75);
this.yVelocity -= (Math.cos(angleRad)*.75);
};
Ship.prototype.turnLeft = function() {
trace("Turning "+this.player+" left");
this.rotation -= 10;
};
Ship.prototype.turnRight = function() {
trace("Turning "+this.player+" right");
this.rotation += 10;
};
Ship.prototype.fireGun = function() {
trace(this.player+" is firing their gun.");
_root.attachMovie("bullet", this.player+"Shot_mc", 10);
_root[this.player+"Shot_mc"]._x = _root[this.player+"_Ship_mc"]._x;
_root[this.player+"Shot_mc"]._y = _root[this.player+"_Ship_mc"]._y;
};
Ship.prototype.calcMovement = function(clipID) {
clipID._rotation = this.rotation;
clipID._x += this.xVelocity+((clipID._x<0)*640)-((clipID._x>640)*640);
clipID._y += this.yVelocity+((clipID._y<0)*480)-((clipID._y>480)*480);
};
var P1_Ship = new Ship(0, 10, 10, "P1");
var P2_Ship = new Ship(0, 100, 10, "P2");
for (var prop in P1_Ship) {
trace("property "+prop+" value is "+P1_Ship[prop]);
}
function testLoop() {
if (Key.isDown(87) == true) {
P1_Ship.applyThrust();
}
if (Key.isDown(65) == true) {
P1_Ship.turnLeft();
}
if (Key.isDown(68) == true) {
P1_Ship.turnRight();
}
if (Key.isDown(83)) {
P1_Ship.fireGun(P1_Ship_mc);
}
if (Key.isDown(38)) {
P2_Ship.applyThrust();
}
if (Key.isDown(37)) {
P2_Ship.turnLeft();
}
if (Key.isDown(39)) {
P2_Ship.turnRight();
}
if (Key.isDown(40)) {
P2_Ship.fireGun(P2_Ship_mc);
}
P1_Ship.calcMovement(P1_Ship_mc);
P2_Ship.calcMovement(P2_Ship_mc);
}
setInterval(testLoop, 60);
stop();
Oh, and I'm using only 3 movieclips if you haven't figured it out. And adding sound shouldn't be too terrible either, even though I haven't got to that yet.
// This is the section with the actual game.
// Create the Ship() constructor class.
function Ship(rot, xP, yP, player) {
this.rotation = rot;
this.xVelocity = 0;
this.yVelocity = 0;
this.hitPoints = 100;
this.player = player;
}
// Adding methods to Ship class.
Ship.prototype.applyThrust = function() {
trace("Applying thrust to "+this.player);
angleDeg = (this.rotation<0)*360+this.rotation;
angleRad = (angleDeg/180)*Math.PI;
this.xVelocity += (Math.sin(angleRad)*.75);
this.yVelocity -= (Math.cos(angleRad)*.75);
};
Ship.prototype.turnLeft = function() {
trace("Turning "+this.player+" left");
this.rotation -= 10;
};
Ship.prototype.turnRight = function() {
trace("Turning "+this.player+" right");
this.rotation += 10;
};
Ship.prototype.fireGun = function() {
trace(this.player+" is firing their gun.");
_root.attachMovie("bullet", this.player+"Shot_mc", 10);
_root[this.player+"Shot_mc"]._x = _root[this.player+"_Ship_mc"]._x;
_root[this.player+"Shot_mc"]._y = _root[this.player+"_Ship_mc"]._y;
};
Ship.prototype.calcMovement = function(clipID) {
clipID._rotation = this.rotation;
clipID._x += this.xVelocity+((clipID._x<0)*640)-((clipID._x>640)*640);
clipID._y += this.yVelocity+((clipID._y<0)*480)-((clipID._y>480)*480);
};
var P1_Ship = new Ship(0, 10, 10, "P1");
var P2_Ship = new Ship(0, 100, 10, "P2");
for (var prop in P1_Ship) {
trace("property "+prop+" value is "+P1_Ship[prop]);
}
function testLoop() {
if (Key.isDown(87) == true) {
P1_Ship.applyThrust();
}
if (Key.isDown(65) == true) {
P1_Ship.turnLeft();
}
if (Key.isDown(68) == true) {
P1_Ship.turnRight();
}
if (Key.isDown(83)) {
P1_Ship.fireGun(P1_Ship_mc);
}
if (Key.isDown(38)) {
P2_Ship.applyThrust();
}
if (Key.isDown(37)) {
P2_Ship.turnLeft();
}
if (Key.isDown(39)) {
P2_Ship.turnRight();
}
if (Key.isDown(40)) {
P2_Ship.fireGun(P2_Ship_mc);
}
P1_Ship.calcMovement(P1_Ship_mc);
P2_Ship.calcMovement(P2_Ship_mc);
}
setInterval(testLoop, 60);
stop();
Oh, and I'm using only 3 movieclips if you haven't figured it out. And adding sound shouldn't be too terrible either, even though I haven't got to that yet.
Wednesday, June 09, 2010
SEO in Waukegan is easy.
Check this out. If you're in a city of less than 100,000 and you localize your information on your website or blog, it's really easy to optimize for a search engine. If you put enough info, it should happen on its own. Regarding that, I'd be willing to bet a dollar that this blog will be somewhere in the first three pages containing the words "SEO" and "Waukegan". And I'm not really trying hard. If you're paying a lot for such services, and you're a small town business catering to a small town audience... Well, you know the ol' adage about a fool and their money.
But hey I'm just one guy that does freelance work as a graphic artist. So what do I know about this kind of stuff? And it's not like you found my blog via those keywords right? ;)
But hey I'm just one guy that does freelance work as a graphic artist. So what do I know about this kind of stuff? And it's not like you found my blog via those keywords right? ;)
Friday, June 04, 2010
The Smallest Graphic Design Place in Waukegan
This is it, my freelancing is the smallest graphic design place in Waukegan. I haven't seen a mention of this site in regards to my hometown, so may as well make it be known. (Although I try to do most stuff over the net, but still I think there may be location specific stuff available.)
Some people may claim to be small, but me? I don't even have a large format printer yet, and I'm a one man show. The real problem is letting people know that there's good talent in their own backyard. And short of doing print jobs (which would still have to go outside), I can do some pretty cool things design-wise. If you want 3D visualizations or animations, Illustrations, and Logos, it will be harder to find better bang for the buck.
So if you've managed to stumble on this, fire off a comment. Or give a hint at your email. Or if that's too much work, here's a hint of mine: pop alpha uniform luck jump snake 7 5 (at) hotmail.
Some people may claim to be small, but me? I don't even have a large format printer yet, and I'm a one man show. The real problem is letting people know that there's good talent in their own backyard. And short of doing print jobs (which would still have to go outside), I can do some pretty cool things design-wise. If you want 3D visualizations or animations, Illustrations, and Logos, it will be harder to find better bang for the buck.
So if you've managed to stumble on this, fire off a comment. Or give a hint at your email. Or if that's too much work, here's a hint of mine: pop alpha uniform luck jump snake 7 5 (at) hotmail.
Sunday, May 23, 2010
This is for you flash people...
I know I'm far from the world's best ActionScript coder, but here's a nugget from something I made a good while back that may be fun to look at and play with. (I know it works in AS2.0, but YMMV with other versions.) Oh yeah, I should mention that it goes on a movieclip.
// Set up initializing parameters.
onClipEvent (load) {
this.stop();
var inertiaX = 0;
var inertiaY = 0;
var angleRad = 0;
thruster_sound = new Sound();
thruster_sound.attachSound("thruster");
}
//Stop sound and thruster animation.
onClipEvent (keyUp) {
this.gotoAndStop(1);
thruster_sound.stop();
}
onClipEvent (enterFrame) {
//Turn left when "A" is pressed.
if (Key.isDown(65) == true) {
this._rotation -= 5;
trace(this._rotation);
}
//Turn right when "D" is pressed.
if (Key.isDown(68) == true) {
this._rotation += 5;
trace(this._rotation);
}
//Convert _rotation to 360deg and radians.
angleDeg = (this._rotation<0)*360+this._rotation;
angleRad = (angleDeg/180)*Math.PI;
//Go forward when "W" is pressed.
if (Key.isDown(87) == true) {
this.play();
thruster_sound.start(0, 2);
inertiaX += Math.sin(angleRad)*.5;
inertiaY -= Math.cos(angleRad)*.5;
trace(angleDeg+" "+angleRad+" "+inertiaX+" "+inertiaY);
}
//Fire shot when "S" is pressed.
if (Key.isDown(83) == true) {
_parent.attachMovie("shot1", "shot1_mc", 10, this);
}
//Keep spacehip on screen by wrapping.
if (this._y<0) {
this._y = 400;
}
if (this._y>400) {
this._y = 0;
}
if (this._x<0) {
this._x = 550;
}
if (this._x>550) {
this._x = 0;
}
//Make spaceship move.
this._x += int(inertiaX);
this._y += int(inertiaY);
//Pass variables to shot fired.
xInit = this._x;
yInit = this._y;
//Check if enemy shot exists.
if (_parent.shot2_mc) {
//Check for enemy shot collision.
if (this.hitTest(_parent.shot2_mc._x, _parent.shot2_mc._y, true)) {
_root.p2Score++;
trace("Hit P2 shot hit P1");
_parent.shot2_mc.removeMovieClip();
}
}
}
// Set up initializing parameters.
onClipEvent (load) {
this.stop();
var inertiaX = 0;
var inertiaY = 0;
var angleRad = 0;
thruster_sound = new Sound();
thruster_sound.attachSound("thruster");
}
//Stop sound and thruster animation.
onClipEvent (keyUp) {
this.gotoAndStop(1);
thruster_sound.stop();
}
onClipEvent (enterFrame) {
//Turn left when "A" is pressed.
if (Key.isDown(65) == true) {
this._rotation -= 5;
trace(this._rotation);
}
//Turn right when "D" is pressed.
if (Key.isDown(68) == true) {
this._rotation += 5;
trace(this._rotation);
}
//Convert _rotation to 360deg and radians.
angleDeg = (this._rotation<0)*360+this._rotation;
angleRad = (angleDeg/180)*Math.PI;
//Go forward when "W" is pressed.
if (Key.isDown(87) == true) {
this.play();
thruster_sound.start(0, 2);
inertiaX += Math.sin(angleRad)*.5;
inertiaY -= Math.cos(angleRad)*.5;
trace(angleDeg+" "+angleRad+" "+inertiaX+" "+inertiaY);
}
//Fire shot when "S" is pressed.
if (Key.isDown(83) == true) {
_parent.attachMovie("shot1", "shot1_mc", 10, this);
}
//Keep spacehip on screen by wrapping.
if (this._y<0) {
this._y = 400;
}
if (this._y>400) {
this._y = 0;
}
if (this._x<0) {
this._x = 550;
}
if (this._x>550) {
this._x = 0;
}
//Make spaceship move.
this._x += int(inertiaX);
this._y += int(inertiaY);
//Pass variables to shot fired.
xInit = this._x;
yInit = this._y;
//Check if enemy shot exists.
if (_parent.shot2_mc) {
//Check for enemy shot collision.
if (this.hitTest(_parent.shot2_mc._x, _parent.shot2_mc._y, true)) {
_root.p2Score++;
trace("Hit P2 shot hit P1");
_parent.shot2_mc.removeMovieClip();
}
}
}
Monday, December 14, 2009
PhotoShop Diet Anyone?
If anyone (is crazy enough and) wants to try a free sample of a "PhotoShop Diet", feel free to ask by commenting to this post. Then I'll try to get in touch, so we can see what I can do with your photo.
That is all for now.
That is all for now.
Saturday, September 12, 2009
I'm gonna make my own FreeCell in Flash.
It probably sounds stupid, because it's likely to have been done hundreds of times before already. But I was trying out a Facebook app version of Freecell that had omitted some important key features of this game that has been a staple item of every Microsoft Windows PC since version 3.1 or so. So in my opinion, that Facebook app is broken. Thus if I can make a version of Freecell that works correctly, then I know other people can. And since there's been versions of it since DOS and Win3.1 days, it's not like it's impossible to implement all the rules correctly.
The tricky part of this game is deducting the rules from a programmatic logic standpoint. The problem is that I'm normally not a programmer. So this is a simple logic puzzle and a break from my normal routine. Let's try to think of how the thing works...
First is the layout:
You have four free cells, and you have four open dump cells (Officially its called a foundation, but since I consider it dumping cards out of the game, that's what I've called it.), then you have the cards that get laid out on the table, and you count any empty spaces on the table as an extra free cell. You have eight columns of cards laid out on the table in a random cascade, face up. And generally it's the cards from the bottom (but not only the bottom - important!) of a cascade that are put into play or dumped into the foundation squares.
The actual rules can be found at Wikipedia. So it's known what we have to work with.
Now the first thing to do is initially randomize the cards. This will involve a loop that populates an array. We know we have 52 cards in a standard deck. So we know we need a list that's 52 values long, and contains non-repeating values between 1 and 52. (Non-repeating is important, because there is only one of each card of a given suit and value.) So we use a loop that populates the array. The loop generates a random number between 1 and 52. Then it checks the array to see if the random number matches any already on the array. If there is a match, it goes and generates a new random number and tries again. If there is no match, then it adds the new number to the array. And it keeps doing this until all 52 positions of the array are filled. Easy peasy, right?
Next thing we do... Lay out the cards on the table. This is trickier. I'm thinking of using setting depths (if I recall actionscript correctly) and placing each row across. Since we have the cards in a nice random order from the previous routine, we just populate the table (in more than one way) by drawing from the array. Going across 8 columns, and then down to the next row (and a higher depth), until all 52 cards are used.
Since this is done programmatically, we also need some rules for the suits of the cards. Basically since a simple index number between 1 and 52 is the easiest and most obvious way to identify a card, that's what was done already if you haven't figured it out. But we also need to associate the card's index value with it's suit and it's color. Since I went with diamonds, spades, hearts, clubs as the order of suits, this is how associated variable values are figured out. Index numbers 1-13, diamonds. Index 14-26, spades. Index 27-39, hearts. Index 40-52, clubs. Likewise red-black, red-black. So by pulling up any index number, the function automagically lets you know what the card is. And some simple if-greater than statements and some math routines gives the value from the index number. So now we get the traditional cards suits, colors, and values based upon the index number. And again index numbers are what we use to pick and label any of the cards program-wise.
The easiest rule is for the free cells, thus the name of this solitaire card game. Any card may be placed upon an unoccupied free cell. And no other cards may move on an occupied cell. And any card in the "free" cell, may be put back into play on the table or into the dump (foundation) cells.
What's next? We have the four "dump" foundation places. The rules for dumping cards into the foundation is why we needed that variable that "knows" the suit. So we got to make some if-then statements as some rules. If foundation is empty, an ace (1, 14, 27, and 40 from the index) of any suit may go there. If a card of any suit is in the slot, then check that the suits match. If not, disallow the move. Next check to see if the value of the card being placed is that of the lower card +1. If not, then also disallow the move. Once a card is placed into a foundation position, it's no longer allowed in play.
After that, we need the rest of the rules. Which is tricker to implement. On the table, an empy position can be used by any card. Then if a card is in a playable spot, only a card of an alternate color and a value lower by -1 may be placed on it. However the tricky thing to implement is the moving of stacks of cards. (And this is where the Facebook app that inspired the idea is broken.) If you have a stack of alternating cards in downward order, then entire stacks of cards are playable based on the value of the topmost card. But the playable topmost card of a stack is determined by number of free cells and open columns on available the table. The number of cards that can be moved as a stack are 1 + open columns + free cells. (There's also some programmatic trick in the MS version that anticipates some other moves and allows even more cards, depending on how many table columns are empty.)
The tricky thing is figuring out how to keep stacks together. I'll probably have to to assign variables that tell which row and column a card is currently placed in on the table. Then it's a matter of doing some routine that swaps the depths for all the cards in play so they layout properly from a visual perspective when moved. Scripting is fun (*half-sarcastic lol*), isn't it?
And once all cards are played from the table and free cells and into the foundation cells, the game is a win. If no moves are possible to clear the table (I've still got to figure out how that works programatically, I think I'll just have a manual button in my first implementation), then the game is a loss.
I think I'll give this a shot. I already did the card graphics. Now it's time to start digging into my books and reviewing the actionscript stuff. Other things to add are some stats. Total plays, wins, losses, and win/loss ratio. Maybe some time stats too, like fastest game and average play time. (If other freecell players are like I am, they could care less about other ways of scoring.) I'm also thinking of throwing some quirky goodies into the game, that spoofs the king icon in the MS version. Maybe even have it talk and say random insults when a move isn't allowed, just to make it unique and a bit more fun.
The tricky part of this game is deducting the rules from a programmatic logic standpoint. The problem is that I'm normally not a programmer. So this is a simple logic puzzle and a break from my normal routine. Let's try to think of how the thing works...
First is the layout:
You have four free cells, and you have four open dump cells (Officially its called a foundation, but since I consider it dumping cards out of the game, that's what I've called it.), then you have the cards that get laid out on the table, and you count any empty spaces on the table as an extra free cell. You have eight columns of cards laid out on the table in a random cascade, face up. And generally it's the cards from the bottom (but not only the bottom - important!) of a cascade that are put into play or dumped into the foundation squares.
The actual rules can be found at Wikipedia. So it's known what we have to work with.
Now the first thing to do is initially randomize the cards. This will involve a loop that populates an array. We know we have 52 cards in a standard deck. So we know we need a list that's 52 values long, and contains non-repeating values between 1 and 52. (Non-repeating is important, because there is only one of each card of a given suit and value.) So we use a loop that populates the array. The loop generates a random number between 1 and 52. Then it checks the array to see if the random number matches any already on the array. If there is a match, it goes and generates a new random number and tries again. If there is no match, then it adds the new number to the array. And it keeps doing this until all 52 positions of the array are filled. Easy peasy, right?
Next thing we do... Lay out the cards on the table. This is trickier. I'm thinking of using setting depths (if I recall actionscript correctly) and placing each row across. Since we have the cards in a nice random order from the previous routine, we just populate the table (in more than one way) by drawing from the array. Going across 8 columns, and then down to the next row (and a higher depth), until all 52 cards are used.
Since this is done programmatically, we also need some rules for the suits of the cards. Basically since a simple index number between 1 and 52 is the easiest and most obvious way to identify a card, that's what was done already if you haven't figured it out. But we also need to associate the card's index value with it's suit and it's color. Since I went with diamonds, spades, hearts, clubs as the order of suits, this is how associated variable values are figured out. Index numbers 1-13, diamonds. Index 14-26, spades. Index 27-39, hearts. Index 40-52, clubs. Likewise red-black, red-black. So by pulling up any index number, the function automagically lets you know what the card is. And some simple if-greater than statements and some math routines gives the value from the index number. So now we get the traditional cards suits, colors, and values based upon the index number. And again index numbers are what we use to pick and label any of the cards program-wise.
The easiest rule is for the free cells, thus the name of this solitaire card game. Any card may be placed upon an unoccupied free cell. And no other cards may move on an occupied cell. And any card in the "free" cell, may be put back into play on the table or into the dump (foundation) cells.
What's next? We have the four "dump" foundation places. The rules for dumping cards into the foundation is why we needed that variable that "knows" the suit. So we got to make some if-then statements as some rules. If foundation is empty, an ace (1, 14, 27, and 40 from the index) of any suit may go there. If a card of any suit is in the slot, then check that the suits match. If not, disallow the move. Next check to see if the value of the card being placed is that of the lower card +1. If not, then also disallow the move. Once a card is placed into a foundation position, it's no longer allowed in play.
After that, we need the rest of the rules. Which is tricker to implement. On the table, an empy position can be used by any card. Then if a card is in a playable spot, only a card of an alternate color and a value lower by -1 may be placed on it. However the tricky thing to implement is the moving of stacks of cards. (And this is where the Facebook app that inspired the idea is broken.) If you have a stack of alternating cards in downward order, then entire stacks of cards are playable based on the value of the topmost card. But the playable topmost card of a stack is determined by number of free cells and open columns on available the table. The number of cards that can be moved as a stack are 1 + open columns + free cells. (There's also some programmatic trick in the MS version that anticipates some other moves and allows even more cards, depending on how many table columns are empty.)
The tricky thing is figuring out how to keep stacks together. I'll probably have to to assign variables that tell which row and column a card is currently placed in on the table. Then it's a matter of doing some routine that swaps the depths for all the cards in play so they layout properly from a visual perspective when moved. Scripting is fun (*half-sarcastic lol*), isn't it?
And once all cards are played from the table and free cells and into the foundation cells, the game is a win. If no moves are possible to clear the table (I've still got to figure out how that works programatically, I think I'll just have a manual button in my first implementation), then the game is a loss.
I think I'll give this a shot. I already did the card graphics. Now it's time to start digging into my books and reviewing the actionscript stuff. Other things to add are some stats. Total plays, wins, losses, and win/loss ratio. Maybe some time stats too, like fastest game and average play time. (If other freecell players are like I am, they could care less about other ways of scoring.) I'm also thinking of throwing some quirky goodies into the game, that spoofs the king icon in the MS version. Maybe even have it talk and say random insults when a move isn't allowed, just to make it unique and a bit more fun.
Labels:
actionscript,
creation,
flash,
freecell,
game,
programming
Tuesday, August 25, 2009
Thingamabob
Friday, August 14, 2009
Automotive Design Terminology
Yeah, this should be an interesting post. Maybe these terms have bounced around elsewhere, but I figured it would be neat to gather them and put in this blog post. At one time way back I even made a wiki of this, but it was deleted a long time back. So now I've got to start over from scratch...
Here it goes.
Cab: The enclosed or semi-enclosed volume of the car that contains the driver and vehicle occupants.
Cab forward: The passenger area is weighted to the front of the vehicle.
Cab back: The passenger area is moved to the aft of the vehicle.
Greenhouse: The upper section of the cab surrounded by windows. Thus the term.
Wheel arch: The definitive shape made by side on view of a wheel enclosure.
Wheel bucket: The volume of the wheel enclosure.
Fender: An area of the car body or an attached piece that surrounds a wheel.
Fender flare: an outward exension of the body surrounding the wheel arch.
Quarter-panel: a section of a car body that is removable from the main chassis.
Wing: Rear topside spoiler. U.K. also uses this term for fender.
Beltline: An implied line going through the vertical center of the lower body of a vehicle. Sometimes accentuated with trim or two-tone paint.
Swage line: A distinctive line or crease added to the body of a car that enhances the appearance of a visual shape.
cladding: Pieces of trim added to the lower body of a car. Also to protect body paint from road debris.
Spoilers: Trim or body pieces added to the car with the intent of adding aerodynamic downforce.
Trunk: Rear enclosed portion of a sedan or coupe. U.K. calls this a boot.
ground effects: cladding or lower body spoilers added for more aesthetic purposes than functional ones.
Hood: Forward enclosed portion of the car that typically contains the engine. U.K. calls this a bonnet.
Brightwork: polished chrome trim pieces added to a car.
Jeweled glass: various facets or shiny reflectors seen in lights and reflectors.
Bling: contemporary term for eyecatching brightwork and jeweled glass.
Roof line: the distinctive shape defined by the top surfaces of a vehicle as viewed side-on.
window line: the distinctive shape defined by the lower edge of the greenhouse glass.
wheelbase: distance from bottom of front wheel to bottom of rear wheel.
overhang: distance which overhangs the wheelbase, front or rear.
Here it goes.
Cab: The enclosed or semi-enclosed volume of the car that contains the driver and vehicle occupants.
Cab forward: The passenger area is weighted to the front of the vehicle.
Cab back: The passenger area is moved to the aft of the vehicle.
Greenhouse: The upper section of the cab surrounded by windows. Thus the term.
Wheel arch: The definitive shape made by side on view of a wheel enclosure.
Wheel bucket: The volume of the wheel enclosure.
Fender: An area of the car body or an attached piece that surrounds a wheel.
Fender flare: an outward exension of the body surrounding the wheel arch.
Quarter-panel: a section of a car body that is removable from the main chassis.
Wing: Rear topside spoiler. U.K. also uses this term for fender.
Beltline: An implied line going through the vertical center of the lower body of a vehicle. Sometimes accentuated with trim or two-tone paint.
Swage line: A distinctive line or crease added to the body of a car that enhances the appearance of a visual shape.
cladding: Pieces of trim added to the lower body of a car. Also to protect body paint from road debris.
Spoilers: Trim or body pieces added to the car with the intent of adding aerodynamic downforce.
Trunk: Rear enclosed portion of a sedan or coupe. U.K. calls this a boot.
ground effects: cladding or lower body spoilers added for more aesthetic purposes than functional ones.
Hood: Forward enclosed portion of the car that typically contains the engine. U.K. calls this a bonnet.
Brightwork: polished chrome trim pieces added to a car.
Jeweled glass: various facets or shiny reflectors seen in lights and reflectors.
Bling: contemporary term for eyecatching brightwork and jeweled glass.
Roof line: the distinctive shape defined by the top surfaces of a vehicle as viewed side-on.
window line: the distinctive shape defined by the lower edge of the greenhouse glass.
wheelbase: distance from bottom of front wheel to bottom of rear wheel.
overhang: distance which overhangs the wheelbase, front or rear.
Subscribe to:
Posts (Atom)


