Wednesday, February 25, 2009

New Logo using JavaScript and Canvas


Been working on a new logo for my nemesisstar.com website. Well not changing the logo really, just adding a bit of flair to it without using flash. If you want to take a look at it you can find it here. Again, don't bother trying to look at it using IE, as the internet explorer browser does not yet support canvas, and no official work that i know of that IE8 will support it either. 

Break down of how the script is working ...

Ok, for speed reasons I'm using 3 canvas's, not just one. All the base objects are wrapped in a div tag, the first 'img' tag inside the div will be used for those browsers that do not support the canvas object. For non-game stuff I have not reason not to provide some sort of backwards-compatibility support ... at very least so the search engines can still browse the site. the very last. I will throw everything into  a nice style sheet and make it pretty a bit later.


Setup of the cavas objects ...

    var logo = document.getElementById('myLogo');
    var logoBG = document.getElementById('myLogoBG');
    var logoBG2 = document.getElementById('myLogoBG2');
    var ctx = logo.getContext('2d');
    var ctxBG = logoBG.getContext('2d');
    var ctxBG2 = logoBG2.getContext('2d');
    ctxWidth = parseInt(document.getElementById('myLogo').offsetWidth);
    ctxHeight = parseInt(document.getElementById('myLogo').offsetHeight);
    document.getElementById('myLogo').width = ctxWidth;
    document.getElementById('myLogo').height = ctxHeight;
    document.getElementById('myLogoBG').width = ctxWidth;
    document.getElementById('myLogoBG').height = ctxHeight;
    document.getElementById('myLogoBG2').width = ctxWidth;
    document.getElementById('myLogoBG2').height = ctxHeight;
    ctx.globalCompositeOperation = 'source-over';
    ctxBG.globalCompositeOperation = 'source-over';
    ctxBG2.globalCompositeOperation = 'source-over';

Because I'm fitting the canvas objects to the screen width and height i need to adjust these values so that they are transformed to their appropriate 000px values. Otherwise, on some browsers at least, everything will have to pass through the scale routines and for some reason things really start to slow down.

Preloading the Graphics ...

Any graphics you use need to be preloaded, or if you are loading them as you need them in your script you need to verify that they are actually loaded before you use them ...

    var imgLogoA = new Image();
    var imgLogoB = new Image();
    var imgLogoC = new Image();
    imgLogoA.src = "assets/images/logo1a2.png";
    imgLogoB.src = "assets/images/logo1d.png";
    imgLogoA.onload = function() { loadCntr++; chkLoad(); }
    imgLogoB.onload = function() { loadCntr++; chkLoad(); }
    function chkLoad()
    {
      if (loadCntr==loadTotal)
      {
        renderLogo();
      }
    }

Very simple if you've done it before, no reason at all to make anything more complicated than you require. If you don't preload then you will get some very funky errors ... but inside the error text it will say 'no data' which is the key point to the error. The browser has 'no data' to work with .. as in, the image has not loaded.

The animation script ...

The script itself is pretty simple if you just walk through it line-by-line. Which I'm not going to do here. First everything needs to be set up and initialized ...

    function renderLogo()
    {
      ctxBG.drawImage(imgLogoA, centerX-203, centerY-203);
      window.setTimeout(doRotate, 100);
    }

The ctxBG is the middle layer which is holding the static logo. It is not moving at all in this portion of the script so their is no reason to keep redrawing it. Plus by sandwiching it between the three layers we can simulate the 3d effect.

angCos[curAng] and angSin[curAng] ...

Very simple simple if you have worked on any sort of 3d application. It takes more time to access Math.sin than it does an array. So we pre-calculate any sin or cos value that we might need and put them into these two arrays. As for the rest of the formula it is a very simple circle drawing routine from basic math class ...

        x = (250 * angCos[curAng]+centerX);
        y = (200 * angSin[curAng]+centerY);
        rad = curAng*0.01745 + offAng;

That tells us exactly where to draw all of the little spikes. The next line of code after the x,y are calculated converts the degree's to radians which is required by the canvas.rotate() function.  After that we actually have to do the drawing but there are two different buffers to draw too.

          if (fbuff==false)

The fbuff variable simply stands for "flip buffer" which tells the screen whether to draw to the foreground or the background based on the 'y' (vertical) value.  After that we do the actual drawing ...

            ctxBG2.save();
            ctxBG2.translate(x,y);
            ctxBG2.rotate(rad);
            ctxBG2.drawImage(imgLogoB, 0, 0);
            ctxBG2.restore();
            curAng += 45;

The canvas.save() and canvas.restore() do exactly like the sound, they save the current state of the canvas, allow us to do our manipulations, then restore it. canvas.translate(x,y) moves the origin point so that when we call the canvas.rotate(radian) function it rotates around the correct point and not the top of the screen (0,0).  canvas.drawImage(img,x,y) does exactly like it sounds ... draw's the little spike to the screen .. finally.

      ctx.translate(0,ctxHeight*((1-scaleY)/2));
      ctxBG2.translate(0,ctxHeight*((1-scaleY)/2));
      ctx.scale(1,scaleY);
      ctxBG2.scale(1,scaleY);

Above all that in the code is this piece which simply adjusts the vertcale scale value and re-centers the origin. The coupled with the buffer flipping is what gives us our pseudo-3d look without having to bother with full 3d code which is slow at best with the current canvas object. Full 3d support is to be added to the canvas object later, but they will have to get past the arguments about the standards first. Myself if i wanted to add full 3D i would just use Unity 3D even though I don't like plug-ins.

Speed of the canvas rendering ...

I've done everything that I've been able to think of to make this run as fast as possible and have a great more that I do wish to add. So far Chrome seems to run it the fastest for me by far and the few people I've had test it have said that a higher end video card does help in the rendering speed. The only thing I don't like is with the black on white it seems a bit shaky in the rendering. I could probably add in 2 more buffers and then flip the visibility after they are rendered to remove that but I'm not positive how that will work out.

Future additions ...
  1. Add interactivity so the user can play with the logo
    * double-click top and it will spin top-to-bottom
    * double-click side and it will spin left-to-right
    * drag the spikes to increase or decrease the spinning speed.
    * be able to click and select a spike
    * add a highlight-glow to currently selected spike/icon
  2. Add icons to the spikes
  3. Make the center image change according to the icon clicked on.
  4. See if i can get more speed by removing the canvas.scale() and converting the spikes to vector drawings instead of images.
  5. Convert the entire script into an animation object/class.
    Will be using this same type of animation in the nemesis-star game so that i can add space-station and such around planets. When being used on a smaller scale like that the animation speed should drastically increase.

Tuesday, February 24, 2009

MMORPG Stories

I had a question the other day relating to MMORPG's that I could not give a good answer too.  The question was ...
Can you name any mmorpg that has an active story line that compels the player to play along with the story, not just walk around and randomly kill mobs, and skill?

Me, I could not think of one single game that did that. I asked a few of my friends and one of them suggested a new game in beta called Jumpgate in which he is participating in the beta. he said.

The player is not REQUIRED to participate
  but the players are actively influenced with the results.
  Example...
  A new line of weapons come out
  If their faction doesn't complete the faction missions, then their weapons isn't released
  and they will be at a collective disadvantage


One of the things I want to do in my lychgate game itself, not the engine, was to make the story more interactive. Encourage group play that goes along with the story and weekly events to defend the 'human kingdom' from attack. While nobody should ever be required to play, it is just a game and not a job. Players should defiantly be encouraged to participate via rewards of some sort. Not just meaningless quests ... "please, this tree monkey offended me so go kill 100 of them and I'll give you some free stuff". Bleh, some quest.

I also think the monsters/mobs themselves need a great deal more AI than what they have.  How hard could it possibly be to script some action in the town and not just have everyone standing in one spot all day and night!

Also, I'm guessing no game designer has ever went deer hunting ... they don't freaking run to attack you! they run away! And a group of Orcs which would supposedly be sentient, i mean they built houses however crude they might be. But you can walk up and attack one, and the others don't run to help their buddy? yeah right. Yes adding some more realism would make it more difficult for the players, but in turn it would also make it a lot less "ok, only 57 more demons and I'll level up again", and a lot more "hey guys, let's go raid the Orc village together before they attack us!".

And in concerns with the deer, unless your stealth can surpass the alertness of a deer (not likely w/o magic), your not going to kill one with your "+10 vorpal sword of deer-slaying".  Use tracking to find it, and a bow or some sort of traps to kill it (traps for smaller game). Or go out with friends, some will be sent around to flush the deer or other game to you. This would not be that difficult to program and I'm not sure why nobody really has yet.  Just too much "kill, gain exp, kill, gain exp" and not enough game anymore.

I'll have a lot more comments on these ideas later. ;-) Feel free to post your ideas and comments about this!

Tuesday, February 17, 2009

Another jobless day

Another day passes, few phone calls yesterday from recruiters but I have not had very much luck with them so I won't get my hopes up.  At this point willing to relocate to just about anywhere to get a job. Wife insists that it's not the economy it's that I'm just lazy and haven't applied my self enough to the job hunt. Me being the quiet mousey type i just sit there and say nothing, I've learned that there's no point in arguing with her, she will keep going until she feels like she has won no matter how long it takes. But still, we're scraping by thanks to the grace of god and as long as that's happening we're a step above a lot of people in this day in age.

Anyways, did a bit more work last night on the canvas engine. Seems like Firebug has changed since I've lasted worked with the profile in the console. It no longer lists all the functions that are called like the old version. The old version would even list what classes were accessed, how often, and how much time it took. But alas I will have to just make due with it, just seems like their development progress took a step back. I have the mini map scrolling properly across the mm buffer, just need to get it updating the main map area fluidly.

Fluid updating of the map .... I've seen other's try this with DHTML and run into problems.  After you have optimized the draw portions of your map-renderer you then need a way to interact with it. Though I do try to avoid global variables for the obvious problems they can cause I've implemented a global boolean variable called notDrawing. This actually should be in the drawing class itself and it will be placed there later when I restructure it.

At the beginning of any event function that will do any rendering to the map the variable 'notDrawing' is set to false. When the calculations and rendering is complete then notDrawing is set to true. This allows you to very simply check the renderer .... 

if (notDrawing)
{
drawDetails(obj, x, y, tx, ty)
}

Very simple, but what is the point you may ask! Ok in order to make the mini map and the large main map move fluid they have to be redrawn as fast as the browser will allow. What you want to avoid though is over sending these draw calls as it will cause a slowdown instead and could lead to the browser being locked up. Even a short lockup of the browser will frustrate users and cause them to leave. 

Some other ways to optimize your JavaScript code... Avoid using EVAL, eval is bad as it forces a delay in your script and causes the browser to call it's parsing program. Other places where you use eval and might not even not it ... widows.setTimeout, or windows.setInterval. It has been common practice for years and i see this mistake in tutorials all the time where they do something like ... windows.setInterval="myFunction();". This is just like an eval statement and forces the browser to call it's parser routine. Instead remove the quotes and the parenthesis so it looks like .... windows.setInterval=myFunction;.

Another way to optimize your JavaScript code is to use VAR. In JavaScript you do not have to declare your variables, but by doing so it becomes a global, and as stated previously use of global's is bad. This is one of the primary problems that people run into when using JS Scripts from multiple sources, the fact that the variables conflict. I've seen some scripts use super long variable names to avoid this, which is ok i guess but seems a bit pointless. Just predeclare all your variables that you use with a VAR statement instead. That limits their scope to inside the {} brackets and I'm pretty sure it limits it to inside the .js script file as well, though i would need to do some testing first to be totally positive on that. 

Ok, time to start wandering around Raleigh dropping off resumes to the local web business's. I was told by a recruiter that this looks desperate ... but then again he drives a Ferrari so I'm pretty sure that he hasn't tried to find a job in quite some time, especially in this economy.

Friday, February 13, 2009

Lychgate Roadmap

Lychgate - the JavaScript Game Engine


This is a portion of a Google document that I have created to assist me in my programming activities. I believe the first full game I will design this engine for will be for my Nemesis Star game. By doing this it will include support for ground, air and space activities across multiple planets. Nemesis Star however encompasses both RTS and RPG elements which should make the design of the basic engine a bit trickier but overall I think it would be a better final product for it.

I will be revising this as I go and put forth a more detailed road-map to a full fledged game, but at the current moment getting these few things done would allow me to open up some closed alpha testing and tweak the game till it works properly. I do have a list started for requests from people to be part of the closed alpha, but if you wish to participate you must make this request before it begins.


A few requirements I have laid down for myself ...


Classes

  1. Classes will be broken into groups based on what they do.
  2. These groups should work as independantly from each other as possible.
  3. Allow dynamic loading and unloading of these classes and scripts.
  4. Each group type will have basic get/put elements that are required for interaction with that group.
    (this all allows multiple types of the same group.)
  5. Cannot load more than one group type at the same time.
