Monday 11 November 2013

Clean and Green Hackathon 2013 Afterthoughts

First Hackathon!

For the last 3 days, I participated in the Clean and Green Hackathon 2013. It's an event where people can form teams with anyone of any skill, be it technical or non-technical, to create apps for Clean and Green Singapore.

I was originally invited by my friend Mingding to join this hackathon about a week before, and my first thoughts was that it was really surprising that our government had this initiative. Our Singapore government had always been very relatively closed to the idea of engaging with the public, or perhaps had no effective means of doing so due to archaic bureaucracy, and were often very old-school in their mindsets and methods. Therefore, I was elated to hear that they were finally catching onto the future of collaborative openness, embracing the public whether for better or worse, and welcoming the ideas of our younger generation.

Difficulty of crossing Games with Green

Personally for myself, I had always wanted to make a difference in the greenness of Singapore, even if it was a small difference. But I could never find out what would be the best way to leverage on my skill set of games development for this totally disconnected cause of greenness.

I've had many thoughts about creating games which encourage green behaviours or create awareness in various problems in our world, but I've always felt that games were a magical world where people had the freedom to play and it was not obvious to me how to allow people to play in a safe world and not get bombarded with educational facts or information. I did not wish to slap on text and images onto a game just to teach people about Greenness. It would be foolish to think that it would work since such a product is not built for the consumer. A teacher may have the intention to teach but a student may not listen. While I do believe that we learn through play, I was never a fan of highly contrived educational games. People learn through the experience of play, meaning the game had to teach something through the mechanics of the system. Great examples are like how Civilization teaches us about history, and how Sim City teaches us about governments. Creating a game with unrelated mechanics only serves to distant the player from the content.

Rant on Gamification

Gamification is also a bad word in my dictionary. I think there is nothing new in the concept of Gamification. It can be seen in any typical employment setup. Salary is Gamification, it encourages people to do things that they otherwise normally would not do. Bonuses and benefits are also often created to entice employees to stay in the agency, they are Gamification. Boy scout and Girl Guide badges are also Gamification. So what's the big deal about all this Gamification? To me, it is just a buzz word.

In my opinion, Gamification does help, but it does not and cannot serve as the core idea of the content. A good example is credit card loyalty points. Many people get many credit cards to get the best of all worlds, which begs the questions, are you still loyal to these card with loyalty points? Gamification can serve to enhance a product or service, but inherently, it has little value on its own.

First Concept: Ingress + Recycle Bin Locations

I attended some talks given on the first day, and one of them was by a StarHub executive who was trying to solve the problem of where to place recycle bins in Singapore.

This problem intrigued me and I believe I could solve it partially by allowing the community to engage and a fight (virtually) over where they thought the bins should be. So Ingress came to mind.

Perhaps players could set up pillars of where they thought a good location for recycling should be and they could get their community to help to enforce and defend that location through the game. The number of pillars would have to be limited which mean that if your neighbourhood was not doing a good enough job, the potential location of the recycling bin would be moved to another neighbourhood that wanted it more. I hoped that this game would be able to:
  • give people a say over where they wanted recycling bins to be
  • encourage people to spread the word of recycling through their community
  • encourage neighbourhoods to group together and collective compete against other neighbourhoods

Pitched Concept: Freecycle Upgraded

After some discussion with Mingding on the first night where we heard all the pitches from various people, we decided to talk to one of the people whose pitch piqued our interest. His name was Marcus Tay and he suggested building an app to upgrade Freecycle, which is a web community that gives away their stuff for free. Let's all admit it, we're spoiled by Google, Apple, Facebook, Instagram, Pinterest and Twitter. We are surrounded by a plethora of great products and services that are easy to use, yet on the freerecycling community they were still bound to the dinosaur-age (15 year old) Yahoo Groups. At least by internet standards, it was built in the dinosaur age.

We were very much impressed that Marcus had done his homework and he found a pain point that really needed to be solved. From some brief brainstorming Mingding and I also came up with these potential extensions of this platform:

  • Community events for charity or christmas giveaways
  • Better data tracking of recycling rate in Singapore
  • Reduction of home and office waste when moving out
  • Growth in recycling through social sharing
  • Self-regulating generous community that could help more needy people
  • Encouraging more barter trading
  • Encouraging Up-cycling (converting waste into new different products)
Based on the fact that we were able to see a potential explosion of possibilities, I thought this was a great idea to work on, so I decided to help Marcus with his idea.

Initial Vision: Free Stuff Exchange

This snapshot of Instagram served as my inspiration.

At least for me the initial vision was to be able to easily share stuff that you want to giveaway. The act of giving something away can already be a very personal and emotional experience. I wanted to make sure that giving away items should be as painless as possible. So these were the use cases I thought would be useful.

Give Away An Item

  • Capture an image of the item on your mobile device.
  • Add the name and description of the item and tag it so it can be found easily.
  • Upload the item.

Searching for Wanted Items


  • Search by tag or browse daily uploads.
  • If there are no items available, you can subscribe to a tag, even creating one if it does not exist.
  • Get notified via email when an item with that tag is available.

Taking an Offered Item

  • Propose method of delivery, either post or collection.
  • Deciding on a place and time to pass the item.

As simple as that!

These were the design considerations I had:
  • Easy to upload (more content -> more users -> better community)
  • Lazy users (push notifications will notify user instead of daily monitoring)
  • Visual and easy navigation (allow for better browsing experience)

Major Development Hurdle: Setting Up

So then we set out to develop this web app. Mingding would do the back-end server work and I would do the front-end.

The first major hurdle for me was setting up a test environment for the app. I had not set up or installed any serves on my development machines going into the hackathon, so I ended wasting half of the first hacking day.

At first, I started with plain old apache and being on a mac, this was relatively easy. The next thing I thought I needed was php, and this was not hard as well since apache supports it but a flag needs to be flipped. Finally, I needed mysql as a database. However, this took a while to download and was not so straightforward to install. 

After I faced some trouble with mysql, I decided maybe a package like xampp would be better, so I switched gear and downloaded that, tried to install it but by this time, I would have already used up at least an hour.

On the previous day, we also talked about the potential of using a plugin like Gridly to do the layout for us. And Gridly required Wordpress. So I tried to download the Wordpress plugin for xampp next.

It was about this time when Mingding arrived, and suggested we use Ruby on Rails because he was much more familiar with that. I agreed since I haven't really done any work and my responsibilities were largely on html and css, which should be independent of the platform.

I then proceeded to install Ruby and Rails but I needed to download Brew first! Brew servers were absurdly slow and served me a 90 mb file at 20 KBps, so it should have taken about an hour to complete. However, my internet connection broke, not once but twice for whatever reason, and I had to restart the download.

