Tuesday, April 23, 2013

RoboSketch

I am trying to stay within the theme of a CHALKBOARD...

And having images just "appear" on the screen is out of character for a chalkboard.

I had this odd idea and tried it out.... It was easier than I had first thought, thanks to this post by one Jason Sturges regarding "live drawing". His post helped solve half of the puzzle. He gave a set of code (that I just cut-n-pasted into a mini project that I titled "MousePen") that allows one to draw with the mouse. It uses lineStyle and MoveTo (along with mouse events) to draw a lot of straight lines from point-to-point as the mouse moves. I made some modifications to that program.

(1) I added a trace command that displayed the line point coordinates, in the correct format, to the Console. Above you can see the trace command which will output a single set of coordinates that maybe looks something like "[101,234,102,236]"  Now I just run the program and draw with my mouse as it outputs all of the data points to the console.
(2) Problem is that I ended up with over a THOUSAND points for a single, simple diagram, because it drew a little line whenever the mouse moved AT ALL. So I added a DISTANCE check. At the very top of the code you can see that I make sure the distance between two points is greater than 4.5 pixels before it actually draws the segment of line. This greatly reduces the number of data points.

Then I just cut-n-paste all of the data points into a second program that I called RoboSketch.

This program uses a big array (called _drawingPoints) that I just paste my few hundred data points into. Then it runs with a timer to slow it down, drawing every line that was recorded, as before. With the delay it LOOKS like someone is sketching, live, as it recreated my pen strokes, in order. In the code above you can see the tail end of the array, then the sketchTimer, and the beginning of the updateTimeHandler event that re-draws the lines.

Here is an example of the ORIGINAL DRAWING on the left, and the RoboSketch drawing, on the right. (This will all make more sense once you see it in action... You have to imagine that the drawing on the right takes about 7 seconds to complete as it looks like someone is drawing it in the moment.)


 
UPDATE: The next day I tried to implement RoboSketch into my actual program. There were several problems, of which I solved many. I was able to create a really neat effect by measuring the time delay while the user picked up the "pen" so that I could accurately simulate the pen strokes when the pen was "in the air" between drawing objects. It worked great. However, when I inserted it into my actual program I found that the graphic method only seemed to work on a BLANK background. I could not get the drawing to go OVER the blackboard image. I believe I could somehow transfer a .bmp image of the blackboard to the background and then draw on top of that, however this is just WAYY too much work to go through for this one effect. I have decided to drop this idea and just go back to inserting .gif images over the blackboard and using them. Too bad. (I added more time at the bottom of this blog entry due to the extra hours "used up" today in this dead-end pursuit.)
 


Time: 4 hours

"Page Numbers" and Better Scene-Tracking

I worked on a few things today: (a) embedding a font that looks like chalk-writing, (b) Page Numbers, and (c) Better Scene-Tracking.

EMBEDDING FONT - I tried this about a month ago and it seemed to work on a limited bases but it was lost somehow. Back then I did not really understand how Adobe Flash Builder worked, which caused me to do some things to create bugs and, well, the embedded font just disappeared. I like the font so much, since it looks like chalkboard writing, that I am trying it again. This time I embedded the font in the main running "application class" and then was able to call it within SceneOne and SceneTwo. Here you can see it in both the "User NameTag" at the top of the screen, and in the words "This is Scene Two"


PAGE NUMBERING - Something else you might notice in the upper/left corner is the text "[ 2/ 2]" which acts as a page number. It stands for "page 2 of 2 total pages." It will serve as a page count to tell the student how far into the assignment they have progressed. But the page numbering is merely a side-effect of improved scene tracking.

BETTER SCENE-TRACKING - I realized that I would need to be able to keep track of HOW FAR a student progressed within a lesson incase he/she decided to go BACK several scenes/pages. Why? Because they should be allowed to hit "fast forward" to jump ahead TO THE POINT WHERE THEY LEFT OFF, even if they don't yet have full access to the entire lesson. Now I have three variables: sceneOnStage (which is the scene/page that is currently shown on the stage), sceneTotal (which is the total number of scenes/pages in the particular lesson), and sceneMax (which is the maximum page number the student is allowed to fast forward to.) Not only does this make it easy to display page numbers and total number of pages, but it makes it easy to determine when the "fast forward" button is dimmed/disabled.