Graphics

  1. Graphic animation strips should be small, 1 animation type/direction per file. This means multiple files however it does give a big speed processing. I've tested this quite a bit and the larger the file the more the slowdown when clipping from it.
  2. The graphics library must support dynamic buffering. This would be the dynamic creating/deletion of canvas objects where needed. Back-buffering is a very old trick but it does very much apply when using the canvas tag to render scenes and animations. By pre-rendering certain things you get a great improvement in performance.
  3. Dynamic loading and unloading of graphics. The map object will be designed to support a nearly infinite amount of different tile terrains. Because the base graphics are loaded into via smaller files the map engine itself can select what terrain tiles that it wishes to load. This allows the coder to put just what they want into the map from any terrain library that they wish.
  4. A simple web-based graphics editor. Not really so much for creating graphics as for clipping, arranging animations and such. Can make the graphics editor more complicated later.
  5. Web-based map editor. Their is none, map edits would be made by the GM/Owner in real time in the game world itself. Why create two version of the same thing.

The to do list ...

  1. A Super-Basic RPG

    1. Basic Client Side Graphics Development

      1. Create the Draw Class

        1. This class is responsible for all the drawing

      2. Create the Sprite Class

        1. This is an extension of the ‘Draw’ class as it gives it the ability to use tiny buffers to perform animations and movement.

      3. Create the Timer Class

        1. This is what controls the Sprite Class and Draw class in order to insure that everything runs at the same speed across all supported types of computer systems.

      4. Map-Drawing Layers

        1. Ground Layer

        2. Object Layer

        3. Mini-map

        4. Character Map

      5. Create the Panel Class, this utilizes the Draw class to display the panel information. But all the information itself is contained within this class. The “Overall Display” is a series of Panels so that they are more easily moved and migrated as required.

      6. Primary Information Panel

      7. Overall Generic Display Setup

    2. Basic Server Side Database

      1. Tables

        1. MOB

        2. Map

        3. Player

        4. NPC

        5. Scripts

      2. Encapsulation

      3. Write DB Access scripts, ultimately should support SQL and postGreSQL, (access support would be useless to include, so don’t!)

        1. Methods … (Check W3C? or another Open Source Solution first?)

          • Open

          • Get

          • Set

        2. Properties

    3. Basic Server Side Data Server

      1. Basic AJAX setup, XML

      2. Challenge-Pass.( Insure login through every connection via Sessions and Privacy Protection.)

      3. XML Packages …

        1. Note: Packages should ultimately be scriptable though an Admin section. The packages will be XML Templates with pre-programmed variables and scripting methods. This is done to ease later programming and increase the overall flexibility of the server.

        2. MAP Package

        3. Player Package

        4. MOB Package

        5. NPC Package

        6. Script Package

        7. Graphics Package

    4. Navigating the Map

      1. Now we add the ability to move around. Phase 1.1 is where we test our ability to draw the map. This is in all encapsulated in a draw class.

      2. Create the MOB class, “Mobile Object”

      3. Create the Player Class

        1. Add ability for the player to move

        2. Add animations

      4. Create the NPC Class

        1. This first instance is super generic and only displays the NPC as a static object. We give it the ability to move later in Phase 1.06.

      5. Create the Collision Class

        1. An extension of the Map Class but does no drawing.

        2. Prevents the player from moving into certain area’s

        3. Controls trigger areas

      6. Create the Script Class

        1. The script class load/unload scripts

        2. Is what the Collision class activates, specifically triggers.

    5. Our first battle

      1. Loading from remote server

        1. Battle-map

        2. Players

          • The first battle this will be a single player

        3. Enemies

          • Initial Monster will be the standard ole Green Slime. After that it will be a combination of slimes and/or goblins.

        4. NPC’s

          • The NPC will be the second part to this phase, buy a mercenary from the shop and it will participate in the battle with you.

      2. Initial Drawing Setup

        1. Map

        2. Mini-Map

        3. Battle Panel Overlay

        4. Pre-load and Pre-draw Common Animations for speed

      3. Initiative Phase

        1. Determine type of battle (turn-based or real-time)

        2. Set Initial Initiative Matrix

      4. Battle Sequence

        1. Using Initiative Matrix begin the battle

        2. When in turn-based mode everyone goes one-at a time.

        3. When in real-time mode everyone goes at the same time.

        4. Keep repeating until one team is victorious

      5. Ending Sequence

        1. Give out items and experience to winners if the player is victorious.

      6. Cleanup

        1. Close and destroy all object and classes created in this battle. Each object is stored in an object array called ‘trashcan’ when it is created.

      7. Draw player onto map

    6. Interacting with NPC’s

      1. Simple NPC Shop

        1. The NPC should already be drawn by this time.

        2. Setup NPC animations

        3. Setup shop window

        4. Setup shop XML Package. Refer to 1.3.3.a for details on this

        5. Retrieve Data Package from server for specific NPC


