Skip to content

noJS-3-flappy-bird#408

Open
QuarkNerd wants to merge 2 commits intoScottLogic:gh-pagesfrom
QuarkNerd:gh-pages
Open

noJS-3-flappy-bird#408
QuarkNerd wants to merge 2 commits intoScottLogic:gh-pagesfrom
QuarkNerd:gh-pages

Conversation

@QuarkNerd
Copy link
Contributor

@QuarkNerd QuarkNerd commented Feb 17, 2026

Please add a direct link to your post here:
https://quarknerd.github.io/blog/2026/02/14/noJS-3-flappy-bird.html

Have you (please tick each box to show completion):

  • [x ] Added your blog post to a single category?
  • [x ] Added a brief summary for your post? Summaries should be roughly two sentences in length and give potential readers a good idea of the contents of your post.
  • [ x] Checked that the build passes?
  • [x ] Checked your spelling (you can use npm install followed by npx mdspell "**/{FILE_NAME}.md" --en-gb -a -n -x -t if that's your thing)
  • [ x] Ensured that your author profile contains a profile image, and a brief description of yourself? (make it more interesting than just your job title!)
  • Optimised any images in your post? They should be less than 100KBytes as a general guide.

Posts are reviewed / approved by your Regional Tech Lead.

@QuarkNerd QuarkNerd force-pushed the gh-pages branch 2 times, most recently from def100d to 2a9ea38 Compare February 18, 2026 10:38
Copy link
Contributor

@jstrong-scottlogic jstrong-scottlogic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool

/* And so on */
~~~

Above, I make use of the [has selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:has), which is relatively new; it allows you to select a parent element or a previous sibling element with respect to a reference element. In this case, it will select `:root` (`html`) when it has an `input[id^="1"]:checked`. `^=` is a begins with selector.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* is a 'begins with' selector may read better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that not what I said?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean in quotes would read better

Demonstration of the hidden labels used for randomisation
</video>

The key thing to remember is that in the actual game, the shaded regions are completely grey. The css logic looks like..
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* CSS


`--click-box-height` is the height of the label; this does mean that there is a precision limit based simply on how large the labels are. `--bird-frame-base-top` is just a base value for the position of the bird frame (bird and labels). `--active-number` is determined by the most recent label clicked; each value is just an integer indicating its position. `--bird-delta-y` is the animated variable from earlier.

The code above changes the nature of the animation, but we still need to reset the animation on each click. This is done by simply having two sets of inputs, which swap in and out on every click. Each set has a full collection for setting `--active-number`, they set a different identical animation. The changing of the animation resets it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'Each set has a full collection for setting --active-number, they set a different identical animation.' It is unclear to me what this means.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll rephrase

/* Duplicate */
}

/* Ensure that the jump-holders (divs contains labels) swap in and out on every click */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* divs containing labels?


All the radio buttons have the same `name`, which means that only one can be selected at any one time. So when one from `#jump-label-holder-2` is selected, it deselects the one from `#jump-label-holder-1`.

If a user clicks down on a label, it is possible for that label to move out of the way, and another label takes its place, then no selection is detected. To deal with this, we can increase the height of the label when the user presses down by making use of the `:active` label. We can also use `:active` to animate the wings by simply swapping out the image.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is 'clicks down' here distinct from just 'clicks?'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trying to distinguish between down and up, a 'click' can be the full down and up motion?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll rephrase


### Collision Detection and game end

Pipes are great and all, but what's the point if they don't hurt the bird? Here is a simplified version of my collision detection, which is done independently by each pipe.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Poor bird 🐦 😢

}
~~~

The calculation is split into an overlap in x and in y. The first bit of the x calculation determines if the bird's right side is past the pipe's left side; the first max returns a `0px` if not. Similarly, the second bit determines if the bird's left side is behind the pipe's right side; if both of these are true, the pipe and the bird overlap in the x dimension and the value of `--overlap-in-x` will be none-zero There is an equivalent calculation for y (that takes into account the gap between pipes).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* will be non-zero. (missing full stop). I also wonder whether here and throughout x and y should be within backticks?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've been doing it mainly for code legibility

~~~

The calculation is split into an overlap in x and in y. The first bit of the x calculation determines if the bird's right side is past the pipe's left side; the first max returns a `0px` if not. Similarly, the second bit determines if the bird's left side is behind the pipe's right side; if both of these are true, the pipe and the bird overlap in the x dimension and the value of `--overlap-in-x` will be none-zero There is an equivalent calculation for y (that takes into account the gap between pipes).
The result of this calculation is that if there is an overlap of a pipe with the bird, `--collision` will be non-zero. Once we have this, we simply create a game-ending div which has a height of `200vh * var(--collision)`, forcing the user to hover on it. On hover, this div pauses all animations and remains on screen.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

div - same thought about comment above regarding HTML tag names in text?


I had to do a lot of debugging in this; the use of counters and [this trick](https://www.youtube.com/shorts/ii-lSK2_Nu4) helped. I imagine the former is unlikely to come up day to day, however, I look forward to using the second.

If a div changes its position or height as a result of a `transform` being animated, it will not cause the `:hover` state to be recalculated, as shown above. It works for properties directly, so our game-ending logic still works. Finally, dimensions are important in css, while making my collision detection formula, I has some issue and realised it's because I was assigning things like `1px*1px` to something wanting a length.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CSS

I've never heard of CSS being used for styling, but anything is possible, I guess.

#### Why is the bird square?
I have a square bird for ornithological accuracy and not because I think it made collision detection easier, and I was too lazy to get back to it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove 'I think', as well as the last clause: 'and I was too lazy to get back to it.'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments