Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
29d9017
create test pages
BenZeng04 Nov 5, 2021
eb02fef
Merge pull request #3 from mcpt/master
BenZeng04 Nov 5, 2021
d212687
Merge pull request #6 from mcpt/master
BenZeng04 Nov 6, 2021
46b8b68
Add Drag and Drop Tutorial
ji-mmyliu Nov 9, 2021
ff183d1
Add Path For Balloons Tutorial
Averesoft Nov 9, 2021
6f667f0
Create UpdatingBalloons.md
toaster203 Nov 9, 2021
33aca35
Create HealthChecking.md
toaster203 Nov 9, 2021
0891055
Create towervaliditychecking.md
Averesoft Nov 9, 2021
0a95b5e
Add sample code segments
ji-mmyliu Nov 9, 2021
a7088ef
Update towervaliditychecking.md
Averesoft Nov 9, 2021
53043b3
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
Averesoft Nov 9, 2021
8c84f3e
Update UpdatingBalloons.md
toaster203 Nov 10, 2021
e9593f2
Update HealthChecking.md
toaster203 Nov 10, 2021
93043f5
Remove sections involving checking legal drop
ji-mmyliu Nov 10, 2021
1643ec5
Rotating towers almost done
V1ad20 Nov 10, 2021
64476ab
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
V1ad20 Nov 10, 2021
5c3d630
edited rotating towers page
V1ad20 Nov 10, 2021
2f7780d
p5js: show only result
nyiyui Nov 10, 2021
5d6b6b9
p5js: show only result
nyiyui Nov 10, 2021
3c0dc03
Merge branch 'x-p5js' of github.com:mcpt/learning into x-p5js
nyiyui Nov 10, 2021
3c73f97
Change TL;DR into notice
Averesoft Nov 10, 2021
dac0936
Merge pull request #7 from mcpt/x-p5js
BenZeng04 Nov 10, 2021
9fdc76c
Adjust weights & Shorten Titles
BenZeng04 Nov 10, 2021
98e9dd8
Merge pull request #8 from mcpt/master
BenZeng04 Nov 10, 2021
77ae06e
updated rotating towers page
V1ad20 Nov 10, 2021
055ef84
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
V1ad20 Nov 10, 2021
a178aff
rotating towers finalized
V1ad20 Nov 11, 2021
4548a26
Change url for towervaliditychecking.md
Averesoft Nov 11, 2021
7835893
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
Averesoft Nov 11, 2021
587741c
Add links to ArrayList explanation
ji-mmyliu Nov 11, 2021
d4b42c7
Add demo to introduction page
BenZeng04 Nov 11, 2021
3c8e5c8
Update updatingballoons.md
toaster203 Nov 11, 2021
91969c2
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
ji-mmyliu Nov 11, 2021
9882734
Add attachments
Averesoft Nov 11, 2021
5c0d54b
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
Averesoft Nov 11, 2021
8a9574f
Update TowerValidityTemplate.zip
Averesoft Nov 11, 2021
ccb6ead
Finalize introduction page
BenZeng04 Nov 11, 2021
6b153c3
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
BenZeng04 Nov 11, 2021
3d4ee28
updated rotating towers
V1ad20 Nov 11, 2021
34c5a6d
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
V1ad20 Nov 11, 2021
1d6fe02
Update TowerValidityTemplate.zip
Averesoft Nov 11, 2021
7f26bab
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
Averesoft Nov 11, 2021
f50a491
Resize p5js canvas to content width
dulldesk Nov 11, 2021
69f866a
Merge pull request #11 from mcpt/resize-p5js
BenZeng04 Nov 11, 2021
71b1b24
p5js: use safeCSS
nyiyui Nov 11, 2021
7985ea1
Add files via upload
toaster203 Nov 11, 2021
3cfaecd
Update healthchecking.md
toaster203 Nov 11, 2021
0244205
Update updatingballoons.md
toaster203 Nov 11, 2021
d7fe3a7
Add DragAndDrop Template
ji-mmyliu Nov 11, 2021
94fc7dc
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
ji-mmyliu Nov 11, 2021
6beeabd
p5js: add note about the list of callbacks
nyiyui Nov 11, 2021
1451006
Delete HealthBarTemplate.zip
toaster203 Nov 11, 2021
8a06f92
Delete BalloonWavesTemplate.zip
toaster203 Nov 11, 2021
6977793
Add files via upload
toaster203 Nov 11, 2021
20ce70f
Added tracking template
V1ad20 Nov 11, 2021
f8819ee
Enhance demo graphics
BenZeng04 Nov 11, 2021
d78cf57
p5js: cleanup
nyiyui Nov 11, 2021
d2a89c9
Merge branch 'prototype' of github.com:mcpt/learning into prototype
nyiyui Nov 11, 2021
0546d06
p5js: fix wrong css selector
nyiyui Nov 11, 2021
5c52603
tracking done
V1ad20 Nov 11, 2021
bb4830e
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
V1ad20 Nov 11, 2021
19c9f8a
final edits made to rotating towers page
V1ad20 Nov 11, 2021
0555cf8
Add to site and game-dev index, modify and edit introduction
skyflaren Nov 11, 2021
1186141
fix overall HP
BenZeng04 Nov 11, 2021
4d7fd83
Put code blocks in toggles
toaster203 Nov 11, 2021
db009f8
Merge branch 'prototype' of https://github.com/mcpt/learning into pro…
toaster203 Nov 11, 2021
b7af421
Add challenge prompt (no template)
BenZeng04 Nov 11, 2021
1b00045
Adjust demo
BenZeng04 Nov 11, 2021
01035cb
Update challenge.md
BenZeng04 Nov 11, 2021
1e1bc21
Update introduction.md
BenZeng04 Nov 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ home = ["HTML", "RSS", "JSON"]

