Not setting variable to rectangle in canvas - javascript

I am trying to get the rectangle to move when you click a button by adding 1 to the x/y pos of the rectangle but the speed variable keeps saying undefined.
// . . . //
function component(width, height, color, x, y) {
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function(){
ctx = gameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
this.newPos = function(){
this.x += this.speedX;
this.y += this.speedY;
}
}
function updateGameArea(){// Update games at 50fps
gameArea.clear();
bluePiece.newPos();
bluePiece.update();
}
function moveUp(piece){
piece.speedY -= 1;
console.log("UP "+piece+" S:"+piece.speedY);
}
function moveDown(piece){
piece.speedY += 1;
console.log("DOWN "+piece+" S:"+piece.speedY);
}
function moveLeft(piece){
piece.speedX -= 1;
console.log("LEFT "+piece+" S:"+piece.speedX);
}
function moveRight(piece){
piece.speedY += 1;
console.log("RIGHT "+piece+" S:"+piece.speedX);
}
Note: If you would like to see the full code to better understand what is going on, please go here and press ctrl+U to view full code.

you are passing a string to the function and after that accessing the property of String, which definitely will be undefined.
Try console.log(typeof piece);

Related

js -Uncaught TypeError: Cannot read property 'x' of undefined at object (ball

Hello I'm am getting the above error message when trying to run this code and I can't for the life of me figure out what's wrong with it, help would be very appreciated. Excuse any rookie mistakes you may see. I've created a ball and I am trying to move it.
class Ball{
constructor(x,y,xSpeed,ySpeed,r){
this.x =x;
this.y=y;
this.xSpeed=xSpeed;
this.ySpeed=ySpeed;
this.r= r;
}
draw(){
ctx.clearRect(0,0, 500, 200);
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.stroke();
}
move()
{
this.x+=this.xSpeed; //error is here
this.y+=this.ySpeed;
if (this.x==0)
{
this.xSpeed=2;
}
else if(this.x==500)
{
this.xSpeed=-2;
}
if (this.y==200)
{
this.ySpeed=-1;
}
else if (this.y==0)
{
this.ySpeed=1;
}
window.requestAnimationFrame(this.move);
}
}
var canvas = document.getElementById("canvas-for-ball");
var ctx = canvas.getContext("2d")
let balls=new Ball (10,10,2,1,5);
balls.draw();
balls.move();
The problem is that when you call requestAnimationFrame and pass it a reference to move as its callback, the this binding to your Ball instance is lost when the callback is executed. Instead, you must pass move in such a way that this is still bound to your Ball instance. You can do this by passing the function reference using the .bind() method, which takes an argument that specifies what the this binding will be when the callback function runs.
class Ball {
constructor(x,y,xSpeed,ySpeed,r){
this.x = x;
this.y = y;
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
this.r = r;
}
draw(){
ctx.clearRect(0,0, 500, 200);
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.stroke();
}
move(){
this.x += this.xSpeed;
this.y += this.ySpeed;
if (this.x == 0) {
this.xSpeed = 2;
} else if(this.x == 500) {
this.xSpeed =- 2;
}
if (this.y == 200) {
this.ySpeed =- 1;
} else if (this.y == 0) {
this.ySpeed = 1;
}
window.requestAnimationFrame(this.move.bind(this));
}
}
var canvas = document.getElementById("canvas-for-ball");
var ctx = canvas.getContext("2d")
let balls = new Ball(10,10,2,1,5);
balls.draw();
balls.move();
<canvas id="canvas-for-ball"></canvas>

Why will my animation not work if I declare my variable locally?

I'm quite new to JS so please excuse my ignorance but I can't figure out why my animation if statement doesn't work if I declare my speed variable locally in the move() function.
If I don't declare the speed variable globally, the girl gets to the windowWidth and gets stuck moving a couple of pixels back and forth. Basically staying there rather than moving the other way.
let speed = 2;
class Girl {
constructor(x, y) {
this.x = x,
this.y = y
}
body() {
noStroke();
fill(239, 101, 233);
rect(this.x, this.y, 20, 40);
fill(249, 192, 155);
triangle(this.x, this.y, this.x + 20, this.y, this.x + 10, this.y + 15);
}
move() {
if (this.x > windowWidth + 50 || this.x < -50) {
speed = speed * -1;
}
this.x = this.x + speed;
}
}
I should mention I'm using the p5 library in case I'm using any funky functions. It works but I'm sure I could tidy this up a little bit. Any advice would be more than welcome.
Thanks in advance!
You should not declare it as a local variable inside the move method (as that would make it get re-initialised to 2 on every call), but you should make it a property of the instance that gets initialised in the constructor and modified in the move method (just like x and y).
class Girl {
constructor(x, y) {
this.x = x;
this.y = y;
this.speed = 2;
}
body() {
noStroke();
fill(239, 101, 233);
rect(this.x, this.y, 20, 40);
fill(249, 192, 155);
triangle(this.x, this.y, this.x + 20, this.y, this.x + 10, this.y + 15);
}
move() {
if (this.x > windowWidth + 50 || this.x < -50) {
this.speed = this.speed * -1;
}
this.x = this.x + this.speed;
}
}
Because the value of speed is shared across multiple calls to move. If you declare it inside move then it gets created for each call to move, thus any previous value of speed will be ignored.
If you don't want speed to be a global variable, then you can make it a property of the class Girl:
class Girl {
constructor(x, y) {
this.x = x;
this.y = y;
this.speed = 2; // make 'speed' a property of the class
}
/* ... */
// use 'this.speed' inside 'move' instead of just 'speed'
move() {
if (this.x > windowWidth + 50 || this.x < -50) {
this.speed = this.speed * -1;
}
this.x = this.x + this.speed;
}
}
Problem here is this.x > windowWidth + 50 || this.x < -50. Try to log this inside move() function and you will see that it is referring to move().x instead of Girl.x. So this.x is undefined and undefined > 10 + 50 is always false.
P.s. I dont know p5 so this is vanilla.
So to fix this you need to declare another variable to get Girl scope.
var Girl = function(){
var self = this;
//code goes here
function move(){
self.x = setValue;
console.log(this.x) //undefined
}
}

Particle (made with constructor) expand and fade upon collision

When a user clicks on any particle I want it to expand and fade and upon collision with any other particle and that particle will also expand and fade. Now my problem is that I want to know if there is a way in which I can get those particles (made with constructor in this case) to effect each other when they get collide. Link to Codepen
var bubbles = [];
function setup() {
frameRate(25);
// Creates Canvas
createCanvas(windowWidth, windowHeight);
//Genrates 100 Particles with random a & y
for (var i = 0; i < 80; i++) {
var x = random(width);
var y = random(height);
bubbles[i] = new Bubble(x, y);
}
}
function mousePressed() {
for (var i = 0; i < bubbles.length; i++) {
bubbles[i].clicked();
}
}
function draw() {
clear();
//Adds color and motion
for (var bubble of bubbles) {
fill(bubble.color.red, bubble.color.green, bubble.color.blue);
bubble.move();
bubble.display();
}
}
function Bubble(x, y) {
this.x = x;
this.y = y;
this.wh = 15;
this.speedX = random(1, 5);
this.speedY = random(1, 5);
//Individual Particle Creation
this.display = function() {
noStroke();
ellipse(this.x, this.y, this.wh, this.wh);
};
//Interactivity
this.clicked = function() {
var d = dist(this.x, this.y, mouseX, mouseY);
if (d < 8) {
this.wh = 100;
}
};
//Randomizes colors
this.color = {
red: random(255),
green: random(255),
blue: random(255)
};
//Particle Motion
this.move = function() {
//Motion in X direction
this.x += this.speedX;
//Bouncing back on X-axis
if (this.x > windowWidth || this.x < 0) {
this.speedX = -this.speedX;
}
//Motion in Y Direction
this.y += this.speedY;
//Bouncing back on Y-axis
if (this.y > windowHeight || this.y < 0) {
this.speedY = -this.speedY;
}
};
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
::-webkit-scrollbar{
display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.10/p5.js"></script>
Use a nested for loop.
Step 1: Loop over the bubbles. Do this with a for loop.
Step 2: For each bubble, loop over the rest of the bubbles (if you're on bubble 4, start with bubble 5). Do this with another for loop inside the first one.
Step 3: Now that you have two bubbles, do the collision between them.
If you're having trouble getting that working, then please start smaller. Start with a simpler program that just shows two hard-coded bubbles and does collision detection between them.

How can i change the color of a javascript object?

I've created a simple code that looks a bit like "Impossible Game". I'm new with javascript so my question might sound a bit strange but i've created a few opjects like you can see below. When i change the color with ctx.fillstyle all my objects change this specific color. How can i give each object a different color?
Thanks ;)
var PlayerX;
var Blocka;
var Ground
var canvas = document.getElementById("gamefield");
ctx = canvas.getContext("2d");
var Gamespeed = 5;
var Gravity = 0.9;
var Score = 0;
var velocity = 0.01;
var jumping;
PlayerX = new Player();
Blocka = new Block(1);
Ground = new Gameground();
setInterval(Update, 20);
function startGame() {
}
function Player() {
// this staat voor verwijzing naar zichzelf
this.width = 30;
this.height = 50;
this.x = canvas.width / 4;
this.y = canvas.height / 3 * 2;
this.draw = function() {
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
function Block(kolb) {
this.width = 20;
this.height = 40;
this.show = true;
//this.x = canvas.width/2;
this.x = canvas.width + 20;
this.y = (canvas.height / 3 * 2) + 10;
this.draw = function() {
this.move();
if (this.show) {
if (kolb == 1) {
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
}
this.move = function() {
this.x -= Gamespeed;
this.death();
}
this.death = function() {
if (this.x <= 20) {
this.show = false;
}
}
}
function Gameground() {
// this staat voor verwijzing naar zichzelf
this.width = 800;
this.height = 150;
this.x = 0;
this.y = 450;
this.draw = function() {
ctx.fillStyle = "#00FFBF"
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
function Update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
Blocka.draw();
PlayerX.draw();
if (PlayerX.x < Blocka.x + Blocka.width &&
PlayerX.x + PlayerX.width > Blocka.x &&
PlayerX.y < Blocka.y + Blocka.height &&
PlayerX.height + PlayerX.y > Blocka.y) {
// collision detected!
ctx.fillStyle = "#FF0000";
}
Ground.draw();
}
window.addEventListener("keydown", checkKeyPressed, false);
function checkKeyPressed(e) {
if (e.keyCode == "32") { //kijkt of de spatiebalk is ingedrukt
var interval1, interval2, velo, tijd;
velo = 0.00001;
tijd = 20;
interval1 = setInterval(plus, tijd);
function plus() {
if (velo < 20) {
velo += 1.5;
} else {
velo -= 1.5;
}
if (PlayerX.y > 480) {
clearInterval(interval1);
interval2 = setInterval(min, tijd);
}
PlayerX.y += velo;
console.log(PlayerX.y);
}
function min() {
if (velo < 20) {
velo += 1.5;
} else {
velo -= 1.5;
}
if (PlayerX.y < 430) {
clearInterval(interval2);
}
PlayerX.y -= velo;
console.log(PlayerX.y);
}
}
}
You can use ctx.save(); and ctx.restore(); before and after your individual color changes.
This will save the current context state before changing the color, and then restore it back to it's original state after that one specific rectangle was drawn, yet before the others are drawn.
See below for example.
ctx.save();
ctx.fillStyle = "#00FFBF";
ctx.fillRect(this.x, this.y, this.width, this.height);
ctx.restore();
--- EDIT ---
As per the comments on OP's question - another resolution is to ensure that you call the fillStyle function before each fillRect function. See example and fiddle (provided by OP) below.
this.draw = function(){
ctx.fillStyle = "#00FFBF";
ctx.fillRect(this.x, this.y, this.width, this.height);
}
Here's OP's fiddle - https://jsfiddle.net/Nielsvangils/v9hL9d3k/

javascript Centipede, key press not working

I built centipede in javascript from a Khan Academy tutorial. Then I figured out how to put it into a web browser. however, the key presses are not working. I have tried to change the keyCode values, and change some of the function definitions to "void" but nothing has worked. The app uses processing .js to work. Here is the section of js dealing with the keys:
var Player = function(x,y,size,speed){
this.x = x;
this.y = y;
this.size = size;
this.speed = speed;
this.update = function(){
if(keys[LEFT]){
this.x -= this.speed;
}
if(keys[RIGHT]){
this.x += this.speed;
}
if(keys[DOWN]){
this.y += this.speed;
}
if(keys[UP]){
this.y -= this.speed;
}
if(keys[76] && bulletDelay < 0){
var b = new Bullet(this.x, this.y, 5,5);
bullets.push(b);
bulletDelay = 40;
}
if (this.x < 0){
this.x = 0;
}
if (this.x > width){
this.x = width;
}
if (this.y > 800){
this.y = 800;
}
//This adjusts the max height the player can move up on y-axis. Adjust to make more like Atari version
if (this.y < 100) {
this.y = 100;
}
noStroke();
fill(0,255,0);
ellipse(this.x, this.y, this.size, this.size);
};
};
I sorted it out. The keyPress and keyRelease functions needed to be changed from
var keyPressed = function(){
to
void keyPressed() . . .
similar for the keyReleased function
The syntax
if(keys[LEFT])
should be
if(keyCode == LEFT)
See the Processing.js keyCode reference and key
EDIT 1: For special keys (arrow, space), you should use keyCode instead of key.

Categories

Resources