Week 4 – 2019 – Explorers

Hello everyone.

Good to see everyone there on Saturday. We finished our game from the previous week, similar to on old game called Breakout.

wipeout

We used a number of important coding concepts again this week, loops and decisions, Variables, broadcasting, etc.

concepts

Don’t forget we are off for the next two weeks. Enjoy the Break!

Here is a link to the notes: CDA-S8_Week 8-Wipeout.pdf

 

Martha

Creators: Shootah Part 4 – Colliders

 

This week we mainly dealt with building and using a box collider in our game. The box colliders are written in a way such that:

  • They are connected to something in the game and follow it around
    • What they are attached to must have the properties x and y for position
  • It is possible to test if they are touching each other
  • If two colliders are found to be touching, we tell the things that they’re attached to that they’ve been hit by something
    • What they are attached to must have a function hit() that we can call

 

Extents of the Collider

Our collider is a box, of a given width and height, centred on the x and y of the thing it’s connected to:

Untitled Diagram

For checking collisions, we need to know the values of the left and right side of the box and the y values of the top and the bottom of the box.

For convenience, we write a function which returns an object (using curly brackets) with the left, righttop, and bottom values (shortened lr, t and b respectively) as properties:

extents(){
  return {
    l: this.connected.x - this.width / 2,
    r: this.connected.x + this.width / 2,
    t: this.connected.y - this.height / 2,
    b: this.connected.y + this.height / 2
  };
}

When making an object like this, we set a property value by first writing the property name, followed by a  colon (:)  and then a space and the value we want it to have. Each property is separated with a comma. The don’t need to be on separate lines, but it makes it easier to read.

 

Touching Colliders

So how do we know that two colliders are touching? Actually there are four ways in which they definitely can’t be touching:

  • One is completely to the left of the other
  • One is completely to the right of the other
  • One is completely above the other
  • One is completely below the other

And if none of these are true, then it must be touching. So actually, we’re going to check that they’re not NOT touching (double negative, used correctly!).

How do we know if something is completely to the left of something else? Look at this diagram:

 

Untitled Diagram (1)

We know that box 2 (in blue) is totally to the left of box 1 (in orange) because we can see it is, but how could get the computer to check it? Remember, left and right are just x values on the screen. Box 2 is left of box 1 because both it’s left and right values are smaller than the left value of box 1.

The checks for the other directions are very similar:

  • The second box is right of the first box when both of it’s x values (left and right) are greater than the first’s right side.
  • The second box is above of the first box when both of it’s y values (top and bottom) are less than the first’s top side.
  • The second box is below of the first box when both of it’s y values (top and bottom) are greater than the first’s bottom side.

 

Sending Messages

Each collider has a property disc that describes the thing, or type of thing, that it’s connected to.

All colliders know what they’re connected to, so when we determine two have touched, we call a function called hit() on each of the connected objects, passing it the desc of the other collider. This means, in our game, when our enemy is hit, it can know that it’s been hit by a bullet – or maybe something else – and react appropriately.

 

Checking Every Collider Against Every Other

In our code, we gather all the active colliders at each frame. We then need to check each one against each every other one. How can we do that?

Consider a list of four items:

Untitled Diagram (2)

To check them all against each other we first need to check 0 against the other three. Simple enough.

We we need to check 1. But we don’t need to check 1 against 0, since we already did that. Nor do we need to check it against itself. We only need to check it against 2 and 3.

If we write out the full sequence, we see that for four items we need three passes to check all combinations:

  • First pass: Check 0-1, 0-2, 0-3
  • Second pass: Check 1-2, 1-3
  • Third pass: Check 2-3

We can write a pair of loops to do this:

for (let i = 0; i < c.length - 1; i++){
  for (let j = i + 1; j < c.length; j++){
    c[i].touching(c[j]);
  }
}

Note two things about these loops:

  • The first loop goes from zero, but stops one short of the last item in the list (i < c.length – 1). It picks the first item to be checked.
  • The second loop doesn’t start from zero. It starts from what ever i currently is, plus one. It picks the second item to be checked.

 

Other Stuff

We also did a few other things this week:

  1. We fixed a small bug that was keeping our spaceship moving when we didn’t want it.
  2. We added a little drag to slow the spaceship down to a stop when we lift our fingers off the keys
  3. We set bullets inactive when they hit something

 

Download

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

Hackers – Controlling Robot Wheels and Handling Interrupts in Arduino

IMG_20190202_135834

Controlling Robot Wheels

