First of all, here are better links (thanks, Robert Helmer) for the Canvas arc method:
- Reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D#arc%28 (note that this hangs off of CanvasRenderingContext2D, not Canvas).
- Guide: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Drawing_shapes#Arcs (note this is part of a larger topic on drawing shapes with Canvas).
- From now on, I'll try to reference Mozilla Developer Network. I'm guilty of quick look ups on W3 Schools, but MDN really is the authority on Firefox!
- You have other stuff on the screen you don't erase?
- What if you have to do a lot of calculations to redraw something that doesn't need to be done?
- Draw something.
- Calculate the move.
- Erase the thing you want to move.
- Draw the thing in its new position.
So here's the code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>
Canvas Bounce Draw Circle and Erase
</title>
<script>
// Global variables
var canvas;
var ctx;
var boardWidth = 320;
var boardHeight = 460;
var ballHor = boardWidth / 2;
var ballVer = boardHeight /2;
var oldHor;
var oldVer;
var changeHor = 10;
var changeVer = 10;
// Listen to that page load!
window.addEventListener("load", getLoaded, false);
// Run this when the page loads.
function getLoaded(){
// Make sure we are loaded.
console.log("Page loaded!");
// Load the image and the canvas.
loadMyImage();
// Start the game loop.
gameLoop = setInterval(doMainLoop,16);
}
// This will run every 16 milliseconds.
function doMainLoop(){
// Move the ball.
ballMove();
}
function ballMove() {
// Changes are calculated but do not
// take effect until next time through loop.
// Get the old ball coordinates.
oldHor = ballHor;
oldVer = ballVer;
// Erase the ball where it is now.
// Color is White.
ctx.lineWidth = 0;
ctx.beginPath();
ctx.arc(oldHor, oldVer, 10, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = "White";
ctx.fill();
// Calculate new vertical component.
ballVer = ballVer + changeVer;
// If top is hit, change direction.
if (ballVer + changeVer < -10)
changeVer = -changeVer;
// If bottom is hit, reverse direction.
if (ballVer + changeVer > boardHeight - 10)
changeVer = -changeVer;
// Calculate new horizontal component.
ballHor = ballHor + changeHor;
// If left edge hit, reverse direction.
if (ballHor + changeHor < -10)
changeHor = -changeHor;
// If right edge is hit, do something.
if (ballHor + changeHor > boardWidth - 10)
changeHor = -changeHor;
// Draw a ball using canvas arc function.
// Color is Fuchsia.
// Make the radius one pixel smaller.
ctx.beginPath();
ctx.arc(ballHor, ballVer, 10, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = "Fuchsia";
ctx.fill();
}
// Load the image and the canvas.
function loadMyImage() {
// Get the canvas element.
canvas = document.getElementById("myCanvas");
// Make sure you got it.
if (canvas.getContext) {
// Specify 2d canvas type.
ctx = canvas.getContext("2d");
}
}
</script>
</head>
<body bgcolor="White">
<canvas id="myCanvas" width="320" height="460">
</canvas>
</body>
</html>
This is nearly the same code as last time, with these few small changes:
- I added temporary variables to track the previous positions of the ball.
- In the ballMove section, I added erasing the ball.
- The main loop (doMainLoop) no longer clears the screen every time.
This code erases the ball:
// Get the old ball coordinates.
oldHor = ballHor;
oldVer = ballVer;
// Erase the ball where it is now.
// Color is White.
ctx.lineWidth = 0;
ctx.beginPath();
ctx.arc(oldHor, oldVer, 10, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = "White";
ctx.fill();
It is nearly the same as drawing the ball, but the fillStyle is White. The old ball position is created and used to erase where the ball was drawn.
But Wait! Something is wrong!
When I ran this code, it looked like this in the Simulator:
I'm hoping that the picture is clear enough to show that the bouncing ball is leaving a trail of ghost shapes behind it. Well, it was Halloween, but I'm not sure that would account for the behavior today.
The ball bounces all right, but its not cleaning up after itself. I did some research and it turns out that when you draw on Canvas, the pixels get scattered a little too far and you get artifacts that can cause problems. This is called aliasing, and is often a problem with drawing shapes onto a screen. And this is why many people recommend clearing the canvas every time you move an object.
There are two solutions I have found:
- You can erase part of a screen by using
context.clearRect ( x , y , w , h );
You can do this to clear a specific rectangle at x,y with a width and height. - You can overlap the drawing a little to get rid of the spilled pixels.
ctx.arc(ballHor, ballVer, 10, 0, Math.PI * 2, true);
so it reads:
ctx.arc(ballHor, ballVer, 9, 0, Math.PI * 2, true);
The ball is slightly smaller, but all of it gets erased. I'm not happy with this, but I looked and saw that this isn't a bug, it is a feature of not only Firefox, but Chrome and IE. Throwing pixels around is a bit imprecise, and that's one of the reasons I'm not 100% happy with Canvas. But it works with lots of stuff. I'm still more happy CSS. See my Bouncing a Ball in CSS topic. I'll come back to CSS later, but there's still a few more things to look at with Canvas.
Programming Tip
When you install an app to the ZTE Open, there is a delay of a few seconds before you get a message telling you the app is installed. And you'll have to reboot the ZTE Open before you can see your app's icon.
Also, screenshots are still tricky. You have to hit two buttons at nearly the same time. But I'm learning how to do this. I was sending the screenshots to myself from the gallery with my email, but I figured out I could use the cable to download the screenshots from a folder named screenshots. There's a short delay before the screenshot appears in the gallery. However, if you want to take a screenshot, you must unplug the cable first. A little annoying, but liveable. This is a version 1 of an new product that never lived before, so the baby steps can be amusing and appealing.
No comments:
Post a Comment