Tag Archives: How-to

Code Robotron: 2084’s twin-stick action | Wireframe #38

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/code-robotron-2084s-twin-stick-action-wireframe-38/

News flash! Before we get into our Robotron: 2084 code, we have some important news to share about Wireframe: as of issue 39, the magazine will be going monthly.

The new 116-page issue will be packed with more in-depth features, more previews and reviews, and more of the guides to game development that make the magazine what it is. The change means we’ll be able to bring you new subscription offers, and generally make the magazine more sustainable in a challenging global climate.

As for existing subscribers, we’ll be emailing you all to let you know how your subscription is changing, and we’ll have some special free issues on offer as a thank you for your support.

The first monthly issue will be out on 4 June, and subsequent editions will be published on the first Thursday of every month after that. You’ll be able to order a copy online, or you’ll find it in selected supermarkets and newsagents if you’re out shopping for essentials.

We now return you to our usual programming…

Move in one direction and fire in another with this Python and Pygame re-creation of an arcade classic. Raspberry Pi’s own Mac Bowley has the code.

Robotron: 2084 is often listed on ‘best game of all time’ lists, and has been remade and re-released for numerous systems over the years.

Robotron: 2084

Released back in 1982, Robotron: 2084 popularised the concept of the twin-stick shooter. It gave players two joysticks which allowed them to move in one direction while also shooting at enemies in another. Here, I’ll show you how to recreate those controls using Python and Pygame. We don’t have access to any sticks, only a keyboard, so we’ll be using the arrow keys for movement and WASD to control the direction of fire.

The movement controls use a global variable, a few if statements, and two built-in Pygame functions: on_key_down and on_key_up. The on_key_down function is called when a key on the keyboard is pressed, so when the player presses the right arrow key, for example, I set the x direction of the player to be a positive 1. Instead of setting the movement to 1, instead, I’ll add 1 to the direction. The on_key_down function is called when a button’s released. A key being released means the player doesn’t want to travel in that direction anymore and so we should do the opposite of what we did earlier – we take away the 1 or -1 we applied in the on_key_up function.

We repeat this process for each arrow key. Moving the player in the update() function is the last part of my movement; I apply a move speed and then use a playArea rect to clamp the player’s position.

The arena background and tank sprites were created in Piskel. Separate sprites for the tank allow the turret to rotate separately from the tracks.

Turn and fire

Now for the aiming and rotating. When my player aims, I want them to set the direction the bullets will fire, which functions like the movement. The difference this time is that when a player hits an aiming key, I set the direction directly rather than adjusting the values. If my player aims up, and then releases that key, the shooting will stop. Our next challenge is changing this direction into a rotation for the turret.

Actors in Pygame can be rotated in degrees, so I have to find a way of turning a pair of x and y directions into a rotation. To do this, I use the math module’s atan2 function to find the arc tangent of two points. The function returns a result in radians, so it needs to be converted. (You’ll also notice I had to adjust mine by 90 degrees. If you want to avoid having to do this, create a sprite that faces right by default.)

To fire bullets, I’m using a flag called ‘shooting’ which, when set to True, causes my turret to turn and fire. My bullets are dictionaries; I could have used a class, but the only thing I need to keep track of is an actor and the bullet’s direction.

Here’s Mac’s code snippet, which creates a simple twin-stick shooting mechanic in Python. To get it working on your system, you’ll need to install Pygame Zero. And to download the full code and assets, go here.

You can look at the update function and see how I’ve implemented a fire rate for the turret as well. You can edit the update function to take a single parameter, dt, which stores the time since the last frame. By adding these up, you can trigger a bullet at precise intervals and then reset the timer.

This code is just a start – you could add enemies and maybe other player weapons to make a complete shooting experience.

Get your copy of Wireframe issue 38

You can read more features like this one in Wireframe issue 38, available directly from Raspberry Pi Press — we deliver worldwide.

And if you’d like a handy digital version of the magazine, you can also download issue 38 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Code Robotron: 2084’s twin-stick action | Wireframe #38 appeared first on Raspberry Pi.

Code a homage to Lunar Lander | Wireframe #37

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/code-a-homage-to-lunar-lander-wireframe-37/

Shoot for the moon in our Python version of the Atari hit, Lunar Lander. Mark Vanstone has the code.

Atari’s cabinet featured a thrust control, two buttons for rotating, and an abort button in case it all went horribly wrong.

Lunar Lander

First released in 1979 by Atari, Lunar Lander was based on a concept created a decade earlier. The original 1969 game (actually called Lunar) was a text-based affair that involved controlling a landing module’s thrust to guide it safely down to the lunar surface; a later iteration, Moonlander, created a more visual iteration of the same idea on the DEC VT50 graphics terminal.

Given that it appeared at the height of the late-seventies arcade boom, though, it was Atari’s coin-op that became the most recognisable version of Lunar Lander, arriving just after the tenth anniversary of the Apollo 11 moon landing. Again, the aim of the game was to use rotation and thrust controls to guide your craft, and gently set it down on a suitably flat platform. The game required efficient control of the lander, and extra points were awarded for parking successfully on more challenging areas of the landscape.

The arcade cabinet was originally going to feature a normal joystick, but this was changed to a double stalked up-down lever providing variable levels of thrust. The player had to land the craft against the clock with a finite amount of fuel with the Altitude, Horizontal Speed, and Vertical Speed readouts at the top of the screen as a guide. Four levels of difficulty were built into the game, with adjustments to landing controls and landing areas.

Our homage to the classic Lunar Lander. Can you land without causing millions of dollars’ worth of damage?

Making the game

To write a game like Lunar Lander with Pygame Zero, we can replace the vector graphics with a nice pre-drawn static background and use that as a collision detection mechanism and altitude meter. If our background is just black where the Lander can fly and a different colour anywhere the landscape is, then we can test pixels using the Pygame function image.get_at() to see if the lander has landed. We can also test a line of pixels from the Lander down the Y-axis until we hit the landscape, which will give us the lander’s altitude.

The rotation controls of the lander are quite simple, as we can capture the left and right arrow keys and increase or decrease the rotation of the lander; however, when thrust is applied (by pressing the up arrow) things get a little more complicated. We need to remember which direction the thrust came from so that the craft will continue to move in that direction even if it is rotated, so we have a direction property attached to our lander object. A little gravity is applied to the position of the lander, and then we just need a little bit of trigonometry to work out the movement of the lander based on its speed and direction of travel.

To judge if the lander has been landed safely or rammed into the lunar surface, we look at the downward speed and angle of the craft as it reaches an altitude of 1. If the speed is sufficiently slow and the angle is near vertical, then we trigger the landed message, and the game ends. If the lander reaches zero altitude without these conditions met, then we register a crash. Other elements that can be added to this sample are things like a limited fuel gauge and variable difficulty levels. You might even try adding the sounds of the rocket booster noise featured on the original arcade game.

Engage

The direction of thrust could be done in several ways. In this case, we’ve kept it simple, with one directional value which gradually moves in a new direction when an alternative thrust is applied. You may want to try making an X- and Y-axis direction calculation for thrust so that values are a combination of the two dimensions. You could also add joystick control to provide variable thrust input.

Here’s Mark’s code snippet, which creates a simple shooting game in Python. To get it working on your system, you’ll need to install Pygame Zero. And to download the full code and assets, go here.

Get your copy of Wireframe issue 36

You can read more features like this one in Wireframe issue 37, available directly from Raspberry Pi Press — we deliver worldwide.

And if you’d like a handy digital version of the magazine, you can also download issue 37 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Code a homage to Lunar Lander | Wireframe #37 appeared first on Raspberry Pi.

Make a Side Pocket-esque pool game | Wireframe #36

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/make-a-side-pocket-esque-pool-game-wireframe-36/

Recreate the arcade pool action of Data East’s Side Pocket. Raspberry Pi’s own Mac Bowley has the code.

In the original Side Pocket, the dotted line helped the player line up shots, while additional functions on the UI showed where and how hard you were striking the cue ball.

Created by Data East in 1986, Side Pocket was an arcade pool game that challenged players to sink all the balls on the table and achieve a minimum score to progress. As the levels went on, players faced more balls in increasingly difficult locations on the table.

Here, I’ll focus on three key aspects from Side Pocket: aiming a shot, moving the balls, and handling collisions for balls and pockets. This project is great for anyone who wants to dip their toe into 2D game physics. I’m going to use the Pygame’s built-in collision system as much as possible, to keep the code readable and short wherever I can.

Making a pool game

Before thinking about aiming and moving balls, I need a table to play on. I created both a border and a play area sprite using piskelapp.com; originally, this was one sprite, and I used a rect to represent the play area (see Figure 1). Changing to two sprites and making the play area an actor made all the collisions easier to handle and made everything much easier to place.

Figure 1: Our table with separate border. You could add some detail to your own table, or even adapt a photograph to make it look even more realistic.

For the balls, I made simple 32×32 sprites in varying colours. I need to be able to keep track of some information about each ball on the table, such as its position, a sprite, movement, and whether it’s been pocketed or not – once a ball’s pocketed, it’s removed from play. Each ball will have similar functionality as well – moving and colliding with each other. The best way to do this is with a class: a blueprint for each ball that I will make copies of when I need a new ball on the table.

class Ball:
def __init__(self, image, pos):
self.actor = Actor(image, center=pos, anchor=(“center”, “center”))
self.movement = [0, 0]
self.pocketed = False

def move(self):
self.actor.x += self.movement[0]
self.actor.y += self.movement[1]
if self.pocketed == False:
if self.actor.y < playArea.top + 16 or self.actor.y > playArea.bottom-16:
self.movement[1] = -self.movement[1]
self.actor.y = clamp(self.actor.y, playArea.top+16, playArea.bottom-16)
if self.actor.x < playArea.left+16 or self.actor.x > playArea.right-16:
self.movement[0] = -self.movement[0]
self.actor.x = clamp(self.actor.x, playArea.left+16, playArea.right-16)
else:
self.actor.x += self.movement[0]
self.actor.y += self.movement[1]
self.resistance()

def resistance(self):
# Slow the ball down
self.movement[0] *= 0.95
self.movement[1] *= 0.95

if abs(self.movement[0]) + abs(self.movement[1]) < 0.4:
self.movement = [0, 0]

The best part about using a class is that I only need to make one piece of code to move a ball, and I can reuse it for every ball on the table. I’m using an array to keep track of the ball’s movement – how much it will move each frame. I also need to make sure it bounces off the sides of the play area if it hits them. I’ll use an array to hold all the balls on the table.

To start with, I need a cue ball:

