I am trying to move the arcs along the x-axis, but it's giving an error that x is not defined in the update function. Are the variables not properly placed or some reference is missing??
Code
<canvas id="myCanvas"></canvas>
<script>
var myCanvas = document.getElementById("myCanvas");
var c = myCanvas.getContext("2d");
var redArc = new Circle(50, 60, 10, "red");
var greenArc = new Circle(80, 60, 15, "green");
var blueArc = new Circle(120, 60, 20, "blue");
function Circle(x, y, radius, color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.draw = function() {
c.beginPath();
c.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
c.fillStyle = this.color;
c.fill();
}
this.update = function() {
redArc.x += 1;
greenArc.x += 1;
blueArc.x += 1;
this.draw();
}
this.update();
}
function animate() {
requestAnimationFrame(animate);
c.clearRect(0, 0, myCanvas.clientWidth, myCanvas.clientHeight);
redArc.update();
greenArc.update();
blueArc.update();
}
animate();
How do I go about fixing it? Any suggestions
Thanks!!
Replace your update method with the following :
this.update = function() {
this.x += 1;
this.draw();
}
you should be using this.x , not the variable names.
var myCanvas = document.getElementById("myCanvas");
var c = myCanvas.getContext("2d");
var redArc = new Circle(50, 60, 10, "red");
var greenArc = new Circle(80, 60, 15, "green");
var blueArc = new Circle(120, 60, 20, "blue");
function Circle(x, y, radius, color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.draw = function() {
c.beginPath();
c.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
c.fillStyle = this.color;
c.fill();
}
this.update = function() {
this.x += 1;
this.draw();
}
this.update();
}
function animate() {
c.clearRect(0, 0, myCanvas.clientWidth, myCanvas.clientHeight);
redArc.update();
greenArc.update();
blueArc.update();
requestAnimationFrame(animate);
}
animate();
<canvas id="myCanvas"></canvas>
Related
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 have a html5 canvas that I'm drawing circles with. These circles need images in the center of them, but also need to update. With the help of this SO question
I have come up with this code to draw everything:
var Circle1 = new Circle((c.width / 8) + (c.width / 2), 200, eighthWidth / 2.5, Color1, "1");
var Circle2 = new Circle(c.width - eighthWidth, 200, eighthWidth / 2.5, Color2, "2");
function Circle(x, y, radius, color, name) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.name = name;
this.draw = function () {
var MiddleImage = new Image();
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.fill();
ctx.closePath();
ctx.drawImage(MiddleImage, this.x - MiddleImage.width / 2, this.y - MiddleImage.height / 2);
MiddleImage.src = "/Images/" + this.name + ".png";
}
this.update = function () {
this.x += 1;
this.draw();
}
this.update();
}
This isn't drawing the image like I hope it would, but if I take it out this method like below, it does work?
function drawCircle() {
var MiddleImage = new Image();
MiddleImage.onload = function () {
var X = c.width - eighthWidth;
var Y = 200;
ctx.beginPath();
ctx.arc(X, Y, eighthWidth / 2.5, 0, 2 * Math.PI);
ctx.clip;
ctx.fillStyle = Color1;
ctx.fill();
ctx.closePath();
ctx.drawImage(MiddleImage, X - MiddleImage.width / 2, Y - MiddleImage.height / 2);
};
BankImage.src = "/Images/1.png";
requestAnimationFrame(drawCircle);
}
I have also tried using the Image.onLoad method, as I have copied the working method into the new loop.
The console is showing no errors.
You can see a JSFiddle here
The problem you're having is that you're loading the image within the draw function at every frame and not waiting for it to be loaded.
I've tweaked your code slightly so it will load and attach the image to your circle as you wish.
var c = document.getElementById('canvas');
c.width = window.innerWidth;
c.height = 400;
var ctx = c.getContext("2d");
var eighthWidth = c.width / 8;
var Color1 = "#9c9c9b";
var Color2 = "#9c9c9b";
var Circle1 = new Circle((c.width / 8) + (c.width / 2), 200, eighthWidth / 2.5, Color1, "1");
var Circle2 = new Circle(c.width - eighthWidth, 200, eighthWidth / 2.5, Color2, "2");
function Circle(x, y, radius, color, name) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.name = name;
this.image = new Image();
this.image.src = "https://www.gstatic.com/webp/gallery3/1.png";
var _this = this;
this.image_loaded = false;
this.image.addEventListener('load', function() {
_this.image_loaded = true;
} );
this.draw = function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.fill();
ctx.closePath();
ctx.save();
ctx.clip();
ctx.drawImage(this.image, this.x - this.image.width / 2, this.y - this.image.height / 2);
ctx.restore();
}
this.update = function() {
//if(!this.image_loaded) return;
this.x += 1;
this.draw();
}
}
function animate() {
ctx.clearRect(0, 0, window.innerWidth, 400);
Circle1.update();
Circle2.update();
requestAnimationFrame(animate);
}
animate();
<canvas id="canvas" style="width:100%;"></canvas>
Is this what you want?
I'm trying to make my "YellowTrack" var move, bu I'm getting crazy and i can't achieve it. I don't know why, but the "y" coordinate doesn't update, so It doesn't move. I've tried a lot of cases but any of them could solve the movement problen Could anybody help me? PD: Sorry for my bad code writing
The code is below:
function startGame() {
myGameLines1 = new DrawingLines(200, 0, 200, 600, "black");
myGameLines2 = new DrawingLines(350, 0, 350, 600, "black");
myGameLines3 = new DrawingLines(500, 0, 500, 600, "black");
myGameLines4 = new DrawingLines(650, 0, 650, 600, "black");
myGameLines5 = new DrawingLines(800, 0, 800, 600, "black");
myGameFinalLine = new FinalLine(100, 500, 800, 20, "purple");
myGameFixedSquare1 = new DrawingFixedSquares(171, 475, 60, 60, "yellow");
myGameFixedSquare2 = new DrawingFixedSquares(321, 475, 60, 60, "red");
myGameFixedSquare3 = new DrawingFixedSquares(471, 475, 60, 60, "#F34621");
myGameFixedSquare4 = new DrawingFixedSquares(621, 475, 60, 60, "blue");
myGameFixedSquare5 = new DrawingFixedSquares(771, 475, 60, 60, "green");
myGameArea.start();
YellowTrack = new DrawingFixedSquares(171, 200, 60, 60, "yellow");
animate(YellowTrack, canvas, ctx, startTime);
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 1000;
this.canvas.height = 600;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0;
this.interval = setInterval(updateGameArea, 20);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
var ctx = myGameArea.context;
var canvas = myGameArea.canvas;
function DrawingLines(x1, y1, x2, y2, color) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.update = function(){
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.lineWidth="2";
ctx.strokeStyle="black";
ctx.moveTo(this.x1,this.y1);
ctx.lineTo(this.x2,this.y2);
ctx.stroke();
}
}
function DrawingFixedSquares(x, y, width, height, color) {
this.height = height;
this.width = width;
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);
}
}
function FinalLine(x, y, width, height, color) {
this.height = height;
this.width = width;
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);
}
}
function updateGameArea() {
myGameArea.clear();
myGameLines1.update();
myGameLines2.update();
myGameLines3.update();
myGameLines4.update();
myGameLines5.update();
myGameFinalLine.update();
myGameFixedSquare1.update();
myGameFixedSquare2.update();
myGameFixedSquare3.update();
myGameFixedSquare4.update();
myGameFixedSquare5.update();
YellowTrack.update();
}
function animate(YellowTrack, canvas, ctx, startTime) {
var time = (new Date()).getTime() - startTime;
var linearSpeed = 100;
var newY = linearSpeed * time / 1000;
if(newY < canvas.height) {
YellowTrack.y = newY;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
requestAnimFrame(function() {
animate(YellowTrack, canvas, ctx, startTime);
});
}
setTimeout(function() {
var startTime = (new Date()).getTime();
animate(YellowTrack, canvas, ctx, startTime);
}, 1000);
Animating things on a canvas is quite easy with window.requestAnimationFrame.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: black;
}
canvas {
position: absolute;
margin: auto;
left: 0;
right: 0;
border: solid 1px white;
border-radius: 10px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="application/javascript">
// Anonymous closure to sandbox my code
void function() {
// Tells the JS engine to use strict syntax rules
// e.g. creating variables without var, let or const
// creates an error in strict mode
"use strict";
var canvasWidth = 180;
var canvasHeight = 160;
var canvas = null;
var ctx = null;
var mouse = {x: 0.0, y: 0.0};
var box = {x: 0.0, y: 0.0, width: 20, height: 20};
var boxMoveSpeed = 25.0;
// Called whenever the mouse moves
// (canvas.onmousemove can be used too)
window.onmousemove = function(e) {
if (canvas) {
// Gets the canvas' offset from the top left of the screen
var boundingRect = canvas.getBoundingClientRect();
mouse.x = e.clientX - boundingRect.left;
mouse.y = e.clientY - boundingRect.top;
}
}
// Game loop
function loop() {
// Tick (Update game logic)
box.x += (mouse.x - box.x - box.width * 0.5) / boxMoveSpeed;
box.y += (mouse.y - box.y - box.height * 0.5) / boxMoveSpeed;
// Render
ctx.fillStyle = "#333333";
ctx.fillRect(0,0,canvasWidth,canvasHeight);
ctx.lineWidth = 3;
ctx.strokeStyle = "black";
ctx.fillStyle = "darkred";
ctx.beginPath();
ctx.rect(box.x,box.y,box.width,box.height);
ctx.fill();
ctx.stroke();
// Handy function that loops this
// function at 60Hz (60 fps) for me.
requestAnimationFrame(loop);
}
// Called when the page finishes loading
// I treat it like a 'main method' you see
// in other languages
window.onload = function() {
canvas = document.getElementById("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
ctx = canvas.getContext("2d");
loop();
}
}();
</script>
</body>
</html>
I am making a game. I want the player to not go outside the circular game region. the player should not cross the red circular line. It should remain inside and could move along the boundary.
I have written a simple function for collision detection between circles. I have found a bug in it too. I am getting a console.log() message of outside even if I am inside the game area.
It's happening when the player is at [x < 0]. Help me out please.
var Game = (function(window) {
var canvas = document.getElementById("game"),
ctx = canvas.getContext("2d");
var SCREEN_WIDTH = window.innerWidth,
SCREEN_HEIGHT = window.innerHeight;
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
var ROCK = "rock",
PAPER = "paper",
SCISSOR = "scissor";
var BG_IMAGE = document.getElementById("bg");
// this is the game area Radius
var GAME_R = 500;
var offsetX = 0,
offsetY = 0;
var player;
// circle collision detection
function checkCollision(x1, y1, r1, x2, y2, r2) {
var x = x1-x2;
var y = y1-y2;
var d = Math.hypot(x, y);
return d < r1 + r2;
}
function start() {
player = new Entity();
addEventListener("mousemove", function(e) {
var angle = Math.atan2(e.clientY - SCREEN_HEIGHT/2, e.clientX - SCREEN_WIDTH/2);
player.setAngle(angle);
}, true);
animLoop();
}
function update() {
offsetX = player.x - SCREEN_WIDTH/2;
offsetY = player.y - SCREEN_HEIGHT/2;
player.update();
}
function draw() {
ctx.save();
ctx.translate(-offsetX, -offsetY);
// bg
ctx.fillStyle = ctx.createPattern(BG_IMAGE, "repeat");
ctx.fillRect(offsetX, offsetY, SCREEN_WIDTH, SCREEN_HEIGHT);
// game area border
ctx.beginPath();
ctx.arc(0, 0, GAME_R, 0, Math.PI * 2);
ctx.closePath();
ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.stroke();
// player
player.draw();
ctx.restore();
}
function gameLoop() {
update();
// here
if(checkCollision(player.x, player.y, player.x, 0, 0, GAME_R)) {
console.log("inside");
} else {
console.log("outside");
}
draw();
}
function animLoop() {
window.requestAnimationFrame(animLoop);
gameLoop();
}
// player
function Entity() {
var self = {
x: 0,
y: 0,
r: 50,
entityType: PAPER,
angle: 0,
speed: 5
}
self.setSpeed = function(speed) {
this.speed = speed;
}
self.setAngle = function(angle) {
this.angle = angle;
}
self.update = function() {
this.x += this.speed * Math.cos(this.angle);
this.y += this.speed * Math.sin(this.angle);
}
self.draw = function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle = "grey";
ctx.fill();
ctx.fillStyle = "#fff";
ctx.font = "30px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(this.entityType, this.x, this.y);
}
return self;
}
start();
})(window);
<canvas id="game"></canvas>
<div style="display: none;">
<img id="bg" src="https://i.imgur.com/9qjEwiz.png">
</div>
This will check if the inner Circle inside the outer
function checkCollision(cxInner, cyInner, rInner, cxOuter, cyOuter, rOuter) {
return Math.sqrt(Math.pow(cxInner-cxOuter, 2) + Math.pow(cyInner-cyOuter, 2)) < rOuter - rInner;
}
complete code:
var Game = (function(window) {
var canvas = document.getElementById("game"),
ctx = canvas.getContext("2d");
var SCREEN_WIDTH = window.innerWidth,
SCREEN_HEIGHT = window.innerHeight;
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
var ROCK = "rock",
PAPER = "paper",
SCISSOR = "scissor";
var BG_IMAGE = document.getElementById("bg");
// this is the game area Radius
var GAME_R = 500;
var offsetX = 0,
offsetY = 0;
var player;
// circle collision detection
function checkCollision(cxInner, cyInner, rInner, cxOuter, cyOuter, rOuter) {
return Math.sqrt(Math.pow(cxInner-cxOuter, 2) + Math.pow(cyInner-cyOuter, 2)) < rOuter - rInner;
}
function start() {
player = new Entity();
addEventListener("mousemove", function(e) {
var angle = Math.atan2(e.clientY - SCREEN_HEIGHT/2, e.clientX - SCREEN_WIDTH/2);
player.setAngle(angle);
}, true);
animLoop();
}
function update() {
offsetX = player.x - SCREEN_WIDTH/2;
offsetY = player.y - SCREEN_HEIGHT/2;
player.update();
}
function draw() {
ctx.save();
ctx.translate(-offsetX, -offsetY);
// bg
ctx.fillStyle = ctx.createPattern(BG_IMAGE, "repeat");
ctx.fillRect(offsetX, offsetY, SCREEN_WIDTH, SCREEN_HEIGHT);
// game area border
ctx.beginPath();
ctx.arc(0, 0, GAME_R, 0, Math.PI * 2);
ctx.closePath();
ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.stroke();
// player
player.draw();
ctx.restore();
}
function gameLoop() {
update();
// here
if(!checkCollision(player.x, player.y, player.r, 0, 0, GAME_R)) {
player.back();
}
draw();
}
function animLoop() {
window.requestAnimationFrame(animLoop);
gameLoop();
}
// player
function Entity() {
var self = {
x: 0,
y: 0,
r: 50,
entityType: PAPER,
angle: 0,
speed: 5
};
self.setSpeed = function(speed) {
this.speed = speed;
};
self.setAngle = function(angle) {
this.angle = angle;
};
self.update = function() {
this.x += this.speed * Math.cos(this.angle);
this.y += this.speed * Math.sin(this.angle);
};
self.back = function() {
this.x -= this.speed * Math.cos(this.angle);
this.y -= this.speed * Math.sin(this.angle);
};
self.draw = function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle = "grey";
ctx.fill();
ctx.fillStyle = "#fff";
ctx.font = "30px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(this.entityType, this.x, this.y);
};
return self;
}
start();
})(window);
<canvas id="game"></canvas>
<div style="display: none;">
<img id="bg" src="https://i.imgur.com/9qjEwiz.png">
</div>
So I'm trying to make a pong game in JavaScript. I've tried lots of stuff, but whatever I do won't get the ball to move.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var Game = {};
var Player = function(x, y) {
this.x = x;
this.y = y;
}
Player.prototype.draw = function() {
ctx.beginPath();
ctx.rect(this.x, this.y, 20, 80);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
}
var Ball = function(x, y, diam) {
this.x = x;
this.y = y;
this.diam = diam;
this.xvel = 5;
this.yvel = 5;
}
Ball.prototype.draw = function() {
ctx.beginPath();
ctx.rect(canvas.width/2 - 10, canvas.height/2 - 10, 20, 20);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
};
Ball.prototype.moveBall = function() {
this.x = this.x + this.xvel;
this.y = this.y + this.yvel;
};
var p1 = new Player(20, canvas.height/2 - 40);
var p2 = new Player(canvas.width-20-20, canvas.height/2 - 40);
var ball = new Ball(canvas.width/2 - 10, canvas.height/2 - 10, 20);
Game.draw = function() { p1.draw(); p2.draw(); ball.draw(); };
Game.update = function() { ball.moveBall(); };
Game.run = function() { Game.update(); Game.draw(); };
Game.fps = 50;
Game._intervalId = setInterval(Game.run, 1000 / Game.fps);
I can't get the ball to move. Any Ideas? Also, what the neater way of classes? Is there a different way to do it than with functions?
Maybe like
class Apple {
function draw() {
//draw here
}
}
You are always drawing the ball in the same place, dead-center:
ctx.rect(canvas.width/2 - 10, canvas.height/2 - 10, 20, 20);
You're updating this.x and this.y elsewhere, but not using them. Try:
ctx.rect(this.x, this.y, 20, 20);
Now you have the problem of knowing when to stop moving, but that's a separate question.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var Game = {};
var Player = function(x, y) {
this.x = x;
this.y = y;
}
Player.prototype.draw = function() {
ctx.beginPath();
ctx.rect(this.x, this.y, 20, 80);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
}
var Ball = function(x, y, diam) {
this.x = x;
this.y = y;
this.diam = diam;
this.xvel = 5;
this.yvel = 5;
}
Ball.prototype.draw = function() {
ctx.beginPath();
ctx.rect(this.x, this.y, 20, 20);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
};
Ball.prototype.moveBall = function() {
this.x = this.x + this.xvel;
this.y = this.y + this.yvel;
};
var p1 = new Player(20, canvas.height/2 - 40);
var p2 = new Player(canvas.width-20-20, canvas.height/2 - 40);
var ball = new Ball(canvas.width/2 - 10, canvas.height/2 - 10, 20);
Game.draw = function() { p1.draw(); p2.draw(); ball.draw(); };
Game.update = function() { ball.moveBall(); };
Game.run = function() { Game.update(); Game.draw(); };
Game.fps = 50;
Game._intervalId = setInterval(Game.run, 1000 / Game.fps);
<canvas id="myCanvas" height="300px" width="300px" />
I got your ball moving. you had just forgot to set the position to this.x and this.y in the draw function.
you'll notice it leaves a streak. So you'll need to either (1) clear everything and redraw everything on each frame, or (2), keep an oldx and oldy and draw white over oldx oldy before drawing black at x and y. Happy coding.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var Game = {};
var Player = function(x, y) {
this.x = x;
this.y = y;
}
Player.prototype.draw = function() {
ctx.beginPath();
ctx.rect(this.x, this.y, 20, 80);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
}
var Ball = function(x, y, diam) {
this.x = x;
this.y = y;
this.diam = diam;
this.xvel = 5;
this.yvel = 5;
}
Ball.prototype.draw = function() {
ctx.beginPath();
ctx.rect(this.x, this.y, 20, 20);
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
};
Ball.prototype.moveBall = function() {
this.x = this.x + this.xvel;
this.y = this.y + this.yvel;
};
var p1 = new Player(20, canvas.height/2 - 40);
var p2 = new Player(canvas.width-20-20, canvas.height/2 - 40);
var ball = new Ball(canvas.width/2 - 10, canvas.height/2 - 10, 20);
Game.draw = function() { p1.draw(); p2.draw(); ball.draw(); };
Game.update = function() { ball.moveBall(); };
Game.run = function() {console.log("hi"); Game.update(); Game.draw(); };
Game.fps = 5;
Game._intervalId = setInterval(Game.run, 1000 / Game.fps);
#myCanvas{width:200px;height:200px}
<canvas id="myCanvas"></canvas>
Here's a good html canvas game instructions that follows the style you're doing pretty well:
http://www.html5rocks.com/en/tutorials/canvas/notearsgame/