Frontend & Web

Deno Dino Runner: Obstacles & Collisions Added

The digital dinosaur is no longer just jogging aimlessly. This installment injects genuine peril with obstacles and the unforgiving logic of collision detection.

{# Always render the hero — falls back to the theme OG image when article.image_url is empty (e.g. after the audit's repair_hero_images cleared a blocked Unsplash hot-link). Without this fallback, evergreens with cleared image_url render no hero at all → the JSON-LD ImageObject loses its visual counterpart and LCP attrs go missing. #}
Screenshot of a dinosaur runner game showing a dinosaur character jumping over a cactus obstacle.

Key Takeaways

  • Stage 3 introduces obstacles and collision detection to the Deno-based dinosaur runner game, transforming it from a simple loop into an engaging challenge.
  • Obstacle spawning is managed by timers and rates, with a minimum rate ensuring difficulty increases as the game speed ramps up.
  • Collision detection is implemented using geometric comparisons of bounding boxes between the player and obstacles, triggering the game over state upon overlap.

The digital dinosaur, once content with its solitary jog across the canvas, now faces peril. We’re not just talking about a brisk pace anymore; we’re talking about concrete, unavoidable, game-ending obstacles.

This isn’t just another coding tutorial; it’s a dissection of how core game mechanics, the very essence of play, are woven into the fabric of a browser-based application using Deno. Stage 3 of this series moves beyond the basic loop and rendering, pushing the nascent dino runner toward actual challenge and consequence.

The Stakes Are Raised: Introducing Peril

Forget the abstract concept of ‘game state’ for a moment. Think about what makes a game a game. It’s the moment-to-moment tension, the risk-reward calculation, the binary outcome of success or failure. That’s precisely what this latest iteration aims to deliver. By introducing obstacles and the unforgiving mechanics of collision detection, the developer is building not just code, but a genuine experience.

Previously, our protagonist was merely a visual element on a screen. Now, it’s an actor in a drama, where a single misstep—a poorly timed jump—results in the abrupt end of its digital existence. It’s a fundamental shift from passive animation to active gameplay.

The developer’s task is to imbue this digital world with consequences. This involves not just drawing static objects, but managing their lifecycle, their movement, and crucially, their interaction with the player character. It’s a deep dive into the architecture of simple, yet engaging, game loops.

Engineering Obstacles and the Inevitable Collisions

At the heart of this stage lies a surprisingly sophisticated approach to object management. The DinoGame constructor, already a hub for game state, now burgeons with properties dedicated to the chaotic ballet of obstacles. We’re talking about this.obstacles = [], an array that will soon teem with spiky, menacing forms, and this.obstacleSpawnTimer alongside this.obstacleSpawnRate—the silent arbiters of when the next threat will materialize. This isn’t just about adding enemies; it’s about engineering the flow of the game, the pacing that keeps players on edge.

obstacleSpawnRate isn’t a static number. The introduction of this.minObstacleSpawnRate hints at a more dynamic difficulty curve, a subtle acknowledgment that as the player improves—as their score climbs—the game must evolve to meet them, or rather, to challenge them more aggressively. The game speed itself, a scalar derived from the player’s success, will dictate the cadence of these threats.

This is where the rubber meets the road for collision detection. It’s not magic; it’s geometry. The checkCollisions() method embodies this, performing a series of simple, yet critical, boolean comparisons. The core logic, elegantly distilled into a few lines, checks for overlap between the bounding boxes of the player and each obstacle. If this.dino.x < obstacle.x + obstacle.width (among other conditions), a collision is imminent. It’s a direct translation of physical reality into algorithmic logic.

Collision detection just compares the dino’s rectangle with each obstacle’s rectangle. If they overlap, the run ends.

This is the critical juncture. The gameOver() method, previously a mere placeholder, is now the consequence engine. It’s not just a function call; it’s the terminal state of the game loop when the player fails to navigate the engineered challenges.

The Deno Advantage: A Silent Contributor?

While the core mechanics here—game loops, collision detection, object spawning—are language-agnostic in principle, the choice of Deno is far from incidental. For a project focused on browser-based interactivity, Deno’s modern JavaScript/TypeScript runtime, its built-in tooling, and its secure-by-default approach offer a cleaner, more streamlined development experience compared to older environments. There’s less boilerplate, fewer dependencies to wrangle, and a more integrated ecosystem that’s particularly appealing for frontend-heavy projects where backend logic might also be handled, as hinted at by future stages involving databases and leaderboards.

The ability to use modern JavaScript features directly in the backend (or in this case, as the runtime for the browser game’s logic, even if the script eventually runs client-side) reduces friction. It’s about getting to the core game design problem faster, without being bogged down by tooling configuration. Deno aims to be that less intrusive, more intuitive environment, allowing developers to focus on the ‘how’ and ‘why’ of the game itself.

This series consistently emphasizes building the game logic first, and Deno facilitates that focus. As we progress towards more complex features like leaderboards and player profiles, this underlying architectural choice—a modern, batteries-included runtime—will likely prove its worth, allowing for a more cohesive full-stack development pipeline, even if the ‘stack’ is currently just a browser and a script.

What’s Next on the Digital Savannah?

The dinosaur runner is no longer just a toy. It’s a nascent system capable of posing a challenge. With obstacles in play and the specter of collision looming, the game has a pulse. Future installments promise to flesh out this experience further, introducing the social and competitive elements that turn simple games into enduring pastimes.

But for now, the core of ‘play’ has been established. The code isn’t just executing; it’s orchestrating moments of tension and, inevitably, moments of defeat. It’s the fundamental dance of challenge and response that defines interactive entertainment.


🧬 Related Insights

Written by
DevTools Feed Editorial Team

Curated insights, explainers, and analysis from the editorial team.

Worth sharing?

Get the best Developer Tools stories of the week in your inbox — no noise, no spam.

Originally reported by Deno Blog

Stay in the loop

The week's most important stories from DevTools Feed, delivered once a week.