balls = []
cue_ball = Ball(“cue_ball.png”, (WIDTH//2, HEIGHT//2))
balls.append(cue_ball)

Aiming the shot

In Side Pocket, players control a dotted line that shows where the cue ball will go when they take a shot. Using the joystick or arrow buttons rotated the shot and moved the line, so players could aim to get the balls in the pockets (see Figure 2). To achieve this, we have to dive into our first bit of maths, converting a rotation in degrees to a pair of x and y movements. I decided my rotation would be at 0 degrees when pointing straight up; the player can then press the right and left arrow to increase or decrease this value.

Figure 2: The dotted line shows the trajectory of the ball. Pressing the left or right arrows rotates the aim.

Pygame Zero has some built-in attributes for checking the keyboard, which I’m taking full advantage of.

shot_rotation = 270.0 # Start pointing up table
turn_speed = 1
line = [] # To hold the points on my line
line_gap = 1/12
max_line_length = 400
def update():
global shot_rotation

## Rotate your aim
if keyboard[keys.LEFT]:
shot_rotation -= 1 * turn_speed
if keyboard[keys.RIGHT]:
shot_rotation += 1 * turn_speed

# Make the rotation wrap around
if shot_rotation > 360:
shot_rotation -= 360
if shot_rotation < 0:
shot_rotation += 360

At 0 degrees, my cue ball’s movement should be 0 in the x direction and -1 in y. When the rotation is 90 degrees, my x movement would be 1 and y would be zero; anything in between should be a fraction between the two numbers. I could use a lot of ‘if-elses’ to set this, but an easier way is to use sin and cos on my angle – I sin the rotation to get my x value and cos the rotation to get the y movement.

# The in-built functions need radian
rot_radians = shot_rotation * (math.pi/180)

x = math.sin(rot_rads)
y = -math.cos(rot_rads)
if not shot:
current_x = cue_ball.actor.x
current_y = cue_ball.actor.y
length = 0
line = []
while length < max_line_length:
hit = False
if current_y < playArea.top or current_y > playArea.bottom:
y = -y
hit = True
if current_x < playArea.left or current_x > playArea.right:
x = -x
hit = True
if hit == True:
line.append((current_x-(x*line_gap), current_y-(y*line_gap)))
length += math.sqrt(((x*line_gap)**2)+((y*line_gap)**2) )
current_x += x*line_gap
current_y += y*line_gap
line.append((current_x-(x*line_gap), current_y-(y*line_gap)))

I can then use those x and y co-ordinates to create a series of points for my aiming line.

Shooting the ball

To keep things simple, I’m only going to have a single shot speed – you could improve this design by allowing players to load up a more powerful shot over time, but I won’t do that here.

shot = False
ball_speed = 30


## Inside update
## Shoot the ball with the space bar
if keyboard[keys.SPACE] and not shot:
shot = True
cue_ball.momentum = [x*ball_speed, y*ball_speed]

When the shot variable is True, I’m going to move all the balls on my table – at the beginning, this is just the cue ball – but this code will also move the other balls as well when I add them.

# Shoot the ball and move all the balls on the table
else:
shot = False
balls_pocketed = []
collisions = []
for b in range(len(balls)):
# Move each ball
balls[b].move()
if abs(balls[b].momentum[0]) + abs(balls[b].momentum[1]) > 0:
shot = True

Each time I move the balls, I check whether they still have some movement left. I made a resistance function inside the ball class that will slow them down.

Collisions

Now for the final problem: getting the balls to collide with each other and the pockets. I need to add more balls and some pocket actors to my game in order to test the collisions.

balls.append(Ball(“ball_1.png”, (WIDTH//2 - 75, HEIGHT//2)))
balls.append(Ball(“ball_2.png”, (WIDTH//2 - 150, HEIGHT//2)))

pockets = []
pockets.append(Actor(“pocket.png”, topleft=(playArea.left, playArea.top), anchor=(“left”, “top”)))
# I create one of these actors for each pocket, they are not drawn

Each ball needs to be able to collide with the others, and when that happens, the direction and speed of the balls will change. Each ball will be responsible for changing the direction of the ball it has collided with, and I add a new function to my ball class:

def collide(self, ball):
collision_normal = [ball.actor.x - self.actor.x, ball.actor.y - self.actor.y]
ball_speed = math.sqrt(collision_normal[0]**2 + collision_normal[1]**2)
self_speed = math.sqrt(self.momentum[0]**2 + self.momentum[1]**2)
if self.momentum[0] == 0 and self.momentum[1] == 0:
ball.momentum[0] = -ball.momentum[0]
ball.momentum[1] = -ball.momentum[1]
elif ball_speed > 0:
collision_normal[0] *= 1/ball_speed
collision_normal[1] *= 1/ball_speed
ball.momentum[0] = collision_normal[0] * self_speed
ball.momentum[1] = collision_normal[1] * self_speed

When a collision happens, the other ball should move in the opposite direction to the collision. This is what allows you to line-up slices and knock balls diagonally into the pockets. Unlike the collisions with the edges, I can’t just reverse the x and y movement. I need to change its direction, and then give it a part of the current ball’s speed. Above, I’m using a normal to find the direction of the collision. You can think of this as the direction to the other ball as they collide.

Our finished pool game. See if you can expand it with extra balls and maybe a scoring system.

Handling collisions

I need to add to my update loop to detect and store the collisions to be handled after each set of movement.

# Check for collisions
for other in balls:
if other != b and b.actor.colliderect(other.actor):
collisions.append((b, other))
# Did it sink in the hole?
in_pocket = b.actor.collidelistall(pockets)
if len(in_pocket) > 0 and b.pocketed == False:
if b != cue_ball:
b.movement[0] = (pockets[in_pocket[0]].x - b.actor.x) / 20
b.movement[1] = (pockets[in_pocket[0]].y - b.actor.y) / 20
b.pocket = pockets[in_pocket[0]]
balls_pocketed.append(b)
else:
b.x = WIDTH//2
b.y = HEIGHT//2

First, I use the colliderect() function to check if any of the balls collide this frame – if they do, I add them to a list. This is so I handle all the movement first and then the collisions. Otherwise, I’m changing the momentum of balls that haven’t moved yet. I detect whether a pocket was hit as well; if so, I change the momentum so that the ball heads towards the pocket and doesn’t bounce off the walls anymore.

When all my balls have been moved, I can handle the collisions with both the other balls and the pockets:

for col in collisions:
col[0].collide(col[1])
if shot == False:
for b in balls_pocketed:
balls.remove(b)

And there you have it: the beginnings of an arcade pool game in the Side Pocket tradition. You can get the full code and assets right here.

Get your copy of Wireframe issue 36

You can read more features like this one in Wireframe issue 36, available directly from Raspberry Pi Press — we deliver worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 36 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Make a Side Pocket-esque pool game | Wireframe #36 appeared first on Raspberry Pi.

Code Hyper Sports’ shooting minigame | Wireframe #35

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/code-hyper-sports-shooting-minigame-wireframe-35/

Gun down the clay pigeons in our re-creation of a classic minigame from Konami’s Hyper Sports. Take it away, Mark Vanstone

Hyper Sports

Hyper Sports’ Japanese release was tied in with the 1984 Summer Olympics.

Hyper Sports

Konami’s sequel to its 1983 arcade hit, Track & Field, Hyper Sports offered seven games – or events – in which up to four players could participate. Skeet shooting was perhaps the most memorable game in the collection, and required just two buttons: fire left and fire right.

The display showed two target sights, and each moved up and down to come into line with the next clay disc’s trajectory. When the disc was inside the red target square, the player pressed the fire button, and if their timing was correct, the clay disc exploded. Points were awarded for being on target, and every now and then, a parrot flew across the screen, which could be gunned down for a bonus.

Making our game

To make a skeet shooting game with Pygame Zero, we need a few graphical elements. First, a static background of hills and grass, with two clay disc throwers each side of the screen, and a semicircle where our shooter stands – this can be displayed first, every time our draw() function is called.

We can then draw our shooter (created as an Actor) in the centre near the bottom of the screen. The shooter has three images: one central while no keys are pressed, and two for the directions left and right when the player presses the left or right keys. We also need to have two square target sights to the left and right above the shooter, which we can create as Actors.

When the clay targets appear, the player uses the left and right buttons to shoot either the left or right target respectively.

To make the clay targets, we create an array to hold disc Actor objects. In our update() function we can trigger the creation of a new disc based on a random number, and once created, start an animation to move it across the screen in front of the shooter. We can add a shadow to the discs by tracking a path diagonally across the screen so that the shadow appears at the correct Y coordinate regardless of the disc’s height – this is a simple way of giving our game the illusion of depth. While we’re in the update() function, looping around our disc object list, we can calculate the distance of the disc to the nearest target sight frame, and from that, work out which is the closest.

When we’ve calculated which disc is closest to the right-hand sight, we want to move the sight towards the disc so that their paths intersect. All we need to do is take the difference of the Y coordinates, divide by two, and apply that offset to the target sight. We also do the same for the left-hand sight. If the correct key (left or right arrows) is pressed at the moment a disc crosses the path of the sight frame, we register a hit and cycle the disc through a sequence of exploding frames. We can keep a score and display this with an overlay graphic so that the player knows how well they’ve done.

And that’s it! You may want to add multiple players and perhaps a parrot bonus, but we’ll leave that up to you.

Here’s Mark’s code snippet, which creates a simple shooting game in Python. To get it working on your system, you’ll need to install Pygame Zero. And to download the full code and assets, go here.

Get your copy of Wireframe issue 35

You can read more features like this one in Wireframe issue 35, available now at Tesco, WHSmith, and all good independent UK newsagents.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 35 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Code Hyper Sports’ shooting minigame | Wireframe #35 appeared first on Raspberry Pi.

Recreate Flappy Bird’s flight mechanic | Wireframe #29

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/recreate-flappy-birds-flight-mechanic-wireframe-29/

From last year’s issue 29 of Wireframe magazine: learn how to create your own version of the simple yet addictive side-scroller Flappy Bird. Raspberry Pi’s Rik Cross shows you how.

Flappy Bird: ridiculously big in 2014, at least for a while.

Flappy Bird was released by programmer Dong Nguyen in 2013, and made use of a straightforward game mechanic to create an addictive hit. Tapping the screen provided ‘lift’ to the main character, which is used strategically to navigate through a series of moving pipes. A point is scored for each pipe successfully passed. The idea proved so addictive that Nguyen eventually regretted his creation and removed it from the Google and Apple app stores. In this article, I’ll show you how to recreate this simple yet time-consuming game, using Python and Pygame Zero.

The player’s motion is very similar to that employed in a standard platformer: falling down towards the bottom of the screen under gravity. See the article, Super Mario-style jumping physics in Wireframe #7 for more on creating this type of movement. Pressing a button (in our case, the SPACE bar) gives the player some upward thrust by setting its velocity to a negative value (i.e. upwards) larger than the value of gravity acting downwards. I’ve adapted and used two different images for the sprite (made by Imaginary Perception and available on opengameart.org), so that it looks like it’s flapping its wings to generate lift and move upwards.

Pressing the SPACE bar gives the bird ‘lift’ against gravity, allowing it to navigate through moving pipes.

Sets of pipes are set equally spaced apart horizontally, and move towards the player slowly each frame of the game. These pipes are stored as two lists of rectangles, top_pipes and bottom_pipes, so that the player can attempt to fly through gaps between the top and bottom pipes. Once a pipe in the top_pipes list reaches the left side of the screen past the player’s position, a score is incremented and the top and corresponding bottom pipes are removed from their respective lists. A new set of pipes is created at the right edge of the screen, creating a continuous challenge for the player. The y-position of the gap between each newly created pair of pipes is decided randomly (between minimum and maximum limits), which is used to calculate the position and height of the new pipes.

The game stops and a ‘Game over’ message appears if the player collides with either a pipe or the ground. The collision detection in the game uses the player.colliderect() method, which checks whether two rectangles overlap. As the player sprite isn’t exactly rectangular, it means that the collision detection isn’t pixel-perfect, and improvements could be made by using a different approach. Changing the values for GRAVITY, PIPE_GAP, PIPE_SPEED, and player.flap_velocity through a process of trial and error will result in a game that has just the right amount of frustration! You could even change these values as the player’s score increases, to add another layer of challenge.

Here’s Rik’s code, which gets an homage to Flappy Bird running in Python. To get it working on your system, you’ll first need to install Pygame Zero. And to download the full code, go here.

If you’d like to read older issues of Wireframe magazine, you can find the complete back catalogue as free PDF downloads.

The latest issue of Wireframe is available in print to buy online from the Raspberry Pi Press store, with older physical issues heavily discounted too. You can also find Wireframe at local newsagents, but we should all be staying home as much as possible right now, so why not get your copy online and save yourself the trip?

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. And subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Recreate Flappy Bird’s flight mechanic | Wireframe #29 appeared first on Raspberry Pi.

Code a homage to Marble Madness | Wireframe #34

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/code-a-homage-to-marble-madness-wireframe-34/

Code the map and movement basics of the innovative marble-rolling arcade game. Mark Vanstone shows you how.

The original Marble Madness

Each of Marble Madness’ six levels got progressively harder to navigate and had to be completed within a time limit.

Marble Madness

Hitting arcades in 1984, Atari’s Marble Madness presented a rather different control mechanism than other games of the time. The original arcade cabinet provided players with a trackball controller rather than a conventional joystick, and the aim was to guide a marble through a three-dimensional course in the fastest possible time. This meant that a player could change the angle and speed of the marble as it rolled and avoid various obstacles and baddies.

During development, designer Mark Cerny had to shelve numerous ideas for Marble Madness, since the hardware just wasn’t able to achieve the level of detail and interaction he wanted. The groundbreaking 3D display was one idea that made it through to the finished game: its pre-rendered, ray-traced isometric levels.

Marble Madness was the first game to use Atari’s System 1 upgradeable hardware platform, and also boasted the first use of an FM sound chip produced by Yamaha to create its distinctive stereo music. The game was popular in arcades to start with, but interest appeared to drop off after a few months – something Cerny attributed to the fact that the game didn’t take long to play. Marble Madness’s popularity endured in the home market, though, with ports made for most computers and consoles of the time – although inevitably, most of these didn’t support the original’s trackball controls.

Our Python version of Marble Madness

In our sample level, you can control the movement of the marble using the left and right arrow keys.

Making our game

For our version of Marble Madness, we’re going to use a combination of a rendered background and a heightmap in Pygame Zero, and write some simple physics code to simulate the marble rolling over the terrain’s flats and slopes. We can produce the background graphic using a 3D modelling program such as Blender. The camera needs to be set to Orthographic to get the forced perspective look we’re after. The angle of the camera is also important, in that we need an X rotation of 54.7 degrees and a Y rotation of 45 degrees to get the lines of the terrain correct. The heightmap can be derived from an overhead view of the terrain, but you’ll probably want to draw the heights of the blocks in a drawing package such as GIMP to give you precise colour values on the map.

The ball rolling physics are calculated from the grey-shaded heightmap graphic. We’ve left a debug mode in the code; by changing the debug variable to True, you can see how the marble moves over the terrain from the overhead viewpoint of the heightmap. The player can move the marble left and right with the arrow keys – on a level surface it will gradually slow down if no keys are pressed. If the marble is on a gradient on the heightmap, it will increase speed in the direction of the gradient. If the marble hits a section of black on the heightmap, it falls out of play, and we stop the game.

That takes care of the movement of the marble in two dimensions, but now we have to translate this to the rendered background’s terrain. The way we do this is to translate the Y coordinate of the marble as if the landscape was all at the same level – we multiply it by 0.6 – and then move it down the screen according to the heightmap data, which in this case moves the marble down 1.25 pixels for each shade of colour. We can use an overlay for items the marble always rolls behind, such as the finish flag. And with that, we have the basics of a Marble Madness level.

The code you'll need to make Marble Madness

Here’s Mark’s code snippet, which creates a Marble Madness level in Python. To get it working on your system, you’ll need to install Pygame Zero. And to download the full code, go here.

Module Madness

We use the image module from Pygame to sample the colour of the pixel directly under the marble on the heightmap. We also take samples from the left diagonal and the right diagonal to see if there is a change of height. We are only checking for left and right movement, but this sample could be expanded to deal with the two other directions and moving up the gradients, too. Other obstacles and enemies can be added using the same heightmap translations used for the marble, and other overlay objects can be added to the overlay graphic.

Get your copy of Wireframe issue 34

You can read more features like this one in Wireframe issue 34, available now at Tesco, WHSmith, all good independent UK newsagents, and the Raspberry Pi Store, Cambridge.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 34 for free in PDF format.

Wireframe #34

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Code a homage to Marble Madness | Wireframe #34 appeared first on Raspberry Pi.

Code a Zaxxon-style axonometric level | Wireframe #33

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/code-a-zaxxon-style-axonometric-level-wireframe-33/

Fly through the space fortress in this 3D retro forced scrolling arcade sample. Mark Vanstone has the details

A shot from Sega's arcade hit, Zaxxon

Zaxxon was the first arcade game to use an axonometric viewpoint, which made it look very different from its 2D rivals.

Zaxxon

When Zaxxon was first released by Sega in 1982, it was hailed as a breakthrough thanks to its pseudo-3D graphics. This axonometric projection ensured that Zaxxon looked unlike any other shooter around in arcades.

Graphics aside, Zaxxon offered a subtly different twist on other shooting games of the time, like Defender and Scramble; the player flew over either open space or a huge fortress, where they had to avoid obstacles of varying heights. Players could tell how high they were flying with the aid of an altimeter, and also the shadow beneath their ship (shadows were another of Zaxxon’s innovations). The aim of the game was to get to the end of each level without running out of fuel or getting shot down; if the player did this, they’d encounter an area boss called Zaxxon. Points were awarded for destroying gun turrets and fuel silos, and extra lives could be gained as the player progressed through the levels.

A shot of our Pygame version of Zaxxon

Our Zaxxon homage running in Pygame Zero: fly the spaceship through the fortress walls and obstacles with your cursor keys.

Making our level

For this code sample, we can borrow some of the techniques used in a previous Source Code article about Ant Attack (see Wireframe issue 15) since it also used an isometric display. Although the way the map display is built up is very similar, we’ll use a JSON file to store the map data. If you’ve not come across JSON before, it’s well worth learning about, as a number of web and mobile apps use it, and it can be read by Python very easily. All we need to do is load the JSON file, and Python automatically puts the data into a Python dictionary object for us to use.

In the sample, there’s a short run of map data 40 squares long with blocks for the floor, some low walls, higher walls, and a handful of fuel silos. To add more block types, just add data to the blocktypes area of the JSON file. The codes used in the map data are the index numbers of the blocktypes, so the first blocktypes is index 0, the next index 1, and so on. Our drawMap() function takes care of rendering the data into visual form and blits blocks from the top right to the bottom left of the screen. When the draw loop gets to where the ship is, it draws first the shadow and then the ship a little higher up the screen, depending on the altitude of the ship. The equation to translate the ship’s screen coordinates to a block position on the map is a bit simplistic, but in this case, it does the job well enough.

Cursor keys guide the movement of the spaceship, which is limited by the width of the map and a height of 85 pixels. There’s some extra code to display the ship if it isn’t on the map – for example, at the start, before it reaches the map area. To make the code snippet into a true Zaxxon clone, you’ll have to add some laser fire and explosions, a fuel gauge, and a scoring system, but this code sample should provide the basis you’ll need to get started.

Code for our Zaxxon homage

Here’s Mark’s code snippet, which creates a side-scrolling beat-’em-up in Python. To get it working on your system, you’ll need to install Pygame Zero. And to download the full code, go here.

Get your copy of Wireframe issue 33

You can read more features like this one in Wireframe issue 33, available now at Tesco, WHSmith, all good independent UK newsagents, and the Raspberry Pi Store, Cambridge.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 33 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Code a Zaxxon-style axonometric level | Wireframe #33 appeared first on Raspberry Pi.

Code a Kung-Fu Master style beat-’em-up | Wireframe #32

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/code-a-kung-fu-master-style-beat-em-up-wireframe-32/

Punch and kick your way through a rabble of bad dudes in a simple scrolling beat-’em-up. Mark Vanstone shows you how

Although released to tie in with Jackie Chan’s Spartan X, Kung-Fu Master was originally inspired by the Bruce Lee film, Game of Death.

Kung-Fu Master

Kung-Fu Master hit arcades in 1984. Its side-scrolling action, punching and kicking through an army of knife-throwing goons, helped create the beat-’em-up genre. In fact, its designer, Takashi Nishiyama, would go on to kickstart the Street Fighter series at Capcom, and later start up the Fatal Fury franchise at SNK.

In true eighties arcade style, Kung-Fu Master distils the elements of a chop-socky action film to its essentials. Hero Thomas and his girlfriend are attacked, she’s kidnapped, and Thomas fights his way through successive levels of bad guys to rescue her. The screen scrolls from side to side, and Thomas must use his kicks and punches to get from one side of the level to the other and climb the stairs to the next floor of the building.

Our Kung-Fu Master homage features punches, kicks, and a host of goons to use them on.

Making our brawler

To recreate this classic with Pygame Zero, we’ll need quite a few frames of animation, both for the hero character and the enemies he’ll battle. For a reasonable walk cycle, we’ll need at least six frames in each direction. Any fewer than six won’t look convincing, but more frames can achieve a smoother effect. For this example, I’ve used the 3D package Poser, since it has a handy walk designer which makes generating sequences of animation much easier.

Once we have the animation frames for our characters, including a punch, kick, and any others you want to add, we need a background for the characters to walk along. The image we’re using is 2000×400 pixels, and we start the game by displaying the central part so our hero can walk either way. By detecting arrow key presses, the hero can ‘walk’ one way or the other by moving the background left and right, while cycling through the walk animation frames. Then if we detect a Q key press, we change the action string to kick; if it’s A, it’s punch. Then in our update() function, we use that action to set the Actor’s image to the indicated action frame.

Our enemy Actors will constantly walk towards the centre of the screen, and we can cycle through their walking frames the same way we do with the main hero. To give kicks and punches an effect, we put in collision checks. If the hero strikes while an enemy collides with him, we register a hit. This could be made more precise to require more skill, but once a strike’s registered, we can switch the enemy to a different status that will cause them to fall downwards and off the screen.

This sample is a starting point to demonstrate the basics of the beat-’em-up genre. With the addition of flying daggers, several levels, and a variety of bad guys, you’ll be on your way to creating a Pygame Zero version of this classic game.

The generation game

Because we’re moving the background when our hero walks left and right, we need to make sure we move our enemies with the background, otherwise they’ll look as though they’re sliding in mid-air – this also applies to any other objects that aren’t part of the background. The number of enemies can be governed in several ways: in our code, we just have a random number deciding if a new enemy will appear during each update, but we could use a predefined pattern for the enemy generation to make it a bit less random, or we use a combination of patterns and random numbers.

Here’s Mark’s code snippet, which creates a side-scrolling beat-’em-up in Python. To get it working on your system, you’ll need to install Pygame Zero. And to download the full code, go here.

Get your copy of Wireframe issue 32

You can read more features like this one in Wireframe issue 32, available now at Tesco, WHSmith, all good independent UK newsagents, and the Raspberry Pi Store, Cambridge.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 32 for free in PDF format.

Look how lovely and glowy it is.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Code a Kung-Fu Master style beat-’em-up | Wireframe #32 appeared first on Raspberry Pi.

Make a Spy Hunter-style scrolling road | Wireframe #31

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/make-a-spy-hunter-style-scrolling-road-wireframe-31/

Raspberry Pi’s own Mac Bowley shows you how to make the beginnings of a top-down driving game inspired by 1983’s Spy Hunter.

Spy Hunter, an arcade game from 1983

Spy Hunter was one of the very first games with both driving and shooting.

Spy Hunter

The 1983 arcade classic Spy Hunter put players at the wheel of a fictitious Interceptor vehicle and challenged them to navigate a vertically scrolling road, destroying enemy vehicles.

Here, I’ll show you how you can recreate the game’s scrolling road to use in your own driving games. The road will be created using the Rect class from Pygame, with the road built from stacked rectangles that are each two pixels high.

Making the scrolling road in Python

First, I create two lists; one to hold the pieces of road currently being drawn on screen, and another to hold a queue of pieces that will be added as the road scrolls. To create the scrolling road effect, each of the current pieces of road will need to move down the screen, while a new piece is added to the end of the list at position y = 0.

Pygame can schedule functions, which can then be called at set intervals – meaning I can scroll my road at a set frame rate. The scroll_road function will achieve this. First, I loop over each road piece, and move it down by two pixels. I then remove the first item in the queue list and append it to the end of the road. The Pygame clock is then set to call the function at intervals set by a frame_rate variable: mine is set to 1/60, meaning 60 frames per second.

Our top-down rolling road in Python

Our code snippet provides a solid basis for your own top-down driving game. All you need now are weapons. And a few other cars.

My road can either turn left or right, a random choice made whenever the queue is populated. Whichever way the road turns, it has to start from the same spot as the last piece in my queue. I can grab the last item in a list using -1 as an index and then store the x position; building from here will make sure my road is continuous. I use a buffer of 50 pixels to keep the road from moving off the edge of my screen – each time a turn is made, I check that the road doesn’t go beyond this point.

I want the turn amount to be random, so I’m also setting a minimum turn of 200 pixels. If this amount takes my car closer than the buffer, I’ll instead set the turn amount so that it takes it up to the buffer but no further. I do this for both directions, as well as setting a modifier to apply to my turn amount (-1 to turn left and 1 to turn right), which will save me duplicating my code. I also want to randomly choose how many pieces will be involved in my turn. Each piece is a step in the scroll, so the more pieces, the longer my turn will take. This will make sure I have a good mix of sharp and elongated turns in my road, keeping the player engaged.

Our rolling road Python code

Here’s Mac’s code snippet, which creates a winding road worthy of Spy Hunter in Python. To get it working on your system, you’ll need to install Pygame Zero. And to download the full code, go here.

Speeding up the game

To make things more exciting, the game can also be speeded up by decreasing the frame_rate variable. You could even gradually increase this over time, making the game feel more frantic the further you get.
Another improvement would be to make the turns more curvy, but make sure you’re comfortable with algebra before you do this!

Get your copy of Wireframe issue 31

You can read more features like this one in Wireframe issue 31, available now at Tesco, WHSmith, all good independent UK newsagents, and the Raspberry Pi Store, Cambridge.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 31 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Make a Spy Hunter-style scrolling road | Wireframe #31 appeared first on Raspberry Pi.

Receive AWS Developer Tools Notifications over Slack using AWS Chatbot

Post Syndicated from Anushri Anwekar original https://aws.amazon.com/blogs/devops/receive-aws-developer-tools-notifications-over-slack-using-aws-chatbot/

Developers often use Slack to communicate with each other about their code. With AWS Chatbot, you can configure notifications for developer tools resources such as repositories, build projects, deployment applications, and pipelines so that users in Slack channels are automatically notified about important events. When a deployment fails, a build succeeds, or a pull request is created, developers get notifications where they’re most likely to see and react to them.

The AWS services which currently support notifications are:

In this post, I walk you through the high-level steps for creating a notification that alerts users in a Slack channel every time a pull request is created in a CodeCommit repository.

Solution overview

You can create both the notification rule to listen for required events and the Amazon SNS topic used for notifications on the same web page. You can then configure AWS Chatbot so that notifications sent to that Amazon SNS topic appears in a Slack channel.

To set up notifications, follow the following process, as shown in the following diagram:

  1. Create a notification rule for a repository. This includes creating an Amazon SNS topic to use for notifications.
  2. Configure AWS Chatbot to send notifications from that Amazon SNS topic to a Slack channel.
  3. Test it out and enjoy receiving notifications in your team’s Slack channel.

This diagram describes the notification workflow and how impacted services are connected.

Prerequisites

To follow along with this example, you need an AWS account, an IAM user or role with administrative access, a CodeCommit repository, and a Slack channel.

Configuration steps

Step 1: Create notification rule in CodeCommit

Follow these steps to create a notification rule in CodeCommit:

1 . Select the repository in CodeCommit about which you want to be notified. In the following screenshot, I have selected a repository called Hello-Dublin. Screen-shot of the repository view

2. Select a repository for which you want to receive notifications. Choose Notify, then Create notification rule.Screen-shot of how to select option to create a notification rule

3. Provide a name for your notification rule. I suggest leaving the default Detail Type as Full. By selecting Full, you get extra information beyond what is present in the resource events. Also, you get updated information about your selected event types whenever new information is added about them.

  • For example, if you want to receive notifications whenever a comment is made on a pull request, select Basic, and your notification informs you that a comment has been made.
  • If you select Full, the notification also specifies the exact comment that was made. If the notification feature is enhanced and extra information is added to be a part of the notification, you start receiving the new information without modifying your existing notification rule.

4. In Event types, in Pull request, select Created.

5. In Targets, choose Create SNS topic. This automatically sets up a new Amazon SNS topic to use for notifications, applying a policy that allows notification events to be sent to it.

6. Finish creating the rule. Keep a note of the Amazon SNS ARN, as you need this information to configure Slack integration in the next step.

For complete step-by-step instructions for creating a notification rule, see Create a Notification Rule.

Step 2: Integrate your Amazon SNS topic with AWS Chatbot

Follow these steps to integrate your Amazon SNS topic with AWS Chatbot.

1. Open up your Slack channel. You need information about it as well as your notification rule to complete integration.

2. Open the AWS Chatbot console and choose Try the AWS Chatbot beta.

3. Choose Configure new client, then Slack, then Configure.

4. AWS Chatbot asks for permission to access your Slack workplace, as seen in the following screenshot. Once you give permission, you are asked to configure your Slack channel.

Screen-shot of a prompt about AWS Chatbot requesting permission to access the notifications Slack workspace

Step 3: Test the notification

In your repository, create a pull request. In this example, I named the pull request This is a new pull request. Watch as a notification about that event appears in your Slack channel, as seen in the following screenshot.

Example of a notification received on a Slack channel when a new pull request is created

Step 4: Clean-up

If you created notification rule just for testing purposes, you should delete the SNS topic to avoid any further charges.

Conclusion

And that’s it! You can use notifications to help developers to stay informed about the key events happening in their software development life cycle. You can set up notification rules for build projects, deployment applications, pipelines, and repositories, and stay informed about key events such as pull request creation, comments made on your code or commits, build state/phase change, deployment project status change, manual pipelines approval, or pipeline execution status change. For more information, see the notifications documentation.

Code a Boulder Dash mining game | Wireframe #30

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/code-a-boulder-dash-mining-game-wireframe-30/

Learn how to code a simple Boulder Dash homage in Python and Pygame. Mark Vanstone shows you how. 

The original Boulder Dash was marked out by some devious level design, which threatened to squash the player at every turn.

Boulder Dash

Boulder Dash first appeared in 1984 for the Commodore 64, Apple II, and the Atari 400/800. It featured an energetic gem collector called Rockford who, thanks to some rather low-resolution graphics, looked a bit like an alien. His mission was to tunnel his way through a series of caves to find gems while avoiding falling rocks dislodged by his digging. Deadly creatures also inhabited the caves which, if destroyed by dropping rocks on them, turned into gems for Rockford to collect.

The ingenious level designs were what made Boulder Dash so addictive. Gems had to be collected within a time limit to unlock the exit, but some were positioned in places that would need planning to get to, often using the physics of falling boulders to block or clear areas. Of course, the puzzles got increasingly tough as the levels progressed.

Written by Peter Liepa and Chris Gray, Boulder Dash was published by First Star Software, which still puts out new versions of the game to this day. Due to its original success, Boulder Dash was ported to all kinds of platforms, and the years since have seen no fewer than 20 new iterations of Boulder Dash, and a fair few clones, too.

Our homage to Boulder Dash running in Pygame Zero. Dig through the caves to find gems – while avoiding death from above.

Making Boulder Dash in Python

We’re going to have a look at the boulder physics aspect of the game, and make a simple level where Rockford can dig out some gems and hopefully not get flattened under an avalanche of rocks. Writing our code in Pygame Zero, we’ll automatically create an 800 by 600-size window to work with. We can make our game screen by defining a two-dimensional list, which, in this case, we will fill with soil squares and randomly position the rocks and gems.

Each location in the list matrix will have a name: either wall for the outside boundary, soil for the diggable stuff, rock for a round, moveable boulder, gem for a collectable item, and finally, rockford to symbolise our hero. We can also define an Actor for Rockford, as this will make things like switching images and tracking other properties easier.

Here’s Mark’s code, which gets an homage to Boulder Dash running in Python. To get it working on your system, you’ll first need to install Pygame Zero. And to download the full code, go here.

Our draw() function is just a nested loop to iterate through the list matrix and blit to the screen whatever is indicated in each square. The Rockford Actor is then drawn over the top. We can also keep a count of how many gems have been collected and provide a congratulatory message if all of them are found. In the update() function, there are only two things we really need to worry about: the first being to check for keypresses from the player and move Rockford accordingly, and the second to check rocks to see if they need to move.

Rockford is quite easy to test for movement, as he can only move onto an empty square – a soil square or a gem square. It’s also possible for him to push a boulder if there’s an empty space on the other side. For the boulders, we need to first test if there’s an empty space below it, and if so, the boulder must move downwards. We also test to see if a boulder is on top of another boulder – if it is, the top boulder can roll off and down onto a space either to the left or the right of the one beneath.
There’s not much to add to this snippet of code to turn it into a playable game of Boulder Dash. See if you can add a timer, some monsters, and, of course, some puzzles for players to solve on each level.

Testing for movement

An important thing to notice about the process of scanning through the list matrix to test for boulder movement is that we need to read the list from the bottom upwards; otherwise, because the boulders move downwards, we may end up testing a boulder multiple times if we test from the beginning to the end of the list. Similarly, if we read the list matrix from the top down, we may end up moving a boulder down and then when reading the next row, coming across the same one again, and moving it a second time.

Get your copy of Wireframe issue 30

You can read more features like this one in Wireframe issue 30, available now at Tesco, WHSmith, all good independent UK newsagents, and the Raspberry Pi Store, Cambridge.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 30 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Code a Boulder Dash mining game | Wireframe #30 appeared first on Raspberry Pi.

Building an AWS IoT Core device using AWS Serverless and an ESP32

Post Syndicated from Moheeb Zara original https://aws.amazon.com/blogs/compute/building-an-aws-iot-core-device-using-aws-serverless-and-an-esp32/

Using a simple Arduino sketch, an AWS Serverless Application Repository application, and a microcontroller, you can build a basic serverless workflow for communicating with an AWS IoT Core device.

A microcontroller is a programmable chip and acts as the brain of an electronic device. It has input and output pins for reading and writing on digital or analog components. Those components could be sensors, relays, actuators, or various other devices. It can be used to build remote sensors, home automation products, robots, and much more. The ESP32 is a powerful low-cost microcontroller with Wi-Fi and Bluetooth built in and is used this walkthrough.

The Arduino IDE, a lightweight development environment for hardware, now includes support for the ESP32. There is a large collection of community and officially supported libraries, from addressable LED strips to spectral light analysis.

The following walkthrough demonstrates connecting an ESP32 to AWS IoT Core to allow it to publish and subscribe to topics. This means that the device can send any arbitrary information, such as sensor values, into AWS IoT Core while also being able to receive commands.

Solution overview

This post walks through deploying an application from the AWS Serverless Application Repository. This allows an AWS IoT device to be messaged using a REST endpoint powered by Amazon API Gateway and AWS Lambda. The AWS SAR application also configures an AWS IoT rule that forwards any messages published by the device to a Lambda function that updates an Amazon DynamoDB table, demonstrating basic bidirectional communication.

The last section explores how to build an IoT project with real-world application. By connecting a thermal printer module and modifying a few lines of code in the example firmware, the ESP32 device becomes an AWS IoT–connected printer.

All of this can be accomplished within the AWS Free Tier, which is necessary for the following instructions.

An example of an AWS IoT project using an ESP32, AWS IoT Core, and an Arduino thermal printer

An example of an AWS IoT project using an ESP32, AWS IoT Core, and an Arduino thermal printer.

Required steps

To complete the walkthrough, follow these steps:

  • Create an AWS IoT device.
  • Install and configure the Arduino IDE.
  • Configure and flash an ESP32 IoT device.
  • Deploying the lambda-iot-rule AWS SAR application.
  • Monitor and test.
  • Create an IoT thermal printer.

Creating an AWS IoT device

To communicate with the ESP32 device, it must connect to AWS IoT Core with device credentials. You must also specify the topics it has permissions to publish and subscribe on.

  1. In the AWS IoT console, choose Register a new thing, Create a single thing.
  2. Name the new thing. Use this exact name later when configuring the ESP32 IoT device. Leave the remaining fields set to their defaults. Choose Next.
  3.  Choose Create certificate. Only the thing cert, private key, and Amazon Root CA 1 downloads are necessary for the ESP32 to connect. Download and save them somewhere secure, as they are used when programming the ESP32 device.
  4. Choose Activate, Attach a policy.
  5. Skip adding a policy, and choose Register Thing.
  6. In the AWS IoT console side menu, choose Secure, Policies, Create a policy.
  7. Name the policy Esp32Policy. Choose the Advanced tab.
  8. Paste in the following policy template.
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "iot:Connect",
          "Resource": "arn:aws:iot:REGION:ACCOUNT_ID:client/THINGNAME"
        },
        {
          "Effect": "Allow",
          "Action": "iot:Subscribe",
          "Resource": "arn:aws:iot:REGION:ACCOUNT_ID:topicfilter/esp32/sub"
        },
    	{
          "Effect": "Allow",
          "Action": "iot:Receive",
          "Resource": "arn:aws:iot:REGION:ACCOUNT_ID:topic/esp32/sub"
        },
        {
          "Effect": "Allow",
          "Action": "iot:Publish",
          "Resource": "arn:aws:iot:REGION:ACCOUNT_ID:topic/esp32/pub"
        }
      ]
    }
  9. Replace REGION with the matching AWS Region you’re currently operating in. This can be found on the top right corner of the AWS console window.
  10.  Replace ACCOUNT_ID with your own, which can be found in Account Settings.
  11. Replace THINGNAME with the name of your device.
  12. Choose Create.
  13. In the AWS IoT console, choose Secure, Certification. Select the one created for your device and choose Actions, Attach policy.
  14. Choose Esp32Policy, Attach.

Your AWS IoT device is now configured to have permission to connect to AWS IoT Core. It can also publish to the topic esp32/pub and subscribe to the topic esp32/sub. For more information on securing devices, see AWS IoT Policies.

Installing and configuring the Arduino IDE

The Arduino IDE is an open-source development environment for programming microcontrollers. It supports a continuously growing number of platforms including most ESP32-based modules. It must be installed along with the ESP32 board definitions, MQTT library, and ArduinoJson library.

  1. Download the Arduino installer for the desired operating system.
  2. Start Arduino and open the Preferences window.
  3. For Additional Board Manager URLs, add
    https://dl.espressif.com/dl/package_esp32_index.json.
  4. Choose Tools, Board, Boards Manager.
  5. Search esp32 and install the latest version.
  6. Choose Sketch, Include Library, Manage Libraries.
  7. Search MQTT, and install the latest version by Joel Gaehwiler.
  8. Repeat the library installation process for ArduinoJson.

The Arduino IDE is now installed and configured with all the board definitions and libraries needed for this walkthrough.

Configuring and flashing an ESP32 IoT device

A collection of various ESP32 development boards.

A collection of various ESP32 development boards.

For this section, you need an ESP32 device. To check if your board is compatible with the Arduino IDE, see the boards.txt file. The following code connects to AWS IoT Core securely using MQTT, a publish and subscribe messaging protocol.

This project has been tested on the following devices:

  1. Install the required serial drivers for your device. Some boards use different USB/FTDI chips for interfacing. Here are the most commonly used with links to drivers.
  2. Open the Arduino IDE and choose File, New to create a new sketch.
  3. Add a new tab and name it secrets.h.
  4. Paste the following into the secrets file.
    #include <pgmspace.h>
    
    #define SECRET
    #define THINGNAME ""
    
    const char WIFI_SSID[] = "";
    const char WIFI_PASSWORD[] = "";
    const char AWS_IOT_ENDPOINT[] = "xxxxx.amazonaws.com";
    
    // Amazon Root CA 1
    static const char AWS_CERT_CA[] PROGMEM = R"EOF(
    -----BEGIN CERTIFICATE-----
    -----END CERTIFICATE-----
    )EOF";
    
    // Device Certificate
    static const char AWS_CERT_CRT[] PROGMEM = R"KEY(
    -----BEGIN CERTIFICATE-----
    -----END CERTIFICATE-----
    )KEY";
    
    // Device Private Key
    static const char AWS_CERT_PRIVATE[] PROGMEM = R"KEY(
    -----BEGIN RSA PRIVATE KEY-----
    -----END RSA PRIVATE KEY-----
    )KEY";
  5. Enter the name of your AWS IoT thing, as it is in the console, in the field THINGNAME.
  6. To connect to Wi-Fi, add the SSID and PASSWORD of the desired network. Note: The network name should not include spaces or special characters.
  7. The AWS_IOT_ENDPOINT can be found from the Settings page in the AWS IoT console.
  8. Copy the Amazon Root CA 1, Device Certificate, and Device Private Key to their respective locations in the secrets.h file.
  9. Choose the tab for the main sketch file, and paste the following.
    #include "secrets.h"
    #include <WiFiClientSecure.h>
    #include <MQTTClient.h>
    #include <ArduinoJson.h>
    #include "WiFi.h"
    
    // The MQTT topics that this device should publish/subscribe
    #define AWS_IOT_PUBLISH_TOPIC   "esp32/pub"
    #define AWS_IOT_SUBSCRIBE_TOPIC "esp32/sub"
    
    WiFiClientSecure net = WiFiClientSecure();
    MQTTClient client = MQTTClient(256);
    
    void connectAWS()
    {
      WiFi.mode(WIFI_STA);
      WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    
      Serial.println("Connecting to Wi-Fi");
    
      while (WiFi.status() != WL_CONNECTED){
        delay(500);
        Serial.print(".");
      }
    
      // Configure WiFiClientSecure to use the AWS IoT device credentials
      net.setCACert(AWS_CERT_CA);
      net.setCertificate(AWS_CERT_CRT);
      net.setPrivateKey(AWS_CERT_PRIVATE);
    
      // Connect to the MQTT broker on the AWS endpoint we defined earlier
      client.begin(AWS_IOT_ENDPOINT, 8883, net);
    
      // Create a message handler
      client.onMessage(messageHandler);
    
      Serial.print("Connecting to AWS IOT");
    
      while (!client.connect(THINGNAME)) {
        Serial.print(".");
        delay(100);
      }
    
      if(!client.connected()){
        Serial.println("AWS IoT Timeout!");
        return;
      }
    
      // Subscribe to a topic
      client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);
    
      Serial.println("AWS IoT Connected!");
    }
    
    void publishMessage()
    {
      StaticJsonDocument<200> doc;
      doc["time"] = millis();
      doc["sensor_a0"] = analogRead(0);
      char jsonBuffer[512];
      serializeJson(doc, jsonBuffer); // print to client
    
      client.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer);
    }
    
    void messageHandler(String &topic, String &payload) {
      Serial.println("incoming: " + topic + " - " + payload);
    
    //  StaticJsonDocument<200> doc;
    //  deserializeJson(doc, payload);
    //  const char* message = doc["message"];
    }
    
    void setup() {
      Serial.begin(9600);
      connectAWS();
    }
    
    void loop() {
      publishMessage();
      client.loop();
      delay(1000);
    }
  10. Choose File, Save, and give your project a name.

