Monday, December 3, 2012

Developing a Developer: Weekly Report 4


I've read the second part of the 17th chapter (which covers animations) and the entire 18th chapter (which covers input). This week I've decided to change the Reverse Engineering phase I did in the previous weeks. Now, either I improve the program (in the way I did making a new AI for Reversi) or I made my own program. In fact, I've done many pygame tests this week and I think the best way to show my current skills is through a video.







Rotating Ball


You can download the script here.

It's just a ball that bounces across the screen. The most interesting part about it is that I used polar coordinates for the mark that gives the impression of rotation and them I transform them into Cartesian coordinates in the following way:

x = r * cos(o)
y = r * sin(o)

x, y = Cartesian coordinates
r = distance from the centre of the ball to the centre of the small mark (which is a circle, by the way)
o = angle that constantly increments or decrements depending on the rotation direction



Spiral


You can download the script here.

OK, drawing a ball is easy, because Pygame has a built-in function called “pygame.draw.circle” which does the job for us. In order to draw a spiral, I've implemented a class which contains the formula of the spiral and remembers the value of the always incrementing angle in polar coordinates. Outside this class, in the game loop the angle is incremented and a straight line is drawn from the previous point to the new point calculated using the nextPoint method in the spiral class.

There are a few more sophistications that you can find in the source code, but I find particularly interesting the precision attribute in the spiral class. This attributes set the increment of the angle in polar coordinates and thus it will determine the smoothness of the line. It might be confusing, but since the precision attribute determines the increment of the angle, the slower it's value the higher the actual precision is going to be (counterintuitive, my mistake). See the pictures below.


Spiral: PRECISION = 1

Spiral: PRECISION = 0.005



Balls and Input



You can download the script here.

I basically take the rotating ball I've explained above and wrapped it into a class. Then, each time the player clicks on the screen, I call to the class constructor and create a new ball with new attributes. That way, I can have many rotating balls with different attributes such as speed, direction, rotation direction, etc. I confess I enjoy clicking and clicking insanely into the screen.

clickBall.py




Platforms


You can download the script here.

In this test I've had many headaches. It works with both input and collision detection in the context of a platforms game. The code is a little bit long to explain everything here, so I'll explain directly the most difficult function:


def controlFalling(self, rects):
    # control jumping
    if self.jumping:
        self.rect.top -= self.JUMPSPEED
        self.jumped += self.JUMPSPEED
        if self.jumped >= self.MAXJUMP:
            self.jumping = False
            self.falling = True

        # check if we hurt our head with some sort of ceiling
        collisionCeiling = 0
        for r in rects:
            if self.rect.colliderect(r):
                collisionCeiling = r.bottom

        # if this is the case, correct position
        if collisionCeiling > self.rect.top:
            self.rect.top = collisionCeiling
            self.jumping = False
            self.falling = True

    # fall
    else:
        self.rect.bottom += self.FALLINGSPEED

    # see if rects collide and detect current ground
    collisionGround = self.floorY
    for r in rects:
        if self.rect.colliderect(r):
            collisionGround = r.top

    # if the object is in the ground, correct it's position
    if collisionGround < self.rect.bottom:
        self.rect.bottom = collisionGround
        self.falling = False


 

There are two cases to consider.
a) The object is jumping
b) The object is falling

In both cases, I firstly move the object (upwards if it's jumping and backwards if it's falling) and then I see if it's colliding with something. If this is the case, I correct the position of the object, for I don't want to display it overlapping with anything. In the case of jumping, we also stop the jumping boolean attribute of the player, because the player must fall (although he could grab something in the ceiling and hang... Mmmm... Maybe for another test).

1 comment: