Advancers – Week 16 – Magnify Part 1

This week we did the first week of the Magnify Project, there will definitely be Part 2 and maybe Part 3.

The Magnify project is designed to allow you to create your own detailed Map of something, by magnifying part of the screen to view more information and then Magnify part of that screen to dig even deeper in to your Map.

For example, you might start with an image of the Solar System, showing all the Planets, then you can click on a Planet to see more details. If you clicked on the Earth for example you would be able to see all the countries, and maybe click on a Country to see even more information.

Part 1.

For Part 1 all we did was build a framework with 2 coloured squares that you could click on to Zoom in/Zoom out of.

The code in both squares is identical apart from the Values given to 5 (or 6!) Variables that were defined for that Sprite only.

The Variables are:

MyName – Who am I
MyParent – Who is my Parent
MyLevel – What level do I belong to
MyX – Where am I on the screen
MyY – Where am I on the screen
MyText – What should I say when the Mouse is on me.

Once all these variables are set correctly for each Sprite everything will simply work. For example these are the values that we used for the 2 example Sprites:

SpriteMyNameMyParentMyLevelMyXMyYMyText
Sprite1Sprite11100100Click Me
Sprite2Sprite2Sprite1200Click Me Too.

You can see that the second Sprite has Sprite1 as the Parent and is a level 2 which is one below Sprite1, these variables basically tell each Sprite whether it should be on show and what size it should be.

To see how it works have a look at the example project on the Scratch Web Site:

https://scratch.mit.edu/projects/1004906611

If you have any questions either here, or make a comment on the project on the Scratch Web Site.

Process

Once the Framework is in place, it is quite easy to add extra levels or sprites at the same level, basically copy either the Parent sprite or another Sprite at the same level you want. Update the Costume with your new image, then simply change the Variables so it has the correct Parent and Level information and it should all work.

AND Homework for next week!

Have a think about what you want to Magnify and see if you can gather some images to use. The more images you have the better the project will end up.

Bodgers – Servos

This week we will connect a SG90 mini servo to our Pico.

Wire the breadboard as shown below:

First test that the buttons are working correctly with the following code.

from machine import Pin
from time import sleep

button_1 = Pin(18, Pin.IN, Pin.PULL_UP)
button_2 = Pin(19, Pin.IN, Pin.PULL_UP)

while True:
    if button_1.value() == 0:
        print("Button 1 is Pressed")
    if button_2.value() == 0:
        print("Button 2 is Pressed")
    sleep(0.1)

Next here is the code for the Servo.

from machine import Pin, PWM
from time import sleep

servo_pin = PWM(Pin(0))
servo_pin.freq(50)

def servo(degrees):
    if degrees > 180:
        degrees = 180
    if degrees < 0:
        degrees = 0
       
    max_duty = 8050
    min_duty = 1650
       
    new_duty = (min_duty + (max_duty - min_duty) * (degrees/180))
    servo_pin.duty_u16(int(new_duty))

servo(0)
sleep(0.5)
servo(90)
sleep(0.3)
servo(180)
sleep(0.3)

This weeks challenge is to combine both pieces of code above so that when button 1 is pressed the servo arm will move one way and when button 2 is pressed it will move in the opposite direction.

Creators – Week 12

This week we took our Blender creations back into Unity. We started with the same file, ShipsAndEnv3.5,blend, which can be found here on our Teams site (for site members only).

Export from Blender

Blender offers extensive export options and we quickly ran through the list. The one we’re going to use is FBX. It’s a widely used format, well supported in lots of 3D software, with good material and animation support.

To export the file, we made sure all object were unhidden, and chose File|Export|FBX. We left all the options as-is except the “Apply Transforms” option, which we selected. This option has a warning next to it, as it doesn’t work with animations, but that doesn’t apply to us here.

The resulting FBX file was saved to the same folder as our BLEND file.

Import into Unity

To import the FBX file into Unity, we created a new folder called “Model” and dragged the FBX file from Windows Explorer/macOS Finder into it.

We decided to extract the materials from the file. This will allow us to change them in Unity. To do that we selected the FBX in the Model folder in Unity and in the Inspector window, went to the Material tab and chose “Extract Materials”. All the materials in the FBX were then extracted as Unity materials in the same folder as the FBX file.

Prefabs