Flashing the ESP32

  1. Plug the ESP32 board into a USB port on the computer running the Arduino IDE.
  2. Choose Tools, Board, and then select the matching type of ESP32 module. In this case, a Sparkfun ESP32 Thing was used.
  3. Choose Tools, Port, and then select the matching port for your device.
  4. Choose Upload. Arduino reads Done uploading when the upload is successful.
  5. Choose the magnifying lens icon to open the Serial Monitor. Set the baud rate to 9600.

Keep the Serial Monitor open. When connected to Wi-Fi and then AWS IoT Core, any messages received on the topic esp32/sub are logged to this console. The device is also now publishing to the topic esp32/pub.

The topics are set at the top of the sketch. When changing or adding topics, remember to add permissions in the device policy.

// The MQTT topics that this device should publish/subscribe
#define AWS_IOT_PUBLISH_TOPIC   "esp32/pub"
#define AWS_IOT_SUBSCRIBE_TOPIC "esp32/sub"

Within this sketch, the relevant functions are publishMessage() and messageHandler().

The publishMessage() function creates a JSON object with the current time in milliseconds and the analog value of pin A0 on the device. It then publishes this JSON object to the topic esp32/pub.

void publishMessage()
{
  StaticJsonDocument<200> doc;
  doc["time"] = millis();
  doc["sensor_a0"] = analogRead(0);
  char jsonBuffer[512];
  serializeJson(doc, jsonBuffer); // print to client

  client.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer);
}