Last week, we figured out how to control a motor with a H-bridge. We expanded this to controlling a pair of wheels using the H-bridge. Above is a photo of the hardware. The wiring of the H-bridge is:

  • H-bridge [+] and [-] are connected to a 9V battery
  • H-bridge [IN1] to [IN4] is connected to Arduino Pins 6, 7, 8, 9
  • H-bridge [Motor A] and [Motor B] pins are connected directly to the two motors

Below is Arduino code by Hackers member Luke to control this.

// Luke Madden, CoderDojo Athenry
// Control motors using a H Bridge

// The H bridge has 4 input pins: in1-in4
#define in1 6
#define in2 7
#define in3 8
#define in4 9

int fast = 150;// range 1-255
int slow = 80;// slower speed
int hyperspeed = 255;// hits the hyperdrive

void setup() {
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  drive();
}

 void drive() {
  // Test the functions
  Serial.println("move forward");
  forward();
  delay(2000);

  Serial.println("hit the hyperdrive");
  hyperdrive();
  delay(2000);

  Serial.println("go backwards");
  backwards();
  delay(2000);
}

void forward() {
  //makes motor go forwards
  analogWrite(in1, fast);
  analogWrite(in2, 0);
  analogWrite(in3, fast);
  analogWrite(in4, 0);
}

void hyperdrive() {
  //hits the hyperdrive
  analogWrite(in1, hyperspeed);
  analogWrite(in2, 0);
  analogWrite(in3, hyperspeed);
  analogWrite(in4, 0);
}

void backwards() {
  //makes motor go backwards
  analogWrite(in1, 0);
  analogWrite(in2, fast);
  analogWrite(in3, 0);
  analogWrite(in4, fast);
}

void stopping(){
  //makes it stop
  analogWrite(in1, 0);
  analogWrite(in2, 0);
  analogWrite(in3, 0);
  analogWrite(in4, 0);
}

Handling Interrupts in Arduino

In Arduino, you can set up special functions that are a called depending on the state of some digital pins – these are called Interrupt Service Routines (ISRs). These routines are called separately from the main loop() that is always running, even if the main loop() is in the middle of another operation.

For controlling our robots, our Arduino might receive a signal on a pin, and if we want the robot to react quickly, an ISR can handle it. The ISR can send a signal on a different pin or change the state of a variable.

This code is simple and correctly-working demonstration of how interrupts work. Note that you don’t need to build any circuitry to try this out. A built-in LED on the Arduino, at pin 13, turns on/off depending on whether Pin 2 is connected/disconnected from the the GROUND pin.

There are three main tasks:

  1. Define the ISR function: this is a function declared as void with no arguments: for example, our ISR is called changed and is defined as:
    void changed() { … }
    In our code, it sets the value of a variable called controlState and it turns the LED on/off. Note that the value of controlState is printed out repeatedly in the main program loop, showing how the ISR can change a variable that is used elsewhere.
  2. In the setup() function, set the pin mode of the control pin to INPUT or INPUT_PULLUP (see below for the difference). For example, we have defined the variable control to have value 2 and are setting its mode like this:
    pinMode(controlPin, INPUT_PULLUP);
  3. In setup(), attach the ISR to the pin:
    attachInterrupt(digitalPinToInterrupt(controlPin), changed, CHANGE);

One extra note about the above line of code: all pins have numbers and all interrupts have numbers, and these are not (necessarily) the same numbers. The function digitalPinToInterrupt() returns the interrupt number corresponding to a given digital pin.

Some other things to note:

  • The Interrupt Service Routine (ISR) should be short and run fast: delay() calls are ignored and print() can cause problems.
  • You can’t attach two interrupts to the one pin: use CHANGE and then test pin state
  • If you initiate the pin with INPUT_PULLUP, it is triggered by connecting it to GROUND; otherwise, if you initiate it with INPUT, you need a circuit with 10k resistor.
  • On an Uno, can only attach interrupts to pins 2 and 3.
  • If you are changing a variable in the ISR and need to use it elsewhere, declare it as volatile.

Here is the full Arduino code:

// Michael Madden, CoderDojo Athenry
//
// Test a pin interrupt to which an interrupt service routine (ISR) is attached.
// When the control pin is connected to GROUND, the LED on the board is turned on.