We then wanted to break apart the combined FBX file into it’s separate parts. To do that we first created a blank scene and dropped the model from the “Model” folder into the Hierarchy window. We checked the Inspector window to make sure it was positioned at (0, 0, 0) and adjusted it if needs be.

Note that Unity showed the model coloured blue in the Hierarchy. This means it was treating it as a “Prefab”. A prefab in Unity is just a collection of GameObjects and components that are treated as a template. It’s easy to create copies of them at run-time.

We want prefabs of all the things in the FBX file, not the FBX model itself. To separate out the bits from the FBX model, we right-clicked on it in the hierarchy and chose Prefab|Break Apart Completely. Not much obviously changed except everything in the hierarchy turned black, indicating it was no longer a prefab, just normal objects.

We then created a new folder called “Prefabs” and dragged everything inside the FBX model (but not the FBX model itself) into it. That’s all you have to do to make something you already have in a Unity scene into a prefab, drag it into the Project window. Now we can create copies of all these objects at run-time very easily.

Adding our Ship to the Scene

To add our ship to the scene, we dragged the Ship prefab from the Prefabs folder and dropped it onto the Player gameobject in the Hierarchy. The Ship model was then a child of the Player object. We needed to rotate the Ship by -90 around the Y axis to make it point in the correct direction. We also set the scale of teh Plater object to (1, 1, 1) and removed the Mesh Filter, Mesh Renderer and Box Collider components from Player, as these were no longer needed.

Our game looks better already with a ship model rather than a flying mattress!

Some Test Code

We tested two simple components on a test cube added to the scene. One which created constant movement in a particular direction and the other which deletes the attached gameobject once we’ve traveled a set distance from where we started.

The first of these, ConstantMovement.cs looks like this:

using UnityEngine;

public class ConstantMovement : MonoBehaviour
{
  public Vector3 Direction = Vector3.forward;
  public float Speed = 10.0f;

  // Update is called once per frame
  void Update()
  {
    Vector3 offset = Direction.normalized * Speed * Time.deltaTime;
    transform.position = transform.position + offset;
  }
}

Two public variables define the direction and speed respectively. In Update() we calculate how to move this frame by multiplying the normalised version of the Direction (normalised meaning the length is set to 1) by the speed and Time.deltaTime (the time since the last frame). We then set a new value for the position by adding this offset to the previous position.

The second DestroyAfterDistance.cs looks like this:

using UnityEngine;

public class DestroyAfterDistance : MonoBehaviour
{
  public float Distance = 10.0f;

  private Vector3 _initPos;

  // Start is called before the first frame update
  void Start()
  {
    _initPos = transform.position;      
  }

  // Update is called once per frame
  void Update()
  {
    Vector3 offset = _initPos - transform.position;
    float offsetDist = offset.magnitude;

    if (offsetDist >= Distance)
    {
      Destroy(gameObject);
    }
  }
}

It just has once public variable, the distance the GameObject is allowed to travel. It also has one private variable, set in Start(), which stores the initial position.

In Update() we check how far we’ve travelled by getting the vector difference between the start position and our current position and then getting it’s magnitude (aka length). This tells us how far we have moved. if this distance is greater than the the specified Distance, we call Destroy(gameObject) thereby destroying the GameObject this component is attached to.

Getting the Code

All the code we’re made this year is on our GitHub. It can be found here. If you don’t have the latest version of our code before any session, use the green Code button on that page to get the “Download ZIP” option which will give you a full copy of all code we’ll be writing this year.

Creators – Week 10

This week we took our cube and made it vaguely more spaceship-shaped by moving it up to (0, 2, 0) and resizing it to (5, 1, 4). We also took our ground plane and scaled it to (10, 10, 10). Now it looks vaguely more like a flying craft than before!

The ship controls still work as before. WASD move the ship horizontally over the ground and there’s no vertical movement. To make it look more like a flying craft, we’d like it to bank (aka. tilt over) as it moves horizontally. That’s going to take a bit of figuring out.

Angles in Unity

Let’s take a little aside to talk about angles in Unity.

