(I'm trying to make a basic space invaders game)I'm very new to coding so this might be a total mess, however, I'm using gameloop(s). One of them is moving the hero, one is moving the missiles, and drawing them. However, I can't seem to split them. I want to split them up so I can change the setTimeout, but it doesn't want to split up.
Tried to split them up by making a gameloop_1();, but that wouldn't move the missiles... sooo... I'm lost
var missiles = [];
function drawMissiles() {
document.getElementById('missiles').innerHTML = ""
for (var i = 0; i < missiles.length; i++) {
document.getElementById('missiles').innerHTML += `<div
class='missile1' style='left:${missiles[i].left}px;
top:${missiles[i].top}px'></div>`;
}
}
function moveMissiles() {
for (var i = 0; i < missiles.length; i++) {
missiles[i].top = missiles[i].top - 15
}
}
function gameLoop() {
setTimeout(gameLoop, 950)
moveMissiles();
drawMissiles();
moveFiende();
drawFiende();
collisionDetection();
}
function gameLoop_1() {
setInterval(gameLoop_1, 100)
moveMissiles();
drawMissiles();
}
gameLoop();
gameLoop_1();
What happens when I split them up, is as I said; The missiles won't then shoot.
Disclaimer:
If you expect an answer for your specific code here, you'll be disappointed, so if you do not intend to start from scratch or something like that, I'm sorry for the whole text.
I think you're misundertanding the purpose of a Game Loop.
There are some things wrong with your code, but I'll stick with the basis of your question, which also happen to be the basis of every game, the Game Loop.
Frames
Let's start with Frames. You probably know what a Frame is. It is like a drawing on the screen of a single moment in time. For example, when you watch a movie, you're actually watching a lot of pictures (frames) being drawn very fast, one after another, which gives the illusion of movement (usually 30 "pictures" per second).
The Game Loop
The Game Loop is the responsible for drawing the frames of the game, one after another, it executes functions, methods, changes variables and based on the results, it finally draws on the screen what is happening on the game.
The Game loop is basically what makes everything in the game possible to happen, it's like what time is for us in real life: without time passing, there would be no past, present or future, we would be stuck in a single frame forever.
The same happens on a game, withou a Game Loop, there would be no iterations, nor changes or frame updates.
Extremely basic game structure
Knowing that, the first thing you must do is always having a "central" game loop, and never split it. Always name other methods as "updates" and call them from the master game loop.
So a most correct structure for your code would be (this is just pseudocode similar to js, not any language in particular):
SpaceInvaders = {
GameLoop(){
UpdatePlayer();
UpdateProjectile();
UpdateEnemies();
setTimeout(GameLoop, 16) // to call the loop each 16ms, thus giving you 60fps
}
UpdatePlayer(){
// do stuff like move the player and fire
}
UpdateProjectile(){
// do stuff like move the projectile and check if it hitted something
}
UpdateEnemies(){
// do stuff like move the enemies
}
}
SpaceInvaders.GameLoop();
If you want to have a more in depth look on Game Loops, please check this amazing article, it helped me a lot when I was starting my first HTML5 canvas game:
https://isaacsukin.com/news/2015/01/detailed-explanation-javascript-game-loops-and-timing
You'll be presented with the hardware compensation problem that comes as consequence of the Game Loop and some other interesting stuff.
Your situation
Now that the Game Loop principle is better explained, let's talk about your specific situation a little more. There are 3 main things that pop into my eye:
First of all, I don't think that it is going to be a good experience to try making a game using only HTML concatenation and CSS, if you really want to do it from scratch all by yourself, I hardly encourage you to try making a game using HTML5 canvas. For me it was a great experience to learn the very basics of game development. As I look back now, tho, I see how my code sucks (used vanilla js, and compensated the hardware by hand on each frame in all moving entities). If you want to see this project done:
https://github.com/diguifi/littlejsworld
Second, you're not working with objects, that's going to make the code very messy in later stages of development and very hard to work with (even if it's just space invaders). What I mean by objectifying your game is, for example: instead of loose methods for "drawMissiles" and "moveMissiles" you should have an object called "Missile" and another called "Player".
The Missiles would have such methods ("draw" and "move", accesible via "Missile.draw()") and the Player would have a list of Missiles (this is just an example, you must use objects for everything in your game, in order to have a well designed project).
And third, seems to me that concatenating divs on innerHtml of an element from the DOM is not a good thing to do, it's very costly, ugly and time consuming.
My suggestions
If you want to make this game as an exercice for learning the basis of game development, I think you should start from scratch using only a canvas element and center your code efforts on the javascript, not messing with html elements to create the game. There are many articles and docs to help you in this task, such as the one I mentioned that talks about game loop.
If your goal is just to make a game, without having to understand basic problems, you should try a game engine, such as:
Godot: a free, easy and lightweight engine to create games, no need to worry about game loop here.
Phaser: code with js, without worrying about game loop management and many other basic stuff.
Unity: code in C# but not so much code is needed
Game Maker Studio: no coding needed, only basic programming logic
Construct 3: same as Game Maker, maybe easier
Related
How can I control the rendering loop frame rate in KineticJS? The docs for Kinetic.Animation show a frame rate being passed to the render callback, and Kinetic.Tween seems to have no frame rate logic, but I don't see anyway to force, say, a 30fps when 60fps is possible.
Loads of context for the curious follows, but the question is that simple. If anyone reads on, other advice is welcome. If you already know the answer, don't waste your time reading on!
I'm developing a music app that combines some DOM-based GUI controls (current iteration using jQuery Mobile) and Canvas-based GUI controls (using KineticJS). The latter involve some animation. Because the animated elements are triggered by music playback, I'm using Kinetic.Tween to avoid the complexity of remembering how long a given note has been playing (which Kinetic.Animation would require doing).
This approach works great at 60fps in Chrome (on a fast machine) but is just slow enough on iOS 6.1 Safari (iPad 2) that manipulating controls while animations are happening gets a little janky. I'm not using WebGL (unless KineticJS or Chrome does this by default for canvas?), and that's not an option when I package for native UIWebView.
As I'm getting beyond prototype into wanting to make more committed tech decisions, I see the following options, in order of perceived goodness:
Figure out how to cap the frame rate. Because my animations heavily use alpha fades but do not involve motion, I believe I could get away with 20-30fps and look fine. Could also scale this up on faster devices.
Don't respond immediately to touch inputs, but add them to a queue which I poll at a constant interval and only use the freshest for things like touchmove. This has no impact on my non-interactive animated elements, but tackles the problem from the other direction, trying to reduce the load of user interaction. This would require making Kinetic controls static and manually tracking touch coordinates (not terrible effort if it actually helped).
Rewrite DOM-based GUI to canvas-based (KineticJS); rewrite WebAudio-based engine to HTML5 audio; leverage CocoonJS or Ejecta for GPU-acceleration. This means having to hand-code stuff like file choosers and nav menus and such (bad). Losing WebAudio is pretty serious as it eliminates features like DSP effects and very fine-grained, low-latency timing (which is working just fine on an iPad 2).
Rewrite the app to separate DOM based GUI and WebAudio from Canvas-based elements, leverage CocoonJS. I'm not sure if/how well this works out, but the fact that CocoonJS passes JavaScript code as strings between the 2 components makes me very skittish about how solid this idea is. It's probably doable, but best case I'm very tied to CocoonJS moving forwards. I don't like architecting this way, but maybe it's not as bad as it sounds?
Make animations less juicy. This is least good not because of its design impact but because, as it is, I'm only animating ~20 simple shapes at any time in my central view component, however they include transparency and span an area ~1000x300. Other components like sliders are similarly bare-bones. In other words, it's not very juicy right now.
Overcome severe allergy to Objective-C; forget about the browser, Android, and that other mobile OS. Have a fast app that performs natively and has shiny Apple-approved widgets. My biggest problem with this approach is not wanting to be stuck in Objective-C reality for years, skillset-wise. I just don't like it.
Buy an iPad 3 or later. Since I already am pretending Android doesn't exist (I don't have any devices to test), why not pretend no one still has iPad 2? I think this is passing the buck -- if I can get acceptable performance on iPad 2, I will feel confident about the app's performance as I add more features.
I may be overlooking options or otherwise naive about how to tackle this. Some would say what I'm trying to build is just silly. But it's working pretty well just not ready for prime time on the iPad 2.
Yes, you can control the Kinetic.Animation framerate
The Kinetic.Animation sends in a frame object which has a frame.time property.
That .time is a running timer that you can use to throttle your animation speed.
Here's an example that throttles the Kinetic.Animation: http://jsfiddle.net/m1erickson/Hn3cC/
var lastTime;
var frameDelay=1000;
var loop = new Kinetic.Animation(function(frame) {
var time = frame.time
if(!lastTime){lastTime=time;}
var elapsed = time-lastTime;
if(elapsed>=frameDelay){
// frameDelay has expired, so animate stuff now
// set lastTime for the next loop
lastTime=time;
}
}, layer);
loop.start();
Working from #markE's suggestions, I tried a few things and found a solution. It's ultimately not rocket science, but sharing what I figured out:
First, tried the hack of doubling Tween durations and targets, using a timer to stop them at 50%. This kinda sorta worked but was hard to get to look good and was pretty error prone in coding bogus targets like negative opacity or height or whatnot.
Second, having read the source to Tween and looked at docs again for Animation, decided I could locally use Animation instances instead of Tween instances, and allow the closure scope to hang onto the relevant note properties. Eventually got this working smoothly and finally realized a big Duh! which is that throttling the frame rate of several independently animating things does not in any way throttle the overall frame rate.
Lastly, decided to give my component a render() method that calls itself in a loop with requestAnimationFrame, exits immediately if called before my clamp time, and inside render() I update all objects in the Kinetic canvas and call layer.drawScene(). Because there is now only one animation, this drops frame rate to whatever I need and the app is fast on iPad 2 (looks exactly the same to my eyes too).
So Kinetic is still helping for its higher level canvas API, and so far my other control widgets are still easy code using Kinetic to handle user input and dragging, now performing much better as the big beast component is not eating up the CPU.
The short answer to my original question is that no, you can't lock the overall frame rate for very complex animations, but as Mark said, you can for anything that fits in a single Animation instance.
Note that I could have still used Animation without giving it a layer or explicitly calling any draw() methods, but since I'd still have to write all the logic to determine individual element's current visual state, there was no gain to doing this. What would be very useful would be if Tween could accept a parameter to not automatically render. This would simplify code like mine, as I could shorthand the animation on individual objects but still choose when to actually do the heavy lifting of rendering everything. Seeing how much this whole exercise gained in performance on the iPad 2, might be worth adding this option to the framework.
I'm trying to make a little platform game with pure HTML5 and JavaScript. No frameworks.
So in order to make my character jump on top of enemies and floors/walls etc., it needs some proper collision detection algorithms.
Since I'm not usually into doing this. I really have no clue on how to approach the problem.
Should I do a re-check in every frame (it runs in 30 FPS) for all obstacles in the Canvas and see if it collides with my player, or is there a better and faster way to do so?
I even thought of making dynamic maps. So the width, height, x- and y coordinates of the obstacle are stored in an object. Would that make it faster to check if it's colliding with the player?
1. Should I re-check in every frame (it runs on 30 FPS)?
Who says it runs in 30 FPS? I found no such thing in the HTML5 specification. Closest you'll get to have anything to say about the framerate at all is to programmatically call setInterval or the newish, more preferred, requestAnimationFrame function.
However, back to the story. You should always look for collisions as much as you can. Usually, writing games on other platforms where one have a greater ability to measure CPU load, this could be one of those things you might find favorable to scale back some if the CPU has a hard time to follow suit. In JavaScript though, you're out of luck trying to implement advanced solutions like this one.
I don't think there's a shortcut here. The computer has no way of knowing what collided, how, when- and where, if you don't make that computation yourself. And yes, this is usually, if not at all times even, done just before each new frame is painted.
2. A dynamic map?
If by "map" you mean an array-like object or multidimensional array that maps coordinates to objects, then the short answer has to be no. But please do have an array of all objects on the scene. The width, height and coordinates of the object should be stored in variables in the object. Leaking these things would quickly become a burden; rendering the code complex and introduce bugs (please see separation of concerns and cohesion).
Do note that I just said "array of all objects on the scene" =) There is a subtle but most important point in this quote:
Whenever you walk through objects to determine their position and whether they have collided with someone or not. Also have a look at your viewport boundaries and determine whether the object are still "on the scene" or not. For instance, if you have a space craft simulator of some kind and a star just passed the player's viewport from one side to the other and then of the screen, and there is no way for the star to return and become visible again, then there is no reason for the star to be left behind in the system any more. He should be deleted and removed. He should definitely not be stored in an array and become part of a future collision detection with the player's avatar! Such things could dramatically slow down your game.
Bonus: Collision quick tips
Divide the screen into parts. There is no reason for you to look for a collision between two objects if one of them are on left side of the screen, and the other one is on the right side. You could split up the screen into more logical units than just left and right too.
Always strive to have a cheap computation made first. We kind of already did that in the last tip. But even if you now know that two objects just might be in collision with each other, draw two logical squares around your objects. For instance, say you have two 2D airplanes, then there is no reason for you to first look if some part of their wings collide. Draw a square around each airplane, effectively capturing their largest width and their largest height. If these two squares do not overlap, then just like in the last tip, you know they cannot be in collision with each other. But, if your first-phase cheap computation hinted that they might be in collision, pass those two airplanes to another more expensive computation to really look into the matter a bit more.
I am still working on something i wanted to make lots of divs and make them act on physics. I will share somethings that weren't obvious to me at first.
Detect collisions in data first. I was reading the x and y of boxes on screen then checking against other divs. After a week it occurred to me how stupid this was. I mean first i would assign a new value to div, then read it from div. Accessing divs is expensive. Think dom as a rendering stage.
Use webworkers if possible easy.
Use canvas if possible.
And if possible make elements carry a list of elements they should be checked against for collision.(this would be helpful in only certain cases).
I learned that interactive collisions are way more expensive. Because you have to check for changes in environment while in normal interaction you simulate what is going to happen in future, and therefore your animation would be more fluid and more cpu available.
i made something very very early stage just for fun: http://www.lastnoob.com/
I'm working on a multiple projectile simulator for a college project and I'm wondering how to best setup timing in JavaScript rendering to a HTML5 canvas
I'm using an Euler integrator setup for physics and accuracy is very important for this project. The rendering is very bare bones
My question is how to best setup the timing for all this.
Right now I have:
The physics and other logic running in a function that loops using setTimeout() with a fixed time step
The rendering in another function that loops using a requestAnimationFrame() call (flexible time step)
These two loops run sort of simultaneously (I know JavaScript doesn't really support threads without Web Workers) but I don't want the rendering (currently running at a much higher FPS than needed) to be unnecessarily 'stealing' CPU cycles from the physics simulation, if you see what I mean.
Given that physics accuracy is most important here how would you recommend setting up the timing system? (Maybe using Web Workers would be useful here but I havent seen this used in other engines)
Thanks!
I'd suggest that you don't try to 'multithread' unless you're actually doing it, and even then, I wouldn't necessarily recommend it.
The best way to keep everything in synch is to have a single thread of execution. A single setTimeout loop of about 33ms seems to work ok for my games.
Also, in my experience at least, setTimeout offers a much more aesthetic experience than setInterval or requestAnimationFrame. With setInterval, Javascript tries to hard to 'catch up' when frames are delivered late, which makes animation frames inconsistent. With requestAnimationFrame, frames are skipped to ensure a smooth running game, which actually makes things harder, because your users aren't entirely sure their view is up to date at any given second.
One way would be to set an interval for processing physics, and once per x frames, render everything.
var physicsTime;
var renderFrequency;
var frameCount;
setInterval(function(){updateStuff()},physicsTime);
then in updateStuff()
function updateStuff(){
frameCount ++;
if (frameCount >= renderFrequency){
frameCount -= renderFrequency;
render();
}
physics();
}
Right now I've got two game loops in a game I'm making. A draw loop that loops through an array of objects on screen and a logic loop that does game logic. I have the logic loop running about 10 more frames than the draw loop. I have this set up like this because doing game logic may take longer and I don't want it to interfere with the draw loop.
I have the logic loop set up like this:
vs.logicloop = function(){
vs.Gameloop();
//do the updating of object scripts
if(vs.windowActive){
var l = vs.scenegraph.length;
var i = 0;
while(i < l){
vs.scenegraph[i].logicScript();
i++;
}
}
//restart loop
setTimeout(vs.logicloop, 1000/(vs.fps+10));
};
and the draw loop like this:
vs.drawloop = function(){
//clear the screen
vsd.clr();
//goes through everything in the scene
//graph and draws it and runs each object's
//personal draw code
if(vs.windowActive){
var l = vs.scenegraph.length;
var i = 0;
while(i < l){
vs.ctx.save();
vs.scenegraph[i].update();
vs.scenegraph[i].draw();
vs.scenegraph[i].drawScript();
vs.ctx.restore();
i++;
}
}
//restart loop
setTimeout(vs.drawloop, 1000/vs.fps);
};
I'm using setTimeout because I heard that setInterval will cause loops to overlap if one isn't finished yet. Are there any optimizations I can do to really get some speed? Especially optimizing the game loops.
I've heard of some javascript engines getting thousands of objects on screen at once. I can't imagine how they do that, at most mine can get up to 100 objects on screen on a very old computer and about 700 on a reasonably stocked computer. And that's without a lot of game code running in the background and before I've worked out how to do pixel perfect collision detection and physics.
My process is to draw a background color fillRect over the canvas every draw loop, then looping through all the objects and drawing their draw code. Also it doesn't try to draw objects out of view.
This is my first paying job, and I really want to impress. Plus I can keep ownership of the engine once I'm done with the game.
Thanks A Lot
if you use floating values for sprite coordinates, try converting them to integers. that will cost you losing subpixel rendering but you will gain a lot of speed.
don't use images with odd widths. always use widths as powers of 2.
this one is hard to implement in some cases but if your game is suitable, don't clear screen and redraw everything each frame. instead, draw changed parts.
if you have to clear the canvas, don't draw a blank rectangle. try setting the canvas width/height again with the same size. that should reset the pixels faster than rectangle drawing.
rest of the methods i can suggest are not HTML5 canvas dependent but general subjects like using bit shiftings, inverse loops, and operator instead of modulo when possible, precalculations etc.
Oh geez, I could probably write you a full sonnet here if you posted all your code. Here's a quick rundown:
Read Emir's answer. All of those are good except the last one which is very dependent on the situation. Setting canvas.width = canvas.width to clear the canvas can be faster on some browsers but it also clobbers all canvas state (ie the last set fill and font) which can slow things down because setting those properties is actually painfully slow.
Read my articles on Canvas performance: http://simonsarris.com/blog/tag/performance
I have a lot of other tips saved up in a private document that I'm writing a small ebook out of. If you want early access to it I can probably allow that.
Pick up High performance JavaScript by Zakas and read it.
Don't use save() and restore() like you are in the quoted code unless you must. They are just slowing things down.
For the timer see http://paulirish.com/2011/requestanimationframe-for-smart-animating/
Multiple canvases for foreground-background-middleground can definitely help. Caching things on in-memory canvases can definitely help. It all depends on what you're drawing.
A lot of performance problems are due to death by a thousand tiny cuts. For instance:
vs.scenegraph[i].update();
vs.scenegraph[i].draw();
vs.scenegraph[i].drawScript();
To
var scene = vs.scenegraph[i];
scene.update();
scene.draw();
scene.drawScript();
Will help a minute amount. How many opportunities for minute-amount stuff you have I don't know - we'd need to see a lot more code.
I heard that setInterval will cause loops to overlap if one isn't finished yet.
This is false, JavaScript is single threaded. This means that if your first interval is still running when it hits the next step, the next step will be delayed until the first step has finished computing. This also means that you can't rely on setInterval to be accurate if you start doing a lot of computations.
I'd echo much of all has been said by other people. Integer values, use request animation frame, etc. If drawing text be careful how often you set fonts. Also you might find using an object pool can help if you are creating lots of temporary objects per frame.
As a general read on game loops I'd recommend this: http://www.koonsolo.com/news/dewitters-gameloop/
I'm trying to learn how to program a (virtual) Trading Card Game game (similar to Magic the Gathering) in Javascript. I've read a little about MVC architecture and controllers, but it's all over my head (I don't have any formal CS education) and I'm wondering if anyone has any good links or tips about how I might learn more about code architecture at a beginner's level.
Would each "card" be represented as an object, and all the logic of the cards' rules be wrapped inside one large game engine function, or many small functions that are connected to each other?
Here's an example question:
Imagine there's a card which says, "When this card comes into play, draw a card." How should I architect the game to prepare for this situation, and how is it triggered (most efficiently)? Does the card trigger the game engine, or does the game engine parse each card that's played?
Here's another example:
Imagine there's a card which says, "All your cards cost 1 less to play." and it stays in play permanently. How does the game understand that it needs to alter its rules in this case? Is this a function which listens for card to be played and interrupts the cost? As each turn resolves, where is this rule stored? Are there variables which store the base rules of the game (global card cost modifier: 0; your card cost modifier: 0) and other variables which store those new rules which cards introduce (your card cost modifier: -1), or are these variables dynamically created by the game engine as cards alter the rules (your elf cost modifier: -2)? And how do the rules know to change when a card has been destroyed, thus removing the card's rule modification?
Is what I need a primer on listeners and events? (I don't really know anything about them, but I've seen references to them from time to time.) Could you point me in the direction of a good resource?
To be clear, I'm not trying to make a long-winded request for folks to manually Google for me; I'm blindly fumbling in the dark and asking if someone would point me to the right words or phrases to search. Thank you!
There is a very nice blog about recreating a similar card game: Hearthstone from Blizzard. Allthough it is written in C# and uses Unity as a view layer, you get a pretty good understanding of how one goes about creating a suitable architecture for such a game. A fair warning though, recreating Magic the Gathering in Javascript can prove incredibly complicated and mess with your head a lot (I have first hand experience).
Blog: http://theliquidfire.com/2017/08/21/make-a-ccg-intro/
You need to go a level deeper here and think about the "game" itself. The game you're describing will actually be built around a "state machine" which is a core CS concept you should dive into and understand before you start building.
The rules of your game are going to be a state machine and the events (cards) triggered (by being played) during your game can modify those rules. You'll want some kind of interpreter to "read" the card and to modify either the rules or the game state. And then you'll need something to iterate the game through turns and phases, reading the state and taking appropriate action.
You'll also want to learn about stacks. If your game lets players interrupt each other you'll need a way to keep track of which event should happen first because events will want to be able to affect, block, redirect other events. A stack will help you keep track of that ordering.