I am trying to make a HTML5 Canvas/JavaScript game. I watched some tutorials, and I understand what everying is meant for, but I don't get the right controls for touch devices.
I want to get my 'airship', where my finger touches the screen. It is not only working with where my mouse is positioned.
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
<script type="text/javascript">
window.onload = function() {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var canvasWidth = canvas.offsetWidth;
var canvasHeight = canvas.offsetHeight;
var bg1 = new Image();
var bg2 = new Image();
bg1.src = "img/spritesheet.png";
bg2.src = "img/spritesheet.png";
var increment = -5;
var sYbg1 = 0;
var sYbg2 = 960;
var ship = new Image();
ship.src = "img/spritesheet.png";
var mouseX;
var mouseY;
canvas.onmousemove = function() {
mouseX = window.event.clientX - canvas.offsetLeft; // mousePositionX
inside the <canvas> element
mouseY = window.event.clientY - canvas.offsetTop; // mousePositionY
inside the <canvas> element
};
var animate = function() {
context.clearRect(0,0,canvasWidth,canvasHeight);
context.drawImage(bg1,0,sYbg1,canvasWidth,canvasHeight,0,0,canvasWidth,canvasHeight);
context.drawImage(bg2,0,sYbg2,canvasWidth,canvasHeight,0,0,canvasWidth,canvasHeight);
sYbg1 += increment;
sYbg2 += increment;
if(sYbg2 <= 0) {
sYbg1 = 0;
sYbg2 = 960;
}
context.drawImage(ship,320,0,65,105,(mouseX-32),(mouseY-52),65,105);
setTimeout(animate,25);
};
animate();
}
</script>
</head>
<body>
<canvas id="canvas" width="320" height="480"></canvas>
</body>
</html>
(!MY CODE IS ONLY WORKING IN CHROME!) --> But thats not important not, I know about the window.event and that it's not working in FF.
I hope someone can explain to me what I need to do. I tried to fix my problem to use onmousemove and onmousedown together, but that wasn't working for me too. Thanks a lot for the help!
I will provide a hint, in case you haven't gotten there yet, and for future researchers. You have a mouse event handler (mousemove). I don't see a touch event handler. There are some options depending on your browser, which is unclear to me which you want to use...
However you can start looking at https://developers.google.com/ or MDN https://developer.mozilla.org/en-US/ as good starting points.
Related
I attempted to animate a sprite sheet using html and javascript to no avail. Here is my sprite sheet
Below is lines 36-59 of my code. I'm not getting any errors so I don't really know what's wrong. How do I fix/improve my code?
This is for a project I'm doing. I've tried using different methods I've found online but none really worked either. I've tried shifting the image as well.
<html>
<head>
<title>Tree Animation</title>
</head>
<body>
<canvas id='canvas'></canvas>
<script>
var canWidth = 400;
var canHeight = 100;
//position where the frame will be drawn
var x = 0;
var y = 0;
var srcX;
var srcY;
var sheetWidth = 230;
var sheetHeight = 79;
var frameCount = 5;
var width = sheetWidth/frameCount;
var height;
var currentFrame = 0;
var tree = new Image();
tree.src = "tree sprite.jpg"
var canvas = document.getElementById('canvas');
canvas.width = canWidth;
canvas.height = canHeight;
var ctx = canvas.getContext('2d');
function updateFrame(){
currentFrame = ++currentFrame%frameCount
srcX = currentFrame*width;
srcY = 0;
ctx.clearRect(x, y, width, height);
}
function draw(){
updateFrame();
}
setInterval(function(){
draw();
}, 100);
</script>
</body>
</html>
I expect the output to be an animation of a tree growing, but instead I'm getting a blank page.
you should provide more code or a snippet, there are several variables didn't show up in your code
and it's hard to debug your code if u use setInterval, you should make sure your code can work first.
maybe you can try step by step:
draw the whole img on the canvas first. if it works, go next
invoke your draw() function manually, check if the img drawed
invoke more, such assetTimout(draw, 1000), check the result
ok, and i think you can console.log these variables in draw
I am trying to use the method 'requestAnimationFrame' with the help I can find on Internet. I can move an element, but when I want to do it with sprites, I am lost.
For example, the code below is working normally with 'setInterval', but I cannot manage to make it work with 'requestAnimationFrame'.
<!DOCTYPE html>
<html>
<head>
<title>Animating Sprites in HTML5 Canvas</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, user-scalable=no">
<style>
.demo {background: #aaaaaa;}
#myCanvas{background: #cccccc}
</style>
</head>
<body class="demo">
<canvas id="myCanvas" width="800" height="100"></canvas>
<script>
(function() {
// Canvas
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
// Set the fill style for the drawing context.
ctx.fillStyle = '#3399ff';
// VARIABLES
var width = 48; // Width CANVAS
var height = 60; // Height CANVAS
var xFrame = 0; // Frame x coordinate
var yFrame = 0; // Frame y coordinate
var dxFrame = 0; // Frame dx position in canvas
var dyFrame = 0; // Frame dy position in canvas
// SPRITE used
image = new Image()
image.src = 'myRunner2.png';
//
var requestID;
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element){
window.setTimeout(callback, 1000 / 60);
};
})();
// FUNCTION DRAWING MOVE (xFrame = 0 & yFrame = 1)
var drawMove = function(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(image, width * xFrame, height * yFrame, width, height, dxFrame, dyFrame, width, height);
if (xFrame == 7) {
xFrame = 0;
} else {
xFrame++
dxFrame+=2;
}
//window.requestAnimFrame(eMove);
}
// ANIMATION in 3 moves: Idle + Move + Tired
var intA;
function eMove() {
// Runner in motion (8 frames)
yFrame = 1;
xFrame = 0;
clearInterval(intA);
intA = setInterval(drawMove, 100);
}
eMove();
}());
</script>
</body>
</html>
I am looking for help about this issue, a portion of code will be great but a way to work or a direction to look for will be good as well. How to manipulate sprite with the method 'requestAnimationFrame'?
Ultimately, my goal is to move a sprite in one direction and the background in the other direction. I can move the sprite in one direction with setTimeout/setInterval methods alone or I can move in the other direction the background with 'requestAnimationFrame', but also separately.
I hope you understand my problem.
Thank you,
JLuc01
For requestAnimationFrame to work well it needs an accurate timer by which it can update the progress. The animation would then also depend on this variable. Of course a total duration will have to be set as well (to measure the progress). Here's a general piece of code :
var initial = update = new Date().getTime(), progress = 0, duration = 2000;
requestAnimationFrame(frameSequence);
function frameSequence() {
update = new Date().getTime();
var elapsed = update-initial;
progress = Math.max(elapsed/duration, 1);
someFunction(); // do calculations and implement them based on progress
if (progress < 1) requestAnimationFrame(frameSequence);
}
And a live example (relevant code at the bottom)
http://codepen.io/Shikkediel/pen/vEzqoX?editors=001
Edit - some comments promoted to update :
The requestAnimationFrame call is just a basic loop really to replace the timeout. It could be as simple as using requestAnimationFrame(drawMove) instead of clearInterval(intA); intA = setInterval(drawMove, 100). It'll probably do the whole thing in 8/60 of a second that way though (I see there are 8 frames and 60 is the common display refresh rate) - hence a timer would be needed.
This would optimise and work for sure : setInterval(requestAnimationFrame(drawMove), 100). It will not force a frame on the display then like a timeout does (giving performance issues and flickering) but make it wait for the first appropriate instance when there is a new paint of the screen. But not using timeouts at all is a much better approach.
Just giving canvas a go for the first time with the intention of creating a game. I have an image displaying but oddly the fillStyle method doesn't seem to be working. ( At least the canvas background is still white in google chrome.)
Note that in my code the canvas var is actually the canvas elements 2d context, maybe that's where i'm getting myself confused? i can't see the problem, would appreciate if anyone else could.
LD24.js:
const FPS = 30;
var canvasWidth = 0;
var canvasHeight = 0;
var xPos = 0;
var yPos = 0;
var smiley = new Image();
smiley.src = "http://javascript-tutorials.googlecode.com/files/jsplatformer1-smiley.jpg";
var canvas = null;
window.onload = init; //set init function to be called onload
function init(){
canvasWidth = document.getElementById('canvas').width;
canvasHeight = document.getElementById('canvas').height;
canvas = document.getElementById('canvas').getContext('2d');
setInterval(function(){
update();
draw();
}, 1000/FPS);
}
function update(){
}
function draw()
{
canvas.clearRect(0,0,canvasWidth,canvasHeight);
canvas.fillStyle = "#FFAA33"; //orange fill
canvas.drawImage(smiley, xPos, yPos);
}
LD24.html:
<html>
<head>
<script language="javascript" type="text/javascript" src="LD24.js"></script>
</head>
<body>
<canvas id="canvas" width="800" height="600">
<p> Your browser does not support the canvas element needed to play this game :(</p>
</canvas>
</body>
</html>
3 notes:
fillStyle does not cause your canvas to be filled. It means that when you fill a shape it will be filled with that color. Therefore you need to write canvas.fillRect( xPos, yPos, width, height).
Wait until your image actually loads, otherwise the rendering may be inconsistent or buggy.
Careful of cross-domain images used in your canvas - most browsers will throw a security exception and stop executing your code.
Wait till image loads as well:
var img = new Image();
img.onload = function() {
handleLoadedTexture(img);
};
img.src = "image.png";
function handleLoadedTexture(img) {
//call loop etc that uses image
};
Or maybe you were just missing
canvas.fill();
after
canvas.drawImage(smiley, xPos, yPos);
I want to implement dragging of an image within a canvas. I want simplest code for that. So far I have seen a lot of examples but they have used complex ways of implementation. I want an example that is easy to learn and implement.
It's pretty difficult. You'll first need to write a function that can detect when you click a particular element. However, before we can do that, we must define what we mean by "element". Is it the product of a single draw instruction (e.g. a rectangle or arc), or something complex? (Imagine I wanted to draw a cat and make the entire cat draggable as a unit.)
A canvas is nothing but a collection of pixels. If you want your program to have an idea of "shapes" or even "collections of shapes treated as a unit" you'll need to implement them yourself as data structures external to the canvas itself. Once you have that, you can write an onmousedown handler that takes the x/y point clicked and determine what shape (if any) the click falls inside of (and if it falls inside of multiple shapes, check which has the foremost z-index). Then add an onmousemove handler that erases and redraws the shape on the canvas based on the information in the shape data object.
This is a moderately difficult problem with very difficult prerequisite problems (creating data structures that can describe a wide range of shapes as well as collections of shapes). I highly recommend you use a canvas drawing library that has already solved these problems. I use cake.js but there are loads of options available.
If you don't have to use the HTML5 canvas, jQuery UI is a lot simpler:
HTML:
<img class="drag-me" src="http://www.google.com/images/srpr/logo3w.png">
JavaScript:
$(function() {
$('.drag-me').draggable();
});
See it in action:
http://jsfiddle.net/flackend/TQzSe/
The jQuery UI API has a lot of options too to make it act how you want:
http://jqueryui.com/demos/draggable/
Plus, if it doesn't do what you need, it's easy to implement yourself. Post here if you need help with that.
jsfiddle.net/Zevan/QZejF/5 This may help you.
<html>
<head>
<title>Test Page</title>
<script type="text/javascript" src="jquery.js"></script>
</head>
<body>
<canvas id="c" width = "500" height = "500" ></canvas>
<script type="text/javascript">
var canvas = $("#c");
var c = canvas[0].getContext("2d");
//var path = "http://wonderfl.net/images/icon/e/ec/ec3c/ec3c37ba9594a7b47f1126b2561efd35df2251bfm";
var path = "blue.jpg";
var path2 = "purple.jpg";
var image1 = new DragImage(path, 200, 100);
var image2 = new DragImage(path2, 300, 100);
var loop = setInterval(function() {
c.fillStyle = "gray";
c.fillRect(0, 0, 500, 500);
image1.update();
image2.update();
}, 30);
var mouseX = 0,
mouseY = 0;
var mousePressed = false;
var dragging = false;
canvas.mousemove(function(e) {
mouseX = e.offsetX;
mouseY = e.offsetY;
})
$(document).mousedown(function() {
mousePressed = true;
}).mouseup(function() {
mousePressed = false;
dragging = false;
});
function DragImage(src, x, y) {
var that = this;
var startX = 0,
startY = 0;
var drag = false;
this.x = x;
this.y = y;
var img = new Image();
img.src = src;
this.update = function() {
if (mousePressed ) {
var left = that.x;
var right = that.x + img.width;
var top = that.y;
var bottom = that.y + img.height;
if (!drag) {
startX = mouseX - that.x;
startY = mouseY - that.y;
}
if (mouseX < right && mouseX > left && mouseY < bottom && mouseY > top) {
if (!dragging){
dragging = true;
drag = true;
}
}
} else {
drag = false;
}
if (drag) {
that.x = mouseX - startX;
that.y = mouseY - startY;
}
c.drawImage(img, that.x, that.y);
}
}
</script>
</body>
</html>
I really only care about Webkit, but in general, is Raphael JS expected to perform well when building thousands of rectangles?
Additionally, I would need to be able to handle events on each of these rectangles (yipes).
I've got a C++ solution which works but I'd rather use RaphaelJS.
Thanks :)
I don't know nothing about RaphaelJS but I can give you a performance hint with this code:
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<title></title>
<script>
window.onload = function () {
var rectangles = 5000;
for (var i = 0; i < rectangles; i ++) {
var height = 50;
var width = 50;
var canvas = document.createElement ("canvas");
canvas.height = height;
canvas.style.margin = "15px";
canvas.width = width;
canvas.addEventListener ("click", function () {
alert ("You like to MOVE !");
}, false);
var ctx = canvas.getContext ("2d");
ctx.fillStyle = "silver";
ctx.fillRect (0, 0, width, height)
document.body.appendChild (canvas);
}
canvas = document.body.getElementsByTagName ("canvas");
window.setInterval (function () {
for (var i = 0; i < canvas.length; i ++) {
canvas[i].style.margin = (Math.floor (Math.random () * 16)) + "px";
}
}, 100);
}
</script>
</head>
<body></body>
</html>
5000 rectangles moving around with "onclick" event:
If you would like to test out performance of Raphael JS I've posted a quick example of plotting 10,000 points. Tests render and clear times.
http://jsfiddle.net/jaRhY/1049/