[params]
themeVariant = "mcpt"
custom_js_urls = ['//toolness.github.io/p5.js-widget/p5-widget.js']
custom_js_urls = ['/js/p5.min.js', '/js/p5.sound.min.js']
custom_css = ['/css/p5js.css']

[markup.goldmark.renderer]
unsafe = true
4 changes: 2 additions & 2 deletions content/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ title = "Home"

# MCPT Learning Home
---
The learning branch is here to help you through the ICS curriculum while also expanding your world of coding knowledge in an interactive, informative, and (most importantly) fun way!
The Learning Branch is here to help you through the ICS curriculum while also expanding your world of coding knowledge in an interactive, informative, and (most importantly) fun way!

{{% notice info "Next Event: Game Series - Part I" %}}
Join us this **Thursday 11th** at **4:15pm** for our **Game Dev** series, as you’ll build your very own tower defense game! Get ready for an hour of interactive learning suited for all skill levels, preparing you for our keynote Game Jam during the Winter Break!
Join us **today** (Thursday 11th) at **4:15pm** for our **Game Dev** series, as you’ll build your very own tower defense game! Get ready for an hour of interactive learning suited for all skill levels, preparing you for our keynote Game Jam during the Winter Break!
{{% /notice %}}

### Jump To:
Expand Down
2 changes: 2 additions & 0 deletions content/game-dev/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ weight = 1

Welcome to the return of MCPT's Game Development Series!

Inspired by **Bloons Tower Defense**, you will learn how to code your very own tower-defense game in Processing by the end of a series of workshops. Keep scrolling through the pages to dive in!

![Banner](/img/Game_Dev_Banner.png)
4 changes: 3 additions & 1 deletion content/game-dev/part-i/_index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
+++
chapter = true
alwaysopen = false
pre = "<b>1.</b> "
title = "Part I"
weight = 1
+++
Expand All @@ -12,4 +13,5 @@ weight = 1
*Premiere, Interactive, Tower-Defense Game Workshop for Programmers of All Levels...*
{{% /notice %}}

![Banner](/img/Game_Dev_Banner.png)
![Banner](/img/Game_Dev_Banner.png)

51 changes: 51 additions & 0 deletions content/game-dev/part-i/challenge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
+++
title = "Challenge: Movement"
weight = 7
+++
---
## Moving along the path

Now that you've created a custom path using the `ArrayList` structure, how are we going to get our balloons to move along it smoothly?

### Key Concepts
1. **Coordinate** based representation
2. **Distance** based representation
3. Converting between the two (Challenge)

### Coordinate representations for positions

Normally when we have an object in a game that moves around, we will store two numbers - the **x-coordinate** and the **y-coordinate**.

![Coordinate Representation](/img/coordinate.gif)

**Drawing** an object using coordinates is extremely simple - all we need to do is create a shape using one of our graphics functions (`ellipse()`, `rect()`, etc.) and it will draw a shape right there. Nothing new.

**Moving** an object along our path with this representation, however, is difficult - because our path can contain lots of twists and turns, it is very hard to figure out the next location a balloon should travel to at any given time.

_Is there a way we can simplify movement?_

### Distance representations for positions

What if instead of storing two co-ordinates, we decided to store a single number, representing the **distance travelled** along our path?

![Distance Representation](/img/distance.gif)

**Moving** an object with this representation is now very simple - all we need to do is increase this number by the **speed** of the balloon every frame.

**Drawing** this object now becomes an issue - how are we supposed to figure out where the balloon is on the screen, just from a single number?

### Representation Conversion

In our game, we will make use of the benefits of **both representations** in order to move our balloons along the path.

