Javascript motion picture experiment, part 2

I wasn’t very happy with the result for my first take on the motion picture so I decided to revisit them. I did the following:

  • Remove the precision timing requirements by just calculating the film speed, position it correctly and have the shutter be triggered when the frame is passing through it.
  • Fix the shutter so that it’s not open/closed 50% of the time, instead it opens for 10 milliseconds and closes back, regardless of the desired frame rate.

 

Much better! if frame rate is high enough this looks pretty fluid, but may be too dark! (Note that the 1FPS example is skipping some frames, that’s an artifact of the animated GIF)

To compensate for the short shutter speed I added a white mask to simulate stronger lighting, then I increase the contrast of the film to make it look sharper under the increased lighting.

This also added a natural vignette effect to the movie. The final change I did was simulating a bit of imprecision on the shutter, making it randomly open a bit too late for some frames.

It actually looks much better when running directly (and at higher frame rates), things are happening just too quickly for the GIFs to get all important frames. I’ll clean up and push it to github soon for the curious, for the moment you can check it out online HERE.

I think I achieved what I was aiming for first, however for a real application it may be too tiring for the eyes… may be a hybrid approach (faking part of the visual effects) would be more appealing.

JavaScript motion picture experiment

While developing Curse of Wallachia, I was assaulted with a great curiosity: Would it be possible to emulate the way traditional film movies work using javascript?

The idea was pretty simple: Emulating the “film strip” as individual frames moving quickly (very quickly) on the screen, and then having an overlay area act as a shutter, synchronized with the film strip so that it showed a single frame at a time.

I decided to stream my adventure, which involved a lot of exploring the different options. You can check it out here and here

The goal was to make it so that the movie played at lower FPS than the actual game was running. I ended up doing the following calculations:

Given:

  • SHUTTER_HEIGHT in Pixels.
  • TARGET_FRAME_RATE in Frames per second

Then:

  • MILLIS_PER_FRAME = 1000 / FRAME_RATE
  • SHUTTER_SPEED = 1000 / TARGET_FRAME_RATE
    • in Milliseconds per shutter cycle
    • Each shutter cycle consists on it being opaque and then transparent for the same amount of time.
  • FILM_SPEED_MILLIS = SHUTTER_HEIGHT / SHUTTER_SPEED
    • in Pixels per millis
    • How quick should the film move so that a single frame is shown for each shutter cycle.
  • FILM_SPEED = FILM_SPEED_MILLIS * MILLIS_PER_FRAME
    • Converted to pixels per frame.
    • All sprites in the film strip move this distance on every frame.

Here are my observation after the first try:

  • It’s very hard to time the sprites correctly to move at this high speed and sync their position with the shutter. This is caused in part by the varying real frame rate and the high precision required for the timing.
  • Even if this was possible, having the shutter block the image 50% of the time reduces its brightness a lot (if I’m correct, they fixed this using stronger reflectors historically).
  • Ultimately, I missed the fact that the persistence of vision effect wouldn’t be achievable at low frame rate speeds so in order for this to work I’d have to work with higher frame rates, complicating the emulation even more.

I decided to give up this idea. I realize I may be doing something wrong so if someone wants to take on the challenge (or elaborate on why it’s not feasible) please post in the comments!

Later on I thought on alternatives to achieve my goal, I figured the only way to go was is faking both the Phi phenomenon and the Persistence of Vision effect as follows:

  • Keep the motion of the “film strip” using the same previous calculations.
  • Remove the shutter altogether, instead put a “still frame” sprite on top of the film strip. (This simulates the persistence of vision effect)
  • As the sprites from the film strip come close to a the “still frame” sprite, “burn” the sprite image into it. Since the film strip is moving quickly, this will simulate the phi phenomenon at lower speed (giving it the desired “retro” feel).

Here are the results:

 

I’m pretty happy with these results, admittedly I could have cheated and just put a blurb of pics as the film strip, since they are barely noticeable when over 8FPS… but this was fun and I think it feels more authentic 🙂

Finally, I made the still frame move around a bit when captured to simulate a bit of “jankiness” and imprecision.

cinema-janki

If you have followed the development of Curse of Wallachia, you may have an idea what I’m going to use this for.

Curse of Wallachia, further dev

So, you must know what this is about if you have seen Netflix’s Castlevania animated series. If not… go now and come back here 🙂

The goal for now is to create a video for the Prologue and Stage 1 (covering about 1.5 episodes).

Day 5

  • Add whip animation

Since the whip sprite moves around the player, implemented my own simple animation handler for the weapons.

Day 6

  • Make priest draw staff in cutscene
  • Attack priest on cutscene

Day 7

  • Add support for “hostile” npcs / monsters (chasing the player around)
  • Create sprites for “Knife Monk” including walking animations based on Grant’s

Day 8

  • Make NPCs attack player when close
  • Add attack animations for NPCs

Day 9

  • Show UI on top
  • Make enemies damage player when attacking (and knock player back)

Spent some time trying to offset the position of the layers created by Phaser’s Tiled map loading functions but didn’t have luck. In the end decided to add 4 rows of blackness on top of the maps 🙂

Likewise, had to add another slight hack for the collisions between the player and hostile NPCs, since the normal collisions would trigger the physics system meaning the sprites being pushed around (which doesn’t look a lot like the original). So instead of doing a normal sprite vs group collision I’m manually checking the intersection between the sprite bodies.

Curse of Wallachia – First Days of Dev

Day 0

  • Hesitated to work on this, tried to team up with someone
  • Considered different alternatives for engines.

Day 1

  • Decided to go ahead with Phaser by adapting the OAX6 engine
  • Created test maps
  • Can move sprite around with walking animation

Day 2

  • Arcade Physics, Jumping
  • NPCs moving around
  • Stage transitions
  • Talking to NPCs
  • Started work in portraits, using the amazing 8bit photo lab

Day 3

  • Design levels and intro
  • Added support for lowercase letters and portraits to dialogs
  • Started working on cutscenes support, added simple timed dialogs

Day 4

  • Added animation for dialogs to display one letter at a time
  • Added full Engrish script for cutscene 1