Code Monkey home page Code Monkey logo

avo-adventure-mk3's People

Contributors

shaunanoordin avatar

Watchers

 avatar  avatar

avo-adventure-mk3's Issues

Idea: replace Objects with Maps

Code Improvement

As of e8fc6f3, AvO's rules stores stores Rules in an object {}. While this is functional, I've learnt that a Map might be a better data type.

Notably, the documentation says that the order of key-value pairs in objects {} cannot be fully trusted to be deterministic, where as Maps have a defined key order. (The first key-value pair added to a map will always be iterated through first, for example.)

Status

Recommended. Minor effort required.

Idea: use canvas transforms when drawing sprites/shapes

Code Improvement

When drawing sprites/shapes, we currently calculate the camera offset and sprite scaling at canvas.getContext('2d').drawImage(). e.g.:

c2d.drawImage(hero.img, 0, 0, hero.sizeX, hero.sizeY, hero.x + camera, hero.y + camera, hero.sizeX * 2, hero.sizeY * 2)

Instead, we should consider using canvas transforms, e.g.:

c2d.save()  // Save existing transforms
c2d.translate(hero.x + camera, hero.y + camera)
c2d.scale(2, 2)
c2d.drawImage(hero.img, 0, 0, hero.sizeX, hero.sizeY, 0, 0, hero.sizeX, hero.sizeY)
c2d.restore()  // Restore previous transforms

This should allow for more dynamic renderings (such as 1. allowing sprites to shrink or enlarge, or 2. allowing the camera to zoom in/out, or 3. allowing sprites to rotate/flip) without too much additional mathematical coding.

Idea: simulate consistent time steps / frames per second

Experimental Idea

As of e8fc6f3, each time step (for each frame of action) is calculated dynamically based on the user's device. The code looks like this...

main (time) {
  const timeStep = (this.prevTime) ? time - this.prevTime : time
  this.play(timeStep)
  ...
  this.nextFrame = window.requestAnimationFrame(this.main.bind(this))
}

...so the value of timeStep can be anything, as determined by window.requestAnimationFrame(). On average, we expect 60 frames per second, so the value of timeStep will be ~16.6666666667.

The Problem

This is considered the "correct" way of calculating frames (as far as I can tell), but this can also make the physics and timing code in play() a pain to calculate! If we want a character to move at a speed of 8 pixels a second, we'd need to have the speed per frame to be 8 pixels / 60 fps = 0.133 pixels per frame, then alter that 0.133 to fit the actual timeStep, i.e. 0.133 pixels per frame * actualTimeStepForThisFrame / expectedTimeStepPerFrame.

As a result, it's possible that the results of physics and timing to be less than 100% deterministic. (To be fair, it may just be that my mathematical skills aren't ready for the challenge.) So with the example above, given 60 frames (~1 second) of simulation, instead of moving exactly 8 pixels, the character might actually move 7.91 pixels or 8.12 pixels or etc

The Potential Solution(s)

What I'd like to do is lock the timeSteps to a consistent value.

Idea 1: use setInterval() instead of window.requestAnimationFrame(). To be honest, I probably won't use this, as this was the old pattern I've been trying to move away from.

Idea 2: keep window.requestAnimationFrame(), but use a 'buffer' to trigger consistent logic frames.

const EXPECTED_TIMESTEP = 1000 / 60
this.timeStepCounter = 0

main (time) {
  const timeStep = (this.prevTime) ? time - this.prevTime : time
  this.timeStepCounter += timeStep

  while (this.timeStepCounter >= EXPECTED_TIMESTEP) {
    this.play(EXPECTED_TIMESTEP)  // Here's where we lock the time step!
    this.timeStepCounter -= EXPECTED_TIMESTEP
  }
  ...
  this.nextFrame = window.requestAnimationFrame(this.main.bind(this))
}

โš ๏ธ Potential dangers: what if the timeStepCounter gets TOO HUGE? (e.g. if a user tabs away from the window, does the timer still keep ticking? Then when the come back, will it suddenly run )

Status

Experimental. In consideration, but the current timing logic for the frames aren't completely broken (as far as I can tell) so no changes are strictly necessary.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.