Explorers Week 11 – Pacman

For the last week we worked on a Pacman type game. We tried to put in all the code we have learned over this year and all the games were brilliant and all so different.

This week is our very important week, our last week but the week we award our belts for all your great work during the year. There also might be some Pizza and the odd sausage.

Remember if you haven’t been in the last couple of weeks that doesn’t matter, come along we would love to see everyone.

 

Here are the notes in PDF CDA-S8 Week_11-PACMA.PDF

See u Saturday

Martha

Julie, Ruaidhrí and Eoin

Rock-Paper-Scissors for 1 and 2 Players

The Plan

Michael led the Advancers group this week, as Oliver was unavailable. Our plan was to work on 3 versions of Rock-Paper-Scissors:

  1. A one-person version where you play against the computer
  2. A two-person version where you and a friend play against each other on one computer
  3. A two-person version where you and a friend play against each other on different computers, using cloud variables (we did not get around to this)

We began by thinking about how the game works, and what we would need.

In our design, we need three sprites:

  1. My Player
  2. Opponent (either another player or the computer, depending on the version)
  3. Controller (a sprite that displays instructions, does the countdown, and uses broadcasts to sync the start and end

We also need several variables, the most important of which are:

  • my-pick: what I pick (rock/paper/scissors)
  • other-pick: what the opponent picks
  • result: based on the picks, will be set to “I win”, “I lose”, or “Draw”
  • number: a random number in the range 1-3 that the computer picks, which we translate into either a value for other-pick of “rock”, “paper”, or “scissors”

One-Person Version

Here is the logic:

1player

The controller has 5 costumes: one with instructions and four with big numbers 3,2,1,0 for the countdown.

The controller looks after the countdown, and broadcasts messages at the start and end of the countdown. Here is the controller’s code:

code1

My sprite takes my keyboard input. When the countdown is over, it calculates who wins (result). Also, when the countdown is over, it says what I picked, waits 3 seconds, and then says who won.

Here is the start of its code – you will have to figure out the other combinations yourself!

code2

The opponent sprite is the computer. Its sprite picks a random number 1-3 and converts it into a word rock/paper/scissors. It also says what it picked when the time is up. Here is the code:

code3

Two-Person Version

Here is the design:

2player

In this version, the Controller and My Sprite are the same as in the one-player version, except you might want to change My Sprite to use keys 1,2,3 for Rock, Paper, Scissors.

The Opponent Sprite code is different than before, but it is simpler: the opponent is your friend who will press 7, 8, 9 for Rock, Paper, Scissors, so you just need the code to read those key-presses:

code4

Possible Enhancements

Here are some ideas:

  • You could add sound effects, celebrations, and different costumes
  • You could find the rules for a more complex version and implement it: Rock-Paper-Scissors-Lizard-Spock
  • You could figure out cloud variables!

Creators – Random Dungeon

This week we took a look at a technique for generating random dungeons. Although never mentioned on the day, this technique is often called “marching squares”. It looks at the four corners of a space at a time, some of which are open and some of which are closed, and picks a shape that blocks off the closed corners.

There are sixteen possible combinations of corners on and off. All of these can be covered with these five shapes (or a rotation of them) to represent the closed off areas:

marchs

Generating the Dungeon

We generated a 2D array (a list of lists) to store our dungeon layout. At each point we used a 2D Perlin noise value (using the noise() function) to calculate a value. The point was deemed to be either open or closed based on whether this value was higher or lower than a threshold value we specified. Varying this threshold value can make the dungeon more open, or more closed in.

Drawing the Dungeon

To draw these shapes we first defined each of them as a list of x, y points defining the shape.

We then used beginShape()vertex(), and endShape() functions to draw them at the correct size, location and orientation by scale(), transform() and rotate().

Once we were able to draw the shapes, we just needed to loop over our grid, inspecting each set of four adjacent corners in turn and drawing the appropriate shape.

Here’s a screenshot of one random dungeon. Dots (green for open, red for closed) are drawn to show the grid and the lines between the individual shapes are also shown for clarity:

d2

and here is is without these overlays:

d1

Download

The files for this week can be found on our GitHub repository.

Creators – Quiz and Hacking

Screenshot 2019-05-02 at 00.23.50.png

This week we had a quiz. There were three rounds on Technology, Creators 2019 and Pop Culture. There was a very high proportion of correct answers on all questions. The quizes can be found here, for anyone that wants them:

Creators 2019

Pop Culture

Technology

 

After that we set everyone a programming challenge: make an animated scene. People got busy and there was some good progress. We will continue with that next week. Mark and I (Kieran) got in on the action figuring out how to draw clouds. My attempt is shown in the image at the top of this post. The code can be found, as always, on the CoderDojo Athenry Creators 2018 GitHub.

Explorers Week 10 – Scrolling Backgrounds

Hi everyone

Thank you to everyone who came on Saturday.

We did scrolling backgrounds and this is very useful in any type of game and can add an extra dimension to your game whether its a driving game or a flying game.

We were scrolling horizontally so we were using the xpos but remember you can just as easily scrolling vertically by just using the ypos

Here are the notes in PDF form

CDA-S8 Week_10-scrollingbackgrounds.pdf

 

Enjoy the long weekend and we will see you all the week after.

Martha

Julie, Eoin and Ruaidhrí

Creators – Flying Over Dynamic Terrain

 

This week we creating a game where a tiny plane flies over dynamically generated terrain picking up as many boxes as possible. The player scores a point for every box, but that also makes the plane fly faster, making the game more challenging.

Perlin Noise

Normal random-number generators produce values that jump around all over the place. Perlin noise is different. It is also random, but it varies smoothly. This makes it great for mimicking the sort of randomness we see in nature.

1D Perlin Noise Landscape

Our smooth and changing landscape is generated using a one-dimensional Perlin noise value generated by the P5.js function noise(xoff).

We start with a loop that goes across from 0 -> width across the screen. We’re looking to generate a set of [xy] points that define our shape.

We use these values:

  1. xstart: A starting value for xoff
  2. xinc: An amount to increment xoff by for every new location
  3. ymin: The smallest y value we want for our landscape – something a little below the top of the screen
  4. ymax: The largest y value we want for our landscape – something a little above the bottom of the screen

Each call to noise() generates a single value in the range 0-1. We use the P5.js function map() to change this value in the range 0-1 into a value in the range ymin-ymax.

Changing the size of xinc controls how choppy or smooth the landscape is. We tune it to a value that gives approximately two peaks and two valleys across the screen, and looks right for our game.

Moving the Landscape

Moving the landscape is achieved by changing the starting value of xoff (aka. xstart) each time we update the screen. By making it a little larger each time, the effect is that the landscape seems to scroll from right to left.

Other Parts of the Game

The other parts of the game are very standard. We define a simple plane shape (drawn using rect() calls)  that can move up or down in response to the arrow keys.

We define “cargo” containers that are randomly generated on the surface of the landscape and move right-to-left at the same speed.

The cargo containers have an active property that is false if they move beyond the left-edge of the screen or get sufficiently close to the plane to be “picked up”.

We added a function to the landscape class (Ground.js) that checks for a given [x, y] location to see if that point us under the ground by checking what the height of the landscape is at that x value. If the plane is below the ground we consider it crashed.

We added a simple scoring mechanism that tracks how many boxes were collected and makes the plane move faster (really – the ground scroll faster) every time a box is collected.

Download

The files for this week can be found on our GitHub repository.

Explorers Week 7 – Truchet Tiles

Hello everyone

Nice big room last week as we had Advancers and Explorers in the one room. As I said on Saturday, we will continue to combine the both groups for the next two weeks.

We are starting Stop/Start Animation this coming week and if you could bring some or all of the following it would be helpful.

PDF notes of the session can be found here CDA-S7-Week_07-TruchetTiles.pdf

 

See you next week,

Martha

Julie, Ruaidhrí and Eoin McG

Hackers – code for our first prototype remote-controlled robot

Here is a video of the first tests of our remote-controlled robot with 2-wheel drive.

The control for this is based on the calculations we described in an earlier post: https://coderdojoathenry.org/2019/02/24/hackers-how-to-control-a-robots-wheel-motors-based-on-joystick-movements/

Here is the code:

// Code by Luke Madden, CoderDojo Athenry, with some comments added by Michael.
// This code controls a robot with 2-wheel drive, based on movements of a joystick.

// These are the motor H bridge control pins
#define in1 8
#define in2 9
#define in3 10
#define in4 11

// These hold values read from channels of the LemonRX receiver
int ch1;
int ch2; // not currently used
int ch3;

// These are the min and max values we read on each channel when we move the joystick
int joymin = 950;
int joymax = 1950;

// X and Y are joystick values in range -1 to +1
float X;
float Y;

// M1 and M2 are values for Motors 1 and 2, in range -1 to +1
int M1;
int M2; 

void setup() {
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);

  Serial.begin(9600);
}

