Giter Site home page Giter Site logo

sh's Issues

Try Pixi to see if webgl improves smoothness on mobile

Apparently it will, and even moreso when images are introduced.

Hence, it is probably worth it. However, there is also substantial value in having zero deps and building everything from scratch, given, this game is simple.

The main challenges we will probably have to overcome are: webgl is faster than canvas, textures are probably faster with webgl.

Try using webgl myself in my render function. See if mobile performance is much better. It will take too long to try it. Easier to use PixiJS directly.

Basic screens

Screens

  • Start
    • Title
    • Start button
  • Game
    • Score
  • Gameover
    • Score
    • High score
    • Play again

Strategy

  • Keep canvas as square (adjust padding as per screen width)
  • Use a mixture of canvas and HTML UI elements
  • Will need to introduce a top-level model to encapsulate the additional UI state
  • We can have a top level view function that is responsible for creating/updating UI elements in JS depending on the status of model and possibly a hint which can let the view function know what to re-render. For example, the initial model -> create title, create canvas, etc. This view function can be called from anywhere, anytime. NOTE: Let's think about whether this will ever block the main thread/block ability to request the next animation frame... another approach could be to somehow make this async, or, make the game loop itself consume queued UI update operations.

Optimizations

Implement as needed:

  • Track frame rate and memory utilization.
  • Intercept touch input at global level, prevent down-bubbling.
  • Mitigate choppy frames by using variable dt.
  • Use window.devicePixelRatio to adapt canvas resolution to different screen sizes to avoid computing unnecessary pixels.
  • Render text outside of canvas.
  • Render static assets (background, etc) outside of canvas.
  • Compress assets, multiple asset sizes, and sprite sheets.
  • Reduce memory usage and expensive computations within game loop.
  • Consider using PixiJS to increase performance via WebGL (hardware accelerated) rendering. -- As seen in this codepen, even with a super simple example using PixiJS only, mobile exhibits frame drops at 60 FPS. Essentially, frame drop is likely unavoidable for most mobile devices when running at 60 FPS.

New game states

GAME_INIT -> GAME_READY -> GAME_IN_PROGRESS -> GAME_OVER -> GAME_TERM

Add food to game

  • 3 types?
  • Rarity, point value, and speed may vary?
  • Launch timing should be fully random

Enemy speeds

The fast shuriken should be much faster, so that it is more of a test of reaction speed... even if that means it won't be fired with any other shuriken's simultaneously (to ensure fairness / respect reaction speed).

Bug: Vertical scroll on mobile

function onResize() {
  document.querySelector(".container").style.height = `${window.innerHeight}px`;
  document.querySelector("canvas").style.width = `${Math.min(Math.min(window.innerWidth, window.innerHeight) - 32, 512)}px`;
}

window.addEventListener("resize", onResize);
window.addEventListener("load", onResize);

Framerate independent game state updates

There are 2 main options:

  1. Fixed time step: Update function is called 0-n times every frame, however many times to match as closely as possible the time elapsed since the last frame (possibly with some wiggle room). Update function always progresses the game state by some fixed time step.
    • Pro: Extremely predictable physics
    • Pro: Tries to make rendering as smooth as possible while still using fixed time steps (e.g. by allowing updates sometimes when not enough time has passed, or, only updating once when slightly more than time than the the fixed time step duration had elapsed).
    • Con: For any FPS that is further from a multiple of the fixed time step, the game will run slightly too slow or too fast.
  2. Fixed time step with very small dt: Same as above, but, we make the time step very small (e.g. run update function 10x per frame at 60 fps). This allows any arbitrary framerate to be approximated more closely by the update function, at the cost of computational work.
  3. Variable time step: Update function is called 1-n times every frame. Update function progresses game by at most some max duration (beyond this, the update function may allow tunneling, etc).
    • Pro: True frame rate independence.
    • Pro: Smooth rendering.
    • Con: More complicated math and less predictable physics.

What is right for SH?

  • Physics needed: Jumps, linear motion, falling
  • For these needs, the math is simple enough
  • Conclusion: try variable time step since it grants us smoother rendering, true framerate independence, and given that we use a "max dt" the physics should still behave quite predictably.

Resolution independence and efficiency

Goals

  1. All game dimensions relative to eachother remain consistent regardless of resolution
  2. Compute the fewest canvas pixels needed (efficiency)
  3. Avoid scaling artifacts

Notes

  1. I think we are going to stay away from pixel art.
  2. Using ctx.scale() should be ok as it should re-sample the original image data (if images are used). And it has a pretty minor effect on performance. However, if it is not much effort, manually handling the scaling factor is probably the most performant and provides the greatest level of control.

Ideas

  1. SVG
  2. "Stepped" scaling, e.g. as screen resolution and size increase, only grow the canvas at pre-defined widths.
  3. Canvas has 1 fixed sized. Canvas DOM element is scaled up (blurry) and scaled down (unnecessary pixel computations) as needed
  4. Canvas resolution is set to match device resolution. Game logic uses virtual dimension units which are then scaled appropriately.
  5. Want a standalone unit system for lengths that is independent of canvas dimensions etc.

Look and feel

Theme

Pretty sure I want the game to be bunny themed. Snack can be carrots. And enemies can still be shurikens. Imagine... a bunny training to become a ninja. Title: Shurikens Hurt! Tagline: Ninja bunny trainer.

Or, player could be a gummy bear... or a cat...

Screenshot 2024-08-18 at 2 08 37 PM

^Bunny loaf for resting state
^Bunny "bear" for jumping/rotating state
^Only those 2 states. Too much animation frames will make the game feel too polished.

Difficulty

The fast shuriken should be much faster, so that it is more of a test of reaction speed... even if that means it won't be fired with any other shuriken's simultaneously (to ensure fairness / respect reaction speed).

Setup project lint file

If we stick with pure HTML and JS, setup a lint file for IDEs to use when developing this repo.

Refactor create enemy logic

Ensure

  • Cap difficulty so game is endurance based -- DONE
  • Prevent star-on-start overlap at jump site -- SKIP
  • Never shoot star less than REACTION_TIME_MS before a jump -- DONE
  • Respect jump cooldown and per-star shot cooldown -- DONE

Strategy 1: Segments

  • Difficulty: (1) # of jumps per segment, (2) # stars per segment, (3) L vs R distribution
  • A segment is comprised of: (1) a fixed active duration, (2) a fixed cooldown, (3) a set of jump times within the active duration, (4) a computed set of shoot times based on the jump times
  • After each segment reaches the cooldown, the next segment is generated

Strategy 2: Continuous

  • Difficulty: (1) jump probability, (2) # stars per jump probability, (3) current L vs R distribution
  • During each frame: (1) schedule a new jump in the future based on jump frequency, (2) for that newly schedule jump only, compute future shoot times based on shoot frequency

Strategy 3: Continus-Simplified

  • Difficulty: # stars per jump probability; jump probability is fixed (some jumps will have no stars)
  • During each frame: (1) schedule a new jump in the future based on jump frequency, (2) for that newly schedule jump only, compute future shoot times based on shoot frequency

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.