The code above is from SceneTwo, but it is identical in SceneOne. It checks to see if the current scene on stage is equal to the maximum number of scenes that the student has reached. If that condition is TRUE then it (1) disables the Forward button, and (2) sets its alpha to 0.2 which dims it. This works nicely to automatically disable the Forward button on the very last page of whatever lesson I make because all I have to do is set the sceneMax to the total number of available pages.

Time: 2 hours

Monday, April 22, 2013

Three Scenes (and they can cycle)

After completing some of the modifications earlier today I was able to set up a generic starter file that is comprised of three scenes total: Log In, Scene One, and Scene Two.

The navigation buttons allow the student to jump back-and-forth amongst all three scenes. Every time a scene is changed the previous scene is deleted (null) and the next seen is created anew, complete with new buttons, frame, and blackboard background.

Here is a picture of scene two:


I was able to jump back-and-forth over 20 times with no apparent ill effects in the running program. (So, it looks like all of the elements are being deleted and re-created as needed without any old code hanging out and clogging up the system.)

Time: 1 hour

Proper "Clean Up" after Swapping Scenes

Now that I have some control buttons at the top of the frame I can experiment with jumping forward/backward between scenes...

And I found some problems.

And fixed them.

The two main problems: First, when you jump BACK into a scene that you already left, the scene comes back JUST AS YOU LEFT IT the first time.... This mean that, when I jump back into the "log-in" screen it was already displaying "Logging In, Please Wait" and other problems occurred because of it. Second, after I left the first scene there seemed to be some left-over code running in the background. (When I pressed the "Enter" key while in Scene One it ACTED like I was STILL in Log In scene, and it let me log in again!!!??? The button_press event listeners from the PREVIOUS scene were still running during the next scene.)

Solutions...

First, in the main scene-handler program I made some modifications to allow the student/user to move forward and backward between scenes.

Here is the code that moves the scene FORWARD:
The above code will advance scenes from "LogIn" to "Scene One". It removes the Log In scene, then sets it to null (which basically deletes it... However, evenlisteners keep running). Then I make a new Scene One object, and place it on the stage. (It then sets _sceneOnStage to 1 to let "everyone" know that Scene One is on the stage) 

Here is the code that moves the scene BACKWARDS:

