sprite fall from top of screen with gravity acceleration in plain js - javascript

Hi i am trying to move a spite from the top of the screen to the bottom. I want to achieve a gravity like effect. To pre-empt people suggesting using a game engine, A: this js is running on a node.js server and not a client (you may suggest a game engine for node) and B: this is the only place i need to use a gravity effect so i feel that surely it is simpler just to make a loop with some kind of acceleration calculations inside?
In this example i don't need to do anything except the calculations.
var theMeteor = {
"x":500, //the start x position
"y":1000, //the start y position
"v":1 // the velocity
};
function MeteorFall(dt){
theMeteor.y += (theMeteor.v * dt) * -1; // move the meteor down
theMeteor.v++;// increase the velocity
// keep looping until its at the bottom
if(theMeteor.y <= 0){
// its at the bottom so clear the loop
clearInterval(theDeamon);
}
}
var dt = 0.025; //set this to whatever the loop refreshes at (0.025 = 25)
var theDeamon = setInterval(MeteorFall, 25, dt);
This works but it's not very good at all, is there any one who can show me how to do this correctly please?

Related

Javascript sprites moving between two points

I'm wanting to get some sprites moving between two points in my (very basic) javascript game. Each sprite is randomly placed in the level, so I want them to move back and forth between their base position. I have the code below
function Taniwha(pos) {
this.basePos = this.pos;
this.size = new Vector(0.6, 1);
this.move = basePos + moveDist(5,0));
}
Taniwha.prototype.type = "taniwha"
var moveSpeed = 4;
Taniwha.prototype.act = function(step) {
this.move = ???
and this is where I get stuck. I'm not sure how to tell it to go left, back to base pos, right then back to base pos again (I plan to loop this). Does anyone have any advice? (also using Eloquen Javascript's example game as an outline/guide for this, if how I'm doing things seems odd!)
For horizontal movement, change x coordinate of the position.
var pos = { x: 1, y: 2 };
pos.x++ ; // This will move right
pos.x-- ; // This will move left
Likewise for vertical movement. You also need to update the coordinates after change for the object which you are drawing.
In truth ,there are lots of library to develop a game.
Use those, control a sprite is very easy.
Like:
Pixijs
CreateJS
Both of them are opensource project, you can watch and learn the source.
And have lots of examples and document.

HTML5 Canvas game loop delta time calculations

I'm new to game development. Currently I'm doing a game for js13kgames contest, so the game should be small and that's why I don't use any of modern popular frameworks.
While developing my infinite game loop I found several articles and pieces of advice to implement it. Right now it looks like this:
self.gameLoop = function () {
self.dt = 0;
var now;
var lastTime = timestamp();
var fpsmeter = new FPSMeter({decimals: 0, graph: true, theme: 'dark', left: '5px'});
function frame () {
fpsmeter.tickStart();
now = window.performance.now();
// first variant - delta is increasing..
self.dt = self.dt + Math.min(1, (now-lastTime)/1000);
// second variant - delta is stable..
self.dt = (now - lastTime)/16;
self.dt = (self.dt > 10) ? 10 : self.dt;
self.clearRect();
self.createWeapons();
self.createTargets();
self.update('weapons');
self.render('weapons');
self.update('targets');
self.render('targets');
self.ticks++;
lastTime = now;
fpsmeter.tick();
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
};
So the problem is in self.dt I've eventually found out that first variant is not suitable for my game because it increases forever and the speed of weapons is increasing with it as well (e.g. this.position.x += (Math.cos(this.angle) * this.speed) * self.dt;..
Second variant looks more suitable, but does it correspond to this kind of loop (http://codeincomplete.com/posts/2013/12/4/javascript_game_foundations_the_game_loop/)?
Here' an implementation of an HTML5 rendering system using a fixed time step with a variable rendering time:
http://jsbin.com/ditad/10/edit?js,output
It's based on this article:
http://gameprogrammingpatterns.com/game-loop.html
Here is the game loop:
//Set the frame rate
var fps = 60,
//Get the start time
start = Date.now(),
//Set the frame duration in milliseconds
frameDuration = 1000 / fps,
//Initialize the lag offset
lag = 0;
//Start the game loop
gameLoop();
function gameLoop() {
requestAnimationFrame(gameLoop, canvas);
//Calcuate the time that has elapsed since the last frame
var current = Date.now(),
elapsed = current - start;
start = current;
//Add the elapsed time to the lag counter
lag += elapsed;
//Update the frame if the lag counter is greater than or
//equal to the frame duration
while (lag >= frameDuration){
//Update the logic
update();
//Reduce the lag counter by the frame duration
lag -= frameDuration;
}
//Calculate the lag offset and use it to render the sprites
var lagOffset = lag / frameDuration;
render(lagOffset);
}
The render function calls a render method on each sprite, with a reference to the lagOffset
function render(lagOffset) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
sprites.forEach(function(sprite){
ctx.save();
//Call the sprite's `render` method and feed it the
//canvas context and lagOffset
sprite.render(ctx, lagOffset);
ctx.restore();
});
}
Here's the sprite's render method that uses the lag offset to interpolate the sprite's render position on the canvas.
o.render = function(ctx, lagOffset) {
//Use the `lagOffset` and previous x/y positions to
//calculate the render positions
o.renderX = (o.x - o.oldX) * lagOffset + o.oldX;
o.renderY = (o.y - o.oldY) * lagOffset + o.oldY;
//Render the sprite
ctx.strokeStyle = o.strokeStyle;
ctx.lineWidth = o.lineWidth;
ctx.fillStyle = o.fillStyle;
ctx.translate(
o.renderX + (o.width / 2),
o.renderY + (o.height / 2)
);
ctx.beginPath();
ctx.rect(-o.width / 2, -o.height / 2, o.width, o.height);
ctx.stroke();
ctx.fill();
//Capture the sprite's current positions to use as
//the previous position on the next frame
o.oldX = o.x;
o.oldY = o.y;
};
The important part is this bit of code that uses the lagOffset and the difference in the sprite's rendered position between frames to figure out its new current canvas position:
o.renderX = (o.x - o.oldX) * lagOffset + o.oldX;
o.renderY = (o.y - o.oldY) * lagOffset + o.oldY;
Notice that the oldX and oldY values are being re-calculated each frame at the end of the method, so that they can be used in the next frame to help figure out the difference.
o.oldX = o.x;
o.oldY = o.y;
I'm actually not sure if this interpolation is completely correct or if this is best way to do it. If anyone out there reading this knows that it's wrong, please let us know :)
The modern version of requestAnimationFrame now sends in a timestamp that you can use to calculate elapsed time. When your desired time interval has elapsed you can do your update, create and render tasks.
Here's example code:
var lastTime;
var requiredElapsed = 1000 / 10; // desired interval is 10fps
requestAnimationFrame(loop);
function loop(now) {
requestAnimationFrame(loop);
if (!lastTime) { lastTime = now; }
var elapsed = now - lastTime;
if (elapsed > requiredElapsed) {
// do stuff
lastTime = now;
}
}
This isn't really an answer to your question, and without knowing more about the particular game I can't say for sure if it will help you, but do you really need to know dt (and FPS)?
In my limited forays into JS game development I've found that often you don't really need to to calculate any kind of dt as you can usually come up with a sensible default value based on your expected frame rate, and make anything time-based (such as weapon reloading) simply work based on the number of ticks (i.e. a bow might take 60 ticks to reload (~1 second # ~60FPS)).
I usually use window.setTimeout() rather than window.requestAnimationFrame(), which I've found generally provides a more stable frame rate which will allow you to define a sensible default to use in place of dt. On the down-side the game will be more of a resource hog and less performant on slower machines (or if the user has a lot of other things running), but depending on your use case those may not be real concerns.
Now this is purely anecdotal advice so you should take it with a pinch of salt, but it has served me pretty well in the past. It all depends on whether you mind the game running more slowly on older/less powerful machines, and how efficient your game loop is. If it's something simple that doesn't need to display real times you might be able to do away with dt completely.
At some point you will want to think about decoupling your physics from your rendering. Otherwise your players could have inconsistent physics. For example, someone with a beefy machine getting 300fps will have very sped up physics compared to someone chugging along at 30fps. This could manifest in the first player cruising around in a mario-like scrolling game at super speed and the other player crawling at half speed (if you did all your testing at 60fps). A way to fix that is to introduce delta time steps. The idea is that you find the time between each frame and use that as part of your physics calculations. It keeps the gameplay consistent regardless of frame rate. Here is a good article to get you started: http://gafferongames.com/game-physics/fix-your-timestep/
requestAnimationFrame will not fix this inconsistency, but it is still a good thing to use sometimes as it has battery saving advantages. Here is a source for more info http://www.chandlerprall.com/2012/06/requestanimationframe-is-not-your-logics-friend/
I did not check the logic of the math in your code .. however here what works for me:
GameBox = function()
{
this.lastFrameTime = Date.now();
this.currentFrameTime = Date.now();
this.timeElapsed = 0;
this.updateInterval = 2000; //in ms
}
GameBox.prototype.gameLoop = function()
{
window.requestAnimationFrame(this.gameLoop.bind(this));
this.lastFrameTime = this.currentFrameTime;
this.currentFrameTime = Date.now();
this.timeElapsed += this.currentFrameTime - this.lastFrameTime ;
if(this.timeElapsed >= this.updateInterval)
{
this.timeElapsed = 0;
this.update(); //modify data which is used to render
}
this.render();
}
This implementation is idenpendant from the CPU-speed(ticks). Hope you can make use of it!
A great solution to your game engine would be to think in objects and entities. You can think of everything in your world as objects and entities. Then you want to make a game object manager that will have a list of all your game objects. Then you want to make a common communication method in the engine so game objects can make event triggers. The entities in your game for example a player would not need to inherent from anything to get the ability to render to the screen or have collision detection. You would simple make common methods in the entity that the game engine is looking for. Then let the game engine handle the entity as it would like. Entities in your game can be created or destroyed at anytime in the game so you should not hard-code any entities at all in the game loop.
You will want other objects in your game engine to respond to event triggers that the engine has received. This can be done using methods in the entity that the game engine will check to see if the method is available and if it is would pass the events to the entity. Do not hard code any of your game logic into the engine it messes up portability and limits your ability to expand on the game later on.
The problem with your code is first your calling different objects render and updates not in the correct order. You need to call ALL your updates then call ALL your renders in that order. Another is your method of hard coding objects into the loop is going to give you a lot of problems, when you want one of the objects to no longer be in the game or if you want to add more objects into the game later on.
Your game objects will have an update() and a render() your game engine will look for that function in the object/entity and call it every frame. You can get very fancy and make the engine work in a way to check if the game object/entity has the functions prior to calling them. for example maybe you want an object that has an update() but never renders anything to the screen. You could make the game object functions optional by making the engine check prior to calling them. Its also good practice to have an init() function for all game objects. When the game engine starts up the scene and creates the objects it will start by calling the game objects init() when first creating the object then every frame calling update() that way you can have a function that you only run one time on creation and another that runs every frame.
delta time is not really needed as window.requestAnimationFrame(frame); will give you ~60fps. So if you're keeping track of the frame count you can tell how much time has passed. Different objects in your game can then, (based off of a set point in the game and what the frame count was) determine how long its been doing something based off its new frame count.
window.requestAnimationFrame = window.requestAnimationFrame || function(callback){window.setTimeout(callback,16)};
gameEngine = function () {
this.frameCount=0;
self=this;
this.update = function(){
//loop over your objects and run each objects update function
}
this.render = function(){
//loop over your objects and run each objects render function
}
this.frame = function() {
self.update();
self.render();
self.frameCount++;
window.requestAnimationFrame(frame);
}
this.frame();
};
I have created a full game engine located at https://github.com/Patrick-W-McMahon/Jinx-Engine/ if you review the code at https://github.com/Patrick-W-McMahon/Jinx-Engine/blob/master/JinxEngine.js you will see a fully functional game engine built 100% in javascript. It includes event handlers and permits action calls between objects that are passed into the engine using the event call stack. check out some of the examples https://github.com/Patrick-W-McMahon/Jinx-Engine/tree/master/examples where you will see how it works. The engine can run around 100,000 objects all being rendered and executed per frame at a rate of 60fps. This was tested on a core i5. different hardware may vary. mouse and keyboard events are built into the engine. objects passed into the engine just need to listen for the event passed by the engine. Scene management and multi scene support is currently being built in for more complex games. The engine also supports high pixel density screens.
Reviewing my source code should get you on the track for building a more fully functional game engine.
I would also like to point out that you should have requestAnimationFrame() called when you're ready to repaint and not prior (aka at the end of the game loop). One good example why you should not call requestAnimationFrame() at the beginning of the loop is if you're using a canvas buffer. If you call requestAnimationFrame() at the beginning, then begin to draw to the canvas buffer you can end up having it draw half of the new frame with the other half being the old frame. This will happen on every frame depending on the time it takes to finish the buffer in relation to the repaint cycle (60fps). But at the same time you would end up overlapping each frame so the buffer will get more messed up as it loops over its self. This is why you should only call requestAnimationFrame() when the buffer is fully ready to draw to the canvas. by having the requestAnimationFrame() at the end you can have it skip a repaint if the buffer is not ready to draw and so every repaint is drawn as it is expected. The position of requestAnimationFrame() in the game loop has a big difference.

Cheat for hidden game "Atari Breakout" in Google Image Search

How would a cheat/auto moving paddle in this hidden html game look like?
There is a
<div id="breakout-ball"><span>●</span></div>
and a
<div id="breakout-paddle"></div>
when moving the mouse the paddle is moved horizontally. How can I connect the movement of the ball with the paddle?
This question will become "community wiki" as soon as possible.
function cheat() {
var ball = document.getElementById('breakout-ball');
var paddle = document.getElementById('breakout-paddle');
paddle.style.left = ball.style.left;
setTimeout(cheat, 20);
}
cheat();
// Add this via the FireBug console.
I modified your solution slightly to account for the scenario of the ball going off screen and breaking the hack and also the ball getting jammed into the corner.
function cheat() {
var ball = document.getElementById('breakout-ball');
var paddle = document.getElementById('breakout-paddle');
var buffer = Math.floor((Math.random()*100)+1);
var leftVal = parseInt(ball.style.left, 10);
if (ball.style.left) {
paddle.style.left = (leftVal - buffer) + 'px';
}
setTimeout(cheat, 100);
}
cheat();
To be honest though, if you are going down that road why not do this?
function cheat() {
var paddle = document.getElementById('breakout-paddle');
paddle.style.width = '100%';
}
cheat();
Anyway I'm going to continue to dig into the code and do some deeper manipulation
in chrome, search the game, ctrl+J, paste the following in, and press enter.
This is a simple goal:
//get the ball's X position from its CSS
function ballx(){
return parseFloat(document.querySelector("#breakout-ball").style.left.split("px")[0]);
}
function update(e){
//throws an exception when the game isn't up. Can be really annoying.
try{document.querySelector("#breakout-paddle").style.left = (ballx() - 75)+"px";}
catch(ex){}
}
var intervalTimer = setInterval(update, 125);//let it have a single weakness in case someone else tries it while I am around.
The lower the interval rate, the faster the paddle will move relative to the ball, but the slower the game goes. The maximum rate can be given with a simple requestAnimationFrame cycle, but that slows the browser down a lot(at least on my laptop).
I tried changing the paddle's size. It doesn't really work.
I'm sure it would be simpler with jQuery, but why make cheating easy when doing it hard core is already so easy?
I have come up with a new way to solve this problem. Whenever the screen size or window size changes, the paddle changes size based on the screen size. To combat this, I simply just added another section that splits the size of the paddle in half then uses that value to find the centre of the paddle. Very simple and very effective.
function autoMove() {
var ball = document.getElementById('breakout-ball')
var paddle = document.getElementById('breakout-paddle')
var leftVal = parseInt(ball.style.left, 10)
var paddleWidth = parseFloat(paddle.style.width, 10) / 2
paddle.style.left = (leftVal - paddleWidth) + 'px'
setTimeout(autoMove, 20)
}
autoMove();
Also, didn't like the function name. It looks way too suspicious so changed it. Hope this helps.

Attempting to get two simultaneous joysticks working with touch events

I've been battling with this for two days. I'm using an HTML5/JS game engine called ImpactJS and someone made a very useful plugin to create joystick touch zones for mobile devices. The idea is that you specify a zone on the screen where the joystick is activated when that area is touched.
The code for the plugin I am using is here. I have modified it slightly to add "curPos" (x and y coordinates of the spot that the user is currently touching), otherwise all code is identical. I have been trying to solve this problem myself as well as contacting the original creator, but they seem to be unreachable at this time and I'm getting nowhere.
I'm sure I'm doing something very wrong here, but while I can get the touch zones to work perfectly on their own, every time I try to use both joysticks at the same time they partially overwrite each other.
I have specified two zones as follows when my game initializes:
this.joystick1 = new TouchJoystickZone(0, 0, ig.system.width / 2, ig.system.height);
this.joystick2 = new TouchJoystickZone(ig.system.width / 2, 0, ig.system.width / 2, ig.system.height);
this.joystick1 is responsible for player rotation. this.joystick2 is responsible for player acceleration. In my Player entity I have the following movement code for the two joysticks. Again, this works perfectly when I only have one finger on the screen/one joystick in use:
if( ig.ua.mobile ) {
// ROTATION
if (ig.game.joystick1.touchStart.x > 0 && ig.game.joystick1.touchStart.x < ig.system.width/2) {
if (Math.abs(ig.game.joystick1.delta.x) >= 50 || Math.abs(ig.game.joystick1.delta.y) >= 50) {
this.joystickAngle = ig.game.Controller.toDegrees(ig.game.Controller.joystickAngle());
if (this.angle > this.joystickAngle + 20) {
this.angle -= this.turnSpeed * ig.system.tick;
}
else if (this.angle < this.joystickAngle - 20) {
this.angle += this.turnSpeed * ig.system.tick;
}
else {
this.angle = this.joystickAngle;
}
}
}
// THRUST
if (ig.game.joystick2.touchStart.x > ig.system.width / 2) {
if (ig.game.joystick2.delta.y <= -50) {
this.accel.x = Math.cos(this.angle*Math.PI/180)*this.thrust;
this.accel.y = (Math.sin(this.angle*Math.PI/180)*this.thrust);
this.fuel -= 0.1;
}
else if (ig.game.joystick2.delta.y >= 50) {
this.accel.x = Math.cos(this.angle*Math.PI/180)*-this.thrust;
this.accel.y = (Math.sin(this.angle*Math.PI/180)*-this.thrust);
this.fuel -= 0.1;
}
}
else {
this.accel.x = 0;
this.accel.y = 0;
}
}
As soon as I place a second finger on the screen, however, the first joystick becomes overwritten. I can rotate and then move or move and then rotate and it works fine, but I need to do both at the same time.
I found out that touchStart.x and touchStart.y seems to be being set for both joysticks when I tap to use the other stick and not just the relevant joystick1 or joystick2, even though in the plugin code those coordinates are only meant to be affected if the touch for that joystick is within the specified zone. I believe this is partly what is contributing to the issue. At this stage I've spent hours trying to figure this out and am just as lost as when I started.
Can someone possibly point me in the right direction with using both of these joysticks at the same time?
The joystick script you are using is only looking for the first finger. The following is from lines 47-48
var x = ev.touches[0].pageX - pos.left,
y = ev.touches[0].pageY - pos.top;
The '0' determines which finger to track.
The script would have the be changed to be aware which finger is on which element and then only track that finger. You could do that by either determining which element was pressed first or by location.
JSFiddle Example: http://jsfiddle.net/7WR88/5/
http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/
As mentioned by #Dcullen, there may be multiple touches in each event starting at the first touch.
It would be a simple solution to iterate through the ev.touches collection and see if each touch falls into a hotzone. If it falls under hot zone 1, treat it as a touch for joystick 1. If it falls under hotzone 2, treat it as a touch for joystick 2.
This would mean that it doesn't matter in which order the touches appear, because they will always map to the correct joystick if they are near to it.

Game programming: remove movement lag (jumping)

I'm developing an HTML5 3D fps-like engine that already looks quite nice, but as this might be one of the worst language choices to make 3D there's noticeable lag sometimes.
I programmed movements (WASD) to be independent of rendering speed, so sometimes it's quite jerky, but other times is working at an acceptable 30+ fps (depending on CPU of course).
The only thing I can't wrap my mind around is jumping: currently the jumping is done by adding a positive constant to the falling variable (gravity is always negative and then corrected by collision detection) and then subtracting a constant, this is called every time a new frame is rendered, the thing is that when fps go low I feel like I'm on the moon. I prefer jerkiness to slow-mo effect.
If I use the same method like I do for moving (calculate time between current and last frame) the deducted variable gets too big sometimes and the jumping apex changes (to half of the value compared to high fps) - this is unacceptable as jumping height must be always the same.
Here's some pseudo-code to help understanding the problem (called during one rendering routine):
// when clicked on spacebar:
if(spacebar)
{
// this defines jumping apex
jump = 0.5
}
// constant added to y (vertical position) later in the code
cy += jump;
// terminal velocity = -2
if(jump > -2)
{
// gravity (apex multiple to get maximum height)
jump -= 0.05;
}
if(collision_with_floor)
{
// stop falling
cy = 0;
if(jump < 0)
{
jump = 0;
}
}
player.position.y += cy;
Now with time dependent jumping (replace in the code above):
// terminal velocity = -2
if(jump > -2)
{
// gravity, 0.4 is an arbitrary constant
jump -= (now - last_frame)*0.4;
last_frame = now;
}
To illustrate even better here's an image of what's going on:
Blue dots indicate frame renders.
I'm not even sure of this is the right way to program jumping routine. Basically jerkiness and constant jumping height is better than smoothness and slow-mo effect.
If the frame updates are coming too slowly to get accurate physics, then maybe you can hack in the jump apex so that the player always hits it. The cue here might be when the y velocity changes from positive to negative. If I'm reading your pseudocode right, then it looks like:
old_cy = cy;
cy += jump;
if(old_cy > 0 && cy <= 0)
player.position.y = jump_apex_height;
In terms of your graph, the idea is that you want to identify the blue dot that reaches the orange line, then bump it up to the dotted line.
And now that I'm thinking about it, if the player really has to reach the jump apex every time, then this might help even for high-rate updates.

Categories