// Things we have figured out:
// * The interrupt service routine (ISR) is a function declared as void with no arguments.
// * It should be short and run fast: delay() calls are ignored and print() can cause problems.
// * You can't attach two interrupts to the one pin: use CHANGE and then test pin state
// * If you initiate the pin with INPUT_PULLUP, it is triggered by connecting it to GROUND;
// * otherwise, with INPUT, you need a circuit with 10k resistor.
// * On an Uno, can only attach interrupts to pins 2 and 3.
// * If you are changing a variable in the ISR and need to use it elsewhere, declare it as volitile.  

const byte controlPin = 2; // Want to react when this pin is triggered
const byte ledPin = 13; // no circuit needed: there is a built in LED on 13
volatile int controlState = 0; // will change this value in ISR

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(controlPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(controlPin), changed, CHANGE);

  Serial.begin(9600);
}

void loop() {
  // The main loop does not do much, it just prints out the value of the
  // control pin's state every 2 seconds.
  Serial.print("Current value of control pin = ");
  Serial.println(controlState);
  delay(2000);
}

void changed()
{
  // This is our interrupt service routine.
  // It is triggered when the control pin changes,
  // so we check its state and turn on/off the LED.
  //
  controlState = digitalRead(controlPin);
  if(controlState > 0) {
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(ledPin, LOW);
  }
}

Creators – Shootah Part 3 – Enemies etc.

This week we continued our Shootah project. We did two main things;

  1. Changed the code to control the total number of bullets to those actually on screen
  2. Added an enemy that loops backwards and forwards across the screen

Controlling the Number of Bullets

In Part 2, we made a new bullet every time the user pressed the Up key and put it in the bullets list.

This meant that after a while we could have a lot of bullets, most off the top of the screen, which was even slowing some machines down.

To limit the number of bullets we did four things:

  1. Added a new property to the Bullet class called active and set it to be true
  2. In the move() function for the bullet class, we added a check for the bullet going off the top of the screen (this.y < 0) and, if true, set the active property to false
  3. In sketch.js, we moved the lines of code in the draw() function responsible for moving and drawing the bullets into a new function called manageBullets() and called it from draw().
  4. In manageBullets() we made a new list called active and put every bullet that was still active into it. We then made this the new bullets list.

We write a little code that printed out the total number of bullets to verify this was working.

Adding an Enemy

We added a new file called enemy.js and included it in the index.html file.

This file looked a lot like player.js. The main different was the move() function. Our enemy moves constantly left-to-right. When it gets too far off the right-hand side of the screen (checked in move()) we set its x position to be off the left-hand side of the screen instead. This makes it loop around.

TODO

We still have loads to do and we made a list on the day:

  • No more infinite bullets!
  • Check edges so spaceship doesn’t disappear
  • Enemies
  • Collision detection
  • Enemies shoot back (bombs)
  • Lives/score
  • Levels
  • Background music
  • Moving background
  • Story

We’ve done two and we’ll do some of the others for sure.

Download

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

 

Hackers – Controlling Motors with an Arduino and H-Bridge

Previously in Hackers we have studied how transistors work, and made a transistor-based circuit to control a motor from an Arduino: Hackers – a Joule Thief and Controlling Motors.

When you write to a pin on the Arduino, it outputs a voltage. However, you can’t use this directly to drive an electric motor, because they require too much current, and it would damage the Arduino. The solution is to use a 6V battery as an external power supply, and connect it to the motor via a transistor circuit. When you apply a signal with small current to the middle leg of the transistor, a much larger current can flow from the battery to the motor.

While this works, a more elaborate circuit is needed if you want to be able to control two motors, and make them go backwards and forwards. This circuit is called a Dual H-Bridge. The Wikipedia page has technical details: https://en.wikipedia.org/wiki/H_bridge

We are using a pre-built integrated circuit for our H-Bridge, as they are low-cost, small, and work well. Here is the one we are using:

h-bridge

It has several connectors:

  • [+] and [-] are where the external battery is connected
  • [IN1] and [IN2] control Motor A (details below)
  • [IN3] and [IN4] control Motor B
  • [Motor A] and [Motor B] each have two pins that are connected directly to motors

To control Motor A, connect [IN1] and [IN2] to two pins of the Arduino, such as 6 and 7:

  • [IN1] HIGH and [IN2] LOW: Motor A goes forward full speed
  • [IN1] LOW and [IN2] HIGH: Motor A goes backward full speed
  • Both LOW: Motor A does not turn (no power, it coasts)
  • Both HIGH: Motor A does not turn (is braked)
  • To control speed, use a value for the pins connected to [IN1] or [IN2] in the range 0-255 (0=LOW, 255=HIGH)

Here is Arduino code to control a motor with a H-Bridge, written by Luke, one of our Hackers:

// Luke Madden, CoderDojo Athenry
// Control motors using a H Bridge

// The H bridge has 4 input pins: in1-in4
#define in1 6
#define in2 7

int fast = 100;// range 1-255
int slow = 50;// slower speed
int hyperspeed = 255;// hits the hyperdrive

void setup() {
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  drive();
}

 void drive() {
  // Test the functions
  Serial.println("move forward");
  forward();
  delay(2000);

  Serial.println("hit the hyperdrive");
  hyperdrive();
  delay(2000);

  Serial.println("go backwards");
  backwards();
  delay(2000);
}

void forward() {
  //makes motor go forwards
  analogWrite(in1, fast);
  analogWrite(in2, 0);
}

void hyperdrive() {
  //hits the hyperdrive
  analogWrite(in1, hyperspeed);
  analogWrite(in2, 0);
}

void backwards() {
  //makes motor go backwards
  analogWrite(in1, 0);
  analogWrite(in2, slow);
}

void stopping(){
  //makes it stop
  analogWrite(in1, 0);
  analogWrite(in2, 0);
}

Week 2 2019 – Explorers – Piano

Hello everyone,

Thank you all for coming again this week. Today we started looking at the Scratch 3. We had some small issues saving but hopefully all these little issues will get sorted with updates over the next couple of weeks.

This week we did a simple Piano so we could familiarise ourselves with it.

piano

We only had to draw two keys, and then could duplicate these and change the names. The same applied to the code. The code is the same for each key apart from one small change so the note is the appropriate for the key.

REMEMBER! You need to make four changes each time you duplicate:

Change the name of the spite to the next Note

Change the name of the TWO costumes

Change the NOTE played

Piano2

Here are notes from this week in PDF cda-s8-week-2-19-piano.pdf

Martha

Julie, Ruaidhrí and Eoin

Advancers – Mad House

Introduction

This week we built a Mad House with different rooms that you could go into and if you found the right place to click something would happen.

The coding for this project shows how you can re-use code, this has 2 benefits, it makes coding quicker and it also makes all the code consistent, so it all looks the same.

The Plan

As always, it’s best to have a little bit of a plan.

We decided on the following:

  • 4 Rooms – each room would have 2 Sprites
  • Clicking a room would make it large
  • Clicking the Space key would make the room small again
  • We would build one room first so we could copy the code.

The Code

The first room we created was the Kitchen, the plan was when you clicked on the saucepan, it would boil over.

The Sprites need to fill the whole screen and also need a coloured background to ensure that the Mouse Click is recognised by the code.

These are the 2 Sprites that I built:

kitchen

 

 

 

 

It’s not easy to see, but the “On” Sprite has some flames coming out of the pot.

 

 

 

 

Because we are having 4 Sprites, when the program starts we need to make the Sprite a quarter of it’s full size and move it to one of the corners of the Screen. We also discovered that we would need a variable (a flag) to indicate if the room was Large (1) or Small (0). We did this in the GreenFlag code like this:

greenflag

