Thursday, March 28, 2024
HomePythonSqueezing House Invaders onto the BBC micro:bit's 25 pixels

Squeezing House Invaders onto the BBC micro:bit’s 25 pixels


How a lot recreation are you able to match into 25 pixels? Fairly a bit it seems.

It is a mini clone of arcade traditional House Invaders for the BBC micro:bit microcomputer.
Utilizing the accelerometer and two buttons for enter, to can beat off wave after wave of aliens
that advance in direction of you.

The display limits the element we are able to handle: every sprite takes up a single pixel on the display.
The aliens do not drop bombs, as you’d have solely 1-2 pixels to react. The buildings/defences at
the underside are lacking, as they’d serve no objective with out the bombs. However it’s nonetheless a variety of enjoyable!

The aliens advance down the display once they attain the sting. Some waves cowl all the width
of the display and can transfer down right away — shoot the perimeters to gradual them down.

The controls are as follows —

  • Tilt left/proper to regulate your fighter, tilt additional to maneuver quicker.
  • Button A – shoot gun
  • Button B – hearth thermonuclear bomb

Bomb? Sure! On this model you get a giant bomb to avoid wasting your self when issues get tough. The blast wipes out 50% of the aliens at present on display, however leaves you blinded for a few strikes. Use properly!

The sport is written in MicroPython. You probably have a BBC micro:bit simply copy and paste the code into the Python net editor
after which flash it to your machine.

python

from microbit import *
import random

MIN_COORD, MAX_COORD = 0, 4  # Vary of legitimate coordinates for the show.
MAX_MISSILES = 5             # Variety of missiles participant can have on display directly.
DIFFICULTY_INCREASE = 0.25   # Enhance in issue between waves.

ALIEN_START_POSITIONS = [
    # Each row is a unique start pattern, defined as tuples of x,y coordinates.
    [(1, 0), (2, 0), (3, 0), (1, 1), (2, 1), (3, 1)],
    [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (2, 1)],
    [(1, 0), (2, 0), (3, 0), (0, 1), (2, 1), (4, 1)],
    [(1, 0), (2, 0), (3, 0), (1, 1), (3, 1), (2, 2)],
]

def wait_for_button():
    # Watch for both button to be pressed.
    whereas not (button_a.was_pressed() or button_b.was_pressed()):
        sleep(1)

def transfer(sprite, x, y):
    """
    Transfer the given sprite by the given x & y quantities.
    """
    return sprite[0] + x, sprite[1] + y

def in_bounds(pos):
    """
    Return True if the place is inside the legitimate display coordinates.
    """
    if pos[0] < MIN_COORD or pos[0] > MAX_COORD:
        return False
    if pos[1] < MIN_COORD or pos[1] > MAX_COORD:
        return False
    return True


