So, I've been trying to make a scrolling shooter example with my game engine and I've come across something odd. A certain image I try to draw doesn't show up. It shows up in Chrome's resources, so it's not a path issue. Also all other images I try to display show up as well. If anyone can help me, it would be appreciated. =)
Link for reference:
http://pandamochi.x10.bz/scrollingshooter.html
Code for Drawing:
ctx.save();
if (this.sprite != ""){
ctx.translate(Math.round(this.x-ds_view.x), Math.round(this.y-ds_view.y));
ctx.scale(this.scaleX,this.scaleY);
ctx.rotate(this.rotateZ);
ctx.translate(-this.width/2,-this.height/2);
ctx.drawImage(this.sprite, this.width*this.sprite_index, 0, this.width, this.height, 0, 0, this.width, this.height);
}
ctx.restore();
Code I used to Set:
enemy.setSprite("images/ship.png",1,4,10);
Edit
So yeah I was way off.
ctx.drawImage(this.sprite, this.width*this.sprite_index, 0, this.width, this.height);
The translations are causing your issue. I changed the line above and can actually see the ship drawing. This isn't the most complete answer, but hopefully it gets you on the right track.
Live Demo
Related
I am trying to create a 'hangman' display for my hangman game with the HTML canvas element. I got the hangman to display one step at a time but I can't seem to clear the canvas (was expecting it to be the easier step...). When I add the clearRect call it causes my whole page to fault out. Can't start the game etc - even when I call it only at the end of a game...
Any advice would be appreciated - new to the web world so assuming I'm doing something silly :)
See the following code pen for the source files and a display of the issue:
https://codepen.io/enewmanMN/pen/LYPWpQq
Tried moving the clearRect call around to avoid calling it right away to see if I could even get the game started with it in the code path but not having any luck.
https://codepen.io/enewmanMN/pen/LYPWpQq
function clearCanvas () {
myStickman = document.getElementById("stickman");
context = myStickman.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height); //CAUSING FAULTS
context.beginPath();
context.strokeStyle = "#fff";
context.lineWidth = 2;
}
Was expecting it to clear the canvas element 'stickman' but instead loose functionality to the page.
When I ran your code with the clearRect uncommented, I got an error saying canvas is not defined. You gave the canvas the name myStickman. This fixed it
context.clearRect(0, 0, myStickman.width, myStickman.height);
I am very new to js as a whole, and have decided that a good way to get to know and javascript as a whole would be to follow a tutorial for building a simple block-breaking game.
The game itself runs just fine, however, I would like to find a way to replace the js-drawn circle with an image of a ball, and the blocks with any other rectangular images.
I know (I think) that I need to implement var img = new Image()
in some way, but I'm not entirely sure how to go about doing this without managing to make my circle disappear altogether.
I believe the offending area of my code may be this part:
function drawBall(){
ctx.beginPath();
ctx.arc(x, y, ballSize, 0, Math.PI*2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
However, given that I am new, I may have completely missed it , and so I also provide a codepen of the project thus far. Codepen
The code that draws the circle is the following:
ctx.arc(x, y, ballSize, 0, Math.PI*2);
ctx.fillStyle = "#0095DD";
ctx.fill();
So instead of drawing a circle (which is done with the .arc), you can draw an image instead using the .drawImage method. See docs. It would look something like this:
ctx.drawImage(image, x, y);
The image argument is an "image source", which could be just a plain <img> element in your HTML. See examples of how to its done in the docs that I linked.
I'm currently using a snippet I got from this JS fiddle I found on google. It works really well with my project and I already have it live on my site.
However. I have a slower connection -- Although I'm not sure if that's why this occurs, but i see "Neon blue circles" floating around the screen displaying the "particle's" before it loads in the .PNG that is animated as a smoke effect.
My question: Is there anyway I can hide these circles? Or possible delay the effect until the .PNG is loaded?
I may be making this more complicated that it sounds. I'm not too great with JS but i can dabble a bit. Any help is much appreciated!
DEMO
#myCanvas{
background:black;
}
You can remove/comment out these lines:
this.context.beginPath();
this.context.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false);
this.context.fillStyle = "rgba(0, 255, 255, 1)";
this.context.fill();
this.context.closePath();
This essentially draws a single circle.
Updated Demo: http://jsfiddle.net/Limitlessisa/Ujz4P/6158/
Step Add style="opacity:0"
<canvas id="myCanvas" style="opacity:0" width="400" height="400"></canvas>
Step Add js line $('#myCanvas').animate({opacity:1});
imageObj.onload = function() {
particles.forEach(function(particle) {
particle.setImage(imageObj);
});
$('#myCanvas').animate({opacity:1});
};
Alternative smoke effect:
JS FIDDLE Example
I'm currently writing a small image editor to learn some javascript. One of the features is obviously a drawing tool. When that is used i'm drawing those pixels to another canvas on top of the actual canvas and then when the mouse is released i copy over the pixels from the top canvas to the underlying one.
This is the code that is used for the copying of the drawn pixels to the underlying canvas.
this.applySketch = function() {
this.revertStack.push(this.ctx.getImageData(0, 0, this.width, this.height));
var real = this.ctx.getImageData(0, 0, this.width, this.height);
var sketch = this.sketchctx.getImageData(0, 0, this.width, this.height);
for(var i = 0; i < sketch.data.length; i += 4) {
// check the alpha value to decide if to copy to the real canvas
if(sketch.data[i+3] > 0) {
real.data[i] = sketch.data[i];
real.data[i+1] = sketch.data[i+1];
real.data[i+2] = sketch.data[i+2];
real.data[i+3] = sketch.data[i+3];
}
}
this.ctx.putImageData(real, 0, 0);
this.sketchctx.clearRect(0, 0, this.width, this.height);
}
The problem i'm experiencing is that the pixels don't look the same when they have been copied to the other layer. Instead there is a thin contour of white pixels around whatever it is i'm copying.
Before mouse release (when the pixels are in the top layer)
http://i.imgur.com/xHvN1iF.jpg
After mouse release (when they have been copied)
http://i.imgur.com/P0sdybs.jpg
I don't really have any clue on what is going on here because it seems pretty straightforward. Could it be anything with antialiasing?
Thanks
I suppose this happens because of antialiasing. When you draw smooth line, some pixels near the line are almost transparent but not fully transparent. This fiddle illustrates the problem. So, you need to merge alpha channel more carefully. The simpliest solution is to add alpha channel value to original value instead of replacing it completely:
real.data[i+3] += sketch.data[i+3];
This fiddle shows the effect. Well, line looks thickly than original line. I suppose you should use some other formula for merging colors.
I use <canvas> to draw all notes and glyphs in my music education web apps:
http://www.musictheory.net/exercises/keysig/bc98yy
A Firefox 15.0.1 user has reported that sometimes the exercise goes on to the next question, but the canvas still shows the previous question. I have seen this occur in testing one time (out of ~500 questions).
When it occurs, the canvas has been cleared via both canvas.width = canvas.width and a call to .clearRect on the context and glyphs have been drawn in JavaScript via .beginPath, .quadraticCurveTo, .closePath, etc. However, it seems like the canvas's backing buffer never gets flushed/drawn into the window.
I have seen bug reports in the past regarding similar issues:
https://bugzilla.mozilla.org/show_bug.cgi?id=787623
https://bugzilla.mozilla.org/show_bug.cgi?id=794337
http://code.google.com/p/chromium/issues/detail?id=55339
I can force a redraw by doing a DOM hack such as inserting a text node as a child of the canvas, and then removing it on the next run loop cycle, or modifying the background-color or padding of the canvas. This seems heavy-handed, however, and I keep having the nagging feeling that I'm missing something obvious.
My drawing code is simple enough:
canvas.width = width;
ctx.clearRect(0, 0, width, height);
ctx.save();
// Lots of drawing code here
ctx.restore()
ctx.clearRect(0, 0, 1, 1); // Helped force a repaint on some older WebKit browsers?
I have ensured that the number of .save and .restore calls are balanced.
1) I am calling this code directly in response to an onclick event handler. Should I instead be using requestAnimationFrame or setTimeout to perform the drawing on a future run loop cycle?
2) I'm not missing something obvious, like a canvas.pleaseRepaintNow() API, right?
3) Have other people encountered similar issues and resorted to DOM modification to force redraws?
Add context.stroke(); to the last line of your onLoad function, it fixes a bug in Firefox. Otherwise changes to the canvas don't render until the window is redrawn.
It worked in my case at least.
window.onload = function() {
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
//Code here...
context.stroke();
}
I tried to get the bug to happen but after madly clicking in Firefox for awhile, I never saw it. This is how I clear the canvas which seems to work, but take it with a grain of salt since I can't get the bug to occur I also can't check to see if this fixes anything...
// Store the current transformation matrix
ctx.save();
// Use the identity matrix while clearing the canvas
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Restore the transform
ctx.restore();