In the Unity Inspector we see three numbers for a transform’s rotation. These numbers represent rotations around the X, Y and Z axis respectively. This way of storing a rotation is known as “Euler angles”. It seems simple and straightforward and, if you’re rotating around just one of the X,Y or Z axes, it is, but for complex rotations it actually has a lot of problems. The order in which you apply the rotations matters. If you rotate first in X then Y and the Z, you get one orientation, but choose a different order and you’ll get something different. It’s ambiguous.

Look at these two boxes. Each are rotated by 90degrees around the X and Z axis but in a different order. They end up in completely different orientations:

Rotations internally in Unity are stored using a special variable called a Quaternion. Euler angles can easily be converted to Quaternions and back again. Quaternions store the axis that the object rotates around and the amount of the rotation. It’s completely unambiguous with no order to worry about.

When we code, we use Quaternions for rotations because that’s what Unity uses.

Variables for Ship Tilt

In ShipControls.cs we add two variables TiltSpeed and TiltLimit to control banking. TiltLimit represents the amount of degrees we’re going to bank as we move horizontally and TiltSpeed is how quickly we can change angle. We don’t want the craft immediately going from tilting one direction to tilting the other – we want a smooth change of rotations. That will look a lot better.

  public float TiltSpeed = 10.0f;
  public float TiltLimit = 10.0f;

Because these are public properties, we see them appear in the inspector for Ship Controller.

Determining What Tilt We Should Have

Tilt is dependent on the user input. If the user is pressing right, we should be titled to the right. If the user is pressing left, we should be tilted to the left. If the user isn’t pressing left or right, we should be level.

In the Update() function in ShipControls.cs we add this code near the top:

    float tiltTarget = 0;

    if (moveInput.x < 0)
      tiltTarget = TiltLimit;
    else if (moveInput.x > 0)
      tiltTarget = -TiltLimit;

    Quaternion targetRotation = Quaternion.Euler(tiltTarget, 0, 0);

So depending on user input, tiltTarget will either be 0, TiltLimit or -TiltLimit (note the minus). We then turn this into a Quaternion representing this amount of a rotation around the X axis.

Moving Smoothly Between Rotations

How do we move smoothly between two rotations, namely the rotation we’re at and the rotation we want to be at?

There’s a general concept called “linear interpolation” for finding a value some proportion of the way between two other values. Let’s imagine a trivial example; if our numbers were 0 and 10 then the number 50% of the way (aka. half) between these would be 5. In Unity linear interpolation is known as “Lerp” and it can be used not just for simple numbers but for Vector3’s (representing positions and directions) and Quaternions (representing rotations) too.

For Quaternions, Unity has a special “Lerp” that works really well for rotations called Quaternion.Slerp(). “Slerp” stands for Spherical liner interpolation. Not a function name you’ll quickly forget. So to “Slerp” between the angle we’re currently at and the angle we’d like to be at, we need to know what proportion of that change we can make this frame. Here’s how we calculate that proportion:

  1. Find the angular different between the rotation we’re at and the rotation we’d like to be at
  2. Calculate how long, given the speed we’ve specified for changing angle, it would take to fully make that change in rotation
  3. Calculate, given the time since the last frame, what proportion of that change we can actually make (it will be just a small bit of the change).

Here’s what the code looks like:

    float rotationDiff = Quaternion.Angle(targetRotation, 
                                          transform.rotation);
    float timeToFullyRotate = rotationDiff / TiltSpeed;
    float rotationProportion = Time.deltaTime / timeToFullyRotate;

Finally we actually set the transform’s rotation using Slerp(), the rotation we’re at, the rotation we’d like to be at and the proportion of the change that we’ve calculated:

transform.rotation = Quaternion.Slerp(transform.rotation, 
                                      targetRotation, 
                                      rotationProportion);

Tuning the Variables

Testing the ship control code we found that good values for the variables were as follows:

Move Speed50
Tilt Speed100
Tilt Limit30

We also noted that any values entered in the inspector override defaults in the code.

Simple Blender Spaceship

We started on a simple spaceship model in Blender, using the proportions of our cube in Unity as a guide [5m x 1m x 4m].

This was mine, but everyone had their own take. If anyone wants to download mine, it can be found here on our Teams site. If you’re not a member of our Teams site yet, get in touch to be added.

When we return after our break, we’ll look to texture this model and export it from Blender and import it into Unity.

Getting the Code

