If I wanted to build a simple game (snake, checkers, pacman or whatever) what would be the better approach - SVG or Canvas ?
Things I'm interested in:
Ease of implementation (learning curve of Canvas vs SVG) . For example if SVG has significantly less tutorials and community support that's crucial to me.
Performance (not critical to me but still important)
And also , in the gaming field , are there specific games that SVG is more suited for than Canvas (or vice versa?)
Games that require a lot of mouse interaction and not much continuous animation (such as checkers or chess, or any board game for that matter) are better suited for SVG because you work with dom elements. Consider a simple button hover, in SVG you can add event listeners or even just place g.button:hover path {fill: blue;} in your CSS and it will work. Canvas, on the other hand, requires keeping track of the hit area and drawing everything in Javascript.
Snake and Pacman would be better suited for canvas, you control everything with your keyboard and painting to canvas is less expensive than moving elements around in SVG. There are excellent gaming libraries for canvas, impact.js is one of them.
Addressing your points:
Ease of use: if you are familiar with pure javascript DOM manipulation SVG is a breeze. If you are blank slate I'd say canvas is easier to grasp, as you just paint on it.
Community support: for gaming canvas wins hands down. There is a strong SVG community but not in the gaming area.
Performance: Mixed. Both canvas and SVG can be slow if you don't pull off a couple of tricks. For example, moving a single square from left to right can be jerky in canvas if you repaint the entire screen on each frame. If you just repaint the area that changed then it's smooth. SVG would handle this case without a hitch. But on the other hand, if you want to animate thousands of rectangles at once, canvas handles it smoothly and SVG bogs down if you don't wrap the rects in a group and move the group around.
All in all, if you want to explore gaming in javascript perhaps Canvas is a better option. I've done three games in SVG, the latest one being http://color.method.ac, but I've dabbled in canvas and I think it's better suited for gaming.
Related
I'm working on a project for school in HTML5 en CSS3.
The goal of the project is to teach young children how to calculate simple equations.
The first step towards learning this is teaching them to recognize numbers in different shapes.
A first exercise would be:
showing a random number and letting the child select a 3D cube and dragging it inside of a grid.
The number of cubes in the grid should correspond ofcourse with the given number.
Example given below:
I have no idea where to start. I know about a canvas in HTML5 but I'm not really familiar with it.
How can I snap the cubes into position when they come close?
How do I even draw a 3D cube in HTML5?
How can I check how many cubes were drawn on screen?
Can I draw something more pleasing for the children to look at than cubes, but still have a 3D effect?
Above all will it be capable of running on a iPad?
A dedicated App is out of the question as it should also be able to run on a desktop.
Hoping some of you might have a good solution.
Thanks
Only way to make genuin 3D cube that will work on ios browser is css3
You can put this cube(graphic representation) in to the present element that will represent its logically and use standard browser ways to manage drag and drop Usefully library and since this is DOM based implementation it can be styled with css. You can add color transition, animation delays or even deformation with the css3 transition it will have much better performance than js animations. Also it's easier to implement.
Here(video, images) is really cool animation guidance from Walt Disney Studios to help you make it visually appealing.
I am planning on creating a real-time multiplayer platformer game in HTML5 using javascript. After searching about 4 hours on the webs, i couldn't find an up-to-date answer on the eternal question: rendering my game with DOM will be faster than rendering it inside a canvas? The game will be the whole document. 2/4 players will be jumping on the map and will shoot at each other, bombs will explode. So? What will it be. I remember I made 2 years ago a draw application with DOM and it worked kinda smoothly, but i guess canvas speed is better nowadays? Thank you guys.
P.S. I think of using Dart too.
I use canvas, and would say to do the same since it's a direct drawing mode. However, you should absolutely make sure it is forced into hardware acceleration wherever possible. You do this by setting the style of the <canvas> element into transform:translateZ(0); (or different browser interpretations of that, e.g. -webkit-transform:translateZ(0);). Manipulating the DOM can be slow now that canvas is closer and closer to native code, especially with simple methods to get the most performance out of it.
My games seem to do pretty well on different platforms with this - not universally well on every single platform (older Android OSes lag, but their JS & browser rendering engines weren't that fast to begin with), but quite well on many platforms.
Canvas is the best choice for the type of game you are describing, but some DOM elements are still very useful even using canvas, for example, asking the player's name, or creating a menĂº or profile section inside the game. You can render a div with absolute position on top of your canvas when you need to display DOM elements, and do all the "game stuff" like drawing and animate sprites in the canvas element.
The reason why Canvas is the best choice is simple. I'm pretty sure that you can't or it would be really hard to do things like this without the canvas element:
http://galloman.github.io/ss2d/samples/skeletons2.html
More at: http://ss2d.wordpress.com/support/
I'm animating a sprite on a pixel grid. I have a few options, with pros and cons for each. I have a fair amount of javascript experience (six years), but none with this kind of thing. The problem is I don't know how expensive each option will be.
The sprite needs to render quite fast, and be inexpensive enough to have at least five running at the same time while running collision detection.
Ideally, I would like to use a grid of elements inside of a wrapper, rendering colour and alpha channels to each element from a multidimensional array.
The major pro here is that I can run pixel-by-pixel collision detection and click past the transparent parts of the sprite. With any image-based sprite, the onClick event will fire even if I click on a transparent pixel (I'll have to do a lot of work to pass clicks through transparent pixels, and it might be quite expensive).
The next option is to use css sprites. css-tricks.com/css-sprites/
This would be easy peasy, but as mentioned previously, onClicks won't pass through the transparent pixels. I can probably force it, but again, it may be expensive, and take a lot of time to impliment.
Another option is animated gifs, but they are huge, limited in the colour department, and hard to control animation-wise. I'd rather not go there.
And then there's the html5 canvas element, which I don't know very much about and would like to stay away from if at all possible. I don't know how any of my code would even work in relation to the canvas element and I doubt it would do what I want in the long-run.
So which is the best for performance? Would the first (and most preferable) be a viable option? Or have I missed something out?
With today's browsers you will be fine on desktop computers for building a sprite out of positioned pixel sub-elements (as long as they aren't too complicated or large), and just to be safe I'd limit yourself to about 10 active sprites. With Mobile things might get a bit slow and clunky, but considering you seem to be designing a game that requires precision "onclicks" I doubt that this will be a problem.
Your most flexible bet is to use HTML5 Canvas, as you have already worked out, but it will involve quite a bit more JavaScript coding. But this sytem will allow you to apply a number of effects to your sprites and will allow you to use pixel perfect detection by using getImageData (which allows you to read the exact pixel colour at any pixel offset).
getPixel from HTML Canvas?
If you wanted to avoid the techinical problems and challenges of having a full screen canvas system (which can be tricky), you can actually create as many smaller Canvas elements and move them around as your sprites (with the ease of HTML Elements).. Then all you have to do is design the code that draws your animation frames, and also tells if the mouse has hit or not hit the sprite using the aforementioned method (along with a click handler and some code to calculate where the user has clicked relative to your canvas elements position). Obviously, it would be best to do this in a generalised way so your code can be applied to all your sprites :)
To draw your images on the canvas you can use a spritesheet as you were mentioning in your question, and use the rather flexible drawImage() method which supports a slicing mode. This just needs to be tied up to a setInterval or requestAnimationFrame style game loop.
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images
http://www.playmycode.com/blog/2011/08/building-a-game-mainloop-in-javascript/
UPDATE - for those who wish to be very optimal
If you wish to take a more optimal route - which is a little bit more involved again - you can do the following. This method benefits if you have many sprites that are exactly the same with only a few (20 or 30) frames of animation:
Power your sprites by normal DIVs with a background image sprite sheet that you shift the background position of. This is the most optimal you can be, save having static images as sprites, because the browser does all the work.
for each sprite type draw your spritesheet on a hidden canvas element that is big enough to incorporate your whole spritesheet.
When a user clicks on one of your DIV sprites, take the background position as coordinates, invert them, and you should then know where on your canvas element (looked up by sprite's type) the pixel data resides.
Use the getPixelData method on your hidden canvas to work out if the user has clicked on the sprite or not.
The above means you only have one canvas element in use - per sprite type, the browser handles all the graphics for you and you get pixel perfect collisions with an onclick.
Hope the above makes sense?
How about splitting your image spirit into 30x30 cells and only have elements where the cell is opaque and leave a gap where the cell is transparent so that clicks fall through. You lose a bit of accuracy in where the cells can be clicked though.
I'm starting a web game, and I would like to know the best way to do it.
The game is a field of hexagons seen from the above, that can be rotated/inclined.
What's the best way to do it? What I was going to do was use a canvas and use 2d transforms to simulate 3d rotations, the problem is that:
The game must work on smartphones
For every rotation i must redraw all the canvas, and there could be 200 hexagons on the screen to redraw many times, so i think canvas are too expensive in terms of resources...
There's two ways I can think of:
Using canvas only. This means quite wide browser support, will have few quirks and generally "just work". Potential problems: Performance on low-end machines like you mentioned. But is rotating the game critical to gameplay? If not, you could consider turning that off on slow smartphones. Users will most likely not miss that feature if it's not important to gameplay.
A combination of canvas and CSS3 transforms (rotating cube example). Could give you better performance than pure canvas solution. Potential problems: requires "mixing" of techniques, which always means a risc of running into unexpected problems or quirks.
You should look at www.kineticjs.com
Canvas is the way to go for drawing 100's of shapes because it doesn't write to the DOM for every path like SVG does.
It has several examples where shapes are programmatically drawn in the 1000s. I recently used it for a similar animation here:
http://movable.pagodabox.com
Intent on creating a canvas-based game in javascript I stand before a choice:
Should I performance-wise keep all the stuff happening in the screen in one canvas (all the moving characters, sprites) and redraw it at constant rate of, say, 60 FPS or should I break the scene into several smaller canvases thus removing the need of redundant redrawing of the scene? I could even create separate canvas elements for the characters' limbs and then do most of the animation by simply manipulating the CSS of the given canvas element (rotation, positioning, opacity).
To me the latter sounds way more plausible and easier to implement, but is it also faster? Also, shouldn't I perhaps use SVG, keep the characters and sprites as elements inside of it and manipulate their XML and CSS properties directly?
So what do you think is the most fitting solution to a scene with severals sprites and characters:
One canvas object redrawn manually (and wastefully) at FPS rate
Several canvas elements, redrawn manually in a more reasonable fashion
Structured vector graphics document like SVG / VML manipulated via DOM
I am mainly concerned about the performance differences, but the legibility of the logical code behind is also of interest (I, having already worked with canvas before, am for example fairly sure that the redrawing function for the entire canvas would be one hard-to-maintain beast of a script).
DOM manipulations are slow in comparison to GPU-accelerated canvas operations, so I would stay away from SVG and VML.
As far as structuring your canvas code goes, it certainly doesn't make sense (especially for performance reasons) to clear and re-draw the entire canvas because the player moved or performed an action. Based on your description here, I'm guessing that your game will be 2D. These types of games lend themselves extremely well to layering unless you're doing something rather complex like Paper Mario. You should be looking at the issue from an object-oriented viewpoint and encapsulating your drawing procedures and objects together as appropriate.
For instance, create a player object that maintains a small canvas representing the character. All the logic needed to maintain the character's state is kept within the object and any changes made to it need not worry about other components of the game's visual representation. Likewise, do the same for the background, user interface, and anything else you can abstract into a layer (within reason). For example, if you're doing a parallax game, you might have a foreground, background, character, and user interface layer.
Ultimately you will need to maintain the state of the different components in your game individually. Player animations, background clouds moving, trees swaying, etc. will all be managed by appropriate objects. Since you will already have that type of code structure setup, it makes sense to just maintain major components on separate canvas elements and composite them together as needed for better performance. If the character moves in the bottom left corner of a scene with a static background, you don't need to re-draw the top right corner (or 95% of the scene, for that matter). If you're considering full-screen capabilities, this is definitely a performance concern.
There's a rule in programming, that you should never try and optimize something before you have a speed problem with it. You'll spend more time trying to figure out how to code something in the best way than to actually code, and will never finish anything.
Draw them all on your canvas at a fixed rate. That's how it's done. If you start creating a canvas for each limb and element and manipulate them using CSS, you're wasting the potential of canvas. Might as well just use images. That's how they did it before canvas. That's the problem canvas was made to solve.
If you ever encounter speed issues, then you can start hammering at them. Check out these slides for some tips (related video). This guy's blog also has some handy tips on canvas performance.