My explanation may be unclear and if so, please leave a comment for further clarification.
I am trying to make the character to jump to the height of the screen.
So far, this is my code:
var limit = 0;
function jump()
{
ball.posy -=10;
limit++;
if(limit>screenheight)
{
//if character reached top of screen stop this jump() function
isjump = false;
limit = 0;
}
}
Above code will enable the character to jump up to the screen height. But if the screen height is smaller (for example, in some mobile device), character jump will be faster.
If there are any game developers who have idea, would you be able to guide me? :) Thank you.
ok the problem is that you need to know the speed of your jump first. now its is doing it depending of your screen for example:
function jump()
myjump += 10 // this is what you are doing now
{
so lets fix that function, how?
lets make that 10 variable depending on the screen height
lets say your screen now is 800px heigh so for a 800px height screen you will add 10px, but for a 400 heigth screen you only need to add 5px!!.
so how we do it?
with this simple formula
var scaleJump = 10 * (screenHeigth/800)
function jump()
myjump += scaleJump
{
so now if your screen heigth is 800 your var scaleJump will be = 10 * ( 800 / 800 ) = 10
and if your screen heigth is 400 scaleJump will be = 10 * ( 400 / 800 ) = 5
so problem solved!! it will increase 5 if screen is 400 and 10 if screen is 800, and scale as needed if anyonther heigth
to fix time
ok how do we know the time it takes to draw a frame?
since: fps = frames / second
so: 1/fps = seconds / frame
this is a differential equation where you have a deltaTime and a deltaDistance
DeltaTime is equals to:
1/fps
and DeltaDistance would be this, if fps were always the same, but like they are not I explain below:
10 * (screenHeigth/800)
now lets set a base speed wich you can change acording to your needs as I dont have your code I am not sure if this will move fast or slow, but you can test it and change it as you need it.
lets set speed to 1 (I dont know if it is fast or slow, just change it latter)
since speed = DeltaDistance / DeltaTime
so lets get the distance you have to add so the speed is the same:
DeltaDistance = Speed * DeltaTime
now your code will look like this
var DeltaDistance;
var DeltaTime = (1 / fps)
var mySpeed = 1
function jump()
DeltaDistance = mySpeed * DeltaTime
myJump += DeltaDistance
{
I miss college :(
Related
Is there a reliable equation to work out pixel size to MM? Or is that not possible cross device?
We are working with a bespoke system that delivers content to many devices with different screen sizes, it can detect the screen width in MM, but we would like to accurately convert this to pixel size to deliver correctly sized images dynamically using a simple jquery script!?
Any ideas?
Cheers
Paul
What i did :
<div id="my_mm" style="height:100mm;display:none"></div>
Then:
var pxTomm = function(px){
return Math.floor(px/($('#my_mm').height()/100)); //JQuery returns sizes in PX
};
tl;dr: If you don't know the DPI of the device, you won't be able to deduce how big the pixel is in the real-world.
Pixels on their own are not real-world units of measurement.
They can become a real-world measurement if you take into account the DPI value of the device that displays them.
The formula is:
mm = ( pixels * 25.4 ) / DPI
So 8 pixels viewed on a 96-DPI screen setting:
( 8 * 25.4 ) / 96 = 2.116mm
All this assuming the device is not scaled/zoomed.
old post but I stumbled upon this today and had to make it work.
the trick is to create an element with dimensions styled in inches and request its width, this will give you the px per inch.
function inch2px(inches) {
$("body").append("<div id='inch2px' style='width:1in;height:1in;display:hidden;'></div>");
var pixels = $("#inch2px").width();
$("#inch2px").remove();
return inches * pixels;
}
function px2inch(px) {
$("body").append("<div id='inch2px' style='width:1in;height:1in;display:hidden;'></div>");
var pixels = $("#inch2px").width();
$("#inch2px").remove();
return px / pixels;
}
now if you need millimetres, just do px2inch(10)*25.4.
You would need to know the DPI of the device and if the display is scaled or not. That would mean that you would have to have a database of the physical screen dimensions and screen resolutions of each device.
No need for jQuery.
function xToPx(x) {
var div = document.createElement('div');
div.style.display = 'block';
div.style.height = x;
document.body.appendChild(div);
var px = parseFloat(window.getComputedStyle(div, null).height);
div.parentNode.removeChild(div);
return px;
}
pixels = xToPx('10cm'); // convert 10cm to pixels
pixels = xToPx('10mm'); // convert 10mm to pixels
Please notice that values in pixels are depending on what resolution the browser of the device tells you. Some browsers (on some phones) lie about this and tell you something different than the actual screen resolution in an attempt to be compatible with older sites. Main important thing is to never port conversion values from one device to another but always use real-time calculations. Even on a desktop the user can change the screen resolution.
To learn more about the units, check out this (short) article on W3:
https://www.w3.org/Style/Examples/007/units.en.html
i use this simple function
function pix2mm(val,dpi){
return (val/0.0393701)/dpi;
}
test outputs it 300,600,900 DPI
var r = pix2mm(100,300); // converting 100 pixels it 300 DPI
console.log(r); // output : 8.4 mm
var r1 = pix2mm(100,600); // converting 100 pixels it 600 DPI
console.log(r1); // output : 4.2 mm
var r2 = pix2mm(100,900); // converting 100 pixels it 900 DPI
console.log(r2); // output : 2.8 mm
DEMO : https://jsfiddle.net/xpvt214o/29044/
You cannot reliably calculate this since there is no way to detect physical screen size.
Based on the #Dawa answer above, this is my solution:
var mmToPx = function(mm) {
var div = document.createElement('div');
div.style.display = 'block';
div.style.height = '100mm';
document.body.appendChild(div);
var convert = div.offsetHeight * mm / 100;
div.parentNode.removeChild(div);
return convert;
};
Just note that the 100mm height, will give you a better precision factor.
The calculation will be instant and the div will not be visible. No need for jQuery
Late but may be useful.
1 px = 0.26458333333719 mm
Milli Meter Pixel
1 mm = 3.779527559 px
So if you have lets say 10px. It will be equal to 10 * 0.26458.. = 2.64mm
ref : https://everythingfonts.com/font/tools/units/px-to-mm
Enjoy :)
I am having trouble converting pixels to metres on my game
how many pixels is a meter in Box2D?
Is an example of my problem, but does not solve it.
This is because this solution, while it works, will not go cross browser, that is, if the conversion rate is something constant like 50px to one meter, than on a device with 400x800 resolution, the objects will appear big, whereas on another device with 4000x8000 resolution (exagurated) the objects will be tiny.
I can understand some solutions to this, but the main reason why I am finding this so hard to implement is because one browser or phone might be 16:9 ratio, whereas another might be 14:7, and these differing ratio's are the kicker, since my entire game is held on the screen as it is not a scrolling game, it is just a simple physics game.
Because of this I understand that It is easier to have to world be a smaller size, and convert it back up when rendering, but these problems that I have mentioned have stumped me, and I was wandering if anyone had any feasible solutions.
Since your
entire game is held on the screen
I suggest you the following:
Decide how many "meters" you need your window width to be. Say you've decided:
any window width (W) is always N "meters"
Then k = W/N where k is a scaling multiplier meaning a part of window width within 1 "meter".
So if W = 400px and N = 100m you have k = 400px/100m = 4px/m.
And when other screen is W = 4000px you have k = 40px/m.
That way you can translate your "meters" to pixels by multiplying your dimensions in "meters" by k and your objects will be always scaled to the screen size.
In JavaScript it looks like:
var N = 100; // window width in "meters"
var k = window.innerWidth / N; // px in 1m
// let's count something simple
var U = 10; // speed in meters per second
var t = 10; // time in seconds
var S = U * t; // distance in meters
var S_px = S * k; // distance in pixels (scaled to the window width)
Using this code:
x = x + (canvas.height/250);
which happens every 1 millisecond should add an amount to x in proportion to the canvas size. x is then drawn so therefore x should move down the canvas at the same speed on different screen sizes (the canvas changes size according to the screen size). However the x moves down at different speeds on my ipod and my pc.
If you want to know the full source code and html file the html is here and the javascript file linked to it is here.
First, let's think about what this line does:
x += canvas.height / 250;
The speed of the object is canvas.height / 250. The distance is canvas.height. We can say that:
distance = speed * time
We already have distance and speed, so:
time = distance / speed = canvas.height / (canvas.height / 250) = 250 ms
So the object always reaches its destination in 2.5 seconds. In order to make that happen, you change the speed based on the screen size.
If you want the speed to be the same in all devices, it shouldn't depend on canvas.height.
The change in traversal time is due to a change in draw time.
If the device is, say, two times slower to draw, the increase
will get done two times less per second, and your object will be
in mid-screen in the slow device when it will have crossed screen in
the other.
To have consistent behavior you must handle your game time.
Then you just have to decide of your objects speed in pixels per milliseconds,
and use the classical equation :
pos = pos + speed * (time step)
the code looks like :
var x = 0;
var speed = canvas.width / 1000 ; // speed in pixels per milliseconds.
var lastTime = 0;
requestAnimationFrame(launchAnimate);
function animate() {
requestAnimationFrame(animate);
var now = Date.now();
var dt = now - lastTime ;
lastTime = now ;
// draw everything
draw();
// update everything with this frame time step.
update(dt);
}
function launchAnimate() {
lastTime = Date.now() ;
requestAnimationFrame(animate);
}
Edit : you can't draw faster than your screen, so on a 60Hz screen, you'll draw at best every 16.666 ms.
Don't be scared by RequestAnimationFrame, it just means : "when the screen is ready, draw the callback that i gave you.".
So you have to re-arm it every time to make your game live.
So for your game, it's time to organize a bit :
have an update function where you put all the code that updates all things.
have a draw function that draws everything.
do not draw in the update (remove the draw calls in moveTrees), and
do not update in the draw. SEPARATION OF CONCERNS, :-)
have each update depend on frame time (dt) for all that's related to time (position, speed, acceleration, forces).
function update( dt ) {
x = x + speed * dt ;
moveTrees(dt);
}
function draw () {
drawTrees();
drawHangGlider();
drawTrees();
}
You'll notice i changed the animate function to call draw and update, still you have a bit of work to re-organize things.
Edit 2 : RequestAnimationFrame is widely ok now :
http://caniuse.com/requestanimationframe
(Chrome for Android is ok).
Rq :
// to use rAF, call this function before your game launches
polyFillRAFNow();
// insert the function in your code.
function polyFillRAFNow() {
// requestAnimationFrame polyfill
var w = window;
var foundRequestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame || w.oRequestAnimationFrame || function (cb) { setTimeout(cb, 1000 / 60); };
window.requestAnimationFrame = foundRequestAnimationFrame;
}
Rq2 : you might be interested in this article i wrote on the game loop http://gamealchemist.wordpress.com/2013/03/16/thoughts-on-the-javascript-game-loop/
So basically you want a relative absolute speed depending on the screen size, which would then appear to be the same on different displays. In order to do this you should use percentages, for example:
var pixels_in_1_percent = canvas.height/100;
x += pixels_in_1_percent
That will increase the speed by 1% of canvas height, if you want more speed then you have to multiply it
x += pixels_in_1_percent * <number_of_percent_to_increase>
Hope that helps.
You said in your question that you are calling the function every 1 millisecond. However, some browsers limit the speed of window.setInterval so if you made the function call once every 50 milliseconds it would be the same on all devices.
window.setInterval(function(){
/// call your function here e.g. add1toxfunction();
}, 50);
I'm currently working on a game, with scrollable screen and I need to find a simple algorithm for placing obstacles in the game. I have a gameSpeed, that is increased in time (from 1 to 12, increased by 0.005 each 1/60s) and a range of available positions between 200 and 600 (ints). I'd like to achieve a bigger probability of receiving smaller number when the speed is bigger, but it's my 14th hour straight coding and I cannot come up with anything usable and not overcomplicated. I'd like to minimize Math and random functions so that the rendering loop won't take too long. Any help appreciated !
You could square or square-root the random number to shift the density in one direction. Math.random()*Math.random() will have a higher probability to produce smaller numbers (near 0) than higher ones (near 1).
Your formula could be like
var position = Math.pow(Math.random(), gameSpeed / 3) * 400 + 200;
The simplest answer I can think of is to create an array having more lower numbers compared to higher ones, for example, for producing random between [1,5] (both inclusive). So your array may look like [1,1,1,1,1,2,2,2,2,3,3,3,4,4,5]
And when you randomly pick an element from that array you will have a higher chance of picking up low number compared to high one.
Another way might be to have two (or more) percentages:
say, start with 10% of the time we access 90% of the range, and 90% of the time we access the other 10%. Then we gradually flip those numbers as the speed increases. For example,
var lBound = 200,
uBound = 600,
range = uBound - lBound,
gameSpeed = 1,
initialMarker = 0.1,
percentageRange = 1 - 2 * initialMarker,
marker = (gameSpeed - 1) / 11 * percentageRange + initialMarker,
position
Math.random() <= marker ? position = Math.floor(Math.random() * (1 - marker) * range) + lBound
: position = uBound - Math.floor(Math.random() * marker * range)
console.log(position)
Try changing gameSpeed and see what happens. Change initialMarker for a different set of percentages (currently set at 0.1, which means 10% / 90%).
I'm building an image preload animation, that is a circle/pie that gets drawn. Each 'slice' is totalImages / imagesLoaded. So if there are four images and 2 have loaded, it should draw to 180 over time.
I'm using requestAnimFrame, which is working great, and I've got a deltaTime setup to restrict animation to time, however I'm having trouble getting my head around the maths. The closest I can get is that it animates and eases to near where it's supposed to be, but then the value increments become smaller and smaller. Essentially it will never reach the completed value. (90 degrees, if one image has loaded, as an example).
var totalImages = 4;
var imagesLoaded = 1;
var currentArc = 0;
function drawPie(){
var newArc = 360 / totalImages * this.imagesLoaded // Get the value in degrees that we should animate to
var percentage = (isNaN(currentArc / newArc) || !isFinite(currentArc / newArc)) || (currentArc / newArc) > 1 ? 1 : (currentArc / newArc); // Dividing these two numbers sometimes returned NaN or Infinity/-Infinity, so this is a fallback
var easeValue = easeInOutExpo(percentage, 0, newArc, 1);
//This animates continuously (Obviously), because it's just constantly adding to itself:
currentArc += easedValue * this.time.delta;
OR
//This never reaches the full amount, as increments get infinitely smaller
currentArc += (newArc - easedValue) * this.time.delta;
}
function easeInOutExpo(t, b, c, d){
return c*((t=t/d-1)*t*t + 1) + b;
}
I feel like I've got all the right elements and values. I'm just putting them together incorrectly.
Any and all help appreciated.
You've got the idea of easing. The reality is that at some point you cap the value.
If you're up for a little learning, you can brush up on Zeno's paradoxes (the appropriate one here being Achilles and the Tortoise) -- it's really short... The Dichotomy Paradox is the other side of the same coin.
Basically, you're only ever half-way there, regardless of where "here" or "there" may be, and thus you can never take a "final"-step.
And when dealing with fractions, such as with easing, that's very true. You can always get smaller.
So the solution is just to clamp it. Set a minimum amount that you can move in an update (2px or 1px, or 0.5px... or play around).
The alternative (which ends up being similar, but perhaps a bit jumpier), is to set a threshold distance. To say "As soon as it's within 4px of home, snap to the end", or switch to a linear model, rather than continuing the easing.