Wednesday, February 11, 2009

Ocean Cleanup




I see a lot of people talk about this and how big of a problem it is, bla bla bla. The only solutions I see offered as of yet is to reduce our use of plastic and/or convert to more bio-degradable plastic. Both good solutions as to not increase this disaster any further but it does little to fix the problem.

The oceans are the life blood of the planet, if we destroy them we might as well move the doomsday clock to midnight. I myself don't go to the beach much, can't even swim, grew up in the Midwest far way from any oceans. But alas I have contributed to this problem as everyone else on the planet has through passiveness and through my contributions to our disposable society.

It would not be a difficult process to begin to gather all of this plastic out of the ocean, it has to be done and the sooner the better. However it would be a lengthy process and then there is the matter of, "ok we got this big chunk of mess out of there, now what". The above link states that it's "twice the size of the continental U.S.".  I'm not sure how dense it is so any real calculations are out the window but it sounds like good material to build our own green island!

Why not? I've seen much dumber ideas pushed through the public (reference: the entire Bush presidency) and you have to do something with it. Can't just throw it into the ground that's a whole other problem in itself. Could burn it but who's going to put a power plant in the middle of the ocean?

Push the water through filters to gather out the particles, use the sun to melt the mass together, walla instant island! then since it would be outside any nations boundaries, declare your own green country! Margaritas anyone!?

ok ok, I was really bored this evening while working on websites. :-) 

Monday, February 9, 2009

Lychgate: a JavaScript MMORPG game

General Info

Ok, so I've finally found a couple of minutes to setup a real blog for this. You can see previous entries for my Lychgate project at http://code.google.com/p/lychgate/wiki/MiniBlog, but it looked like it would start getting a bit long so I've set this one up.

Goal of this project: To create an JavaScript MMORPG using the new HTML5 

Canvas HTML Tag:
Specification: HTML5
Standardized by: WHATWG.org

Initially released by Apple the canvas html element is now supported by FireFox, Opera, Chrome and Safari natively. In short, canvas allows you to draw anything you wish straight to the web-page. No plugins required so you are only limited by your imagination as far as what it can do. The only draw back is lack of support from Microsoft in IE, though there is a very clunky JavaScript version available it will not run the more complicated things that i develop here ... which is of course games.

FAQ

Some questions people have asked me over the year or so that I have been working on this project.


Why Do this?

Because I can! Few other people are really attempting such a project and no others are that I currently know of are developing it in canvas. It is also the best way that I can think of to really show off my skills in JavaScript. While I could do this outside of canvas but this has been done and the results are ok at best with a couple of exceptions, yet even those exceptions have their limitations.

Why not just make a flash game?

Have you played some of the flash games out there? Flash is horrible at best.

What is the best browser to use?

Difficult question, Google's new Chrome browser is by far fastest in pure processing speed, but it does have a few graphic quirks such as it will not properly apply opacity to images. Firefox, though somewhat slower, does render canvas very well but Opera and Safari both are right behind it. So as long as it's not IE it's pretty much up to you unless your on a slower computer then you should use Chrome.

Will this be open source?

Yes the base-code for the client side of the game will be open source. This will not include specialized code for the game I will be developing using this code, nor will it include any server-side code.

Will this require any other JavaScript Modules?

No, it will not require anything else and will be completely self-sustaining to include it's own prototyping and classing systems and at the moment will be built on a maximum of JavaScript 1.5 though I may change this to 1.3 at a later time.

How will you do sound-effect and music?

Unfortunately JavaScript cannot do sound natively. So I plan on writing interpreters in flash, java and unity3d to play sound so that the user can use any or just turn sound off entirely.

Will support be added for Internet Explorer?

Currently there is no plans to add any sort of specialized code to just to make it work in IE.

When will there be a playable alpha version?

I currently work for myself, so that and job-searching takes up a great deal of my time. Such is how life goes at times so unfortunatly there is no definitive release date. People who are paying me to work on their website for them always come first over hobby projects.

How will maps load?

Maps will be qued up and pre-rendered to a buffer to avoid the horrible "loading please wait". The entire engine will be run via a custom Ajax script that I have custom built. While i could just use a pre-built Ajax script such as one mootools offers the requirements of something like this are much more intense than just a simple web2.0 website. This queing of the maps not only reduce/eliminate the loading screens it also has a nice side effect of increasing overall draw-rates.