Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

My game is a top down 2D shmup programmed in a functional style. I\'m struggling

ID: 647214 • Letter: M

Question

My game is a top down 2D shmup programmed in a functional style. I'm struggling with abstracting the code that is responsible for animating the projectiles. There are many types of guns with many types of projectiles. Here are a few that are very different:

A standard gun that shoots a bullet that travels a distance over time.
A laser that shoots a line that goes from start to end in an instant.
This is different from the standard gun projectile because its projectile doesn't travel over time. It's drawn as a line. Unlike the standard gun, the laser beam animation should last after the projectile hits something.
A psychic shockwave that forms a circular blast wave around your body and damages anything in range. The size of the circle is variable.
This is different from the standard gun projectile because its size is variable and circular. Also, it doesn't move. I'm struggling on how I can use a sprite sheet for this. It seems like the best way might be to draw a circle on the screen. All the other projectiles are sprites.
This is different from the laser because it's a circular shape rather than a line.
If this were object oriented, the path I'd take is straight-forward: I'd create an Animation class that is responsible for animating itself. The client code would have no idea how the animation occurs, it would just pass in the necessary objects in order to get it done.

But I'm not sure how to do something like this in a functional style. Right now I represent everything as data. A projectile contains animation data like so:

projectile: {
type: "laser"
animation: ...
}
But what feels very wrong is I have to have one switch to create this projectile, and then in my rendering code, I have to have another switch to decide how to use the data to animate it. EG:

if projectile.type is "standard gun"
rotateBulletTowardsVelocityAndAnimateAtPosition(projectile)
if projectile.type is "laser"
rotateLaserTowardsTargetAndAnimateFromStartToTarget(projectile)
if projectile.type is "psychic shockwave"
drawCircleAroundProjectilePosition(projectile)
This doesn't seem very abstract to me. What's a better way to code this while still being functional about it?

Explanation / Answer

I think you need to invert your dependencies here - those different animation types can be written as standalone functions that given a location, render an animation in that location (or returns an animation-renderer that will execute at that location that you may execute later).

Once you have implemented these rendering functions, what you need to do is have them passed down through the layers. I would put them into your players state such that they have an active gun, and everytime they switch guns, you get a new player state with the new shooting renderer, that renderer can be handed to whatever needs it when they try and shoot.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at drjack9650@gmail.com
Chat Now And Get Quote