The above code checks to see which scene is on stage (scene one) then it removes it, deletes it (null) and makes a NEW "Log In" scene then adds it to the stage. It then sets _sceneOnStage to zero once again. (This code is run when the student presses the "Back" button.

Second, I added some code in each scene to DELETE EVENTLISTENERS whenever the given scene is removed from the stage.

The above code is added to each scene to listen for the time when the scene is removed from the stage. It then runs the "removeFromStageHandler" function:

The function above will be the last function ran in the given stage. It is triggered by the REMOVED_FROM_STAGE event. In this example the KEY_UP and KEY_DOWN KeyboardEventListeners are removed. Then the REMOVED_FROM_STAGE event listener itself is removed. THIS KEEPS THE BUTTON PRESSING EVENTS FROM ONE SCENE FROM EFFECTING THE NEW SCENE. (Before I did this the student was able to hit "ENTER" to re-log in WHILE he was already into the next scene... The event listener was running in the background because I had not deleted it.)

I added similar "removeEventListener" code to other objects, like the Button objects that each have mouse event listeners on them. (There is no reason for the computer to keep listening for mouse events on buttons that were DELETED because the student has moved on to a new scene!)

NOTE: In the final versions of these interactive tutorials the student will NOT ACTUALLY be allowed to "back" into the log-in screen again. The furthest back they could go is Scene One. I am only doing this right now to see HOW to make this happen. I figured that if I can do it with the Log In screen I can probably do it with ANY scene that I create in the future.

Time: 2 hours

Sunday, April 21, 2013

Play/Pause/FFWD Buttons

Today I got to work on the main control buttons that will be at the top of the main frame.

First I spent a couple hours just designing/drawing the buttons using Photoshop. I made three images for each button: (1) button DOWN, (2) button UP, and (3) button HOVER (for when the mouse is hovering over the button)


Then I worked in Adobe Flash Builder to make a sprite/class for each button with all of the controls to: (a) switch button images when required by the mouse, (b) signal a "click" sound when the button is pressed, and (c) dispatch the specific button press event (ex: dispatchEvent(new Event("buttonPausePress", true)) so that whatever has to happen because of the specific button press can happen (which, I have not as of yet programmed, of course! Today I am just "sending up the flags"!)

Here is what the first scene looks like after the student "DENNIS1" logs in.

In this example the student did not enter the correct two-letter code to match his log in name so he only has Level One access to the program. Therefore the "Fast Forward" button is dimmed out and useless to this student. After the student completes this tutorial he will be given one of the two letters to unlock the fast forward button(s).

Note: In the example above I am currently pressing down on the "Rewind" button but you can not see my mouse cursor (hand pointer) because "prt sc" doesn't capture the mouse pointer. (But at least you can see what the button looks like when it is being pressed.)

SAVING LOTS OF MEMORY: Today I discovered that I was using a LOT more memory in my programs than I needed to. According to the Game Design book that I am using my images had to be saved as"web ready" .png format files, or, at best, .gif files. So I had been using .png for ALL of my images, including the large blue frame image (600 kb) and the background chalkboard image (300 kb). However, I was able to turn the blackboard image into a .jpg, and the blue frame image into a .gif (the center is transparent, of course, so jpg wont work). Now my TOTAL .swf file size is UNDER 200kb at the moment (when it USED to be almost 1MB!)  You want your .swf file to be user-friendly so keeping it a manageable size helps.

Time: 6 hours

Saturday, April 20, 2013

Log In Password Encoder

Today I worked on a major portion of Action Script code that will enable me to create log in "keys" for each student's name.


Above is an example of a generic log-in screen that I will use for the virtual labs/puzzlers.

The first seven spots are for the student's log in name. Every student will have a seven-letter (or number) name assigned to them at the beginning of the year. The name will basically be their actual first name plus some numbers if necessary to distinguish them from other students. (My log-in name above is "DENNIS1")

The second row has two parts.

The first part is a four-digit number. The students will get this number by completing the required video lectures. (These four numbers will be hidden within the videos. Students will write them at the bottom/left corner of their printed notes.) To participate in a virtual lab assignment the students will have to have watched the required video lectures. (The four digit Unit password above is "1234")

Then, after completing a virtual lab the student will be rewarded with one of the remaining two letters to the bottom row seen in the image above. The catch: THESE TWO LETTERS WILL ONLY WORK WITH THEIR OWN LOG IN NAME. (In the picture above I have typed in "GH" which was not the correct two digits for "DENNIS1" so I will only have a limited log-in.)

I have been working on an "encryption scheme" that will use (a) patterns in the a student's log in name and (b) a special "Unit key" for each unit. It will take these two and create a two-letter "code" for each student for each Unit.

For example: the Unit 3 key for the above example looks like this: "1234ABYZ"  Which means that the four-digit number to log in is "1234" and the "ABYZ" tells my program how to interpret a student's log-in name in order to come up with a two-letter key. The encryptor is piece of actionscript code that I created that knows how to interpret the Unit key, which is the 8-digit code that I create for every Unit that I will be teaching. (Did I mention that I spent 7 years as an officer in the US Navy? I learned a little something about codes and keys...)

I know this all seems a bit over-the-top, but it is going to be done in order to minimize students efforts at "copying homework" from one-another.

Time: 5 hours

Wednesday, April 17, 2013

ActionScript Work - added keypress sounds & cursor movement

Today I added sound and cursor movement to my log-in screen.

First, I modified the _boxPositions array in my LogIn scene:


Now each input box has four additional numbers besides x and y coordinates: lft, rgt, up, and dwn. These each indicate to which index the cursor (ie: Focus) is to move if the user hits the respective arrow key (or tab button). For example: in the third array element, for box #2 we have x=180, y=100, then lft=1 (the cursor/focus will move to element #1 when the user presses left arrow), rgt=3 (the cursor/focus will move to element #3 when the user presses right arrow), up and down both =2 (the cursor will stay on element #2 if the user presses up or down arrow).

From now on when I add additional input boxes/configurations I can direct the cursor/focus to move logically within that new pattern.

Second, I added the "if" statements within the keyDown handler to (1) move the cursor around, (2) set the correct letter or number (if pressed), and initiate the appropriate sound (a key press click or an error sound).

Line 160 tests to see if a legitimate letter was pressed.

Line 162 sets the current box's letter to match the key pressed.

Line 163 to 165 moves the focus/cursor forward to the next box.

Line 166 dispatches the "keyPressSound" event which triggers the application class (main class) event "makeKeyPressSound" to make the appropriate sound. (next image)



Above you can see the three main sounds that are in the application class. (one sound is a standard keypress. One sound is a higher pitched key press for numbers. The third sound is a quick error sound for when the user presses an incompatible key.)  The sounds were embedded earlier in the application class.

Time: 3 hours