All the code we’re made this year is on our GitHub. It can be found here. If you don’t have the latest version of our code before any session, use the green Code button on that page to get the “Download ZIP” option which will give you a full copy of all code we’ll be writing this year.

Advancers – Week 9 (2023 – 2024)

Programming

This week we created our very own programming language in Scratch.

It reads a list of commands and does what it’s told.

It only understands a few commands:

M = Move
T = Turn
X = Go To X
Y = Go To Y
P = Pen Up or Down
C = Change colour

The Lines in the list have to be in the right format for the code to work. The right format is the Single Letter for the command followed by a colon (:), followed by a Parameter, if the command needs it. For example this command:

M:10

Tells the code to M(ove) 10 steps.

Spirals – To create a list of Commands.

We also spent some time updating the Spirals project so that it could create a List of Commands that could be used by the Programming project to draw the same Spiral.

Export/Import a List

We also experimented with the Export List and Import List options in Scratch to move lists of Commands in and out of different Projects. So for Example you could:

1: Open the Spirals Project.
2: Run a Spiral to add entries to the List.
3: Right Click on the List and Export it to a file.
4: Open the Programming Project.
5: Right click on the List and Import the file you created in step 3.
6: Run the Programming project and it will draw the same spiral.

See it in Action.

Both the Programming Project and the Spirals project that can generate a List have been loaded up to the Scratch Web Site (https://scratch.mit.edu), you should be able to see them without connecting by using the following links:

ClassVersion-Programming https://scratch.mit.edu/projects/953994281/
ClassVersion-Spirals-Programming https://scratch.mit.edu/projects/953995854

If you want to connect and upload your own projects you can use the following details:
username : athenryadvancers
Password : Advancers


Advancers – week 6 (2023 – 2024)

Platformer Game

This week we created a platform game, the objectives of the game is to get as much milk as possible. But the more milk you get the smaller the platforms get and the smaller the milk gets.

If you end up at the bottom of the screen, you will lose a live and start at the top of the screen again.

You can use “Boosts” using the space key to jump up to higher platforms, but beware, you only get a few boosts, but getting milk will also give you 2 more boosts.

And remember, as always (well mostly always!) I have uploaded this to the Scratch web site, you can use the following URL to access it:

https://scratch.mit.edu/projects/930315522/

If you want to Sign In to the Scratch Website you can use the following credentials:

Username : athenryadvancers
Password : Advancers

Don’t forget the uppercase A on the password.

Advancers – Week 5 (2023-2024)

Car Racing Game (RoadRacing)

This week we created a Car Racing game, the object is to get as much score as possible by dodging all the other cars and trucks on the road.

The finished project is available on the Scratch Website:

https://scratch.mit.edu/projects/926443877/

If you want to SignInand edit any of the projects you can use the following credentials:

Username : athenryadvancers
Password : Advancers

Note: The password has an uppercase “A” at the beginning.

Advancers – Week 4 (2023-2024)

Snake

This week we attempted to recreate the old Nokia game of Snake.

We created:

The Snake – This could move around the screen and across the screen edges.
The Tail – This followed the Snake around the screen, wherever the Snake went, the tail would follow.
An Eraser – This followed the Tail rubbing it out, so it stayed the same length all the time.

We still need to complete the following:

The Bug – This will appear on the screen randomly for the Snake to eat. Eating the Bug will increase the length of the Tail.
Score – A simple scoring variable to keep track of how many Bugs we eat.
Music – Some annoying music to play during the Game, it has to be annoying!

I have uploaded 2 versions of the Game to the Scratch Web Site:
ClassVersion-Incomplete – This is from Saturday where we didn’t quite finish everything
ClassVersion-Complete – This is a complete version which has The Bug, The Score and annoying Music.

You can find them both here:

https://scratch.mit.edu/studios/33944393

If you need to log in, use the following details:
Username : athenryadvancers
Password : Advancers (don’t forget the uppercase “A”)
This is an image from the completed version.

Bodgers – Week 2

Hi everyone, it was great to see you all last Saturday.

We worked on a car collision game here is our worksheet:

You can find the images for this game along with images for next week’s game here: https://www.dropbox.com/scl/fo/znirpob0ywen2kzwbgf6k/h?rlkey=ykhlgf8lbr4i35lu3ed8mrbrs&dl=0

Looking forward to seeing you all again next Saturday.

Declan and Kevin