The messageHandler() function prints out the topic and payload of any message from a subscribed topic. To see all the ways to parse JSON messages in Arduino, see the deserializeJson() example.

void messageHandler(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);

//  StaticJsonDocument<200> doc;
//  deserializeJson(doc, payload);
//  const char* message = doc["message"];
}

Additional topic subscriptions can be added within the connectAWS() function by adding another line similar to the following.

// Subscribe to a topic
  client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);

  Serial.println("AWS IoT Connected!");

Deploying the lambda-iot-rule AWS SAR application

Now that an ESP32 device has been connected to AWS IoT, the following steps walk through deploying an AWS Serverless Application Repository application. This is a base for building serverless integration with a physical device.

  1. On the lambda-iot-rule AWS Serverless Application Repository application page, make sure that the Region is the same as the AWS IoT device.
  2. Choose Deploy.
  3. Under Application settings, for PublishTopic, enter esp32/sub. This is the topic to which the ESP32 device is subscribed. It receives messages published to this topic. Likewise, set SubscribeTopic to esp32/pub, the topic on which the device publishes.
  4. Choose Deploy.
  5. When creation of the application is complete, choose Test app to navigate to the application page. Keep this page open for the next section.

Monitoring and testing

At this stage, two Lambda functions, a DynamoDB table, and an AWS IoT rule have been deployed. The IoT rule forwards messages on topic esp32/pub to TopicSubscriber, a Lambda function, which inserts the messages on to the DynamoDB table.

  1. On the application page, under Resources, choose MyTable. This is the DynamoDB table that the TopicSubscriber Lambda function updates.
  2. Choose Items. If the ESP32 device is still active and connected, messages that it has published appear here.

