Mastodon

25.12.12

My coding project, part III

Wherever my nose points at

Now that I had finally fixed the rotation and found out where the hell it's pointing at, the last of the unimplemented basic functions was the movement. My first attempt was, especially in hindsight, ridiculous: if the angle was pointing to one of the cardinal directions, the full acceleration was applied on one axis - if somewhere in between, the acceleration was applied to the two closest ones. While testing it first looked nice, but in a while I noticed that "Heeeeyyy.. this thing jerks around when it's turning and accelerating. It looks pretty odd now". Even the slightest difference from a 3π/2 angle made the polygon accelerate at full speed towards the closest intermediate direction. Whoops.

A bit more realistic change of speed

After a very short but intense moment of screen-staring a lamp went off in my head: if I went and used the same damn trigonometrical functions that told me where thing was facing but using the known speed and angle to get the Δx and Δy values, I'd be done! So, the same trick but opposite direction. Luckily it didn't take me more than a couple of minutes to come up with this.

tempspeed = Vector(self.speed.x, self.speed.y)
dy = math.fabs((math.sin(self._angle))*self._acceleration)
dx = math.fabs((math.cos(self._angle))*self._acceleration)

# ...


Of course this isn't all, the method still needs to check the heading and decide if the Δx and Δy are positive or negative. With that piece of information the acceleration can be applied properly and to the right direction. The main thing is that it looks good to me right now.

Particle effects!

It gets pretty old pretty soon, moving a simple Shape. So I worked on a Star Control (or Auts or V-Wing or Wings) style acceleration effect. Without spending more than a few seconds on thinking where the engines would be located, I just marked* the bottom edges of the triangle shape as the engine points. Now whenever the acceleration is triggered, a set of tiny box Shapes are dropped at the current coordinates. These Shapes fade away slowly and die away after a few cycles. While I was playing with that I made a silly warping method, where the polygon is relocated in the middle of the game area. At the previous coordinates a set of eight particles are created with speeds set so that it looks like an explosion. It's a funny effect even if I say so myself. That was going to be used to do explosions in the game for real, not teleporting 8)

*) I was farsighted this time. The initial version just takes a set of coordinates for the engine exhaust points, as many as I want, so I can do however I want later. More or less. Perhaps this helps me avoid a couple of rounds of "refactoring because stupid".

Adding some friends on the screen

All in all, what do you do with an almost triangle shaped thingamagick on a 2d space if it's there alone? You'd get bored out of your skull pretty quickly, I tell you. So my possibly retarded idea should be clear to everyone: I'm going to dump in some asteroids! 

I was pretty excited when I got my eight-pointed semirandom shapes on the screen in four different sizes, spinning slowly around either clock- or counterclockwise and after a couple of iterations they even flew through the screen on their merry ways. That was an awesome moment.

Swoosh!
At least I was damn proud of that.

18.12.12

My coding project, part II

I think I said the last time that I've never tried to do anything graphic for real, unless you count those TurboC++ tests that just vomit squares and circles on the screen (no, they do not count). So my first problem  jumped out already. It was simple to get my four-pointed polygon in the middle of my surface, but moving it...

I'm going to mumble about my "aha!" moments and ponderings as I remember them and when they have some kind of point to them. I don't guarantee a good quality, just like I never do ;)

Position, rotate, relocate, draw

So my first version used a set of hardcoded coordinates, yay! I thought that it's a good starting point, but oh, how wrong I was. Maybe the issue was within my own rotation methods and it'd all been awesome if my methods had been fine, but maybe it would've sucked anyway. The initial situation was rendered prettily but a single rotation distorted the form beyond recognition.

Via the zero point

From somewhere I came up with an idea (and after talking to a yet another coworker of mine my guess was proven correct) where all the shapes should always be initialized around the (0,0) point. This way the rotation of any polygon would work the same no matter where on the 2d space they are.
So first you always set up the vertices in the same places, then shift the coordinate points to the actual positions where they'll be rendered on the screen. A really simple and I guess it's a childishly basic thing, but who would've told me?

Rotating the 2d coordinates

My mathematical studies are years old at best and I have to admit that in elementary school (even longer ago) I was one of those fucking annoying brats who declared that I would never need maths or trigonometry after the 9th grade. Oh yeah, once again we see that reality doesn't always agree :)
After a couple of weird and stupid "I'll do this myself"-kind of attempt I encountered something called affine transformation. That was a nice, handy thing and the implementation was just about 1:1 with what my dear friend Wikipedia told me. You just drop it each vertex of the polygon at a time and the desired rotation angle (obviously this is always the same for a single shape), this beast simply returns the new coordinates for the given vertex.

def rotate(self, angle):
        rotated_points = []
        for point in self._points:
            new_point = self.affine_transform(Vector(point.x, point.y), angle)
            rotated_points.append(new_point)       
        return rotated_points