void loop() {

  // read pulse width values from each channel of lemonRX
  ch1 = pulseIn(5, HIGH, 25000);
  ch2 = pulseIn(6, HIGH, 25000);
  ch3 = pulseIn(7, HIGH, 25000);

  // Convert them to floats in range -1 to 1: map uses int, so set it to int in range -1000 to 1000 and then divide by 1000.0
  X = map(ch1, joymin, joymax, -1000, 1000)/1000.0;
  Y = map(ch3, joymin, joymax, -1000, 1000)/-1000.0;

  // This is the fomula for how much power to send to each motor
  // Motor values should be in range -255 to 255, not -1 to 1, so multiply by 255
  M1 = (X + Y) * 255;
  M2 = (X - Y) * 255;

  // Our fomula can end up with values greater than 255, so constrain them to this range
  M1 = constrain(M1, -255, 255);
  M2 = constrain(M2, -255, 255);

  // Call our function to actually drive the motors
  drive(M1,M2);

  // print out for debugging
  Serial.print("Channels: C1=\t"); // Print the value of
  Serial.print(ch1);        // each channel
  Serial.print("\t M1=\t");
  Serial.print(M1);
  Serial.print("\t M2=\t");
  Serial.print(M2);
  Serial.print("\t C3:\t");
  Serial.println(ch3);

  // this delay seems to help reading joystick
  delay(300);
}