The TopicPublisher Lambda function is invoked by the API Gateway endpoint and publishes to the AWS IoT topic esp32/sub.

1.     On the application page, find the Application endpoint.

2.     To test that the TopicPublisher function is working, enter the following into a terminal or command-line utility, replacing ENDPOINT with the URL from above.

curl -d '{"text":"Hello world!"}' -H "Content-Type: application/json" -X POST https://ENDPOINT/publish

Upon success, the request returns a copy of the message.

Back in the Serial Monitor, the message published to the topic esp32/sub prints out.

Creating an IoT thermal printer

With the completion of the previous steps, the ESP32 device currently logs incoming messages to the serial console.

The following steps demonstrate how the code can be modified to use incoming messages to interact with a peripheral component. This is done by wiring a thermal printer to the ESP32 in order to physically print messages. The REST endpoint from the previous section can be used as a webhook in third-party applications to interact with this device.

A wiring diagram depicting an ESP32 connected to a thermal printer.

A wiring diagram depicting an ESP32 connected to a thermal printer.

  1. Follow the product instructions for powering, wiring, and installing the correct Arduino library.
  2. Ensure that the thermal printer is working by holding the power button on the printer while connecting the power. A sample receipt prints. On that receipt, the default baud rate is specified as either 9600 or 19200.
  3. In the Arduino code from earlier, include the following lines at the top of the main sketch file. The second line defines what interface the thermal printer is connected to. &Serial2 is used to set the third hardware serial interface on the ESP32. For this example, the pins on the Sparkfun ESP32 Thing, GPIO16/GPIO17, are used for RX/TX respectively.
    #include "Adafruit_Thermal.h"
    
    Adafruit_Thermal printer(&Serial2);
  4. Replace the setup() function with the following to initialize the printer on device bootup. Change the baud rate of Serial2.begin() to match what is specified in the test print. The default is 19200.
    void setup() {
      Serial.begin(9600);
    
      // Start the thermal printer
      Serial2.begin(19200);
      printer.begin();
      printer.setSize('S');
    
      connectAWS();
    }
    
  5. Replace the messageHandler() function with the following. On any incoming message, it parses the JSON and prints the message on the thermal printer.
    void messageHandler(String &topic, String &payload) {
      Serial.println("incoming: " + topic + " - " + payload);
    
      // deserialize json
      StaticJsonDocument<200> doc;
      deserializeJson(doc, payload);
      String message = doc["message"];
    
      // Print the message on the thermal printer
      printer.println(message);
      printer.feed(2);
    }
  6. Choose Upload.
  7. After the firmware has successfully uploaded, open the Serial Monitor to confirm that the board has connected to AWS IoT.
  8. Enter the following into a command-line utility, replacing ENDPOINT, as in the previous section.
    curl -d '{"message": "Hello World!"}' -H "Content-Type: application/json" -X POST https://ENDPOINT/publish

If successful, the device prints out the message “Hello World” from the attached thermal printer. This is a fully serverless IoT printer that can be triggered remotely from a webhook. As an example, this can be used with GitHub Webhooks to print a physical readout of events.

Conclusion

Using a simple Arduino sketch, an AWS Serverless Application Repository application, and a microcontroller, this post demonstrated how to build a basic serverless workflow for communicating with a physical device. It also showed how to expand that into an IoT thermal printer with real-world applications.

With the use of AWS serverless, advanced compute and extensibility can be added to an IoT device, from machine learning to translation services and beyond. By using the Arduino programming environment, the vast collection of open-source libraries, projects, and code examples open up a world of possibilities. The next step is to explore what can be done with an Arduino and the capabilities of AWS serverless. The sample Arduino code for this project and more can be found at this GitHub repository.

Create a turn-based combat system | Wireframe #28

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/create-a-turn-based-combat-system-wireframe-28/

Learn how to create the turn-based combat system found in games like Pokémon, Final Fantasy, and Undertale. Raspberry Pi’s Rik Cross shows you how.

With their emphasis on trading and collecting as well as turn-based combat, the Pokémon games helped bring RPG concepts to the masses.

In the late 1970s, high school student Richard Garriott made a little game called Akalabeth. Programmed in Applesoft BASIC, it helped set the template for the role-playing genre on computers. Even today, turn-based combat is still a common sight in games, with this autumn’s Pokémon Sword and Shield revolving around a battle system which sees opponents take turns to plan and execute attacks or defensive moves.

The turn-based combat system in this article is text-only, and works by allowing players to choose to defend against or attack their opponent in turn. The battle ends when only one player has some health remaining.

Each Player taking part in the battle is added to the static players list as it’s created. Players have a name, a health value (initially set to 100) and a Boolean defending value (initially set to False) to indicate whether a player is using their shield. Players also have an inputmethod attribute, which is the function used for getting player input for making various choices in the game. This function is passed to the object when created, and means that we can have human players that give their input through the keyboard, as well as computer players that make choices (in our case simply by making a random choice between the available options).

Richard Garriott’s Akalabeth laid the groundwork for Ultima, and was one of the earliest CRPGs.

A base Action class specifies an action owner and an opponent, as well as an execute() method which has no effect on the game. Subclasses of the base class override this execute() method to specify the effect the action has on the owner and/or the opponent of the action. As a basic example, two actions have been created: Defend, which sets the owner’s defending attribute to True, and Attack, which sets the owner’s defending attribute to False, and lowers the opponent’s health by a random amount depending on whether or not they are defending.

Players take turns to choose a single action to perform in the battle, starting with the human ‘Hero’ player. The choose_action() method is used to decide what to do next (in this case either attack or defend), as well as an opponent if the player has chosen to attack. A player can only be selected as an opponent if they have a health value greater than 0, and are therefore still in the game. This choose_action() method returns an Action, which is then executed using its execute() method. A few time.sleep() commands have also been thrown in here  to ramp up the suspense!

After each player has had their turn, a check is done to make sure that at least two players still have a health value greater than 0, and therefore that the battle can continue. If so, the static get_next_player() method finds the next player still in the game to take their turn in the battle, otherwise, the game ends and the winner is announced.

Our example battle can be easily extended in lots of interesting ways. The AI for choosing an action could also be made more sophisticated, by looking at opponents’ health or defending attributes before choosing an action. You could also give each action a ‘cost’, and give players a number of action ‘points’ per turn. Chosen actions would be added to a list, until all of the points have been used. These actions would then be executed one after the other, before moving on to the next player’s turn.

Here’s Rik’s code, which gets a simple turn-based combat system running in Python. To get it working on your system, you’ll first need to install Pygame Zero. And to download the full code, go here.

You can read more features like this one in Wireframe issue 28, available now at Tesco, WHSmith, all good independent UK newsagents, and the Raspberry Pi Store, Cambridge.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 28 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Create a turn-based combat system | Wireframe #28 appeared first on Raspberry Pi.

Decoupled Serverless Scheduler To Run HPC Applications At Scale on EC2

Post Syndicated from Emma White original https://aws.amazon.com/blogs/compute/decoupled-serverless-scheduler-to-run-hpc-applications-at-scale-on-ec2/

This post is written by Ludvig Nordstrom and Mark Duffield | on November 27, 2019

In this blog post, we dive in to a cloud native approach for running HPC applications at scale on EC2 Spot Instances, using a decoupled serverless scheduler. This architecture is ideal for many workloads in the HPC and EDA industries, and can be used for any batch job workload.

At the end of this blog post, you will have two takeaways.

  1. A highly scalable environment that can run on hundreds of thousands of cores across EC2 Spot Instances.
  2. A fully serverless architecture for job orchestration.

We discuss deploying and running a pre-built serverless job scheduler that can run both Windows and Linux applications using any executable file format for your application. This environment provides high performance, scalability, cost efficiency, and fault tolerance. We introduce best practices and benefits to creating this environment, and cover the architecture, running jobs, and integration in to existing environments.

quick note about the term cloud native: we use the term loosely in this blog. Here, cloud native  means we use AWS Services (to include serverless and microservices) to build out our compute environment, instead of a traditional lift-and-shift method.

Let’s get started!

 

Solution overview

This blog goes over the deployment process, which leverages AWS CloudFormation. This allows you to use infrastructure as code to automatically build out your environment. There are two parts to the solution: the Serverless Scheduler and Resource Automation. Below are quick summaries of each part of the solutions.

Part 1 – The serverless scheduler

This first part of the blog builds out a serverless workflow to get jobs from SQS and run them across EC2 instances. The CloudFormation template being used for Part 1 is serverless-scheduler-app.template, and here is the Reference Architecture:

 

Serverless Scheduler Reference Architecture . Reference Architecture for Part 1. This architecture shows just the Serverless Schduler. Part 2 builds out the resource allocation architecture. Outlined Steps with detail from figure one

    Figure 1: Serverless Scheduler Reference Architecture (grayed-out area is covered in Part 2).

Read the GitHub Repo if you want to look at the Step Functions workflow contained in preceding images. The walkthrough explains how the serverless application retrieves and runs jobs on its worker, updates DynamoDB job monitoring table, and manages the worker for its lifetime.

 

Part 2 – Resource automation with serverless scheduler


This part of the solution relies on the serverless scheduler built in Part 1 to run jobs on EC2.  Part 2 simplifies submitting and monitoring jobs, and retrieving results for users. Jobs are spread across our cost-optimized Spot Instances. AWS Autoscaling automatically scales up the compute resources when jobs are submitted, then terminates them when jobs are finished. Both of these save you money.

The CloudFormation template used in Part 2 is resource-automation.template. Building on Figure 1, the additional resources launched with Part 2 are noted in the following image, they are an S3 Bucket, AWS Autoscaling Group, and two Lambda functions.

Resource Automation using Serverless Scheduler This is Part 2 of the deployment process, and leverages the Part 1 architecture. This provides the resource allocation, that allows for automated job submission and EC2 Auto Scaling. Detailed steps for the prior image

 

Figure 2: Resource Automation using Serverless Scheduler

                               

Introduction to decoupled serverless scheduling

HPC schedulers traditionally run in a classic master and worker node configuration. A scheduler on the master node orchestrates jobs on worker nodes. This design has been successful for decades, however many powerful schedulers are evolving to meet the demands of HPC workloads. This scheduler design evolved from a necessity to run orchestration logic on one machine, but there are now options to decouple this logic.

What are the possible benefits that decoupling this logic could bring? First, we avoid a number of shortfalls in the environment such as the need for all worker nodes to communicate with a single master node. This single source of communication limits scalability and creates a single point of failure. When we split the scheduler into decoupled components both these issues disappear.

Second, in an effort to work around these pain points, traditional schedulers had to create extremely complex logic to manage all workers concurrently in a single application. This stifled the ability to customize and improve the code – restricting changes to be made by the software provider’s engineering teams.

Serverless services, such as AWS Step Functions and AWS Lambda fix these major issues. They allow you to decouple the scheduling logic to have a one-to-one mapping with each worker, and instead share an Amazon Simple Queue Service (SQS) job queue. We define our scheduling workflow in AWS Step Functions. Then the workflow scales out to potentially thousands of “state machines.” These state machines act as wrappers around each worker node and manage each worker node individually.  Our code is less complex because we only consider one worker and its job.

We illustrate the differences between a traditional shared scheduler and decoupled serverless scheduler in Figures 3 and 4.

 

Traditional Scheduler Model This shows a traditional sceduler where there is one central schduling host, and then multiple workers.

Figure 3: Traditional Scheduler Model

 

Decoupled Serverless Scheduler on each instance This shows what a Decoupled Serverless Scheduler design looks like, wit

Figure 4: Decoupled Serverless Scheduler on each instance

 

Each decoupled serverless scheduler will:

  • Retrieve and pass jobs to its worker
  • Monitor its workers health and take action if needed
  • Confirm job success by checking output logs and retry jobs if needed
  • Terminate the worker when job queue is empty just before also terminating itself

With this new scheduler model, there are many benefits. Decoupling schedulers into smaller schedulers increases fault tolerance because any issue only affects one worker. Additionally, each scheduler consists of independent AWS Lambda functions, which maintains the state on separate hardware and builds retry logic into the service.  Scalability also increases, because jobs are not dependent on a master node, which enables the geographic distribution of jobs. This geographic distribution allows you to optimize use of low-cost Spot Instances. Also, when decoupling the scheduler, workflow complexity decreases and you can customize scheduler logic. You can leverage lower latency job monitoring and customize automated responses to job events as they happen.

 

Benefits

  • Fully managed –  With Part 2, Resource Automation deployed, resources for a job are managed. When a job is submitted, resources launch and run the job. When the job is done, worker nodes automatically shut down. This prevents you from incurring continuous costs.

 

  • Performance – Your application runs on EC2, which means you can choose any of the high performance instance types. Input files are automatically copied from Amazon S3 into local Amazon EC2 Instance Store for high performance storage during execution. Result files are automatically moved to S3 after each job finishes.

 

  • Scalability – A worker node combined with a scheduler state machine become a stateless entity. You can spin up as many of these entities as you want, and point them to an SQS queue. You can even distribute worker and state machine pairs across multiple AWS regions. These two components paired with fully managed services optimize your architecture for scalability to meet your desired number of workers.

 

  • Fault Tolerance –The solution is completely decoupled, which means each worker has its own state machine that handles scheduling for that worker. Likewise, each state machine is decoupled into Lambda functions that make up your state machine. Additionally, the scheduler workflow includes a Lambda function that confirms each successful job or resubmits jobs.

 

  • Cost Efficiency – This fault tolerant environment is perfect for EC2 Spot Instances. This means you can save up to 90% on your workloads compared to On-Demand Instance pricing. The scheduler workflow ensures little to no idle time of workers by closely monitoring and sending new jobs as jobs finish. Because the scheduler is serverless, you only incur costs for the resources required to launch and run jobs. Once the job is complete, all are terminated automatically.

 

  • Agility – You can use AWS fully managed Developer Tools to quickly release changes and customize workflows. The reduced complexity of a decoupled scheduling workflow means that you don’t have to spend time managing a scheduling environment, and can instead focus on your applications.

 

 