def affine_transform(self, point, angle):
        temp_x = ((point.x * math.cos(angle)) + (point.y * math.sin(angle)))
        temp_y = ((-point.x * math.sin(angle)) + (point.y * math.cos(angle)))
        return Vector(temp_x, temp_y )



Hah! The next issues I encountered were the angle (I was, again, making a mess with degrees and radians, but that was because of my infinite stupidity) and the movement. The movement was a bigger issue and took quite a bit longer to fix. Pretty soon I was able to rotate my more-or-less-triangular shape around it's own z-axis but if I tried to accelerate, it started flying towards the top-right corner and beyond. If I tried to rotate and accelerate, it did the same but while corkscrewing carelessly. I was baffled.

How do I calculate where my polygon is facing? 

As my stupid mistake number 74 I forgot my hardcoded "draw this thing in the middle of the surface" -values and another mistake was that the calculate_angle always returned the exact same value for my Object. Somehow I had ended up trying to calculate the facing of my polygon by its sides (because it's basically a triangle). I guess it was otherwise a good idea but it just didn't work here at all.

After a bit of googling and more light headscratching the solution was much more simple than I had thought. Or at least it felt like it for someone as stupid as I am. Because the center point's coordinates are known, as well as the tip's coordinates, you can just take the distance between the coordinate points on  x and y axises (Δx and Δy) and feed that to arctan to get the angle in radians.


I guess that clarifies a bit... or not :p


def calculate_angle(self, center, nose):
        dx = center.x - nose.x
        dy = center.y - nose.y       
        radian_angle = math.atan2(dy, dx)
        return radian_angle


Geniously simple, I say. At this point it looks like that no one can read one word more of this crap on one go. Therefore I'll continue this topic on the next iteration of the Project Mumblings.

11.12.12

Some background for my coding project

Background

I guess "everyone" who has ever programmed anything at all has entertained the idea of making their own game. A couple of decades ago I fooled around with QuickBasic that came with the 486 machine, but nothing spectacular happened. The biggest problem I encountered was that I didn't know anything and all I had was the (somewhat awful) manual and I didn't know where to look for more information.
For some odd reason, most likely my laziness,  I never started poking at game making even when I was actually studying programming and even learned something. From time to time the thought came to me. Just for the fun of it, if nothing else.

Python - Pygame

Some years ago a coworker of mine hinted of this Ruby-based Shoooes thing that I actually wanted to try out but as usual, I didn't get anything mentionable done. That attempt, like so many others that started with the usual "Hey, let's try this thing!"-enthusiasm, died  away. Maybe a year, one and a half ago I encountered Pygame in my rss feeds, a game developing library for Python. To honor the traditions I did give it a try but just left it. I blame it on the lack of good (= implementable) ideas. Drawing circles and squares doesn't entertain for a horribly long time :p

for idea in ideas:

Because coming up with 100% original ideas isn't that simple, what then? Copy others or climb on the shoulders of those giants and wave your arms.
Another of my coworkers had started working on his Roguelike, so so much for that one, even though I wasn't going to do anything under the usual fantasy theme unlike him. In my childhood I spent countless hours on desperately difficult Xenon 2 and years later I got hooked on awesome Tyrian.

Xenon II: Megablast

In that sense I was pretty interested in working on a classic horizontal/vertical scroller shoot'em up. With these my huge issue (before I even started checking anything or wrote even a single line of code) was the levels and all that, so I left those ideas in my ideas box, with the rest of the filth I've conjured up during my years.


Tyrian
Sandboxes, openness, freedom of choice and general randomness (= everything doesn't always go exactly the same way and in the same order) have been things I've liked in games. A total lack of options and especially (tight) time limits are something that make me furious. With this kind of a mindset I was going to have some problems, but you have to start somewhere, no?

Twist!

After all this I approached the whole issue from the opposite end. From my previous top-down to bottom-up -like approach. Not really conciously but half by accident. I was just happily poking around, doing this, seeing what kind of things I could actually do with Pygame and how to do those things.
With a couple of silly coordinate points and a bit of headscratching the pygame.draw.Polygon(...) brought some fascinating things on my drawing surface. "Hey, I could actually go and move that piece based on the keyboard events! How did that work...."

What weirdness am I working on? I'll tell you more next week.
I know I'm an evil teaser and I enjoy it. Muahahhahahaa!

4.12.12

Damage case

A stupid head makes the whole body ache. Or something like that.

What does one do with finger joints anyway?


The story in its shortest form: I broke a plate in my hands and ended up getting stitched. Of course the worst damages I took to my right thumb, so the building project is on a dry dock for a short while at least. Why so? Because after the stitches can be removed it's just about the time for my winter vacation and all the hectic busyness it brings so my modeling time runs low in general. We'll see how it all goes.