void drive(int M1, int M2) {
  // drive both motors at speeds M1, M2 in range -255, 255
  if (M1 > 0) {
    analogWrite(in1, M1);
    analogWrite(in2, 0);
  }
  else {
    analogWrite(in1, 0);
    analogWrite(in2, -M1);
  }

  if (M2 > 0) {
    analogWrite(in3, M2);
    analogWrite(in4, 0);
  }
  else {
    analogWrite(in3, 0);
    analogWrite(in4, -M2);
  }
}

Creators: Shootah Part 6 – Enemy Shooting Back

alien

This week we did our last iteration on Shootah and added a Bomb to be dropped by the enemy to try to hit the player.

Bomb Class

We copied the existing Bullet class and called it Bomb instead. The main changes we had to make were:

  1. Changing the speed to a negative number so that it moved down instead of moving up (as the Bullet does)
  2. Changed the check for the top of the screen to one for the bottom of the screen instead (to account for the fact it moves down)
  3. Changed the check in its hit() function so that the Bomb doesn’t interact with the Enemy when it’s dropped, but will be marked as inactive it if hits anything else.
  4. Changed the colour of the bomb to red

Manages Bombs

It happened that the code we had already written to manage bullets was already perfect for managing bombs as well.

We used Visual Studio Code’s built-in capability to automatically rename symbols to:

  1. Rename the bullets array to projectiles
  2. Rename the manageBullets() function to manageProjectiles()

This was enough to have bombs move, draw and be removed when it becomes inactive.

Dropping Bombs

We added a new function to Ememy called shoot(). In that function we generated a random number from one to two hundred. We then dropped a bomb every time that number was less than five (we tuned this small number to get a good rate of bomb drops). This meant that the enemy dropped a bomb at random intervals, to make it impossible for the player to anticipate.

Download

The files for this week can be found on our GitHub repository.