Once Brew downloaded, I proceeded to install it, and then install ruby and rails following a really long list of steps from this tutorial. But more hiccups entailed, I encountered some errors with git in two directories, and also more errors like this.

By the time I was done successfully installing Ruby and Rails, it was dinner time and I had not even started installing Postgre database yet, which was required for it to work.

In total, I think I spent about 6 hours just trying to set up my test environment but was not successful. Fortunately, around the same time, Mingding had already set up the server on heroku and I suggested to him that I just test directly on the production server instead of on my own machine since I'm only doing visual changes in html and css. I felt we simply couldn't afford to waste any more time in this hackathon.

Future of HTML5 is wonderful!

Fortunately, not all was lost, I did manage to get some css work done and I also test my own custom html for uploading images from my mobile device using Dropbox.

One particular thing that really amazed me was how easy it was to make use of the camera on a mobile device from HTML. All it took was this little tag (ref: http://www.w3.org/TR/html-media-capture/):

<input type="file" name="image" accept="image/*" capture>

Why it is so amazing is because on the mobile, this tag would allow you either select a photo or take a new photo using your mobile camera, and on the desktop, this would allow you select a file to upload. The best part is that it is widely supported on all web browsers so it means it is also cross platform. I love it when web browsers can finally agree on something!

I was surprised to learn that it just worked when I tested it!

Waking at 5 am

At the end of the first day of the hackathon, we had only a photo capture page and pretty much nothing else. The photo upload was not even working. We had only up to 1pm the next day to finish our prototype.

Since time did not wait for me, I decided to sleep and wake up early. The next section I worked on was the grid view css and html. Once again having no local server to test, I decided to fudge some html data and test it locally on my machine. At least I could mess with css and get some work done without the server. so I came up with this:

image here
Item Name
Item Description
RESERVED

I was figuring out a lot of things like padding and margins and also testing colors and box shadows and alignment of the text to the left, while the image is centered, etc. I was also testing the view on mobile to see how it looked.

Following which, I proceeded to customize the page's navbar which was generated using Bootstrap by Mingding. In total, the css for the box and customization of the page took me about 3 hours.

Once I was satisfied, I head down to the venue as our team decided to meet at 930am. Around the same time, Mingding had finished the image viewing code on the server and suddenly the app became usable.

True Hacking = Adrenaline

From that point onwards, everything became super exciting. Once I reached our venue, we basically had 4 hours left including pitch rehearsal.

Within that last 4 hours, we managed to get a working grid view. I originally tried using HTML tables but ruby was spitting things out in a list and it was hard to add the <tr> for table rows with that format. I read about floating divs, but that only worked for divs which were consistent in height. After which, I finally found the solution, which was to use display:inline-table and change the divs to an unordered list.

After which, we swiftly added Offered/Wanted categories, and then also allow users to edit an item data. And I also added Facebook share within half an hour.

Summary

At the end of it all, I really enjoyed the hacking and the adrenaline rush at the end. We got a lot of stuff done for a short period of time.

I also want to finish the project and add tagging and user profiles. Hopefully, we can launch this platform properly in a week or two. Here's a screenshot to enjoy in the mean time:



Tuesday 30 July 2013

Castle Under Siege! Weekend Jam Game.



This (currently unplayable) game was done as a weekend game jam in 48 hours. To read about about my development process, check this previous post! I will be posting the updated playable version if it ever comes out!

Weekend Game Jam with HanMD82

Free source on GitHub
Snow Castellum on SoundCloud

Why this weekend?

So one day, Mr. HanMD82 randomly commented on Facebook that we should do a game jam. It was quite random but I love game jamming, so I try not to turn down a game jam offer nowadays, at least if it's done with some friends, we can always rearrange to a timing that works best. So we decided to do a game jam this past weekend.

Why Tower Defense?

I was itching to do a Tower Defense (TD) game because actually I was rather jaded about design cloning in the games industry. So I decided to make a clone for this game jam to learn about the genre and try to see why it makes people tick so much. I have to qualify though, that I play a lot of TD games myself and I love them too. In fact, I've probably played most of the popular TD games. I wanted to also test my game making skills and see how much faster I can build a game if I was already familiar with the design.

Approach

Having made a tower offense game (perhaps the first of its kind), I knew what I was getting myself into, but the difference here is that I would be hacking my way through everything, and picking the fastest-possible/production-efficient way to do the game. I picked up many lessons through making my previous games and I used these lessons to speed up the process in the jam. I'll share some tips here.

1030am Sat - Idea Generation and TD References

We started the jam around 1030am on Saturday. I showed HanMD82 a slew of TD games that were popular including but not limited to the classic Desktop Defense, Kingdom Rush and Field Runners. We then broke down the games and noticed there's a slight variation in design.

We noticed that in Kingdom Rush you cannot choose to place your towers anywhere on the map, while you could do that Desktop Defense / Field Runners. Therefore, as a player, you would solely focus on eliminating enemies and upgrading towers and you need not plan your placement of towers.

Kingdom Rush

Field Runners


Both designs have different implications on the tech that needs to support it. In Kingdom Rush, a way-point system would be used for AI and level design requires way-points to be placed. But for Field Runners, no level design is required but the paths of the enemies will have to be calculated on the fly, typically using an A star algorithm.

For the jam, we decided to go with the latter, but we would be modding the design a bit and have the enemy units move to a fixed location which would be the castle.

1130am Sat - Begin Production!

Because we already knew we'd be making a TD game, we could break down the game into its parts quite easily.

  • Towers (duh)
  • Tower Upgrades
  • Enemy Units
  • Path-finding
  • Waves
  • Projectiles
  • User Interface
And of course, we'll have some art and music to do as well.
From here, Mr. HanMD82 chose to do the Towers, Tower Upgrades and Projectiles, while I worked on the Enemy Units, Path-finding, Waves and User Interface. I volunteered to do the music as well.

From here, we set up the project on GitHub and started setting up the project folder and structure. We chose to use Starling Framework as we were familiar with it, so the project was done in Actionscript 3 (AS3).

130pm Sat - Enemy Units & Movement

I started working on the enemy units and immediately implemented a quick code to control speed and direction. Basically, we have four things we can set:
  1. Speed : the distance in pixels to move per frame or per second
  2. Direction: the angle in degrees to move
  3. VelocityX or Horizontal Speed: the distance in pixels moved in the x-axis per frame or per second
  4. VelocityY or Vertical Speed: the distance in pixels moved in the y-axis per frame or per second
Setting the Speed or Direction affects Velocities, and setting Velocities affect Speed and Direction, so for e.g. we have a function like:
function setSpeed(value:Number):void
{
    speed = value;

    // update velocities
    velocityX = speed * cos(direction * PI/180);
    velocityY = speed * sin(direction * PI/180);
}

The implementation for Direction and Velocities will be left to the reader (or you can just check the code on GitHub). The point here is that suddenly all you need to do to control the movement of an object becomes very easy since speed and direction are more intuitive to us humans, and also explains why direction has to be in degrees instead of radians (a necessary sacrifice for efficiency over code usability). And in the update function, we can just do:

function update():void
{
    sprite.x += velocityX;
    sprite.y += velocityY;
}

After this we had a quick lunch and I continued to work on various small things here and there like setting up the assets pipeline for importing sprites, etc.

3pm Sat - ...

I had to go to do some Remedial Training at this time, as I failed my yearly physical fitness test from National Service (Army). So that's 5 hours gone.

9pm Sat - Pathfinding

After I came back and had some dinner, I quickly dived into pathfinding. I grabbed the Wikipedia A star algorithm and translated it into AS3. Technically, I've implemented A star a few times before, but I decided to do it again from scratch this time as I was confident of getting it done in a few hours or less. The more times we rinse and repeat, the faster we get.

After translating the algorithm for a bit, I remembered I needed a priority queue to implement the openset. I quickly turned (once again) to the Wikipedia Binary Heap and started implementing that too.

As the game was not coded yet, I couldn't really test my code at this point (without diverting to write unit tests), so I left it alone, while I carried on with other stuff.

12am Sun - Castle Art

Was feeling a little itchy, so I wanted to start drawing stuff. I looked up "castle" on deviantart  and found this image:  http://www.deviantart.com/art/Neuschwanstein-Castle-285791596
DarkSilverflame - Neuschwanstein Castle
I really liked it and even thought it was a photo until writing this blog post, so I used it as a reference to make a sprite for the castle. I picked the color palette for our game using the above image.

At first, I didn't think too much and started drawing, and I came up with this:

I quickly put it into the game and realized I need to draw it in perspective!!! I knew we were going for the top-down perspective so I tried drawing some boxes but they didn't turn out so well:

So then I quickly looked up some references, first thing that came to mind is Zelda, so google images led me to:
http://zelda.salagir.com/dossier/jeux/castle3.jpg

1am Sun - Sleep

Even though I wanted to finished drawing the castle, it was time to sleep. We don't really believe in crunching, so sleep is good.

9am Sun - Music

Music is the fun part for me. I had some experience writing music for previous game jams so this time it was a little easier perhaps. I came up with the tune while on the bus to training the day before (efficient use of traveling time!) and hummed it into my iPhone, so this piece was done a little quicker than other pieces before. I wanted it to sound a little snowy / cold / icy as well as a little bit epic / Skyrim / Zelda. You can listen to Snow Castellum on SoundCloud

12pm Sun - Back to Castle Art

Learn from the masters! I decided to redraw the castle again with the new perspective. It took me a while, but I learned how to use the photoshop line tool along the way. Here's the result:

It was my first time drawing something this complex so it took me a while, about 1 or 2 hours. I drew it in parts starting with the main keep on the left and adding little towers on castle wall, then the big tower with snowy roof.

2pm Sun - Back to code

After lunch, it was back to code again. At this point, I had not finished the Waves, or tested the Path-finding algorithm. I jumped straight back into creating castle object and the spawn point for the enemy, which I needed to start creating a path for the enemies, which will then allow them to walk from the spawn point to the castle.

230pm Sun - Pathfinding Thoughts

I decided the spawn point should just be an object that holds a grid coordinate, and that the waves object would be the actual one spawning the enemies, since that's where most of the spawn data should be stored.

I also thought that doing an A Star search for every enemy unit would be too expensive, so I thought I could optimize it by allowing enemy units from the same spawn point to share a path and then they would only ever need to keep a reference to one path that would be updated and they would search for the nearest node on the path that they could use to follow the path.

>> In hindsight however, this was a mistake as the enemy units ended up failing to re-route correctly when a player placed a tower in the way of some enemies and they would end up passing through the towers to move to the nearest node on the path.

5pm Sun - Waves

Next up was implementing the waves. I created a SpawnParams class and stored them in the waves object, so that each wave can easily tell an Enemy Unit how to spawn, for e.g. the position to spawn at and the delay to use for the spawn. It was quite straightforward.

6pm Sun - Bugs!

Inevitably the Pathfinding had some bugs. I made some very simple mistakes which I should not have made, like for e.g. my Binary Heap did not test the correct value to decide which node is less than which other node, so that led to some strange behaviour where the enemies would walk through some tiles, then suddenly make a loop around some tiles in a triangular fashion, since the generated path was incorrect.

I also made another bug in the getNeighbors function for the nodes, where I missed out on checking if a grid tile was empty or filled with a tower for the left and right directions, but the up and down directions were OK. I guess it was a code readability issue since I knew to add it to some directions but not the others. 

These were minor bugs, and I didn't spend too much time on them, but I'm just recording them here to remind myself not to make them again. Ok, moving along...

I also added the background, which I actually stole from a photo of a mountain with snow, and then reduced the colors palette to 5 colors, which would create the dithering effect you see here:

background with reduced colors

9pm Sun - More Sprites & User Interface

At this time, I had dinner and took a walk with my dogs. I then started to go back to drawing stuff. I drew the UI for the game start and also drew some sprites for the towers and the enemy units. I added a bitmap font and the castle icon to draw the castle hp:


I was thinking about what to draw for the towers, then started with snowman, then my girlfriend was saying that I should draw a rabbit, and then next a pao (chinese bun). Yes, it's kinda weird, but I like it that way, and I figured I could make it 'reasonable' by adding little army men standing on their heads.

As for the enemies, she wanted a fox-like thing and pumpkin, based off the colors I had already picked. I was not ready to animate anything yet, so I decided to just go with some floaty/ghost-like foxes.

12am Mon - Snow!

I grabbed some crappy (but working) Particle code that I wrote before and dumped it into the game. I didn't really want the code anyway since it was badly designed, but I need something quick to make particles. I drew some quick snow images and added it to the game. After some tweaking, I finally managed to get this:
screenshot with snow particles


2am Mon - Sleep

Once again time to sleep. I was happy with the progress so far. Things were shaping up.

10am Mon - Final Touches

For some reason, in my head, I was thinking this would be a 48-hour jam. So yes, Monday morning is still legit. In the final hour, I added some explosion effects to the enemies. And I also fixed up the game retry so that the player could play again if they wanted.

Overall, I think I neglected design quite a bit for this weekend jam, but I'm still happy with the result so far. I'm also glad I got to draw the sprites and get to practice picking colors.

The current game state is not really playable; the waves are not designed, enemy units and towers are not balanced and we're missing a currency system.

However, here is the current state of the demo anyway for those of you who want it, check my next post!

Saturday 27 April 2013

._ for Ludum Dare 26



Controls: Left / Right / Up arrows.
Source Code link.
Ludum Dare entry link

How I found out?
I was subscribed to Loom's mailing list because I downloaded it before they started charging money and I received an email today that they were giving an offer for their engine for the Ludum Dare competition. Thanks to that, I checked out the competition and read that the theme was Minimalism.

Thoughts on the theme
I was not schooled in art but I did know a little bit of Mondrian and Minimalism through a game designer buddy of mine. I can't say I fully understand but I do know it is about taking away as much of something until you cannot take anymore away from it without destroying its essence.

I've read that Will Wright and several other famous game designers often use this technique of taking things away from a game to find its essence. For myself, I did not really spend too much time thinking of a new mechanic to showcase this. Instead I went for something staple which is that of a platformer. I thought of games like Canabalt and Mario and wondered if I could do something interesting other than what was already done before. I started thinking along the lines of gaps and manipulating them.

Other Concepts
My mind did want to explore other more interesting concepts but since I hadn't actually planned to do Ludum Dare and it was a spontaneous challenge, I thought I would just go with the flow and make something for fun, not so much as to break any ground. Some of the other concepts I was thinking about were a minimalist plane shooter, or maybe some even more abstract like some kind grid-base game where you can break a grid cell into 4 quads depending on where you clicked to partially create the Mondrian art style as part of the process.

Engine Choice
I think I should apologize to the Loom guys! I'm so sorry I found out about Ludum Dare through your email but I ended up choosing Flash as my engine choice because I'm more familiar with that. Also, I actually started working in Flash Builder for deployment on iOS but then I read that I should give up my source code so I decided to dump that project setup and move to Flash Pro for Web deployment, since I did not want to give away my source code for my previous mobile projects.

Code flow
Here's the coding flow which I used to make this game.

1. Player
I started by coding the player, it was a simple square that would act under gravity. I did this pretty quick since I have done this many times before. Basically just add velocity and gravity and have them act on the player's position.

2. PlatformsAdded some code to draw a platform.

3. Collision

I decided to go with the simplest kind of collision code of all. Extremely old school but I guess it works for my case, I just check if the player is within the platform manually or not. I actually do not use any hitTest or accurate physics for this.

if(player.x + player.width > platform1.x && 
  player.x < platform1.x+ platform1.width &&
  player.y + player.height > platform1.y &&
  player.y < platform1.y)

4. Game states
I prefer to do this early before the code gets messy so I added GameStart(), GameEnd(), GameUpdate() functions and also added the game over state in GameEnd.

5. Controls
Next up was the controls, I just went with left/right arrow keys for movement. And later I added Up key for jump.

6. Platform generation
There are always only two platforms in the game, especially since this was a minimalist game. I decided you would have to stand on the first before the second one showed up. I spent some time on this getting the platform to fade in according to how much time you stayed on the platform. After that, I swapped out the first platform to be the second and made a new (third) platform. At first I thought I'd just swap out the platform once the player jumped off the first platform, but I found that to be too punishing, and I wanted to allow the player to take his or her time with jump so I changed it such that the platform would only swap out once the player's x position is past the platform's right edge position. This would ensure that the player would have left the platform already and would allow the play to jump as many times as they want on the same platform if they stayed within the platform edges. I also chose to spawn platforms with greater gaps with each successful platform jump.

7. Deaths
Early in the development I actually already added a death sprite to show where the player died, which would indicate to them whether they've beaten their own progress if they replayed it. Then I suddenly had the idea to combine the previous idea of somehow developing a Mondrian painting as you played and I decided that the death markers would serve instead as an aesthetic to the game. So I changed them to be randomized rectangles that had these extending border lines or randomized line widths as well. Then end result was quite aesthetically pleasing such that when you died, you ended up making a splash on a painting.

8. Scoring
Scoring was simple and easy. It's an infinite game and your score is based on how far you manage to jump up to, so it is just the player's x position when he or she died as the score. A highscore is also kept at the top right.

9. To End or Not To End
By game jamming standards, this game was still really 'young', I only spent about 4 hours or so on it, I wondered if I should making the deaths markers be interactable or not. That could make the game really interesting. For example, maybe Blue rectangles could make the player float, Yellow & Red could do something different. But I thought oh well, I had not really planned to Ludum Dare and I was ok with what I had, it was meant to be a minimalist platformer and so it shall be. Not the best concept in the world but I'm glad I could execute it in a short time. It was also a really fun enjoyable concept experience for me.

10. Name
Now I had to think of a name, so I let my girlfriend name it. She came up with "._" which I think was awesome because it represented a minimalist platformer so well. Anyway, for trivia's sake, the working title was Gappy.

11. End
I think the final version of the game was pretty challenging. I ended up changing game variables on each jump so that it would get harder and less predictable as you played. For example, aside from the platform distances getting further, I also changed the jump power, the movement speed (which makes the game really slippery), as well as the camera catch up speed (which was necessary was there were bigger gaps).

12. Sound
And when I thought I had finished, and I even started writing this blog post, I forgot I had to do sound!! So here we go back to do the sound, luckily I'm just going to add one sound. And finally upload and end.

FIN

Sunday 17 February 2013

RYB Color Wheel



As a follow up to my previous post on the RGB color wheel, I made the RYB Color Wheel.

This time I got a bit smarter so I decided to build this wheel in Stage3D, since I could use the GPU to interpolate the colors on the triangle for me. I have not actually coded directly in Stage3D before since I used Starling framework which wraps around Stage3D to make it much easier to use. This Hello Triangle tutorial by Marco Scabia helped me jump through the basic hoops of setting up the render scene.

I first tried to change the formula for the HSV/HSL computation. I remember this graph from the HSL-HSV Wikipedia page which showed me the RGB values behaviour when the hue changes.


HSV-RGB relation


I wanted to modify the mathematical formula to alter this graph to shift the yellow to the green's position to make it a primary color. I tried this out by editing the gradient of the svg file from wikipedia in Adobe Illustrator.


HSV-RYB relation with yellow shifted


This was what I got, but I quickly realized that this method would not suffice as I should not be getting such bright colors, and I should not even see cyan in the wheel. I tried to cut off cyan by adding a node at the 180 hue green and blue and interpolating directly to the 240 hue value and I thought I took a step forward.

However, I also did a quick web search and found a research paper which suited my needs. The paper, titled Paint Inspired Color Compositing by Nathan Gossett and Baoquan Chen, used custom color values for a color cube and did a 1-for-1 mapping between the RGB cube to the new RYB cube and then trilinear interpolated the RYB cubes colors to figure out the RGB values. They got the values from the Johannes Itten color model, which is widely used in art education.

I decided to adopt their method to implement my RYB color wheel, so credits goes to them for the RGB-RYB conversion. I decided to plot the graph again using the values provided by them to see what it looked like:



HSV-RYB relation


Learning Points:

  • RYB can be mapped instead of done via a formula. I think there is still value in building the formula version for efficiency purposes but currently, this suits my needs already.
  • Most of the RYB colors are standard but RYB green is (0.0, 0.66, 0.2)
  • RYB blue is not pure blue (0.163, 0.373, 0.6).
  • RYB black is not pure black (0.2, 0.094, 0.0)!
  • In fact, there is a lot of red everywhere. From the graph, you can tell that red is most prominent color of the three primary colors RGB. Even in black, there is a relatively strong red component, which equates to brownish black.
  • I was wondering if the components of RGB had any effect on Value or Lightness of a color. Reading up Wikipedia tells me that Lightness is actually ambiguous! And there are actually 4 different ways to calculated Lightness of a color. That's definitely something new to me because I knew that if the grayscale version of two colors were the same, they would be the same Lightness, but I did not know that there could be several ways to achieve that.
  • The research paper suggested giving a bias towards to the colors at the corners of the cube by altering the interpolation function to a cubic one. For this reason, I decided to implement a linear function compare the results. You can click the button above in the flash swf to see the difference. I do not have much opinion on which is better at the moment, although linear interpolation would definitely be cheaper computation wise so that may be the function I would probably use for real-time games purposes.
  • In the process of converting RYB to RGB, I came across trilinear interpolation. Trilinear interpolation is essentially interpolating all the 8 corners of a cube to find a point within the cube. It is done by first interpolating the 4 pairs of corners in one axis (e.g. X-axis), then interpolating the 2 pairs of results in the next axis (e.g. Y-axis), and finally interpolating the 1 last pair of result in the last axis (e.g. Z-axis).
  • In writing this blog, I also learned how to use SVG graphics inside Blogger. You can read more here if you are interested.
  • As this is the first time experimenting directly with Stage3D (instead of using the Starling Framework wrapper), I also got into some hiccups with the Matrix which is passed into the vertex shader for view projection. I realized that Stage3D by defaults provides a normalized viewport so for e.g. top left of the screen is (0,0) and bottom right is (1,1). I wanted to look into setting up the projection matrix for a proper camera system but I think I will want to look into that again in future.


Monday 28 January 2013

Cardiary in Global Game Jam 2013

It is the first time making a game entirely on my own and it rocks!
And when I say entirely, I mean doing everything like the game design, code, art and sound from scratch.

This year's Global Game Jam theme was an audio file of a heartbeat.

Welcome to Cardiary - A world where every thing has a heartbeat:
http://globalgamejam.org/2013/cardiary

----Before Game Jam----


Interpretation of Theme
Before I knew the theme, I already wanted my interpretation of the theme to be on the mechanic level. That meant that I would not take it literally like for e.g. to make a game about real heart beating. I would try to use the theme as a game mechanic instead.

Master Game Developer
I also set myself the constraint that I must do everything on my own. I have been a game programmer for the most part of my working life and I also started doing game music since about a year ago in the last game jam. I have also been learning game design from a guru whom also happens to be my business partner. This year, I am interested to explore art, which is also why my previous post is about the Color Wheel. I feel like a true game developer must be able to wield all the different skills in his or her hand to be able to develop great games. Therefore, I decided I should do this game entirely as a solo artist before the jam.

Diversifiers
We were also notified about the diversifiers before the jam and I chose to use the 16 colors diversifier. This helped me limit my color palette for the jam and seemed like it would simplify the art side of things for me.

----Concept----


Day 1 - 7pm

Mechanic Concepts
Upon hearing the theme, I quickly came to a brief idea or concept I liked. I was thinking along the lines of Wreck-It Ralph where the game world itself is sentient and every thing in the game world has a heartbeat. I also started my concepts with a grid world in mind.

Day 1 - 8pm

Controls and Premise
I thought about using really simple mechanics to showcase the concept because I did the jam the last year and I knew I had to keep simple to make a finished product. I thought about using Left/Right controls scheme on a grid world and I set the goal to reach the top of the screen with the player starting at the bottom.

World Idea
I started to think about Tetris at some point and I thought that having the screen-drop as part of the game world would be cool, i.e. everything on the screen would shift down by few rows every few seconds. I felt this could fit in well with the goal because it would be able to give the feeling that player is trying to swim up a river or something along those lines.

Mechanic
I had trouble thinking about what the player could do to reach the top of the screen. First I thought about stairs or ladders which the player could climb or move the player up to the next row. However, I felt that was too easy and would get very boring quickly, especially if my game were to be on a small 16-by-16 grid. Also, I did not want the game to be side-view just as a personal preference. I then decided that I would add power-ups that could propel the player forward, left or right by two squares. These power-ups would have to be generated in a way that would be beneficial to the player.

Collectable
One other idea I had which I wanted to use was ripped off from the old Raiden games, where there would be a collectable power-up and it would change every few seconds or so. In this game, it would change according to its heartbeat and I thought that would be a nice fit for the concept. I brainstormed about collectables that could perhaps add time to the screen-drop or maybe move the player up by two squares.

No Fail
Another design concept that I wanted to experiment with was that there was no game over in this game. It was only either win or if the player does not actively play the game, it would slowly return to the original 'level one' kind of state. This tied in very well with the screen-drop idea I had so I made it such that the player could never go below the screen and die, rather he or she would just remain in the game space and if he or she played well, he or she would be able to reach the top and win.

Player Challenge
Next, I knew I had to add some challenge and I could add enemies that could shoot to provide some tension and I imagined these would come from the top shooting downwards at you like Donkey Kong's barrels. I knew I could also add spikes that the player could not move into. These enemies would scroll into the screen whenever the screen-drop happened as well, so you had time to see them enter and to plan how you would navigate them. It was around this time that I got stuck trying to think of what else could the player do. The game felt very bare and whatever I added was not really helping to make it interesting and just made things unnecessarily complex.

I got quite frustrated with the basic premise of moving to the top and my mind loitered on changing it to be free-form movement where you could move up and down as well, but that would mean I had to change the goal as well, which I was reluctant to since it would be starting from scratch.

Day 1 - 9pm
After two hours of idea generation and getting stuck, I finally stepped outside the jam site for a while and started to have a really quiet time to think by myself. I realized that I had all the elements for a game but I was not making use of them well.

Mechanic and Player Action
The peace of the night helped. I figured out that I could make it inverted in that there were these up-arrow tiles you could stand on, and they would move you up to the next row on their heartbeats and if you did not step on them on their heartbeats, they would change their column position randomly. So the player basically had this immediate goal of moving to match the arrows position and a long term goal of moving to the top of the screen.

At this point, I got really happy at this point because I knew I had a mechanic that could work and secondly, it was also much better than randomly generating power-ups which the player has not control over to move up.

Day 1 - 10pm
We decided to leave the jam site and head home to rest since the journey would take an hour and a half. That's when I took the bus with Alex, another indie developer who was going to do the jam solo as well, and we talked about the ideas we were going to make.

Enemy Spawning
As we talked, Alex asked if the reaction for the player would be too small once the player reached the top. I did not think reaction time would be a problem but that made me realize that I should not spawn enemies at the top, and instead should spawn them from the bottom. This was because if they were to spawn at the top, you had to navigate around them but it seemed like the difficulty would largely be determined by the spawning algorithm and enemy types. If I spawned them from the bottom I could do things like only spawn enemies as the player progresses to control the difficulty accordingly. This would help because you still have to dodge but the game would get more challenging as you played which would be great for flow. Then an idea hit me. Since the player is travelling upwards and the player has to use the up-arrow tiles to move up, I could easily create an enemy on where the player was standing at the same time as when the player moved upwards.

That was another defining moment for the game because it would mean that the core concept was now solid and it sounded to be really interesting to me as well.

Day 1 - 12am
By this time, I had the core mechanics fixed already but I was still not very sure how the dynamics of the game would play out. I went ahead to start on code first and decided to return to the dynamics of the game once it could be played.

----Code + Design----


Day 1 - 11pm

Grid
While on the way and talking about the idea, I actually also started coding on the bus back. I started with just simply drawing the grid. This was done within about half hour.

At first, I was thinking that the grid would hold entities, so that the entities would be able to check who is in which cell. This was the way I made Cubetractor, since each grid square could have multiple entities. However, having done that before and knowing how painful it was to set up such a system, and I decided not to use any large prior systems I had coded before, also partially due to license issues. So I did not to pursue such a grid system and instead just hack all entities to have a grid coordinate position that they could then pretend to be in grid.

Counter
Knowing that I would be making a game where everything has a heartbeat, I made a counter class which could be used in every game object. This class would just need to be updated every frame of the game and I could set the number of frames it should count up to before it would either block (stop counting) or trigger off some action in the game.

Day 1 - 12am

Player Controls

Next I coded the player movement and controls. I wanted the player to be able to move only in fixed grid positions and he could not for e.g. stand in-between cells. Secondly, I also thought the movement should be frame-based in that he could only move maybe every few frames, which would make him also go in timing with the world heartbeat.

Up-Arrow

I quickly added a class for this game object and added it to the game as well. With the counter class and player already prepared, it only took me about 10 minutes to get this up and working and I could already play the core mechanic, which was to move the player left and right to match the arrow tile position and at a certain beat, it would move the player up one row.

Production Planning
Before I headed to bed for the night, I decided I would do a little production planning for the next day so that I could pace myself once I woke up. I decided on the following schedule:

  • Day 2:
    • 8am - 12pm: Compose Music Track because I could then code the game to sync with the beats
    • 1pm: Code features in this order of priority:
      • Grid (Done)
      • Player (Done)
      • Up-Arrow (Done)
      • End-game condition (EGC) and game reset
      • Bottom enemies lasers
      • Screen Drop
      • Collectables
      • Ending Screen
      • Expanding enemies
      • Special Teleport
    • 5pm: Art Drawing (honestly didn't know how long I would take since it would be my first attempt)
    • 10pm: Sound Effects
  • Day 3:
    • 8am - 3pm: Polish!
It was time to sleep. zzZzZzzzzzzZ.


Day 2 - 10am to 4pm
So I managed to complete the music track (more on that below) much earlier than I expected, so I quickly headed back to coding.

EGC and Reset
I wanted to do the end game and reset first because I knew that once I had the structure in place, I could expand on the game all I wanted, but anytime I could not finish any extra features, I could just easily cut them out and the game would still look finished and the player could play to the end. And as I added features to the game, all I needed to was to add their variable resets to the game reset function.

Bottom Enemies

Originally, I thought that I would have two or more enemy types. If you look at my production schedule above, there is another enemy which could expand on its own heartbeat. So I made a system which would be flexible enough to be able to switch between enemy behaviours and sprites on their heartbeats. I did this by having an enemy spawn point which I named EnemyTile, which could attach an Enemy class. If I wanted to have more enemy types, I would derive the Enemy class and the EnemyTile would then be able to swap the enemies types around easily.

On hindsight, once I got the first enemy type down, I lost the urge to make more enemy types because I did not see how much more they would add to the game. Perhaps it was also because I had too many things to focus on, I had no time to go back to the enemy concepts and design again. Anyway, I did not make use of the enemy swapping system at all.

Laser Beams
I then needed to add the missiles the enemies would be shooting out. As a temporary name, I called them LaserBeams and I also needed to add some form of collision for the player to collide with them. Since everything was gridded, I went with the simplest approach which was to just check if the grid cell xy of the two objects are the same, and if so it would collide. I put this into a base class which I could not think of a name for so I called it CollideThing. The CollideThings had a Collide function which I would call when things collided with the player. There were no collisions between two different CollideThings.

Screen Drop
At first I thought this was a big feature, but when it came to actual implementation, it was actually quite straightforward. The first part was of course to add a counter for the world which once it counted down, it would make the screen drop. That was the easy part.

The more challenging area was the actually screen-drop effect. I decided to cheat a little and pause the entire game when the screen is dropping so that I would not have to deal with player input messing around while the screen was dropping. It was also an old nostalgic effect from classic NES games that I liked. I realized that in order to keep the game mechanics synced to the music, I had to work with the 90 frames (1.5 seconds) duration so that the game would skip exactly one bar of music. So I added a blocking counter and set its duration to 90 frames, then initialized the counter to 90 frames as well, because I wanted to just check if the counter was anywhere between 0 and 90, then the game should pause while the screen is animated  the drop. Finally to do the animation effect, I just divided the 90 frames by the number of rows it were to drop and basically just drop each row at that specific interval. For e.g. if it were to drop 3 rows, it would happen at the 30th, 60th and 90th frame.

Collectables
I decided the Raiden color changing mechanic was a good idea and that the enemy tile method was a bad idea so I coded this to be just one game object which had 3 different states for different power-ups. I derived the CollideThing class I made for the laserbeams and quickly hacked this together. In the end it all worked out.

Evil Collectables
While thinking of collectables, I thought it would actually be better if I made one of them evil and two of them good, which would then make the players stop to think about whether to get the power-up or not, rather than just anyhow collect powerups. I made this evil one reduce the time of the screen-drop.

After I finished the Collectables code, I decided to move on to Art because I did not feel comfortable not knowing how much time I would need for doing that. So I 'temporarily' stopped working on features and I had a feeling I would not go back to add more entities, which ended up being true in the end.

Day 2 - 12am to 1am

Collectables Adjustments
I managed to playtest the game with a close friend and got feedback on how the game felt. I learned that the power-ups felt really useless and the game had a negative feedback loop where it would spawn many many enemies if the player performed badly by going up to the next row, then getting hit by a laserbeam which would bring the player down one row again.

I started to think about what could be really useful. One idea I had was that since the laserbeams seemed to be a problem, why not have a power-up that could clear all laser beams. Another idea was to destroy maybe one of the enemies spawners so there would be less laser beams in total.

Finally, another rule I added was to clear away enemy spawners which were two rows above the player's current row. This would help to ensure that if the player were very unlucky and dropped down by 3 or more rows, they would be at an extremely disadvantageous position when going back up.

On hindsight the idea to clear all laser beams sounded very cool but turned out be very useless because most of the laser beams would have passed the player already. I ended up switch back this power-up to the reduce screen-drop time.

Day 3 - 10am to 11am

Particles
The game needed particles to give feedback to the player when they got hit or when the enemy spawners were removed either by dropping 2 rows or by the bomb power-up. Admittedly, for this particular system, I took some code from another game I made and put it into the game, but the code I took was not so well designed even though I wrote it, so I took some time to figure out how to use it. Doing that made me learn about how to improve my old code as well.

Day 3 - 2pm to 3pm

Level Progression
I got more feedback from some friends playtesting my game and we talked about how we could better design the level progression. The problem was that it seemed too hard at the start of the game but it felt just nice for a mid-game difficulty. One idea was make the screen-drop slower at the start of the game and have it ramp up as you moved towards the top. I like the idea and started implementing it by changing the world counter. I got into some unexpected bugs which I took another half an hour to fix. And by that time, it was very late into the jam already and I did not want to upload a potentially broken build. So I decided to just keep this build on my computer first and upload it after the jam was over.

----Music----


Day 2 - 8am to 11am

Song Concept
I started the song concept on my guitar as I just wake up and I am still sitting on my bed, which is the normal thing I do for song concepts. I wanted to make a heartbeat song so I started with a double quaver on every bar, like a THUMP THUMP feeling. I just played out what could be a possible bass line and once I decided on the bass line, I went straight to switch on the computer to key it into GarageBand.

Song Name
Before I could I start writing the music, I had to set a name for the piece. I googled online for Heart and found a suitable name for the piece on Wikipedia. I called it Vena Cavae Bus (link on SoundCloud click here) because I was thinking about how music flows and it transports you through the arteries perhaps into and out of a heartbeat.

Beats Per Minute (BPM)
I also looked up the heart rate of an average human and found it was about 70-80 bpm, so I took that and multiplied by two to get 160 bpm and set that for the music track. Using that I also realized that each bar would be exactly 1.5 seconds for a 4/4 tempo. Since the game was running at 60fps, this meant that I should use 90 frames (i.e. 1.5 seconds) to be able to sync up with the music.

Beats
I knew I wanted to make a song with a strong heartbeat so I picked a drum that could give me a really strong OOMPH and a big THUMP. I had Massive by Native Instruments and I wanted to do like a dubstep thing but I was not equipped with the know-how beforehand so I could not execute it, so in the end I settled on GarageBand's default dance drumkit and I added a Wave Destruction filter over it to make it more chiptune like. It worked!

Song Structure
Originally, I was thinking what kind of song structure I should use. I'll admit right here that I have no music training at all, as in I do not have a teacher or master who I ask stuff. I just make and analyse other people's work. I learned in the previous year from analyzing my favorite Rockman 2 tracks that a 3x structure works super well, in that if you use a 12 bar sequence where every 4 bars are a different set of melody, the music track would magically loop really well and it would hardly get boring at all even if you listened to it 100 times over.

However, I was also noticing a new pattern emerge from recent tracks such as Lifeformed's FastFall tracks from DustForce and other electronic music I have been analyzing where the music generally starts off with a bass line first, then introduces the drums, then finally melody. I decided to try out this pattern in the track I was going to make, but I was also aware that it most likely suited much longer songs where you could have an intro to slowly ease the listener into the song.

After composing for a while, I felt like the song was getting there and I felt like there was not going to be enough time to make a song which was longer than 12 bars. I decided to just stop composing at the 12 bar mark and I had 4 bars of bass, 4 bars of drums, 4 bars of melody. I quickly tweaked the last bar of the melody to make the song conclude.

GarageBands saves the day
As I listened to the track after I thought I had finished composition, I realized the track still sounded a little empty. I then tried to drag in a GarageBand synth loop and immediately liked the end result. It felt more wholistic and also gave the track a new flavour of tension and mystery. At this point, I was happy with it and I exported the track and I considered the job done temporarily. I knew I would get back to it on the next morning.

Day 3 - 7am to 8am

Fixing the Loop
After a full day of listening to the song in the game and also some feedback from a close friend, I could now better hear the mistakes I made in the song and I tweaked the first bass line to be more similar to the melody, so that the song had better cohesion throughout and it could loop without feeling like the song just started again. In other words, I decided to actually combine the intro structure with the 3x structure but retain the best of both. I also made some minor tweaks to the notes because there were some which sounded like it did not belong to the chord. Finally at 8:30 am, I was really happy with result and exported my final version of the song, after which I prepared to head back to the jam site.

----Art----


Day 2 - 5pm to 10pm

Backgrounds
Since it was my first time doing the art, I just did whatever felt natural. I started with backgrounds and I wanted it to tile. I thought about the real floor tiles in my home and I tried to copy the design.

After I put it into the game, it felt too organic and when it tiled there were too many features which distracted the player so I did not like it. So I simplified it to become this.

Sprites
To be honest, I did not put much thought into the character designs. I went with an upside down heart thing for the main character because I felt it was an interesting silhouette more than anything else. For the lasers, I went with some blood vein ball thing that looks quite gross.

Colors
I think opting for the 16 colors diversifiers was good idea. It kept the palette limited for me and I could select colors quickly and swap them around fast if they did not work.

----Balance----


Day 3 - 11am to 3pm
Once I reached the jam site on the last day and after implementing the particle effects, I got some friends to playtest the game. Honestly, I was very surprised at how people played the game. I personally felt that the game was very easy and made the balance hard to the point I was comfortable with. However, when even my hardcore gaming friends at the jam site could not play the game, I was a little befuddled. I guess it was the first time I designed something to be simple but yet was incredibly hard to play.

After watching two or three friends play, I was convinced that I needed to tweak the game balance such as changing the screen-drop rate or number of rows. This led to the idea that I should add level progression via the rows in the game as mentioned below.

----After Game Jam----


Level Progression Feedback
GGJ Submission
After GGJ Level Progression Background

Since I only managed to add in the level progression at the last minute, I was concerned that the player did not have feedback as to why the screen-drop rate was increasing as he progressed towards the goal. I  decided to change the background tiles to show the color of which

Better Power-Ups
I also thought about increasing the value of the power-up collectables since they did not seem very valuable. I changed the code such that it would destroy 3 enemy spawn points rather than just 1. Upon changing it, I had a slight hesitation that that would make the game too easy but after playing it myself, I think it would really help the less skilled players which convinced me to keep it.

Player Statistics
On hindsight, one thing I missed out for the end game was adding the play statistics to be shown at the end-game screen. However, I guess that could only be added once I knew what statistics I could track which would mean I could only add it at the end of the development.

Conclusion
I learnt so much from this game jam that I wish I could do it over and over again. As you can see I did not compromise much of my sleep and I do not think anyone needs to compromise sleep. It is all about perfecting the pacing and scope of the project.

< rant >
On a personal level, I feel that other game developers who did not attempt the jam have sorely missed out on the opportunity and it is a immense loss to them actually, especially if making is their passion. It seemed like there were maybe 10 or so game industry folks out of 150-200 jammers and out of the thousands of developers in Singapore game companies. That's like a 0.01% - 0.1% participation from the industry. I guess not everybody sees the value in the game jam in the same light as I do, but I do feel a bit jaded as to why almost the entire Singapore game industry developers do not take part in such a wonderful activity which also coincidentally just happens to be about games.

I was guilty of that myself two to five years ago when game jam started and I did not take part. I guess part of the reason is because the industry folks do not really want to commit to making a game for 48 hours because they are already crunching to make a game in over 1000 hours. Another reason could be because their spouse would not allow it. Another reason could be because they are shy to show their skill. Another reason could be they are not confident in making anything good in 48 hours. Another reason could be they do not want to team up with strangers. But I suspect most of it is just pure laziness and the lack of passion for the creation process of games because there is NO MONETARY REWARD (or tangible reward) in doing global game jam. I honestly do feel quite sad thinking about it. Well, whatever the reason, I do hope to see more game jammers in Singapore especially from the industry.

I think it is incredibly powerful to be able to make a game in 48 hours and finish it while NOT CRUNCHING, because it allows the creator to experience the whole process and also practice the production strategy and designing of features to fit the scope and time. I believe if more people do game jams, they would get so good at estimations of how long they would take to do any game that they would always ship the game ahead of schedule and still have the game to be super polished with attention to fine detail and maybe even easter eggs. No CUTS in design that break the games and no ABRUPT endings and no BROKEN games which need to be patched and updated after launch. I think that is a super valuable skill to have and I am fully aware many people in the industry do not have that skill, which is why it makes me sad that they do not want to join a game jam and improve their development and production skills. Ok rant over.
</ rant >

I had tons of fun.

Sunday 6 January 2013

Color Wheel, HSV, HSL, RYB, RGB

In my attempt to understand Color Theory better, I decided to make a color wheel in code today. Particularly, I was interested in figuring out how to do a RYB (Red, Yellow, Blue) color wheel. Here is the result:

As you can see, I've only managed to do the RGB color wheel for this post. When I say RYB, I'm aware that it is a subtractive color model and RGB is additive. However, I also mean that Red, Yellow and Blue are equally spaced apart on the wheel, instead of the standard RGB/CMY spacing. I wanted to be able to do this because RYB is actually the natural color spectrum that our eyes can perceive as our eyes react to red, yellow and blue light, something I learned from this incredibly old but insightful video.

Due the difference between RYB and RGB spacing, it occurred to me that the probability of colors in real life is not the same as the probability of the colors we can generate from a computer.

Anyway, here are my learnings from doing this color wheel:

  1. I started off figuring out how to draw a circle or wheel in Flash through code. I knew I could not use the inbuilt drawCircle function as I needed to set the gradient of the circle manually, so I tried to use the curveTo functions in Flash after a quick refresher in control points for quadratic beziers.
  2. Once I did that, I realized that quadratic beziers formed using the corner points of a square does not form a smooth circle. I also did not know how to calculate the control points for generating a circle, given two anchor points from a circle segment. This is why you now see a polygon mesh generated instead.
  3. Flash only allows two types of gradients, LINEAR and RADIAL. I made the mistake of using RADIAL at first but quickly realized that I had to switch to LINEAR since RADIAL is used for a gradient which interpolates from inner circle to outer circle.
  4. However, LINEAR is not ideal as well since it cannot deal with segments of a circle and rather deals with boxes. You can see this effect in the demo above. The gradients interpolate smoothly on the outside edge of the wheel but it is not smooth near the middle of the wheel.
  5. When calculating the matrix for the gradients of each segment, I used an inbuilt function from the Matrix class called createGradientBox. I lost quite a bit of time figuring out this matrix. It was only after I made another Flash tool to interactively see what is happening with the matrix that I realized what was wrong. Flash automatically calculates the offsets (tx,ty), based on the box width and height that was passed in, but the way I was drawing the mesh was with a radius offset, so the solution was to set the offsets (tx,ty) manually after the matrix was created.
  6. After I managed to chop out the segments and get some gradient filling to work. I finally started looking into how to calculate the color hues. I found out on StackOverflow that there was a wiki page on HSV/HSL, which I then used to code the formulae.
  7. The HSV and HSL algorithms are similar, but I would recommend HSL since the spread is of lighter colors are more even as compared to darker colors.
  8. One of the limitations perhaps of the conversion of HSV/HSL to RGB algorithm is that it depends on dividing the hue into six main colors, namely red, yellow, green, cyan, blue, magenta. This means that when you start using a large number of sides to form a circle, you end up with a majority of segments in these primary colors.
    I made a mistake with the hue equation and got the above striked-out behaviour. It was due to the fact that I thought I should floor the h' in the equation to check which segment to apply the respective formulae. The hue now works perfectly on large number of sides.
  9. Part of the problem here is that I could not set the color for each vertex, which is also why I realized I should have made this wheel using triangles on the GPU instead of using Flash gradients. But since this is done, I leave that as a future project.
  10. In summary, if I were to redo this, I would use vertex rendering and the GPU to blend the vertex colors together. On Flash this would mean using Stage3D, or in C++, OpenGl or DirectX are both available.

Get Adsense

Want to earn money like me? Get Google Adsense now by clicking this