Part 1 – serverless scheduler as a standalone solution

 

If you use the serverless scheduler as a standalone solution, you can build clusters and leverage shared storage such as FSx for Lustre, EFS, or S3. Additionally, you can use AWS CloudFormation or to deploy more complex compute architectures that suit your application. So, the EC2 Instances that run the serverless scheduler can be launched in any number of ways. The scheduler only requires the instance id and the SQS job queue name.

 

Submitting Jobs Directly to serverless scheduler

The severless scheduler app is a fully built AWS Step Function workflow to pull jobs from an SQS queue and run them on an EC2 Instance. The jobs submitted to SQS consist of an AWS Systems Manager Run Command, and work with any SSM Document and command that you chose for your jobs. Examples of SSM Run Commands are ShellScript and PowerShell.  Feel free to read more about Running Commands Using Systems Manager Run Command.

The following code shows the format of a job submitted to SQS in JSON.

  {

    "job_id": "jobId_0",

    "retry": "3",

    "job_success_string": " ",

    "ssm_document": "AWS-RunPowerShellScript",

    "commands":

        [

            "cd C:\\ProgramData\\Amazon\\SSM; mkdir Result",

            "Copy-S3object -Bucket my-bucket -KeyPrefix jobs/date/jobId_0 -LocalFolder .\\",

            "C:\\ProgramData\\Amazon\\SSM\\jobId_0.bat",

            "Write-S3object -Bucket my-bucket -KeyPrefix jobs/date/jobId_0 –Folder .\\Result\\"

        ],

  }

 

Any EC2 Instance associated with a serverless scheduler it receives jobs picked up from a designated SQS queue until the queue is empty. Then, the EC2 resource automatically terminates. If the job fails, it retries until it reaches the specified number of times in the job definition. You can include a specific string value so that the scheduler searches for job execution outputs and confirms the successful completions of jobs.

 

Tagging EC2 workers to get a serverless scheduler state machine

In Part 1 of the deployment, you must manage your EC2 Instance launch and termination. When launching an EC2 Instance, tag it with a specific tag key that triggers a state machine to manage that instance. The tag value is the name of the SQS queue that you want your state machine to poll jobs from.

In the following example, “my-scheduler-cloudformation-stack-name” is the tag key that serverless scheduler app will for with any new EC2 instance that starts. Next, “my-sqs-job-queue-name” is the default job queue created with the scheduler. But, you can change this to any queue name you want to retrieve jobs from when an instance is launched.

{"my-scheduler-cloudformation-stack-name":"my-sqs-job-queue-name"}

 

Monitor jobs in DynamoDB

You can monitor job status in the following DynamoDB. In the table you can find job_id, commands sent to Amazon EC2, job status, job output logs from Amazon EC2, and retries among other things.

Alternatively, you can query DynamoDB for a given job_id via the AWS Command Line Interface:

aws dynamodb get-item --table-name job-monitoring \

                      --key '{"job_id": {"S": "/my-jobs/my-job-id.bat"}}'

 

Using the “job_success_string” parameter

For the prior DynamoDB table, we submitted two identical jobs using an example script that you can also use. The command sent to the instance is “echo Hello World.” The output from this job should be “Hello World.” We also specified three allowed job retries.  In the following image, there are two jobs in SQS queue before they ran.  Look closely at the different “job_success_strings” for each and the identical command sent to both:

DynamoDB CLI info This shows an example DynamoDB CLI output with job information.

From the image we see that Job2 was successful and Job1 retried three times before permanently labelled as failed. We forced this outcome to demonstrate how the job success string works by submitting Job1 with “job_success_string” as “Hello EVERYONE”, as that will not be in the job output “Hello World.” In “Job2” we set “job_success_string” as “Hello” because we knew this string will be in the output log.

Job outputs commonly have text that only appears if job succeeded. You can also add this text yourself in your executable file. With “job_success_string,” you can confirm a job’s successful output, and use it to identify a certain value that you are looking for across jobs.

 

Part 2 – Resource Automation with the serverless scheduler

The additional services we deploy in Part 2 integrate with existing architectures to launch resources for your serverless scheduler. These services allow you to submit jobs simply by uploading input files and executable files to an S3 bucket.

Likewise, these additional resources can use any executable file format you want, including proprietary application level scripts. The solution automates everything else. This includes creating and submitting jobs to SQS job queue, spinning up compute resources when new jobs come in, and taking them back down when there are no jobs to run. When jobs are done, result files are copied to S3 for the user to retrieve. Similar to Part 1, you can still view the DynamoDB table for job status.

This architecture makes it easy to scale out to different teams and departments, and you can submit potentially hundreds of thousands of jobs while you remain in control of resources and cost.

 

Deeper Look at the S3 Architecture

The following diagram shows how you can submit jobs, monitor progress, and retrieve results. To submit jobs, upload all the needed input files and an executable script to S3. The suffix of the executable file (uploaded last) triggers an S3 event to start the process, and this suffix is configurable.

