Project name: Swirling
Code: https://editor.p5js.org/Sky-Falling/sketches/ggdwmOlj7
Github:https://sky-falling.github.io/cc-lab/particleworld/
Description: This is a testament to the irreplaceable utility of OOP and an interesting game as well. Player can click on the evil insects on the screen to kill them. If you luckily kill them all, then you will see a big congratulation line: “you win”. As known to all, lake is the main place to breed insects and you can control raindrop to strike them. Besides the fun of game, you can also enjoy the beautiful moment when raindrop collides with the surface of the lake. Worried about computer lag? Don’t worried, even you click your mouse super fast, the garbage collector method will still be able to limit the amount of computer calculation by constantly deleting unused instances.
Video Documentation:
Coding:
isClicked() { if (dist(mouseX, mouseY, this.x, this.y) < 15) { this.life = false; } for (let i = insect.length - 1; i >= 0; i--) { let p = insect[i]; p.isClicked(); if (p.life == false) { insect.splice(i, 1); } }
This is a method within the class “Insect” and it will turn a parameter “life” of the insect to be false if player is detected to click the insect. By doing so, the keyPressed() function can detect and delete the killed insects by method “splice()”. A key point here one should notice is that the for loop should start from the last index to make sure every instances inside the array can be examined.
for (let i = particles.length - 1; i > 0; i--) { let p = particles[i]; p.update(); p.display(); if (p.brightness < 40) { particles.splice(i, 1); } print(particles.length); }
Besides updating the states of all ripples which is quite apparent, this part has another unique function: delete the ripples that are already too dim (below 40 in this case) to reduce calculation for the computer. Without this deletion process, the array will grow extremely large with user’s click time, largely reducing the framerate.
this.x = startX; this.y = startY; this.growth_max = random(1, 6); this.radius_max = random(50, 200); this.radius = int(random(10, this.radius_max)); this.brightness = random(100, 255); this.thickness = random(0.5, 1.5); this.growth = random(this.growth_max); this.start_radius = random(2 * PI); this.arc = random(PI / 5, PI / 2); this.start_radius_speed = random(0.05); this.color1 = random(255); this.color2 = this.color1 + random(-100, 100); this.color3 = this.color1 + random(-100, 100);
You may wonder what do these parameters refer to respectively. Actually, x and y are the positions of the object, growth_max and radius_max determine the growth rate of its radius and its original radius, start_radius and arc determine the exact angle of this arc, and thickness is the stroke weight for the arc.
Failure and Success: The main obstacle is to find an appropriate balance between brightness and amount of calculation. If I increase the thredshould of brightness, then one ripple may disappear too soon, even before it turns dim. If it’s too low, then there will be too many instances at the same time and pose a huge burden on the computer.
Reflection:
- What is Object-Oriented Programming (OOP), a Class and an Instance of the Class?
Answer: A class can be comprehended as a combination of several variables and functions. However, the variables and functions can be seen as only available within the class, which largely tidies and modulizes the code. In OOP, programmers employ “class” to achieve the desired effect rather than defining millions of global variables and functions. Such programming method focus on descirbing the desired effects inside the class constructor, and when he wants to call it, he can simply create some instances and use the corresponding methods to perform such effects. Instance can be understood as a copy of all the elements of the class, so after creating the instance, it will inherit all the methods and variables inside the class.
- Discuss the effectiveness of OOP. When is OOP useful? In what way can it be utilized?
Answer: OOP can make the code easier to read and maintain. As the methods and variable inside a class are only available on a specific kind of object, you don’t need to worry about the problem of repeated names of functions and variable. You can use the same name inside different classes. When the code becomes long and has a complex structure, OOP then is extremely useful under such case. You can first figure out which object needs to achieve what effects, then you can follow this framework and build a class. When you need to use it, you only need to create some instances.
- Describe the objects you have created. What properties and methods were implemented? What kind of behaviors did you create by manipulating them?
I have created 2 obejects: Particles and Insect. The Particles contains lots of properties, including radius, position of the arc, and speed of growing, which together determines a small segment of the ripple. Its method is update() and display(). Insect don’t have too many properties as its movement is relatively straightforward, only the insect’s position and its speed at different direction. Except for update() and display(), it has 2 additional methods named “isClicked” and “checkbound”. One is to detect whether it’s clicked or not and the other is to avoid it wandering off the canvas. So the behaviour of the insect is disappear when being clicked and the behaviour of the ripple is spreading out and becomes dimmer after being generated.
- Please share it if there is any challenging and confusing aspect(s) in the OOP concepts and techniques
I wonder if we can create a method that can work on multiple classes which involves similar properties and movements.
Leave a Reply