I'm having a little problem with my class. It got to be something very easy, but I just cant find out the solution. Class Cuboid works well, but the class Cube is just not okey, I think I've used the super method in a wrong way.
Just give me a little hint. Thank you in advance.
class Cuboid {
constructor(length, width, height) {
this.length = length;
this.width = width;
this.height = height;
}
get surfaceArea() {
return (this.length * this.width + this.length * this.height + this.height * this.width) * 2;
}
get volume() {
return this.length * this.width * this.height;
}
}
class Cube extends Cuboid {
constructor(length) {
super(length);
this.height = length;
}
}
Guys, why do you downvote my question? It's not really nice...
As I suggesting Cube is Cuboid with all 3 dimension equal. So there is 2 options to do it:
1.
class Cube extends Cuboid {
constructor(length) {
super(length, length, length);
}
}
2.
class Cuboid {
constructor(length, width, height) {
this.length = length || 0;
this.width = width || this.length;
this.height = height || this.width;
}
// ....
Related
the follwoing code:
class Rectangle {
constructor(w, h) {
this.w = w;
this.h = h;
}
}
Rectangle.prototype.area = function () {
return (this.w * this.h);
};
class Square extends Rectangle {
constructor(w, h) {
super(w, h);
// this.w = w;
// this.h = h;
}
}
Do I have problems with my inheritance?
I'm trying to use:
const rec = new Rectangle(3, 4);
const sqr = new Square(3);
console.log(rec.area());
console.log(sqr.area());
rec prints the correct answer but sqr print's out: NaN
I also tried maybe adding a Square prototype:
Square.prototype.area = function () {
return (this.w * this.w);
};
but the output is:
-1
-1
so this also affected area for rec.area()
Since the Square constructor will be called with only one argument (since its size is equal at all sides), you need to "translate" this to a Rectangle constructor call that needs 2 arguments (width and height). Since both are equal for the square, you need to pass that single argument twice to the Rectangle constructor:
class Rectangle {
constructor(w, h) {
this.w = w;
this.h = h;
}
area() { // Use this notation for prototype methods
return this.w * this.h;
}
};
class Square extends Rectangle {
constructor(w) { // One argument...
super(w, w); // ...Two arguments, but width == height
}
}
let square = new Square(10);
console.log(square.area());
I am learning p5.js and I don't quite understand how to repeat my function on the y-axis so that the lines appeared on top of the other. I understand that I would need to make a class object but all that I succeeded to do was to freeze the editor XD. Could you help me figure out how to make my function repeat itself with different Y starting point?
let walkers = []; // creation of an array
this.xoff = 0; //changed to go outside of the walker class
this.yoff = 0; //changed to go outside of the walker class
this.x = 0;
y = 200;
function setup() {
createCanvas(600, 600);
background(250);
for (let i = 0; i < 10; i++) { //mix array and class
walkers[i] = new walker(y);
}
}
function draw() {
for (i = 0; i < walkers.length; i++) { // consider the array lenght
walker[i].acceleration(); // call the class and it's function
walker[i].velocity();
walker[i].update();
walker[i].display();
}
}
class walker {
constructor(y) { //divide the class in multiple function
this.y = y
}
acceleration() {
this.accX = 0.1;
this.accY = 0.1;
this.px = this.x;
this.py = this.y;
}
velocity() {
this.velocityY = random(-20, 20);
this.velocityX = 5;
}
update() {
this.x = this.x + this.accX + this.velocityX * noise(this.xoff);
this.y = this.y + this.accY + this.velocityY * noise(this.yoff);
}
display() {
for (this.y < 200; this.y > 400; this.y + 20) {
line(this.x, this.y, this.px, this.py);
}
this.xoff = this.xoff + 1;
this.yoff = this.yoff + 100;
this.px = this.x;
this.py = this.y;
}
}
There are quite a few things wrong with how your code behaves.
Here are a few issues:
walkers it the array used,: e.g.walkers[i].acceleration();, not walker[i].acceleration(); (same hold true for the rest of the calls)
initialize variables if you plan to use them (otherwise using math operators update() will end up with NaN: e.g. this.x, this.xoff, this.yoff, etc.
it's unclear what motion behaviour you're after with position, velocity, acceleration, perlin noise, etc. (which btw are updated with strange increments ( this.yoff = this.yoff + 100;))
The code mostly freezes because of this:
for (this.y < 200; this.y > 400; this.y + 20)
It's unclear what you're trying to do there: this.y < 200; this.y > 400 makes me think you were going for an if condition to only draw lines between 200-400 px on Y axis, however this.y + 20 makes me think you want to increment y for some reason ?
It's also unclear why x,xoff,yoff moved out the walker class ?
There may be some understanding around classes, instances and the this keyword.
As per JS naming convention, class names should be title case.
I can tell you've put a bit of effort trying to build a more complex sketch, however it will won't be helpful for you to add complexity unless you understand all the parts of your code. This is where mastering the fundamentals pays off.
I recommend:
going back to pen/paper sketching to work out your idea until it's clearer
thinking of how you will achieve that by breaking complex tasks into smaller steps
writing basic test sketches for each step/component
Finally, bring one component at a time into a main program, testing again as components interact with another. Be sure to check out Kevin Workman's How to Program guide.
FWIW, here's a modified version of your code, with a tweak to set the initial y position of each Walker on top of each other:
let walkers = []; // creation of an array
y = 200;
function setup() {
createCanvas(600, 600);
background(250);
for (let i = 0; i < 10; i++) { //mix array and class
// incrementally add 10 pixels to y so the initially lines start on top of each other
walkers[i] = new Walker(y + (i * 10));
}
}
function draw() {
for (let i = 0; i < walkers.length; i++) { // consider the array length
// walkers, not walker
walkers[i].acceleration(); // call the class and it's function
walkers[i].velocity();
walkers[i].update();
walkers[i].display();
}
}
class Walker {
constructor(y) { //divide the class in multiple function
this.y = y;
// remember to init all variables you plan to use
this.xoff = 0; //changed to go back inside of the walker class
this.yoff = 0; //changed to go back inside of the walker class
this.x = 0;
}
acceleration() {
this.accX = 0.1;
this.accY = 0.1;
this.px = this.x;
this.py = this.y;
}
velocity() {
this.velocityY = random(-20, 20);
this.velocityX = 5;
}
update() {
this.x = this.x + this.accX + this.velocityX * noise(this.xoff);
this.y = this.y + this.accY + this.velocityY * noise(this.yoff);
}
display() {
// what were you trying ?
//for (this.y < 200; this.y > 400; this.y + 20) {
line(this.x, this.y, this.px, this.py);
//}
this.xoff = this.xoff + 1;
this.yoff = this.yoff + 1;
this.px = this.x;
this.py = this.y;
// reset x, y to 0
if(this.x > width){
this.x = 0;
}
if(this.y > height){
this.y = 0;
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js"></script>
It will definitely be easier to do it using a class. Make different functions inside the class which are responsible for update, movement, etc. You can make a display function too in which you can set the y co-ordinate using a For loop. In that way, it will become very easy to keep changing the y co-ordinate.
If you want to display multiple lines at once, do all of the above and also use an array to store the y co-ordinates and then display them in the For loop.
Do let me know if you need help with the actual code.
Getting an error of illegal return statement on the volume...
tried adding CuboidMaker15.volume to call the object
class CuboidMaker15 {
constructor(cuboidMaker15Attributes){
this.length = cuboidMaker15Attributes.length;
this.width = cuboidMaker15Attributes.width;
this.height = cuboidMaker15Attributes.height;
}
}
volume(); {
return this.length * this.width * this.height;
}
surfaceArea(); {
return 2 * (this.length * this.width + this.length * this.height + this.width * this.height);
}
const cuboid15 = new CuboidMaker15({
length: 4,
width: 5,
height: 5
});
Keeps saying the volume is not defined...
You need to move your methods inside your class definition. Also get rid of ; after the method name:
class CuboidMaker15 {
constructor(cuboidMaker15Attributes) {
this.length = cuboidMaker15Attributes.length;
this.width = cuboidMaker15Attributes.width;
this.height = cuboidMaker15Attributes.height;
}
volume() {
return this.length * this.width * this.height;
}
surfaceArea() {
return 2 * (this.length * this.width + this.length * this.height + this.width * this.height);
}
}
const cuboid15 = new CuboidMaker15({
length: 4,
width: 5,
height: 5
});
console.log(cuboid15);
console.log(cuboid15.volume());
console.log(cuboid15.surfaceArea());
I would like to make the getArea() function a prototype, and am not sure if this ES6 (?) format is automatically doing this for me, or do I still need to declare a prototype in a separate Object.prototype.method = function() {}
construct?
class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
getArea() {
return this.height * this.width;
}
}
It is.
The ES6 class format basically translates to something like this:
function Polygon(height, width) {
this.height = height;
this.width = width;
}
Polygon.prototype.getArea = function() {
return this.height * this.width;
};
I have a card class:
function Card() {
this.image = new Image();
this.x = 0;
this.y = 400;
this.initialX = 0;
this.initialY = 0;
this.scaleFactor = 4;
this.setImage = function(ii){
this.image.src = ii;
};
this.getWidth = function(){
if (this.image == null){
return 0;
}
return this.image.width / this.scaleFactor;
}
this.getHeight = function(){
if (this.image == null){
return 0;
}
return this.image.height / this.scaleFactor;
}
this.pointIsInCard = function(mx, my){
if (mx >= this.x && mx <= (this.x + this.getWidth()) && my >= this.y && my <= (this.y + this.getHeight()))
{
return true;
}
else{
return false;
}
};
};
I then have a deck class:
function Deck(x, y, w, h){
this.x = x;
this.y = y;
this.width = w;
this.height = h;
this.cards = [];
}
I need to add a method in Deck class similar to pointIsInCard instead it will be called pointIsInDeck. The logic will be same i.e to check whether the passed in point falls in the boundary of the object. So seeing this duplication of code I wanted to know what is a good design practice to avoid this duplication? One option I thought of was to extract the method out and create a function for generic object with x, y, width, height but again from OOP principles I thought this method should belong to the class/object. I appreciate any help! Thanks!
A common approach for what you're doing is to attach a Rectangle or similar instance with that functionality to both of your objects, that is:
class Rectangle {
constructor(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
containsPoint(x, y) {
return x >= this.x && x =< this.width &&
y >= this.y && y =< this.height;
}
}
Then just add it to Card and Deck:
function Card() {
this.rect = new Rectangle(/* Your card shape */);
// ...
}
function Deck() {
this.rect = new Rectangle(/* Your deck shape */);
// ...
}
And you can do:
card.rect.containsPoint();
deck.rect.containsPoint();
If these are classes related to drawing, they would both inherit from something like Rectangle, which they would both inherit this behaviour from.
If they are gameplay-related, I would prefer them each referencing a Rectangle (or its subclass) that they would delegate all UI-related tasks to; then reduce this to the previous paragraph's solution.
You can use Function.prototype.call() to set this at a function call
function Card() {
this.x = 1; this.y = 2;
};
function Deck() {
this.x = 10; this.y = 20;
}
function points(x, y) {
// do stuff
console.log(x, this.x, y, this.y); // `this`: `c` or `d`
}
var c = new Card();
var d = new Deck();
points.call(c, 3, 4); // `this`: `c` within `points` call
points.call(d, 100, 200); // `this`: `d` within `points` call