The S3 key of the executable file acts as the job id, and is kept as a reference to that job in DynamoDB. The Lambda (#2 in diagram below) uses the S3 key of the executable to create three SSM Run Commands.

  1. Synchronize all files in the same S3 folder to a working directory on the EC2 Instance.
  2. Run the executable file on EC2 Instances within a specified working directory.
  3. Synchronize the EC2 Instances working directory back to the S3 bucket where newly generated result files are included.

This Lambda (#2) then places the job on the SQS queue using the schedulers JSON formatted job definition seen above.

IMPORTANT: Each set of job files should be given a unique job folder in S3 or more files than needed might be moved to the EC2 Instance.

 

Figure 5: Resource Automation using Serverless Scheduler - A deeper look A deeper dive in to Part 2, resource allcoation.

Figure 5: Resource Automation using Serverless Scheduler – A deeper look

 

EC2 and Step Functions workflow use the Lambda function (#3 in prior diagram) and the Auto Scaling group to scale out based on the number of jobs in the queue to a maximum number of workers (plus state machine), as defined in the Auto Scaling Group. When the job queue is empty, the number of running instances scale down to 0 as they finish their remaining jobs.

 

Process Submitting Jobs and Retrieving Results

  1. Seen in1, upload input file(s) and an executable file into a unique job folder in S3 (such as /year/month/day/jobid/~job-files). Upload the executable file last because it automatically starts the job. You can also use a script to upload multiple files at a time but each job will need a unique directory. There are many ways to make S3 buckets available to users including AWS Storage Gateway, AWS Transfer for SFTP, AWS DataSync, the AWS Console or any one of the AWS SDKs leveraging S3 API calls.
  2. You can monitor job status by accessing the DynamoDB table directly via the AWS Management Console or use the AWS CLI to call DynamoDB via an API call.
  3. Seen in step 5, you can retrieve result files for jobs from the same S3 directory where you left the input files. The DynamoDB table confirms when jobs are done. The SQS output queue can be used by applications that must automatically poll and retrieve results.

You no longer need to create or access compute nodes as compute resources. These automatically scale up from zero when jobs come in, and then back down to zero when jobs are finished.

 

Deployment

Read the GitHub Repo for deployment instructions. Below are CloudFormation templates to help:

AWS RegionLaunch Stack
eu-north-1link to zone
ap-south-1
eu-west-3
eu-west-2
eu-west-1
ap-northeast-3
ap-northeast-2
ap-northeast-1
sa-east-1
ca-central-1
ap-southeast-1
ap-southeast-2
eu-central-1
us-east-1
us-east-2
us-west-1
us-west-2

 

 

Additional Points on Usage Patterns

 

  • While the two solutions in this blog are aimed at HPC applications, they can be used to run any batch jobs. Many customers that run large data processing batch jobs in their data lakes could use the serverless scheduler.

 

  • You can build pipelines of different applications when the output of one job triggers another to do something else – an example being pre-processing, meshing, simulation, post-processing. You simply deploy the Resource Automation template several times, and tailor it so that the output bucket for one step is the input bucket for the next step.

 

  • You might look to use the “job_success_string” parameter for iteration/verification used in cases where a shot-gun approach is needed to run thousands of jobs, and only one has a chance of producing the right result. In this case the “job_success_string” would identify the successful job from potentially hundreds of thousands pushed to SQS job queue.

 

Scale-out across teams and departments

Because all services used are serverless, you can deploy as many run environments as needed without increasing overall costs. Serverless workloads only accumulate cost when the services are used. So, you could deploy ten job environments and run one job in each, and your costs would be the same if you had one job environment running ten jobs.

 

All you need is an S3 bucket to upload jobs to and an associated AMI that has the right applications and license configuration. Because a job configuration is passed to the scheduler at each job start, you can add new teams by creating an S3 bucket and pointing S3 events to a default Lambda function that pulls configurations for each job start.

 

Setup CI/CD pipeline to start continuous improvement of scheduler

If you are advanced, we encourage you to clone the git repo and customize this solution. The serverless scheduler is less complex than other schedulers, because you only think about one worker and the process of one job’s run.

Ways you could tailor this solution:

  • Add intelligent job scheduling using AWS Sagemaker  – It is hard to find data as ready for ML as log data because every job you run has different run times and resource consumption. So, you could tailor this solution to predict the best instance to use with ML when workloads are submitted.
  • Add Custom Licensing Checkout Logic – Simply add one Lambda function to your Step Functions workflow to make an API call a license server before continuing with one or more jobs. You can start a new worker when you have a license checked out or if a license is not available then the instance can terminate to remove any costs waiting for licenses.
  • Add Custom Metrics to DynamoDB – You can easily add metrics to DynamoDB because the solution already has baseline logging and monitoring capabilities.
  • Run on other AWS Services – There is a Lambda function in the Step Functions workflow called “Start_Job”. You can tailor this Lambda to run your jobs on AWS Sagemaker, AWS EMR, AWS EKS or AWS ECS instead of EC2.

 

Conclusion

 

Although HPC workloads and EDA flows may still be dependent on current scheduling technologies, we illustrated the possibilities of decoupling your workloads from your existing shared scheduling environments. This post went deep into decoupled serverless scheduling, and we understand that it is difficult to unwind decades of dependencies. However, leveraging numerous AWS Services encourages you to think completely differently about running workloads.

But more importantly, it encourages you to Think Big. With this solution you can get up and running quickly, fail fast, and iterate. You can do this while scaling to your required number of resources, when you want them, and only pay for what you use.

Serverless computing  catalyzes change across all industries, but that change is not obvious in the HPC and EDA industries. This solution is an opportunity for customers to take advantage of the nearly limitless capacity that AWS.

Please reach out with questions about HPC and EDA on AWS. You now have the architecture and the instructions to build your Serverless Decoupled Scheduling environment.  Go build!


About the Authors and Contributors

Authors 

 

Ludvig Nordstrom is a Senior Solutions Architect at AWS

 

 

 

 

Mark Duffield is a Tech Lead in Semiconductors at AWS

 

 

 

Contributors

 

Steve Engledow is a Senior Solutions Builder at AWS

 

 

 

 

Arun Thomas is a Senior Solutions Builder at AWS

 

 

Code a Frogger-style road-crossing game | Wireframe #27

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/code-a-frogger-style-road-crossing-game-wireframe-27/

Guide a frog across busy roads and rivers. Mark Vanstone shows you how to code a simple remake of Konami’s arcade game, Frogger.

Konami’s original Frogger: so iconic, it even featured in a 1998 episode of Seinfeld.

Frogger

Why did the frog cross the road? Because Frogger would be a pretty boring game if it didn’t. Released in 1981 by Konami, the game appeared in assorted bars, sports halls, and arcades across the world, and became an instant hit. The concept was simple: players used the joystick to move a succession of frogs from the bottom of the screen to the top, avoiding a variety of hazards – cars, lorries, and later, the occasional crocodile. Each frog had to be safely manoeuvred to one of five alcoves within a time limit, while extra points were awarded for eating flies along the way.

Before Frogger, Konami mainly focused on churning out clones of other hit arcade games like Space Invaders and Breakout; Frogger was one of its earliest original ideas, and the simplicity of its concept saw it ported to just about every home system available at the time. (Ironically, Konami’s game would fall victim to repeated cloning by other developers.) Decades later, developers still take inspiration from it; Hipster Whale’s Crossy Road turned Frogger into an endless running game; earlier this year, Konami returned to the creative well with Frogger in Toy Town, released on Apple Arcade.

Code your own Konami Frogger

We can recreate much of Frogger’s gameplay in just a few lines of Pygame Zero code. The key elements are the frog’s movement, which use the arrow keys, vehicles that move across the screen, and floating objects – logs and turtles – moving in opposite directions. Our background graphic will provide the road, river, and grass for our frog to move over. The frog’s movement will be triggered from an on_key_down() function, and as the frog moves, we switch to a second frame with legs outstretched, reverting back to a sitting position after a short delay. We can use the inbuilt Actor properties to change the image and set the angle of rotation.

In our Frogger homage, we move the frog with the arrow keys to avoid the traffic, and jump onto the floating logs and turtles.

For all the other moving elements, we can also use Pygame Zero Actors; we just need to make an array for our cars with different graphics for the various rows, and an array for our floating objects in the same way.
In our update() function, we need to move each Actor according to which row it’s in, and when an Actor disappears off the screen, set the x coordinate so that it reappears on the opposite side.

Handling the logic of the frog moving across the road is quite easy; we just check for collision with each of the cars, and if the frog hits a car, then we have a squashed frog. The river crossing is a little more complicated. Each time the frog moves on the river, we need to make sure that it’s on a floating Actor. We therefore check to make sure that the frog is in collision with one of the floating elements, otherwise it’s game over.

There are lots of other elements you could add to the example shown here: the original arcade game provided several frogs to guide to their alcoves on the other side of the river, while crocodiles also popped up from time to time to add a bit more danger. Pygame Zero has all the tools you need to make a fully functional version of Konami’s hit.

Here’s Mark’s code, which gets a Frogger homage running in Python. To get it working on your system, you’ll first need to install Pygame Zero. And to download the full code, go here.

Get your copy of Wireframe issue 27

You can read more features like this one in Wireframe issue 27, available now at Tesco, WHSmith, all good independent UK newsagents, and the Raspberry Pi Store, Cambridge.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 27 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Code a Frogger-style road-crossing game | Wireframe #27 appeared first on Raspberry Pi.

Code a Phoenix-style mothership battle | Wireframe #26

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/code-a-phoenix-style-mothership-battle-wireframe-26/

It was one of gaming’s first boss battles. Mark Vanstone shows you how to recreate the mothership from the 1980 arcade game, Phoenix.

Phoenix’s fifth stage offered a unique challenge in 1980: one of gaming’s first-ever boss battles.

First released in 1980, Phoenix was something of an arcade pioneer. The game was the kind of post-Space Invaders fixed-screen shooter that was ubiquitous at the time: players moved their ship from side to side, shooting at a variety of alien birds of different sizes and attack patterns. The enemies moved swiftly, and the player’s only defence was a temporary shield which could be activated when the birds swooped and strafed the lone defender. But besides all that, Phoenix had a few new ideas of its own: not only did it offer five distinct stages, but it also featured one of the earliest examples of a boss battle – its heavily armoured alien mothership, which required accurate shots to its shields before its weak spot could be exposed.

To recreate Phoenix’s boss, all we need is Pygame Zero. We can get a portrait style window with the WIDTH and HEIGHT variables and throw in some parallax stars (an improvement on the original’s static backdrop) with some blitting in the draw() function. The parallax effect is created by having a static background of stars with a second (repeated) layer of stars moving down the screen.

The mothership itself is made up of several Actor objects which move together down the screen towards the player’s spacecraft, which can be moved right and left using the mouse. There’s the main body of the mothership, in the centre is the alien that we want to shoot, and then we have two sets of moving shields.

Like the original Phoenix, our mothership boss battle has multiple shields that need to be taken out to expose the alien at the core.

In this example, rather than have all the graphics dimensions in multiples of eight (as we always did in the old days), we will make all our shield blocks 20 by 20 pixels, because computers simply don’t need to work in multiples of eight any more. The first set of shields is the purple rotating bar around the middle of the ship. This is made up of 14 Actor blocks which shift one place to the right each time they move. Every other block has a couple of portal windows which makes the rotation obvious, and when a block moves off the right-hand side, it is placed on the far left of the bar.

The second set of shields are in three yellow rows (you may want to add more), the first with 14 blocks, the second with ten blocks, and the last with four. These shield blocks are fixed in place but share a behaviour with the purple bar shields, in that when they are hit by a bullet, they change to a damaged version. There are four levels of damage before they are destroyed and the bullets can pass through. When enough shields have been destroyed for a bullet to reach the alien, the mothership is destroyed (in this version, the alien flashes).

Bullets can be fired by clicking the mouse button. Again, the original game had alien birds flying around the mothership and dive-bombing the player, making it harder to get a good shot in, but this is something you could try adding to the code yourself.

To really bring home that eighties Phoenix arcade experience, you could also add in some atmospheric shooting effects and, to round the whole thing off, have an 8-bit rendition of Beethoven’s Für Elise playing in the background.

Here’s Mark’s code, which gets a simple mothership battle running in Python. To get it working on your system, you’ll first need to install Pygame Zero. And to download the full code, go here.

Get your copy of Wireframe issue 26

You can read more features like this one in Wireframe issue 26, available now at Tesco, WHSmith, all good independent UK newsagents, and the Raspberry Pi Store, Cambridge.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 26 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Code a Phoenix-style mothership battle | Wireframe #26 appeared first on Raspberry Pi.

Setting up a CI/CD pipeline by integrating Jenkins with AWS CodeBuild and AWS CodeDeploy

Post Syndicated from Noha Ghazal original https://aws.amazon.com/blogs/devops/setting-up-a-ci-cd-pipeline-by-integrating-jenkins-with-aws-codebuild-and-aws-codedeploy/

In this post, I explain how to use the Jenkins open-source automation server to deploy AWS CodeBuild artifacts with AWS CodeDeploy, creating a functioning CI/CD pipeline. When properly implemented, the CI/CD pipeline is triggered by code changes pushed to your GitHub repo, automatically fed into CodeBuild, then the output is deployed on CodeDeploy.

Solution overview

The functioning pipeline creates a fully managed build service that compiles your source code. It then produces code artifacts that can be used by CodeDeploy to deploy to your production environment automatically.

The deployment workflow starts by placing the application code on the GitHub repository. To automate this scenario, I added source code management to the Jenkins project under the Source Code section. I chose the GitHub option, which by design clones a copy from the GitHub repo content in the Jenkins local workspace directory.

In the second step of my automation procedure, I enabled a trigger for the Jenkins server using an “Poll SCM” option. This option makes Jenkins check the configured repository for any new commits/code changes with a specified frequency. In this testing scenario, I configured the trigger to perform every two minutes. The automated Jenkins deployment process works as follows:

  1. Jenkins checks for any new changes on GitHub every two minutes.
  2. Change determination:
    1. If Jenkins finds no changes, Jenkins exits the procedure.
    2. If it does find changes, Jenkins clones all the files from the GitHub repository to the Jenkins server workspace directory.
  3. The File Operation plugin deletes all the files cloned from GitHub. This keeps the Jenkins workspace directory clean.
  4. The AWS CodeBuild plugin zips the files and sends them to a predefined Amazon S3 bucket location then initiates the CodeBuild project, which obtains the code from the S3 bucket. The project then creates the output artifact zip file, and stores that file again on the S3 bucket.
  5. The HTTP Request plugin downloads the CodeBuild output artifacts from the S3 bucket.
    I edited the S3 bucket policy to allow access from the Jenkins server IP address. See the following example policy:

    {
      "Version": "2012-10-17",
      "Id": "S3PolicyId1",
      "Statement": [
        {
          "Sid": "IPAllow",
          "Effect": "Allow",
          "Principal": "*",
          "Action": "s3:*",
          "Resource": "arn:aws:s3:::examplebucket/*",
          "Condition": {
             "IpAddress": {"aws:SourceIp": "x.x.x.x/x"},  <--- IP of the Jenkins server
          } 
        } 
      ]
    }
    
    

    This policy enables the HTTP request plugin to access the S3 bucket. This plugin doesn’t use the IAM instance profile or the AWS access keys (access key ID and secret access key).

  6. The output artifact is a compressed ZIP file. The CodeDeploy plugin by design requires the files to be unzipped to zip them and send them over to the S3 bucket for the CodeDeploy deployment. For that, I used the File Operation plugin to perform the following:
    1. Unzip the CodeBuild zipped artifact output in the Jenkins root workspace directory. At this point, the workspace directory should include the original zip file downloaded from the S3 bucket from Step 5 and the files extracted from this archive.
    2. Delete the original .zip file, and leave only the source bundle contents for the deployment.
  7. The CodeDeploy plugin selects and zips all workspace directory files. This plugin uses the CodeDeploy application name, deployment group name, and deployment configurations that you configured to initiate a new CodeDeploy deployment. The CodeDeploy plugin then uploads the newly zipped file according to the S3 bucket location provided to CodeDeploy as a source code for its new deployment operation.

Walkthrough

In this post, I walk you through the following steps:

  • Creating resources to build the infrastructure, including the Jenkins server, CodeBuild project, and CodeDeploy application.
  • Accessing and unlocking the Jenkins server.
  • Creating a project and configuring the CodeDeploy Jenkins plugin.
  • Testing the whole CI/CD pipeline.

Create the resources

In this section, I show you how to launch an AWS CloudFormation template, a tool that creates the following resources:

  • Amazon S3 bucket—Stores the GitHub repository files and the CodeBuild artifact application file that CodeDeploy uses.
  • IAM S3 bucket policy—Allows the Jenkins server access to the S3 bucket.
  • JenkinsRole—An IAM role and instance profile for the Amazon EC2 instance for use as a Jenkins server. This role allows Jenkins on the EC2 instance to access the S3 bucket to write files and access to create CodeDeploy deployments.
  • CodeDeploy application and CodeDeploy deployment group.
  • CodeDeploy service role—An IAM role to enable CodeDeploy to read the tags applied to the instances or the EC2 Auto Scaling group names associated with the instances.
  • CodeDeployRole—An IAM role and instance profile for the EC2 instances of CodeDeploy. This role has permissions to write files to the S3 bucket created by this template and to create deployments in CodeDeploy.
  • CodeBuildRole—An IAM role to be used by CodeBuild to access the S3 bucket and create the build projects.
  • Jenkins server—An EC2 instance running Jenkins.
  • CodeBuild project—This is configured with the S3 bucket and S3 artifact.
  • Auto Scaling group—Contains EC2 instances running Apache and the CodeDeploy agent fronted by an Elastic Load Balancer.
  • Auto Scaling launch configurations—For use by the Auto Scaling group.
  • Security groups—For the Jenkins server, the load balancer, and the CodeDeploy EC2 instances.

 

  1. To create the CloudFormation stack (for example in the AWS Frankfurt Region) click the below link:
    .

    .
  2. Choose Next and provide the following values on the Specify Details page:
    • For Stack name, name your stack as you prefer.
    • For CodedeployInstanceCount, choose the default of t2.medium.
      To check the supported instance types by AWS Region, see Supported Regions.
    • For InstanceCount, keep the default of 3, to launch three EC2 instances for CodeDeploy.
    • For JenkinsInstanceType, keep the default of t2.medium.
    • For KeyName, choose an existing EC2 key pair in your AWS account. Use this to connect by using SSH to the Jenkins server and the CodeDeploy EC2 instances. Make sure that you have access to the private key of this key pair.
    • For PublicSubnet1, choose a public subnet from which the load balancer, Jenkins server, and CodeDeploy web servers launch.
    • For PublicSubnet2, choose a public subnet from which the load balancers and CodeDeploy web servers launch.
    • For VpcId, choose the VPC for the public subnets you used in PublicSubnet1 and PublicSubnet2.
    • For YourIPRange, enter the CIDR block of the network from which you connect to the Jenkins server using HTTP and SSH. If your local machine has a static public IP address, go to https://www.whatismyip.com/ to find your IP address, and then enter your IP address followed by /32. If you don’t have a static IP address (or aren’t sure if you have one), enter 0.0.0.0/0. Then, any address can reach your Jenkins server.
      .
  3. Choose Next.
  4. On the Review page, select the I acknowledge that this template might cause AWS CloudFormation to create IAM resources check box.
  5. Choose Create and wait for the CloudFormation stack status to change to CREATE_COMPLETE. This takes approximately 6–10 minutes.
  6. Check the resulting values on the Outputs tab. You need them later.
    .
  7. Browse to the ELBDNSName value from the Outputs tab, verifying that you can see the Sample page. You should see a congratulatory message.
  8. Your Jenkins server should be ready to deploy.

Access and unlock your Jenkins server

In this section, I discuss how to access, unlock, and customize your Jenkins server.

  1. Copy the JenkinsServerDNSName value from the Outputs tab of the CloudFormation stack, and paste it into your browser.
  2. To unlock the Jenkins server, SSH to the server using the IP address and key pair, following the instructions from Unlocking Jenkins.
  3. Use the root user to Cat the log file (/var/log/jenkins/jenkins.log) and copy the automatically generated alphanumeric password (between the two sets of asterisks). Then, use the password to unlock your Jenkins server, as shown in the following screenshots.
    .
  4. On the Customize Jenkins page, choose Install suggested plugins.

  5. Wait until Jenkins installs all the suggested plugins. When the process completes, you should see the check marks alongside all of the installed plugins.
    .
    .
  6. On the Create First Admin User page, enter a user name, password, full name, and email address of the Jenkins user.
  7. Choose Save and continue, Save and finish, and Start using Jenkins.
    .
    After you install all the needed Jenkins plugins along with their required dependencies, the Jenkins server restarts. This step should take about two minutes. After Jenkins restarts, refresh the page. Your Jenkins server should be ready to use.

Create a project and configure the CodeDeploy Jenkins plugin

Now, to create our project in Jenkins we need to configure the required Jenkins plugin.

  1. Sign in to Jenkins with the user name and password that you created earlier and click on Manage Jenkins then Manage Plugins.
  2. From the Available tab search for and select the below plugins then choose Install without restart:
    .
    AWS CodeDeploy
    AWS CodeBuild
    Http Request
    File Operations
    .
  3. Select the Restart Jenkins when installation is complete and no jobs are running.
    Jenkins will take couple of minutes to download the plugins along with their dependencies then will restart.
  4. Login then choose New Item, Freestyle project.
  5. Enter a name for the project (for example, CodeDeployApp), and choose OK.
    .

    .
  6. On the project configuration page, under Source Code Management, choose Git. For Repository URL, enter the URL of your GitHub repository.
    .

    .
  7. For Build Triggers, select the Poll SCM check box. In the Schedule, for testing enter H/2 * * * *. This entry tells Jenkins to poll GitHub every two minutes for updates.
    .

    .
  8. Under Build Environment, select the Delete workspace before build starts check box. Each Jenkins project has a dedicated workspace directory. This option allows you to wipe out your workspace directory with each new Jenkins build, to keep it clean.
    .

    .
  9. Under Build Actions, add a Build Step, and AWS CodeBuild. On the AWS Configurations, choose Manually specify access and secret keys and provide the keys.
    .
    .
  10. From the CloudFormation stack Outputs tab, copy the AWS CodeBuild project name (myProjectName) and paste it in the Project Name field. Also, set the Region that you are using and choose Use Jenkins source.
    It is a best practice is to store AWS credentials for CodeBuild in the native Jenkins credential store. For more information, see the Jenkins AWS CodeBuild Plugin wiki.
    .
    .
  11. To make sure that all files cloned from the GitHub repository are deleted choose Add build step and select File Operation plugin, then click Add and select File Delete. Under File Delete operation in the Include File Pattern, type an asterisk.
    .
    .
  12. Under Build, configure the following:
    1. Choose Add a Build step.
    2. Choose HTTP Request.
    3. Copy the S3 bucket name from the CloudFormation stack Outputs tab and paste it after (http://s3-eu-central-1.amazonaws.com/) along with the name of the zip file codebuild-artifact.zip as the value for HTTP Plugin URL.
      Example: (http://s3-eu-central-1.amazonaws.com/mybucketname/codebuild-artifact.zip)
    4. For Ignore SSL errors?, choose Yes.
      .

      .
  13. Under HTTP Request, choose Advanced and leave the default values for Authorization, Headers, and Body. Under Response, for Output response to file, enter the codebuild-artifact.zip file name.
    .

    .
  14. Add the two build steps for the File Operations plugin, in the following order:
    1. Unzip action: This build step unzips the codebuild-artifact.zip file and places the contents in the root workspace directory.
    2. File Delete action: This build step deletes the codebuild-artifact.zip file, leaving only the source bundle contents for deployment.
      .
      .
  15. On the Post-build Actions, choose Add post-build actions and select the Deploy an application to AWS CodeDeploy check box.
  16. Enter the following values from the Outputs tab of your CloudFormation stack and leave the other settings at their default (blank):
    • For AWS CodeDeploy Application Name, enter the value of CodeDeployApplicationName.
    • For AWS CodeDeploy Deployment Group, enter the value of CodeDeployDeploymentGroup.
    • For AWS CodeDeploy Deployment Config, enter CodeDeployDefault.OneAtATime.
    • For AWS Region, choose the Region where you created the CodeDeploy environment.
    • For S3 Bucket, enter the value of S3BucketName.
      The CodeDeploy plugin uses the Include Files option to filter the files based on specific file names existing in your current Jenkins deployment workspace directory. The plugin zips specified files into one file. It then sends them to the location specified in the S3 Bucket parameter for CodeDeploy to download and use in the new deployment.
      .
      As shown below, in the optional Include Files field, I used (**) so all files in the workspace directory get zipped.
      .
      .
  17. Choose Deploy Revision. This option registers the newly created revision to your CodeDeploy application and gets it ready for deployment.
  18. Select the Wait for deployment to finish? check box. This option allows you to view the CodeDeploy deployments logs and events on your Jenkins server console output.
    .
    .
    Now that you have created a project, you are ready to test deployment.

Testing the whole CI/CD pipeline

To test the whole solution, put an application on your GitHub repository. You can download the sample from here.

The following screenshot shows an application tree containing the application source files, including text and binary files, executables, and packages:

In this example, the application files are the templates directory, test_app.py file, and web.py file.

The appspec.yml file is the main application specification file telling CodeDeploy how to deploy your application. Jenkins uses the AppSpec file to manage each deployment as a series of lifecycle event “hooks”, as defined in the file. For information about how to create a well-formed AppSpec file, see AWS CodeDeploy AppSpec File Reference.

The buildspec.yml file is a collection of build commands and related settings, in YAML format, that CodeBuild uses to run a build. You can include a build spec as part of the source code, or you can define a build spec when you create a build project. For more information, see How AWS CodeBuild Works.

The scripts folder contains the scripts that you would like to run during the CodeDeploy LifecycleHooks execution with respect to your application requirements. For more information, see Plan a Revision for AWS CodeDeploy.

To test this solution, perform the following steps:

  1. Unzip the application files and send them to your GitHub repository, run the following git commands from the path where you placed your sample application:
    $ git add -A
    
    $ git commit -m 'Your first application'
    
    $ git push
  2. On the Jenkins server dashboard, wait for two minutes until the previously set project trigger starts working. After the trigger starts working, you should see a new build taking place.
    .

    .
  3. In the Jenkins server Console Output page, check the build events and review the steps performed by each Jenkins plugin. You can also review the CodeDeploy deployment in detail, as shown in the following screenshot:
    .

On completion, Jenkins should report that you have successfully deployed a web application. You can also use your ELBDNSName value to confirm that the deployed application is running successfully.

.

.Conclusion

In this post, I outlined how you can use a Jenkins open-source automation server to deploy CodeBuild artifacts with CodeDeploy. I showed you how to construct a functioning CI/CD pipeline with these tools. I walked you through how to build the deployment infrastructure and automatically deploy application version changes from GitHub to your production environment.

Hopefully, you have found this post informative and the proposed solution useful. As always, AWS welcomes all feedback or comment.

About the Author

.

 

Noha Ghazal is a Cloud Support Engineer at Amazon Web Services. She is is a subject matter expert for AWS CodeDeploy. In her role, she enjoys supporting customers with their CodeDeploy and other DevOps configurations. Outside of work she enjoys drawing portraits, fishing and playing video games.

 

 

Make a Columns-style tile-matching game | Wireframe #25

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/make-a-columns-style-tile-matching-game-wireframe-25/

Raspberry Pi’s own Rik Cross shows you how to code your own Columns-style tile-matching puzzle game in Python and Pygame Zero.

Created by Hewlett-Packard engineer Jay Geertsen, Columns was Sega’s sparkly rival to Nintendo’s all-conquering Tetris.

Columns and tile-matching

Tile-matching games began with Tetris in 1984 and the less famous Chain Shot! the following year. The genre gradually evolved through games like Dr. Mario, Columns, Puyo Puyo, and Candy Crush Saga. Although their mechanics differ, the goals are the same: to organise a board of different-coloured tiles by moving them around until they match.

Here, I’ll show how you can create a simple tile-matching game using Python and Pygame. In it, any tile can be swapped with the tile to its right, with the aim being to make matches of three or more tiles of the same colour. Making a match causes the tiles to disappear from the board, with tiles dropping down to fill in the gaps.

At the start of a new game, a board of randomly generated tiles is created. This is made as an (initially empty) two-dimensional array, whose size is determined by the values of rows and columns. A specific tile on the board is referenced by its row and column number.

We want to start with a truly random board, but we also want to avoid having any matching tiles. Random tiles are added to each board position, therefore, but replaced if a tile is the same as the one above or to it’s left (if such a tile exists).

Our board consists of 12 rows and 8 columns of tiles. Pressing SPACE will swap the 2 selected tiles (outlined in white), and in this case, create a match of red tiles vertically.

In our game, two tiles are ‘selected’ at any one time, with the player pressing the arrow keys to change those tiles. A selected variable keeps track of the row and column of the left-most selected tile, with the other tile being one column to the right of the left-most tile. Pressing SPACE swaps the two selected tiles, checks for matches, clears any matched tiles, and fills any gaps with new tiles.

A basic ‘match-three’ algorithm would simply check whether any tiles on the board have a matching colour tile on either side, horizontally or vertically. I’ve opted for something a little more convoluted, though, as it allows us to check for matches on any length, as well as track multiple, separate matches. A currentmatch list keeps track of the (x,y) positions of a set of matching tiles. Whenever this list is empty, the next tile to check is added to the list, and this process is repeated until the next tile is a different colour.

If the currentmatch list contains three or more tiles at this point, then the list is added to the overall matches list (a list of lists of matches!) and the currentmatch list is reset. To clear matched tiles, the matched tile positions are set to None, which indicates the absence of a tile at that position. To fill the board, tiles in each column are moved down by one row whenever an empty board position is found, with a new tile being added to the top row of the board.

The code provided here is just a starting point, and there are lots of ways to develop the game, including adding a scoring system and animation to liven up your tiles.

Here’s Rik’s code, which gets a simple tile-match game running in Python. To get it working on your system, you’ll first need to install Pygame Zero. And to download the full code, go here.

Get your copy of Wireframe issue 25

You can read more features like this one in Wireframe issue 25, available now at Tesco, WHSmith, all good independent UK newsagents, and the Raspberry Pi Store, Cambridge.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 25 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Make a Columns-style tile-matching game | Wireframe #25 appeared first on Raspberry Pi.

Code your own Donkey Kong barrels | Wireframe issue 24

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/code-your-own-donkey-kong-barrels-wireframe-issue-24/

Replicate the physics of barrel rolling – straight out of the classic Donkey Kong. Mark Vanstone shows you how.

Released in 1981, Donkey Kong was one of the most important games in Nintendo’s history.

Nintendo’s Donkey Kong

Donkey Kong first appeared in arcades in 1981, and starred not only the titular angry ape, but also a bouncing, climbing character called Jumpman – who later went on to star in Nintendo’s little-known series of Super Mario games. Donkey Kong featured four screens per level, and the goal in each was to avoid obstacles and guide Mario (sorry, Jumpman) to the top of the screen to rescue the hapless Pauline. Partly because the game was so ferociously difficult from the beginning, Donkey Kong’s first screen is arguably the most recognisable today: Kong lobs an endless stream of barrels, which roll down a network of crooked girders and threaten to knock Jumpman flat.

Barrels in Pygame Zero

Donkey Kong may have been a relentlessly tough game, but we can recreate one of its most recognisable elements with relative ease. We can get a bit of code running with Pygame Zero – and a couple of functions borrowed from Pygame – to make barrels react to the platforms they’re on, roll down in the direction of a slope, and fall off the end onto the next platform. It’s a very simple physics simulation using an invisible bitmap to test where the platforms are and which way they’re sloping. We also have some ladders which the barrels randomly either roll past or sometimes use to descend to the next platform below.

Our Donkey Kong tribute up and running in Pygame Zero. The barrels roll down the platforms and sometimes the ladders.

Once we’ve created a barrel as an Actor, the code does three tests for its platform position on each update: one to the bottom-left of the barrel, one bottom-centre, and one bottom-right. It samples three pixels and calculates how much red is in those pixels. That tells us how much platform is under the barrel in each position. If the platform is tilted right, the number will be higher on the left, and the barrel must move to the right. If tilted left, the number will be higher on the right, and the barrel must move left. If there is no red under the centre point, the barrel is in the air and must fall downward.

There are just three frames of animation for the barrel rolling (you could add more for a smoother look): for rolling right, we increase the frame number stored with the barrel Actor; for rolling to the left, we decrease the frame number; and if the barrel’s going down a ladder, we use the front-facing images for the animation. The movement down a ladder is triggered by another test for the blue component of a pixel below the barrel. The code then chooses randomly whether to send the barrel down the ladder.

The whole routine will keep producing more barrels and moving them down the platforms until they reach the bottom. Again, this is a very simple physics system, but it demonstrates how those rolling barrels can be recreated in just a few lines of code. All we need now is a jumping player character (which could use the same invisible map to navigate up the screen) and a big ape to sit at the top throwing barrels, then you’ll have the makings of your own fully featured Donkey Kong tribute.

Here’s Mark’s code, which sets some Donkey Kong Barrels rolling about in Python. To get it working on your system, you’ll first need to install Pygame Zero. And to download the full code, go here.

Get your copy of Wireframe issue 24

You can read more features like this one in Wireframe issue 24, available now at Tesco, WHSmith, all good independent UK newsagents, and the Raspberry Pi Store, Cambridge.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can also download issue 24 for free in PDF format.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Code your own Donkey Kong barrels | Wireframe issue 24 appeared first on Raspberry Pi.

Make a keyboard-bashing sprint game | Wireframe issue 23

Post Syndicated from Ryan Lambie original https://www.raspberrypi.org/blog/make-a-keyboard-bashing-sprint-game-wireframe-issue-23/

Learn how to code a sprinting minigame straight out of Daley Thompson’s Decathlon with Raspberry Pi’s own Rik Cross.

Spurred on by the success of Konami’s Hyper Sports, Daley Thompson’s Decathlon featured a wealth of controller-wrecking minigames.

Daley Thompson’s Decathlon

Released in 1984, Daley Thompson’s Decathlon was a memorable entry in what’s sometimes called the ‘joystick killer’ genre: players competed in sporting events that largely consisted of frantically waggling the controller or battering the keyboard. I’ll show you how to create a sprinting game mechanic in Python and Pygame.

Python sprinting game

There are variables in the Sprinter() class to keep track of the runner’s speed and distance, as well as global constant ACCELERATION and DECELERATION values to determine the player’s changing rate of speed. These numbers are small, as they represent the number of metres per frame that the player accelerates and decelerates.

The player increases the sprinter’s speed by alternately pressing the left and right arrow keys. This input is handled by the sprinter’s isNextKeyPressed() method, which returns True if the correct key (and only the correct key) is being pressed. A lastKeyPressed variable is used to ensure that keys are pressed alternately. The player also decelerates if no key is being pressed, and this rate of deceleration should be sufficiently smaller than the acceleration to allow the player to pick up enough speed.

Press the left and right arrow keys alternately to increase the sprinter’s speed. Objects move across the screen from right to left to give the illusion of sprinter movement.

For the animation, I used a free sprite called ‘The Boy’ from gameart2d.com, and made use of a single idle image and 15 run cycle images. The sprinter starts in the idle state, but switches to the run cycle whenever its speed is greater than 0. This is achieved by using index() to find the name of the current sprinter image in the runFrames list, and setting the current image to the next image in the list (and wrapping back to the first image once the end of the list is reached). We also need the sprinter to move through images in the run cycle at a speed proportional to the sprinter’s speed. This is achieved by keeping track of the number of frames the current image has been displayed for (in a variable called timeOnCurrentFrame).

To give the illusion of movement, I’ve added objects that move past the player: there’s a finish line and three markers to regularly show the distance travelled. These objects are calculated using the sprinter’s x position on the screen along with the distance travelled. However, this means that each object is at most only 100 pixels away from the player and therefore seems to move slowly. This can be fixed by using a SCALE factor, which is the relationship between metres travelled by the sprinter and pixels on the screen. This means that objects are initially drawn way off to the right of the screen but then travel to the left and move past the sprinter more quickly.

Finally, startTime and finishTime variables are used to calculate the race time. Both values are initially set to the current time at the start of the race, with finishTime being updated as long as the distance travelled is less than 100. Using the time module, the race time can simply be calculated by finishTime - startTime.

Here’s Rik’s code, which gets a sprinting game running in Python (no pun intended). To get it working on your system, you’ll first need to install Pygame Zero. Download the code here.

Get your copy of Wireframe issue 23

You can read more features like this one in Wireframe issue 23, available now at Tesco, WHSmith, all good independent UK newsagents, and the Raspberry Pi Store, Cambridge.

Or you can buy Wireframe directly from Raspberry Pi Press — delivery is available worldwide. And if you’d like a handy digital version of the magazine, you can download issue 23 for free in PDF format.

Autonauts is coming to colonise your computers with cuteness. We find out more in Wireframe issue 23.

Make sure to follow Wireframe on Twitter and Facebook for updates and exclusive offers and giveaways. Subscribe on the Wireframe website to save up to 49% compared to newsstand pricing!

The post Make a keyboard-bashing sprint game | Wireframe issue 23 appeared first on Raspberry Pi.