We moved to top left corner.
we set the size to 50% (this makes it fill a quarter of the screen
We set the variable to 0 (0 = small, 1 = large)
We set the start costume to the Off costume.

 

 

Next step was to write the code for when the Sprite was clicked, this would make the Sprite fill the screen, slowly! It would also set the flag to say that the Sprite was large.

The biggest piece of the code was making the Sprite grow slowly, we did it in 50 steps, changing the size was easy as it just changed by 1 each step, but the X and Y positions were a little trickier as we needed to make sure they were going in the right direction and also changing by the right amount to reach the full size in 50 steps.

spriteclicked

Only run this code if we are small (0)
Make we can’t run again set the flag to 1.
Make sure we are in front of the other Sprites

X needed to go from -120 to 0, 2.4 each time
Y needed to go from 90 to 0, so -1.8 each time
Size was simple, 1 each time
And to make it nice and smooth, we wait for .1 of a second in each step.

 

We then moved on to the code that should run when the Space key is pressed, this would reverse what happened when the Sprite was clicked.

spacekeyclicked

Again, we only run if we are large (1)

The X and Y changes are the reverse of the ones above.

And finally we set the size back to small again (0)

 

Now we can move on to the code that changes the costume if the user clicked on a certain spot on the screen.

We decided that the user should click on the pan for the costume to change, so first we needed to work out where the pan is on the screen (It’s X and Y positions). This is easy in Scratch 2, when you move the mouse across the Stage the X and Y position is shown at the bottom of the screen, so you just need to place the Mouse on the 4 sides of the Pan and make a note of the X and Y values. X values for the min and max left/right positions, Y values for the min and max up/down positions. Hopefully this picture will help:

pan$

We needed to place the Mouse on each of the positions indicated, which then gave use the correct values to place in the code.

The code then looked like this:

foreverloop

 

We loop forever
Only check X and Y if we are large (1) and the Mouse is clicked. Then check where the Mouse is. This where we use the values we got when checking where the Pan was on the screen.

 

And that is it for the first Room.

The Second Room.

Now that all the code is written for the first Room, the second Room becomes a lot easier, we simply duplicate the first Room Sprite and then make the following changes to the code:

  • Change the 2 Costumes to something else for this new Room.
  • Add a new Variable for this Room
  • Update all the places where the Variable is set to this new one.
  • Update the starting X and Y positions to one of the other corners of the Stage.
  • Update the X and Y changes when the Room grows and shrinks to make sure it is going to the centre of the screen correctly and also back to it’s own corner.
  • Update the X and Y values to a new location on the Screen, depending on what you have drawn on your new Costumes.

The Finished Program

I only got 3 Rooms finished and this what it looked like at the end:

stageandvariables

Next Steps

If you want to improve the program you can look at adding the following:

  • The final Room to make it 4 rooms.
  • Extra code change the Costume back to normal if the item is clicked again, this would check what Costume is currently, this can be done using the “costume #” from the Looks blocks.

Notes

The one I did in the class is available on the Scratch Web Site:

Project Name : ClassVersion-MadHouse

UserId : cdadvancers1819

Password : advancers

Creators – Pixels

543px-Liquid_Crystal_Display_Macro_Example_zoom

This week we looked at pixels. Your screen is made up of thousands of them; the picture on it is created by setting each one to the correct colour. We may ask P5 for an ellipse(), but ultimately some piece of code is deciding which pixels to change to the currently selected fill() colour (for the centre) and which to set to the currently selected stroke() colour (for the edges).

Working with Pixels in P5

P5 contains two main functions for working with pixels. The first is loadPixels(). By default it reads all the pixels from the canvas and copies the information into a huge array (or list) called pixels[].

If we then make a change to pixels[], all we have to do is call updatePixels() to copy this information back to the canvas again.

Sound easy? It almost is, but the content of pixels[] isn’t immediately obvious.

Structure of the pixels[] Array

The pixel[] array is one long list of numbers. It is arranged such all the information for the first row on the canvas is first, followed by the information for the second and so on until the bottom of the canvas.

For each pixel there are four numbers representing the red (R), green (G), blue (B) and alpha/transparency (A) value of the pixel. By the time the pixel has reached the  screen, alpha has no more meaning, so we will ignore it and concentrate on the RGB values.

This diagram represents what we’ve been talking about:

pixel diagram

Getting and Setting a Pixel

To make it easy to get and change the value of a specific pixel we can write two functions:

  • getPixel(x, y) which returns an array containing [r, g, b] values
  • setPixel(x, y, colour) where colour is an array containing [r, g, b] values

Both these functions rely on knowing where in pixels[] the data for the pixel at (x, y) is.

We can work out this as:

  1. Location of R: 4 * ((y * width) + x)
  2. Location of G; Location of R + 1
  3. Location of B: Location of R + 2

Knowing this, the functions can be written as:

function getPixel(x, y){
  let loc = 4 * ((y * width) + x);

  return [pixels[loc + 0],
          pixels[loc + 1],
          pixels[loc + 2]];
}

function setPixel(x, y, c){
  let loc = 4 * ((y * width) + x);
  
  pixels[loc + 0] = c[0];
  pixels[loc + 1] = c[1];
  pixels[loc + 2] = c[2];
}

FIlters
We wrote three filters, all very similar. Each used loops to go over each pixel in turn, retrieve the current colour, change it in some way and set it back.
The first was fade(amount) which took a number between 0 -> 1 for amount. It multiplied each of the original RGB values from the pixel with this value. The closer to zero amount was, the more it faded the image to black.
The second was invert(). It subtracted each RGB value from 255. This has the effect of inverting all colours in the image.
The final one was vignette(). This is like fade() but fades pixels depending on how close to the edge of the picture they are.
Animating Fade
Finally, we also animated fade() so that the picture started black and got brighter over a number of frames.
Putting all the filters together:

Download

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