Code-wise, we will **store** the **distance travelled** for each balloon and use the **custom method** `PVector getLocation(float distanceTravelled)` to convert from **distance representation** to the **coordinate representation**.

When we are displaying balloons, we will call this method and use the converted values in order to display our balloon.

{{% notice info "Challenge" %}}
While this method is already implemented in the templates, we encourage you to try and come up with a solution yourself!

Create an **written explanation** on how such a method would work in theory, earning up to **100** extra points for the Game Jam, on top of the **200** participation points.

After submissions close, we’ll offer our own explanation, explaining exactly how everything in the template works!
{{% /notice %}}
Binary file not shown.
92 changes: 92 additions & 0 deletions content/game-dev/part-i/draganddrop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
+++
title = "Drag And Drop"
weight = 2
+++

---

{{%attachments style="green" title="Drag and Drop Template" /%}}

## Graphic Interface
The drag and drop interface for this game contains a pick up region for the user to pick up towers and a trash box for the user to cancel the pick-up. To pick up a tower, simply click within the light-green pick-up box, drag the tower to a valid position on the field, and release the mouse key. Notice that it will not allow you to place the towers directly on the balloon path. If you decide to change your mind about picking up the tower, just drop it in the trash bin, the dark green rectangle around the pick-up box.

![Interface](/img/Interface-Demo.png)

## Picking Up Towers
To detect when a tower is being picked up, we will use Processing’s built-in `mousePressed()` method, which is called by the system whenever the computer detects that the left mouse button has been pressed down. In order to determine if the user is actually picking up the tower rather than clicking somewhere else on the screen, we will use a method to check if the mouse coordinates are within the pick-up box. It will use "point to rectangle collision" to check if the mouse is within bounds. If both the x distance and the y distance of the mouse from the centre are not greater than half the length of the square, it would be within bounds. See the image and code sample below for reference.

![Collision](/img/Square-Point-Collision.png)

```Java
// Use point to rectangle collision detection to check for mouse being within bounds of pick-up box
boolean pointRectCollision(float x1, float y1, float x2, float y2, float size) {
// --X Distance-- --Y Distance--
return (abs(x2 - x1) <= size / 2) && (abs(y2 - y1) <= size / 2);
}
```

## Dropping Towers
Now, how do we determine when the user has dropped the tower? Processing has a built-in `mouseReleased()` method which is called by the system whenever the user releases the mouse key. If the user was holding a tower when the `mouseReleased()` method is called, then the user has just dropped the tower, and we should handle the drop accordingly.

```Java
// Called by the system whenever the left mouse button is released by the user
void mouseReleased() {
if (within) { // If the user was holding the tower in the previous frame, the tower has just been dropped
handleDrop(); // Call the method to handle the drop and check for drop validity
}

within = false; // The mouse is no longer holding the tower
}
```

The `handleDrop()` method will check if the tower is either in a valid dropping position on the field, in an invalid dropping position, or in the trash box, which is the dark-green rectangle surrounding the pick-up region that cancels a tower pick-up. In order to see if it is in the trash box, we make sure that the x and y coordinates of the tower is within the set bounds of the trash box. If the tower is in a valid position on the field, we will add this tower to a list of placed-down towers (explained below). Checking validity of tower placements is explained <a href="/game-dev/part-i/towervaliditychecking/">here</a>

## Displaying Towers
In order to keep track of all the towers that have been placed down, we need to use an `ArrayList`.

{{% notice info "ArrayLists and PVectors"%}}
`ArrayList` is a built-in feature in Processing and Java that is similar to an array. It stores a sequence of values or elements in a list-like fashion. They have the same functionality as an array, with an additional feature of inserting a new element into the ArrayList at any time. Check out <a href="/game-dev/part-i/pathforballoons/#arraylists">balloon paths</a> for a more detailed explanation or the <a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html">official documentation</a>

`PVector` is a simple data type that stores two numbers and represents an (x, y) coordinate. Official documentation can be found <a href="https://processing.org/reference/PVector.html">here</a>
{{% /notice %}}

We will be using an ArrayList of `PVector` to store the coordinates of every tower that has been placed down. Whenever a tower is dropped in a valid position, we will add that tower’s coordinates to the ArrayList.

```Java
// List of all towers that have been placed down
ArrayList<PVector> towers;

// Adding the location of a new tower to the list of placed-down towers
towers.add(new PVector(x, y));
```

To help with displaying towers, we declared a helper method `drawTowerIcon()` that takes in the basic parameters of the tower that we would like to draw, and draws it onto the canvas.

```Java
// Draw a simple tower at a specified location
void drawTowerIcon(float xPos, float yPos, color colour) {
strokeWeight(0);
stroke(0);
fill(colour);
rectMode(CENTER);
rect(xPos, yPos, towerSize, towerSize); // Draw a simple rectangle as the tower
}
```

At each call of the `draw()` function, we will redraw all the placed-down towers whose coordinates are stored in the ArrayList. To do so, we will access each element of our tower ArrayList using a `for` loop and call the `drawTowerIcon()` to draw each tower in its respective position.

```Java
// Redraws all the towers that have been placed down
void drawAllTowers() {
// Loop through the ArrayList that stores the locations of towers that were placed down
for (int i = 0; i < towers.size(); i++) {
float xPos = towers.get(i).x, yPos = towers.get(i).y; // Get the location of the tower from the ArrayList

// Draw the tower at the specified location
drawTowerIcon(xPos, yPos, towerColour, new PVector(mouseX, mouseY));

fill(#4C6710); // Set the fill colour for text
text("Tower " + (i+1), xPos - 30, yPos - 20); // Write the tower number label
}
}
```
Binary file not shown.
83 changes: 83 additions & 0 deletions content/game-dev/part-i/healthchecking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
+++
title = "Health Bar"
weight = 9
+++

---
{{%attachments style="red" title="Health Checking Template" pattern=".*zip"/%}}

### What You'll Learn
###### In this section, you’ll learn how to implement a system that checks if the balloon has reached the end of the path, then remove it from the waves ArrayList.

### The Functions
#### 1. Checking if the Balloon is at the End of the Path
The method has a parameter of the distance travelled by the current balloon, or distanceTravelled. It is a boolean function, meaning that it returns either a **True** or **False** to the user.
{{% expand "See code" "false" %}}
```java
// Similar code to distance along path
boolean atEndOfPath(float travelDistance) {
float totalPathLength = 0;
for (int i = 0; i < points.size() - 1; i++) {
PVector currentPoint = points.get(i);
PVector nextPoint = points.get(i + 1);
float distance = dist(currentPoint.x, currentPoint.y, nextPoint.x, nextPoint.y);
totalPathLength += distance;
}
if (travelDistance >= totalPathLength){
return true; // This means the total distance travelled is enough to reach the end
}
return false;
}
```
{{% /expand %}}

We keep a float variable to track the total path length, called totalPathLength. Then, we need to assign a value to it, so we loop through the points ArrayList minus the last point (which doesn't contribute to the length of the path), which stores all the points in the path. We calculate the distance between the current and the next point using the distance formula, which is dist() and takes in the (x,y) of point 1 then the (x,y) of point 2. We add this to the total path length distance, and once the loop has finished iterating through the ArrayList, the total path length is assigned to the correct value.

We can check if the balloon has completed its journey if the total distance the balloon has travelled is greater or equal to the total path length. If it has, then we can return true, since the balloon has made it to the end. Otherwise, we return false, since the balloon is still on the path.

#### 2. Drawing the Health Bar
To draw the healthbar, we use two separate functions (line 80 and 84). One to load the image of the heart, and then the other to draw the healthbar.
{{% expand "See code" "false" %}}
```java
void loadHeartIcon() {
heart = loadImage("heart.png");
}
//method to draw a healthbar at the top right of the screen
void drawHealthBar(){
//draw healthbar outline
stroke(0,0,0);
strokeWeight(0);
fill(#830000);
rect(715,455,120,20);

//draw healthbar
noStroke();
rectMode(CORNER);
fill(#FF3131);
rect(655,445.5,health*10,20); //the healthbar that changes based on hp
rectMode(CENTER);
noFill();

//write text
stroke(0,0,0);
textSize(14);
fill(255,255,255);
text("Health: "+health,670,462);

//put the heart.png image on screen
imageMode(CENTER);
image(heart,650,456);
noFill();
}
```
{{% /expand %}}

For these final two functions, we first call the loadImage() method which loads the image specified in parameters to the PImage, in this case it is called heart. The image must be in a folder called data.
Since our file is called balloons.pde, the file explorer should look like:
- Balloons.pde
- data
- heart.png

After we load the image, we can draw the healthbar, with the method drawHealthBar() starting on line 85. In this method, we will draw the updated healthbar, first drawing the rectangle outline for the bar which is done by drawing a rectangle and filling it. Next, we draw the rectangle that reflects how much health the user has, which has 11 sections for the 11 health points the user has. Since the outer rectangle has 132 width, each point of health the user has can be represented as a section of 12 pixels, so we draw a rectangle with width health*12. This second rectangle will shorten as the health variable decreases.

Finally, we can put in the text that tells the user how much health they have left, as well as put in the heart image that we imported earlier. The image() function draws the image at the coordinates provided (second and third parameter). In imageMode(CENTER), these two coordinates represent the centre point of the image.
Binary file not shown.
Loading