Python Asteroids on GitHub

We have some rudimentary fragments. Let’s make some better ones. I spend ages tweaking numbers.

For the regular fragments, which are currently just moving straight horizontal lines, I think I’d like something like this:

  1. Each fragment is a line segment between A and B long, with A and B around 6-10. None is too small, none too large;
  2. Each fragment rotates either clockwise or counter-clockwise, randomly 0.5;
  3. Rotation rate is between C and D revolutions per second, about 1-3 at a guess.

So we randomly roll A/2 <= L < B/2, get end points of left = (-L, 0), right = (L,0). Then we randomly roll 0 <= T < 360, and C <= dT <= D. When we draw, we draw from left.rotate(T) to right.rotate(T). When we tick, in addition to adjusting position we do T += dT*delta_time.

Oh, and let’s have dV range from maybe the raw fragment speed times (0.5 - 1.5).

I don’t think I want to TDD this, I’ll just tweak the numbers until I like it.

Experimentation makes me think that random directions are not good enough, we should make the bits explode at almost uniform directions around the clock. Too often the explosion looks one-sided.

I do this:

    def explosion_at(self, position):
        for i in range(5):
            angle = random.randrange(360)
            fragment = Fragment(position=position, angle=360*i/5)
            self.flyers.append(fragment)

The spread looks good, though not random enough.

I’m going to pause at this setting:

class ExplosionFleet:
    def explosion_at(self, position):
        for i in range(5):
            twiddle = random.randrange(-20, 20)
            fragment = Fragment(position=position, angle=360*i/5 + twiddle)
            self.flyers.append(fragment)

class Fragment:
    def __init__(self, position, angle=None, speed_mul=None):
        angle = angle if angle is not None else random.randrange(360)
        self.position = position
        length = random.uniform(6, 10)
        self.begin = Vector2(-length, 0)
        self.end = Vector2(length, 0)
        speed_mul = speed_mul if speed_mul is not None else random.uniform(0.25, 0.5)
        self.velocity = speed_mul*Vector2(u.FRAGMENT_SPEED, 0).rotate(angle)
        self.theta = random.randrange(0, 360)
        self.delta_theta = random.uniform(180, 360)*random.choice((1, -1))
        self.timer = Timer(u.FRAGMENT_LIFETIME, self.timeout)

That complicated init sets the explosion line half-length (I should call it that) to betseen 6 and 10, the speed between 0.25 and half of FRAGMENT_SPEED, and angle between 0 and 360. angle is the direction of motion.

It then sets the line angle randomly and the rate of rotation between half-around and all the way around per second, randomly left or right.

It looks like this:

explosions

Let’s sum up.

Summary

This was pure graphical twiddling, no fancy test-driving or anything like it. I am not finished with this, but it’s not bad. Commit: Ship explosion Fragments are more random than before. More to come.

It’s quite amazing how much time we can spend trying to make something look good. Presumably it’s worth it.

It was amusing if not actually worth the time. See you next time!