Piader – simple game – part 2

Some time passed and second part is here 🙂 This time we will arm our enemy. Lets give him bombs and ability to drop them !

Bomb will drop vertically. One bomb or more ? We will control this with variable, we will also implement drop rate.

Download source code

Bombs

First create a starting bomb class:

import item


class Bomb(item.Item):
    """Bomb"""
    def __init__(self, x, y):
        """init bomb"""
        self.pos_x = x
        self.pos_y = y
        self.sprite = "@"

    def tick(self):
        """action in tick"""
        self.pos_y += 1

    def get_position(self):
        """enemy position"""
        return self.pos_x, self.pos_y

    def get_sprite(self):
        """get sprite"""
        return self.sprite

Next lets change enemy class.

We need few extra parameters in it, for keeping current number of bombs and max no of bombs. We will also keep percentage chance of dropping bomb.

Modify __init__ , add self.bombs_current = 0, self.bombs_max = 1 and self.bomb_chance = 20.

Next we need to add drop action. But first enemy needs to have ability to add new object to objects dict. But this dict is available only in main loop, so need to pass it. Modify constructor by adding another parameter objects to __init__.

New constructor:

    def __init__(self, x, y, max_x, objects):
        """init enemy"""
        self.pos_x = x
        self.pos_y = y
        self.max_x = max_x
        self.sprite = "<*>"
        self.bombs_current = 0
        self.bombs_max = 1
        self.objects = objects
        self.bomb_chance = 200

and new call (in Game class):

    self.objects.append(enemy.Enemy(2, 0, self.width, self.objects))

Change enemy AI by adding drop chance in function tick.

if self.bombs_max > self.bombs_current and random.randint(1, 100) < self.bomb_chance:
    self.bombs_current += 1
    self.objects.append(bomb.Bomb(self.pos_x + 1, self.pos_y))

Run game now. Our DMO will drop bomb, it will reach bottom of screen and script will crash.

Not good.

Second screen and bomb discard

Problem is in draw function in main Piader class. We are using only one screen, time to fix this. Case is simple, if y is in <0, 3> draw on first screen. If <4, 5> draw on second. But there is one catch, top screen is wider than bottom one. So if x in <0, 1> or <17, 19> discard object. And of course when y > 5 discard it too.

Our new draw function will look like this:

def draw(self, item):
        &quot;&quot;&quot;draw sprite on screen&quot;&quot;&quot;
        lcd_no = 0
        (x, y) = item.get_position()

        if y &gt; 5:
            self.objects.remove(item)
            return

        if y &gt; 3:
            x -= 2
            if x &lt; 0 or x &gt; 15:
                self.objects.remove(item)
                return
            lcd_no = 1
            y -= 4
                    
        lcd = self.lcds[lcd_no]
        lcd.write(item.get_sprite(), x, y)
        lcd.flush()


We also need to add buffer_clear() and flush() in game tick function.

There is one more catch. Bomb is connected with DMO, so when bombs is discarder, DMO must know about it. We will do it by passing caller reference to bomb class. We need to add some event handler, open Item class and add new abstract function:

    def event_discard(self):
        &quot;&quot;&quot;called when onject is discarded&quot;&quot;&quot;
        raise NotImplementedError(&quot;event_discard not implemented&quot;)

Now implement it in Bomb class:

    def event_discard(self):
        &quot;&quot;&quot;discard bomb, decrease DMO bomb counter&quot;&quot;&quot;
        self.dmo.bombs_current -= 1

Finally go back to draw function in Game class and change:

    self.objects.remove(item)

to

    self.objects.remove(item)
    item.event_discard()

Now when you run script it should work. Enemy will drop one bomb. Only after bomb is discarded another will be dropped.

Stop! Jenkins time !

We have some stable source of another part of our game. Its good idea to run Jenkins test.

This time thing that I messed up were:
– variable names – x and y, too short
– too many attributes in enemy class – unfixed, not important problem for now

 Summary

In part 2 we have:
– add bomb
– add second screen
– fixed drawing
– add discard event to abstract Item class
– implement bomb discard event
– DMO now can drop a bomb

Download source code.

Advertisements

2 comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s