class Sport:
    """
    Sport class holds the present recreation state.
    """

    def reset(self):
        # Preliminary values
        self.x = 2  # Participant x coordinate begin (center).
        self.xf = 2.0  # x coordinate float, permits us to make use of tilt for transfer pace.

        self.missiles = []  # Lively missles on display.
        self.aliens = []    # Lively aliens on display.
        self.alien_velocity_x = 1  # Horizontal pace of aliens.

        self.bombs = 3        # Variety of bombs the participant has.
        self.active_bomb = 0  # Countdown timer for the present lively bomb.

        self.rating = 0        # Participant rating.

        self.tick = 0         # Sport loop tick.
        self.degree = 0        # Present recreation degree.
        self.issue = 20  # Is in reverse, decrement to extend.


    def handle_input(self):
        self.tick += 1
        acc_x = accelerometer.get_x()

        # Use the accelerometer / 512 so the participant can transfer x at pace by tilting extra.
        if acc_x < 0:
            self.xf += acc_x / 512
        if acc_x > 0:
            self.xf += acc_x / 512

        # Constrain to the display dimensions.
        if self.xf > MAX_COORD:
            self.xf = MAX_COORD

        if self.xf < MIN_COORD:
            self.xf = MIN_COORD

        self.x = int(self.xf)

        if button_a.was_pressed():
            # Add missile, at gamers present x place.
            self.missiles.append((self.x, 4))

        if button_b.was_pressed() and self.bombs:
            # Fireplace bomb. Flash + take away half the aliens.
            # randint(0,1) can be 50% 1, 50% 0 ..if 0 (False) alien can be skipped.
            self.aliens = [alien for alien in self.aliens if random.randint(0,1)]
            self.active_bomb = 3 # Reduces 1 per tick. Display screen at 3 * shiny.
            self.bombs -= 1

    def add_aliens(self):
        # We have to copy, or we'll me modifying the unique lists.
        alien_position = self.degree % len(ALIEN_START_POSITIONS)
        self.aliens = ALIEN_START_POSITIONS[alien_position].copy()
        self.tick = 0

    def advance_aliens(self):
        """
        If aliens have reached the display edge, advance all of them downwards.
        """
        for alien in self.aliens:
            if (
                (self.alien_velocity_x == -1 and alien[0] == MIN_COORD) or
                (self.alien_velocity_x == +1 and alien[0] == MAX_COORD)
            ):
                # If any aliens are on the far edge, increment y, and reverse.
                self.alien_velocity_x = -self.alien_velocity_x
                self.aliens = [move(alien, 0, 1) for alien in self.aliens]
                # This could occur if indifferent alien slips previous backside.
                self.aliens = [alien for alien in self.aliens if in_bounds(alien)]
                return True  # No different transfer this time.

    def aliens_can_move(self):
        if self.tick > self.issue:
            self.tick = 0
            return True

    def move_aliens(self):
        # Transfer aliens horizontally.
        self.aliens = [move(alien, self.alien_velocity_x, 0) for alien in self.aliens]

    def move_missiles(self):
        # Advance positions of missiles (upwards)
        self.missiles = [move(missile, 0, -1) for missile in self.missiles]
        self.missiles = [missile for missile in self.missiles if in_bounds(missile)]

    def check_collisions(self):
        for missile in self.missiles[:]:  # Iterate a duplicate.
            if missile in self.aliens:
                # Since we retailer by coordinates, we are able to take away utilizing the missile coords.
                self.aliens.take away(missile)
                self.missiles.take away(missile)
                self.rating += 1

        if not self.aliens:
            # Wave full? Enhance issue (decrement) and add new aliens.
            self.issue -= DIFFICULTY_INCREASE
            self.degree += 1
            self.bombs += 1
            self.add_aliens()

    def draw(self):
        show.clear()

        if self.active_bomb:
            # Bomb is drawn as an overlay of steadily decaying mild.
            for dx in vary(MAX_COORD + 1):
                for dy in vary(MAX_COORD + 1):
                    show.set_pixel(dx, dy, self.active_bomb * 3)

            # Decrement so subsequent draw is fainter.
            self.active_bomb -= 1

        # Draw all of the aliens.
        for pos in self.aliens:
            show.set_pixel(pos[0], pos[1], 9)

        # Draw all the present participant missles.
        for pos in self.missiles:
            show.set_pixel(pos[0], pos[1], 5)

        # Draw the gamers spaceship.
        show.set_pixel(self.x, 4, 9)

    def game_over(self):
        return (self.x, 4) in self.aliens



recreation = Sport() # Create our recreation object.


whereas True:

    show.present(Picture.TARGET)
    wait_for_button()

    recreation.reset() # Reset the sport state.
    recreation.add_aliens()

    # Principal loop
    whereas not recreation.game_over():
        recreation.handle_input()
        if recreation.aliens_can_move():
            if not recreation.advance_aliens():
                recreation.move_aliens()
        recreation.move_missiles()
        recreation.draw()
        recreation.check_collisions()

        sleep(100)

    show.present(Picture.ANGRY)
    sleep(1000)
    show.scroll(recreation.rating)

You may alter the issue by adjusting the issue setting, or pace. You could possibly additionally modify the bomb to solely destroy 33% of aliens, or much less, to make it much less of a sure life-saver.

The video under exhibits a brief playthrough and finish of recreation rating.

Have enjoyable!

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments