I have this code and I always have to creat the const ctx at begin of document with same name used in the class, and I wonder if have way make this class more portable for others project
const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
class layer{
constructor(image, speedModifier){
this.x = 0;
this.y = 0;
this.width = 2400;
this.height = 700;
//this.x2 = this.width;
this.image = image;
this.speedModifier = speedModifier;
this.speed = gameSpeed * this.speedModifier
}
update(){
this.speed = gameSpeed * this.speedModifier;
this.x = gameFrame * this.speed % this.width;
}
draw(){
ctx.drawImage(this.image, this.x, this.y, this.width, this.height);
ctx.drawImage(this.image, this.x + this.width, this.y, this.width, this.height);
}
}
Just export your class and make your class take in a context in the constructor.
export class Layer {
constructor(image, speedModifier, context) {
this.context = context;
this.x = 0;
this.y = 0;
this.width = 2400;
this.height = 700;
this.image = image;
this.speedModifier = speedModifier;
this.speed = gameSpeed * this.speedModifier
}
draw(){
this.context.drawImage(this.image, this.x, this.y, this.width, this.height);
this.context.drawImage(this.image, this.x + this.width, this.y, this.width, this.height);
}
}
Now anyone who uses your class can import it:
import { Layer } from './layer.js';
And the user of the class has to get the canvas context. However they can then get that once and pass it in to as many layers as they want:
const context = document.querySelector('canvas').getContext('2d');
const layer1 = new Layer(someImage, 1, context);
const layer2 = new Layer(anotherImage, 1, context);
const layer3 = new Layer(thirdImage, 2, context);
Nothing more you can really do beyond that.
Related
class Snake {
constructor() {
this.x = 400;
this.y = 400;
this.width = 25;
this.height = 25;
}
draw() {
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
let snake = new Snake();
class Food {
constructor() {
this.x = Math.floor(Math.random() * (canvasWidth - 0) + 0)
this.y = Math.floor(Math.random() * (canvasHeight - 0) + 0)
this.width = 50;
this.height = 50;
/* this.image = new Image()
this.image.src = 'img/apple.png' */
}
update() {
}
draw() {
/* ctx.drawImage(this.image, this.x, this.y, this.width, this.height); */
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
let food = new Food()
function collision(){
if(snake.x < food.x + food.width &&
snake.x + snake.width > food.x &&
snake.y < food.y + food.height &&
snake.height + snake.y > food.y){
alert("hit")
}
}
collision()
I have two JS classes one portrays a snake the other portrays food, I tried this collision algorithm I found but it's not working. where is my mistake or how can I make the collision happen?
Just had to call collision() in the animate function
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
snake.draw();
snake.update();
food.draw()
collision()
requestAnimationFrame(animate);
}
animate();
On my canvas I have two rectangles drawn. The first with a larger height and second with a smaller height.
Here is a screen shot:
In my code I represent them with classes and then instantiate them :
Here is how I do it:
class Rectangle {
constructor(x, y, width, height, color, value) {
this.x = x;
this.y = y;
this.height = height;
this.width = width;
this.color = color;
this.value = value;
}
// draw function of this rectance will let it appear on the screen;
draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height , this.color, this.value);
}
// the update function will swap the rectangle's property and redraw them again
update(obj1, obj2) {
var temp;
// saving the values of the first rectancgle in the temp variables
for(var key in obj1) {
this.temp = this.obj1[key];
this.obj1[key] = this.obj2[key];
this.obj2[key] = this.temp;
}
this.obj1.draw();
this.obj2.draw();
}
}
var rect2 = new Rectangle(100, y-20, 50, 25, "pink", 40 );
rect2.draw();
var rect1 = new Rectangle(160, y, 50, 5, "black", 20);
rect1.draw();
rect1.update(rect1, rect2);
What I want to do is now make the pink rectangle appear in place of black and black in place of pink. Can anyone tell me how to do that?
class Rectangle {
constructor(x, y, width, height, color, value) {
this.x = x;
this.y = y;
this.height = height;
this.width = width;
this.color = color;
this.value = value;
}
// draw function of this rectance will let it appear on the screen;
draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height , this.color, this.value);
}
reposition(x,y) {
this.x = x;
this.y = y;
}
}
var rect2 = new Rectangle(100, y-20, 50, 25, "pink", 40 );
rect2.draw();
var rect1 = new Rectangle(160, y, 50, 5, "black", 20);
rect1.draw();
// do this – after some wait, click or however you like to trigger it
let buffer_x = rect1.x, buffer_y = rect1.y;
rect1.reposition(rect2.x,rect2.y);
rect2.reposition(buffer_x,buffer_y);
rect1.draw();
rect2.draw();
You can try swap location of obj1 and obj2!!
ex:
var x1 = this.obj1.x, y1 = this.obj1.y;
this.obj1.x = this.obj2.x;
this.obj1.y = this.obj2.y;
this.obj2.x = x1;
this.obj2.y = y1;
after this, call update
im pretty new at canvas, but im trying to draw a falling object. First im trying to just draw an object, but its not working. How can i just draw an object (and if you could be so nice but not necessary to let me know how i can make it move)? Or what am I doing wrong here? Code:
let c, ctx;
window.onload = function(){
c = document.getElementById("boom");
ctx = c.getContext("2d");
c.width = window.innerwidth;
c.height = window.innerHeight;
setup();
draw();
};
function draw(){
//window.requestAnimationFrame(draw);
ctx.fillStyle = "rgba(0,0,0,1)";
ctx.fillRect(0, 0, c.width, c.height);
ctx.fillStyle = "red";
ctx.fillRect(100, 100, 100, 100);
regen.push(new regen(this.x, this.y, this.w, this.h, this.color));
};
function setup(){
}
function regen(x, y, w, h, color){
this.x = 100;
this.y = 100;
this.width = 20;
this.height = 40;
this.color = "blue";
//this.xSpeed = 4;
//this.ySpeed = 4;
this.draw = function(){
//this.update = function(){
//this.x += this.xSpeed;
//this.y += this.ySpeed;
//}
}
}
function getRndFloat(min, max) {
return Math.random() * (max - min + 1) + min;
}
You got typo in innerwidth: it must be innerWidth. But you got undefined and your canvas has no width
I'm working on a JavaScript canvas API using an Object Oriented approach. My problem is that after using requestAnimationFrame in the animate method I get this as undefined. If I remove the requestAnimationFrame from the animate method the errors goes away - Any idea how to solve this?
Canvas.js
export default class Canvas {
constructor(canvas, ctx) {
this.canvas = canvas;
this.ctx = ctx;
this.x = 100;
this.y = 100;
this.dx = 4;
this.dy = 5;
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
}
drawCircle(x, y) {
for (let i = 0; i < 6; i++) {
this.ctx.beginPath();
this.ctx.fillStyle = "lightblue";
this.ctx.arc(x, y, 30, 0, Math.PI * 2);
this.ctx.fill();
}
}
animate() {
// Clear rect
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
requestAnimationFrame(this.animate);
this.x += 1;
this.drawCircle(this.x, this.y);
}
}
app.js
import Canvas from "./Canvas";
let c = document.getElementById("canvas");
let ctx = c.getContext("2d");
const obj = new Canvas(c, ctx);
obj.animate();
You might need to bind the methods to use this.
Try the below code for Canvas.js
export default class Canvas {
constructor(canvas, ctx) {
this.canvas = canvas;
this.ctx = ctx;
this.x = 100;
this.y = 100;
this.dx = 4;
this.dy = 5;
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
this.drawCircle = this.drawCircle.bind(this);
this.animate = this.animate.bind(this);
}
drawCircle(x, y) {
for (let i = 0; i < 6; i++) {
this.ctx.beginPath();
this.ctx.fillStyle = "lightblue";
this.ctx.arc(x, y, 30, 0, Math.PI * 2);
this.ctx.fill();
}
}
animate() {
// Clear rect
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
requestAnimationFrame(this.animate);
this.x += 1;
this.drawCircle(this.x, this.y);
}
}
function startGame() {
myGamePiece = new component(30, 30, "red", 10, 120);
myGameArea.start();
myWall = new defense(30, 150, "black", 90, 120)
myGameArea.start();
myWall2 = new defense(30, 150, "black", 180, 0)
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 338;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas,
document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 20);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width,
this.canvas.height);
}
}
function defense(width, height, color, x, y) {
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
this.newPos = function(){
this.x;
this.y;
}
}
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 = myGameArea.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;
}
}
There's my snippet of code please help me with my collision between the wall and square. I also have buttons to move the square if you need to know.
Here's some more code for your convenience just please get me a answer thanks in advance.
I know its a lot of code but its also not all of it so ifyou need anything else just ask thanks.
Adding addendum: This code will only check for square entity collisions, ie a tile based 2d style of game. This will not work in a 3d based graphic set, or do any sort of fine collision detection (against non square entities).
Without seeing more of your code, such as how you're rendering or managing state of the entities, you just need a function call during your update() method, wherever that may be.
The method I used in a hobby project several years ago, the collision logic looked like this (a function that would return just a boolean). This is just a jist I can give unless I see more of your code.
function isColliding(entity1, entity2) {
var e1top = entity1.y;
var e1bot = entity1.y + entity1.height;
var e1left = entity1.x;
var e1right = entity1.x + entity1.width;
var e2top = entity2.y;
var e2bot = entity2.y + entity2.height;
var e2left = entity2.x;
var e2right = entity2.x + entity2.width;
var collision = true;
if ((e1top > e2bot) || (e1bot < e2top) || (e1left > e2right) || (e1right < e2left))
collision = false;
return collision;
}