http://www.famitsu.com/freegame/tool/chibi/index1.html
I want to build a character generator exactly like this one. Someone suggested me that it'd be easy to use a canvas library, followed by low level JavaScript programming. Some said I don't need canvas and can do it easily with JavaScript. Since I've only learnt core JavaScript so far, hence I really don't have any knowledge or idea about this scene. So can you suggest me where and how to start this project of mine? And what are the required languages I should acquire first before jumping onto this project?
The components of an interactive, graphic application:
Something on which to draw (canvas)
Something to draw (graphics)
Looping drawing logic (animation loop and how to throttle it)
The game/application's functionality (game loop)
Interactivity (event listeners that can react to key presses, clicks, etc.)
Sound effects and music
These things are the basic building blocks of any interactive, graphic application.
JavaScript is a great language to use when starting out (or even beyond that) because the same concepts apply here as anywhere else, but you can save your code, and run it in your favorite browser!
Here's a Tetris example I've been working on lately in JavaScript that draws the board on an HTML5 canvas. It may seem a little complicated and overwhelming, but all the pieces are there that I've discussed (except for sound =/).
Just for reference, the tick function is my main animation loop. It runs as fast as the window will return animation frames, which is usually quicker than necessary. Once the tick function is called once, it will continue to run until explicitly stopped.
Tet.prototype.tick = function()
{
var _self = this; // needed for next step
// This line is what will make this function run repeatedly
this.requestId = requestAnimationFrame(function(){_self.tick()});
// Get some time information
this.tickNow = Date.now();
this.tickDelta = this.tickNow - this.tickThen;
// If it's been long enough, and it's time to draw a frame...
if (this.tickDelta > this.tickInterval)
{
this.tickThen = this.tickNow - (this.tickDelta % this.tickInterval);
// Run the game loop
this.doGameLoop();
// Draw the updated board
this.renderer.drawBoard(this.data, this.curPiece, this.curPieceGuide);
}
}
Game making can be intimidating at first, because it seems there are SO MANY pieces that need to be understood before you can accomplish what you see in your head, but if you take the concepts one-at-a-time, and start small, you'll be making crazy stuff in no time!
Related
This may be a stupid/previously answered question, but it is something that has been stumping me and my friends for a little while, and I have been unable to find a good answer.
Right now, i make all my JS Canvas games run in ticks. For example:
function tick(){
//calculate character position
//clear canvas
//draw sprites to canvas
if(gameOn == true)
t = setTimeout(tick(), timeout)
}
This works fine for CPU-cheep games on high-end systems, but when i try to draw a little more every tick, it starts to run in slow motion. So my question is, how can i keep the x,y position and hit-detection calculations going at full speed while allowing a variable framerate?
Side Note: I have tried to use the requestAnimationFrame API, but to be honest it was a little confusing (not all that many good tutorials on it) and, while it might speed up your processing, it doesn't entirely fix the problem.
Thanks guys -- any help is appreciated.
RequestAnimationFrame makes a big difference. It's probably the solution to your problem. There are two more things you could do: set up a second tick system which handles the model side of it, e.g. hit detection. A good example of this is how PhysiJS does it. It goes one step further, and uses a feature of some new browsers called a web worker. It allows you to utilise a second CPU core. John Resig has a good tutorial. But be warned, it's complicated, is not very well supported (and hence buggy, it tends to crash a lot).
Really, request animation frame is very simple, it's just a couple of lines which once you've set up you can forget about it. It shouldn't change any of your existing code. It is a bit of a challenge to understand what the code does but you can pretty much cut-and-replace your setTimeout code for the examples out there. If you ask me, setTimeout is just as complicated! They do virtually the same thing, except setTimeout has a delay time, whereas requestAnimationFrame doesn't - it just calls your function when it's ready, rather than after a set period of time.
You're not actually using the ticks. What's hapenning is that you are repeatedly calling tick() over and over and over again. You need to remove the () and just leave setTimeout(tick,timeout); Personally I like to use arguments.callee to explicitly state that a function calls itself (and thereby removing the dependency of knowing the function name).
With that being said, what I like to do when implementing a variable frame rate is to simplify the underlying engine as much as possible. For instance, to make a ball bounce against a wall, I check if the line from the ball's previous position to the next one hits the wall and, if so, when.
That being said you need to be careful because some browsers halt all JavaScript execution when a contaxt menu (or any other menu) is opened, so you could end up with a gap of several seconds or even minutes between two "frames". Personally I think frame-based timing is the way to go in most cases.
As Kolink mentioned. The setTimeout looks like a bug. Assuming it's only a typo and not actually a bug I'd say that it is unlikely that it's the animation itself (that is to say, DOM updates) that's really slowing down your code.
How much is a little more? I've animated hundreds of elements on screen at once with good results on IE7 in VMWare on a 1.2GHz Atom netbook (slowest browser I have on the slowest machine I have, the VMWare is because I use Linux).
In my experience, hit detection if not done properly causes the most slowdown when the number of elements you're animating increases. That's because a naive implementation is essentially exponential (it will try to do n^n compares). The way around this is to filter out the comparisons to avoid unnecessary comparisons.
One of the most common ways of doing this in game engines (regardless of language) is to segment your world map into a larger set of grids. Then you only do hit detection of items in the same grid (and adjacent grids if you want to be more accurate). This greatly reduces the number of comparisons you need to make especially if you have lots of characters.
I'm working on a educational physics project and I've chosen Box2D as my main engine for a "Build your own rocket" like physics game.
Box2D looks very intuitive and the documentation seems pretty good IMMO, but I couldn't find how to set the sleeping time of a given body. Is it possible?
I've already tried the lazy approach:
var newB = new b2BodyDef();
newB.m_sleepTime = 12000;
Unfortunately, the newB still starts to sleep almost instantaneously after it gets into a rest position.
You can SetSleepingAllowed(bool) on an individual body, or set the entire world to not sleep when you create it. Unless you have a huge number of bodies in your simulation, I would just use one of these and keep the body awake all the time. You can also SetAwake(bool) on individual bodies if you know when you'll need them to be awake.
My problem is that my javascript/canvas performs very slowly on lower end computers (Even though they can run even more challenging canvas scripts smoothly).
I'm trying to do a simple animation depending on user selection.
When drawing on the canvas directly proved to be too slow, I draw on a hidden canvas and saved all frames (getImageData) to data and then called animate(1); to draw on my real canvas.
function animate(i){
if(i < 12){
ctx2.putImageData(data[i], 0, 0);
setTimeout(function(){animate(i+1)},1);
}
}
But even this is too slow. What do I do?
Do not use putImageData if you can help it. The performance on FF3.6 is abysmal:
(source: phrogz.net)
Use drawing commands on off-screen canvases and blit sprites to sub-regions using drawImage instead.
As mentioned by #MartinJespersen, rewrite your frame drawing loop:
var animate = function(){
// ...
setTimeout(animate,30); //Max out around 30fps
};
animate();
If you're using a library that forces a clearRect every frame, but you don't need that, stop using that library. Clear and redraw only the portions you need.
Use a smaller canvas size. If you find it sufficient, you could even scale it up using CSS.
Accept that slow computers are slow, and you are standing on the shoulders of a great many abstraction layers. If you want to eek out performance for low-end computers, write in C++ and OpenGL. Otherwise, set minimum system requirements.
The timeout you specified is 1 millisecond. No browser can update the canvas that fast. Change it to 1000 - that'll be 1 second, i.e:
setTimeout(function(){animate(i+1)}, 1000)
UPD. Another thing to try is to prepare as many canvases as there are frames in your animation, set all of them to display:none, then turn display:block on them sequentially. I doubt it's going to be faster than putImageData, but still worth trying.
As already mentioned timeouts with 1 millisecond interval are doomed to fail, so the first step is to stop that.
You are calling setTimeout recursivly which is not ideal for creating animations. Instead initiate all the setTimeouts you need for the entire animation at the same time with increasing delays in a loop and let them run their course, or better yet use setInterval which is the better way of doing animations, and how for instance jQuery's animations work.
It looks like you are trying to redraw the entire canvas at each step of your animation - this is not optimal, try only manipulation the pixels that change. The link you have given to "more challanging canvas scripts" are actually a lot simpler than what you are trying to do, since it's all vector based math - which is what the canvas element is optimized for - it was never made to do full re-rendering every x milliseconds, and it likely never will be.
If what you really need to do is changing the entire image for every frame in your animation - don't use canvas but normal image tags with preloaded images, then it will run smoothly in ie6 on a singlecore atom.
I've got an app that works kind of like Google maps - it lets you click and pan over a large image. I redraw my Canvas heavily, sampling and scaling from a big image each redraw.
Anyway, I happened to try a dual canvas approach - drawing to a (larger) buffer one when needed, then doing a canvas_display.drawImage(canvas_buffer) to output a region to the screen. Not only did I not see a performance gain, but it got significantly slower with the iPhone. Just a datapoint...
OK, first things first. What else is happening while you're doing this animation? Any other javascript, any other timers, any other handlers? The answer, by the way, cannot be nothing. Your browser is repainting the window - the bits you're changing, at least. If other javascript is 'running', remember, that's not strictly true. Javascript is single-threaded by design. You can only queue for execution, so if some other javascript is hogging the thread, you won't get a look in.
Secondly, learn about how timers work. http://ejohn.org/blog/how-javascript-timers-work/ is my personal favorite post on this. In particular, setTimeout is asking the browser to run something after at least the specified time, but only when the browser has an opening to do that.
Third, know what you're doing with function(){animate(i+1);}. That anonymous function can only exist within the scope of its parent. In other words, when you queue up a function like this, the parent scope still exists on the callstack, as #MartinJespersen pointed out. And since that function queues up another, and another, and another... each is going to get progressively slower.
I've put everything discussed in a little fiddle:
http://jsfiddle.net/KzGRT/
(the first time I've ever used jsfiddle, so be kind). It's a simple 10-frame animation at (nominally) 100ms, using setTimeout for each. (I've done it this way instead of setInterval because, in theory, the one that takes longer to execute should start lagging behind the others. In theory - again, because javascript is single-threaded, if one slows down, it would delay the others as well).
The top method just has all ten images drawn on overlapping canvases, with only one showing at a time. Animation is just hiding the previous frame and showing the next. The second performs the putImageData into a canvas with a top-level function. The third uses an anonymous function as you tried. Watch for the red flash on frame zero, and you'll see who is executing the quickest - for me, it takes a while, but they eventually begin to drift (in Chrome, on a decent machine. It should be more obvious in FF on something lower-spec).
Try it on your low-end test machine and see what happens.
I did the setTimeout this way, hope it helps somebody at boosting application:
var do = true;
var last = false;
window.onmousemove = function(evt){
E.x = evt.pageX - cvs.offsetLeft;
E.y = evt.pageY - cvs.offsetTop;
if(do){
draw();
do = false;
//in 23 ms drawing enabled again
var t = setTimeout(function(){do = true;},23);
}else{
//the last operation must be done to catch the cursor point
clearTimeout(last );
last = setTimeout(function(){draw();},23);
}
};
[edit]sigh... the "spam protection" here isn't letting me post the links, so I guess it's URIs instead[/edit]
[edit2]ok, BROKEN forms of the URI that can get past the regexp...[/edit2]
I'll preface this by saying I'm totally new to SVG, and somewhat new to Javascript, having come from a background in low-level C. On a whim, though, I decided to try my hand at writing a realtime game using all these fun new web technologies.
I'm fully prepared for the answer to be "The web can't do that yet, sorry!" This may simply be too much data throughput for a browser.
So I have written the beginnings of an Asteroids clone. It is a thin SVG document, with the entire game being dynamically generated as SVG line/polygon entities from javascript. Much to my surprise, this actually worked. I was able to get mostly smooth animation from Firefox 3.5 (not tested on anything else).
original, as-needed allocation version
(javascript) http - public.codenazi.fastmail.fm/asteroids_dynamic.js
This does variations of this each time a rock it hit:
// on startup
svg_ns = 'http://www.w3.org/2000/svg';
container = svgdoc.getElementById('rocks');
// each time a rock breaks, times ~20
x = svgdoc.createElementNS(svg_ns, "polygon");
x.setAttribute(...various things...);
container.appendChild(x);
Unfortunately, it's not smooth enough. It lags all the time. There are jerks and breaks in the flow, even on my modern 3GHz box. Several friends I have shown it to also immediately complained of stuttering.
I have spent the last week or so reading up on how to optimize javascript, which helped slightly, but I suspect that the issue is all of the insertions/deletions I am doing to the DOM for pretty much every action in the game. I have considered various pre-allocation schemes, and don't really want some complicated memory manager if it's not actually going to help.
What did come up a lot in my research is discussions of "reflow" and "repaint". As I understand it, any insertion/deletion to the DOM will cause some sort of re-parse of the entire tree, which is slow. The common solution was to collect sub-nodes together first, and only do a single insert into the actual document. This model doesn't really work with a game like this, though.
As a test, I sort of combined the two ideas: pre-allocate when possible, and insert in groups when possible. So in this version, each asteroid is replaced with a SVG group, and the asteroid, it explosion effects, and its pop-up score are created all at once. This way, allocations and insertions only happen when asteroids are created (not destroyed). To keep these extra effects hidden until they are needed, I set the "display: hidden" attribute.
new, group-preallocated version: http - public.codenazi.fastmail.fm/asteroids_prealloc.svg
(javascript): http - public.codenazi.fastmail.fm/asteroids_prealloc.js
When the rocks are created, this happens instead:
g = svgdoc.createElementNS(svg_ns, "g");
// make the rock itself
rock = svgdoc.createElementNS(svg_ns, "polygon");
rock.setAttribute(...various things...);
g.appendChild(rock);
// make the destroy effect (repeated many times)
frag = svgdoc.createElementNS(svg_ns, "line");
frag.setAttribute(...various things...);
frag.style.display = 'none';
g.appendChild(frag);
// actually add it
container.appendChild(g);
// then, sometime later when a hit is detected
rock.style.display = 'none';
frag.style.display = 'block';
I think this DID make it a bit smoother! But... it also dropped the framerate significantly. I have to keep track of more elements at once, and some testing has shown that wrapping everything in another element makes the SVG render slower as well.
So my question is this: is this even possible? Can I actually get a reasonably smooth SVG animation like this out of firefox? Or is firefox inherently going to have stalls/stutters? If it is possible, is there some memory/element management technique that can allocate/insert SVG elements in a better way than I currently am?
I kind of suspect that the answer will be to just stick with the first, easier method with fewer elements and wait for the future when browsers are better... -sigh-
I haven't tried SVG animation (yet); but Canvas is surprisingly good at it; especially if you do layers.
In short, create a canvas object for each layer, and erase/redraw each one separately. You can also do quick blitting between an off-screen canvas an the displayed ones.
I know, in theory SVG should be much quicker; but as you've noticed, the DOM parsing kills you. with Canvas there's no need for that.
Okay, first things first:
Dude - that is the most awesome bit of SVG I have ever seen. Thank you for sharing this.
It ran perfectly smoothly on my system, until I destroyed a whole bunch of rocks at once. What if you replace the dynamic frag animation with a pre-made SVG animation? Does that improve performance?
I want to create some randomly flying objects in a Unity 3D game. You can imagine them like fireflies. Now there're some tasks to do with them, include:
They usually fly randomly (of course).
They can fly away or fly back in some conditions.
I have to write some Javascript to do these things, but I don't know how to do. Can you help me? Thank you very much!
EDIT: I think I'll need these functions:
function Fly()
{
//control the gameObject to fly randomly
}
function FlyAway()
{
}
function FlyBack()
{
}
I would suggest that you look at the canvas tag, but then it will not work on IE as I don't know if 3D effects will work on excanvas well.
This gives you a drawable surface to do your graphics.
You will probably need to write your own primitive functions for the graphics, but it is very doable.
EDIT: You will need to use object oriented javascript for each of your fireflies, which will help you to move each of them each frame.
If you show your attempt at drawing graphics you can get more help.
As much as I hate condoning the use of Flash, this really sounds like a Flash job.
However, if you insist on using JavaScript, I'd thumb through some Chrome Experiments for 3D examples (w/canvas): http://www.chromeexperiments.com/
I've done an abstraction library that may help here:
DP_PanelManager
The library makes moving objects pretty simple - at the bottom of the page there's an example called "Useless Animation" - it's basically a checkerboard where each square randomly moves, changes size and changes opacity.
Something like that with fewer panels and a little math to do smoother travel (something like this should be easy enough to modify) should get you close.
The component also has simplified functions for collision detection and distance between panels (with bearing - the function will tell you how far apart two panels are AND in which direction they lay).
Hopes this gives you a headstart.
My approach would be
randomly create a x/y equation (may be from a given set, if you don't know how to 100% randomize this).
Decide, randomly if you go by the x or by the y.
decide the number of steps you take on the axis you chose in step 2.
move your element according to the x/y you get from the equation in step 1.
When you finished to move all the steps (number of steps is given in step 3), go back to step 1. In a loop.