I would like to have nice preloader with percentage before game on, but nothing such appearing in spite of I am procceeding according to the Examples docs and api docs. It is simple HTML5 game based on phaser framework JS library. This is my code. What might be wrong? I am not digging in phaser library I have no time to repair broken libs all the time. I am just awaiting the things working out of the box somehow:
<html>
<head>
<meta charset="UTF-8">
<title>0002game</title>
<script src="phaser.min.js"></script>
<script>
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
var platforms;
var player;
var cursors;
var tehla1;
var tehla2;
var tehla3;
var tehla4;
var tehla5;
var poc=0;
var text=null;
var style=null;
var delta = 25;
var postext = 150;
var rychlost=1;
var text2;
var trafil1=false;var trafil2=false;var trafil3=false;var trafil4=false;var trafil5=false;
function preload() {
game.load.image('sky', 'assets/sky2.png');
game.load.image('wheelbarrow', 'assets/jet.png');
game.load.image('brick', 'assets/meteor.png');
game.load.image('ground', 'assets/ground.png');
game.load.audio('boden', ['assets/sound.wav']);
}
function loadStart() {
text2.setText("Loading...");
}
function loadComplete() {
text2.setText("Loading Completed.");
}
function fileComplete(progress, cacheKey, success, totalLoaded, totalFiles) {
text2.setText("File Complete: " + progress + "% - " + totalLoaded + " out of " + totalFiles);
}
function create() {
text2 = game.add.text(32, 32, 'Loading...', { fill: '#ffffff' });
music = game.add.audio('boden');
//music.play();
sounds = [music];
game.sound.setDecodedCallback(sounds, start, this);
game.world.setBounds(0, 0, 800, 600);
cursors = game.input.keyboard.createCursorKeys();
// We're going to be using physics, so enable the Arcade Physics system
game.physics.startSystem(Phaser.Physics.ARCADE);
// A simple background for our game
game.add.sprite(0, 0, 'sky');
//var tehla = game.add.sprite(3, 3, 'brick');
tehla1 = game.add.sprite((Math.random() * 800), 0.2*game.world.randomY, 'brick');
tehla2 = game.add.sprite((Math.random() * 800), 0.2*game.world.randomY, 'brick');
tehla3 = game.add.sprite((Math.random() * 800), 0.2*game.world.randomY, 'brick');
tehla4 = game.add.sprite((Math.random() * 800), 0.2*game.world.randomY, 'brick');
tehla5 = game.add.sprite((Math.random() * 800), 0.2*game.world.randomY, 'brick');
//game.add.sprite(0, 0, 'wheelbarrow');
// The platforms group contains the ground and the 2 ledges we can jump on
platforms = game.add.group();
// We will enable physics for any object that is created in this group
platforms.enableBody = true;
// Here we create the ground.
var ground = platforms.create(0, game.world.height - 64, 'ground');
// Scale it to fit the width of the game (the original sprite is 400x32 in size)
//ground.scale.setTo(2, 2);
// This stops it from falling away when you jump on it
ground.body.immovable = true;
// Now let's create two ledges
//var ledge = platforms.create(400, 400, 'ground');
//ledge.body.immovable = true;
//ledge = platforms.create(-150, 250, 'ground');
//ledge.body.immovable = true;
player = game.add.sprite(32, game.world.height - 120, 'wheelbarrow');
//player.body.bounce.y = 0.2;
//player.body.gravity.y = 300;
//player.body.collideWorldBounds = true;
style = { font: "25px Arial", fill: "#00ffff", align: "center" };
text = game.add.text(125, 25, "Lod zasiahli: ", style);
text.anchor.set(0.5);
game.load.onLoadStart.add(loadStart, this);
game.load.onFileComplete.add(fileComplete, this);
game.load.onLoadComplete.add(loadComplete, this);
}
function start() {
music.loopFull(1.0);
}
function cikoniec(){
if(poc==5){
alert('Uz ta zasiahlo 5 nepriatelov. Spustam hru znova!');
location.reload();
}
}
function update() {
//if(tehla1.y<game.height) game.add.tween(tehla1).to({ y: game.height*1.1 }, 1000, Phaser.Easing.Linear.None, true);
if(tehla1.y<game.height) tehla1.y+=rychlost;
if(tehla1.y>=game.height) {tehla1.y=game.rnd.integerInRange(20, 200);tehla1.x=game.rnd.integerInRange(20, 500);}
if(Math.abs(tehla1.y-player.y)<delta && Math.abs(tehla1.x-player.x)<delta && trafil1==false ){
poc=poc+1;
postext+=50;
tehla1.destroy();
text = game.add.text(postext, 35, "1", style);
trafil1 = true;
}
//if(tehla2.y<game.height) game.add.tween(tehla2).to({ y: game.height*1.1 }, 1000, Phaser.Easing.Linear.None, true);
if(tehla2.y<game.height) tehla2.y+=rychlost;
if(tehla2.y>=game.height) {tehla2.y=game.rnd.integerInRange(20, 200);tehla2.x=game.rnd.integerInRange(20, 500);}
if(Math.abs(tehla2.y-player.y)<delta && Math.abs(tehla2.x-player.x)<delta && trafil2==false ){
poc=poc+1;
postext+=50;
tehla2.destroy();
text = game.add.text(postext, 35, "2", style);
trafil2 = true;
}
//if(tehla3.y<game.height) game.add.tween(tehla3).to({ y: game.height*1.1 }, 1000, Phaser.Easing.Linear.None, true);
if(tehla3.y<game.height) tehla3.y+=rychlost;
if(tehla3.y>=game.height) {tehla3.y=game.rnd.integerInRange(20, 200);tehla3.x=game.rnd.integerInRange(20, 500);}
if(Math.abs(tehla3.y-player.y)<delta && Math.abs(tehla3.x-player.x)<delta && trafil3==false ){
poc=poc+1;
postext+=50;
tehla3.destroy();
text = game.add.text(postext, 35, "3", style);
trafil3 = true;
}
//if(tehla4.y<game.height) game.add.tween(tehla4).to({ y: game.height*1.1 }, 1000, Phaser.Easing.Linear.None, true);
if(tehla4.y<game.height) tehla4.y+=rychlost;
if(tehla4.y>=game.height) {tehla4.y=game.rnd.integerInRange(20, 200);tehla4.x=game.rnd.integerInRange(20, 500);}
if(Math.abs(tehla4.y-player.y)<delta && Math.abs(tehla4.x-player.x)<delta && trafil4==false ){
poc=poc+1;
postext+=50;
tehla4.destroy();
text = game.add.text(postext, 35, "4", style);
trafil4 = true;
}
//if(tehla5.y<game.height) game.add.tween(tehla5).to({ y: game.height*1.1 }, 1000, Phaser.Easing.Linear.None, true);
if(tehla5.y<game.height) tehla5.y+=rychlost;
if(tehla5.y>=game.height) {tehla5.y=game.rnd.integerInRange(20, 200);tehla5.x=game.rnd.integerInRange(20, 500);}
if(Math.abs(tehla5.y-player.y)<delta && Math.abs(tehla5.x-player.x)<delta && trafil5==false ){
poc=poc+1;
postext+=50;
tehla4.destroy();
text = game.add.text(postext, 35, "5", style);
trafil5 = true;
}
if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
if(player.x>0) player.x -= 15;
cikoniec();
}
else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
if(player.x<660) player.x += 15;
cikoniec();
}
game.physics.arcade.collide(player, platforms);
}
function render() {
game.debug.text('Hold left/right to move the player.');
}
</script>
</head>
<body>
<noscript>Sorry, your browser does not support JavaScript!</noscript>
</body>
</html>
Your best bet is to actually refactor this so that you have a more than one State in your game. Typically game templates will include a Boot and
some sort of Preload (or Preloader) state, as well as a menu (if needed) and the main game. Bold text should help with your search.
If you want to keep going down this path you can make a couple minor tweaks to your code. It will work, but it's not ideal. Again, take a look at States.
If you look at your code you'll notice that the functionality to actually hook up the loading text updates is at the bottom of your create. At this point the Phaser loader has already loaded the images.
If you look at the Load events example you'll see something kind of similar to what you have, but you'll notice that they're manually calling game.load.start().
Since you want the loading to start immediately, you need to get the load event binding done sooner.
Technically you can create whatever you want in the preload, but Phaser doesn't guarantee that you'll have any assets you're loading in. But this doesn't matter for a simple Phaser.Text object.
function preload() {
text2 = game.add.text(32, 32, 'Loading...', { fill: '#ffffff' });
game.load.onLoadStart.add(loadStart, this);
game.load.onFileComplete.add(fileComplete, this);
game.load.onLoadComplete.add(loadComplete, this);
game.load.image('sky', 'assets/sky2.png');
game.load.image('wheelbarrow', 'assets/jet.png');
game.load.image('brick', 'assets/meteor.png');
game.load.image('ground', 'assets/ground.png');
game.load.audio('boden', ['assets/sound.wav']);
}
So basically we add the text object and then hook into the loader, before loading the assets.
In your create function you can remove those four lines we added to preload.
You'll want to tweak it further, but again, I'd highly recommend looking at Phaser's State functionality. :) The first volume of Interphase has a pretty good overview of the functionality as well.
Solved, I did it this way:
<html>
<head>
<meta charset="UTF-8">
<title>0001game</title>
<style>
/* This only works with JavaScript,
if it's not present, don't show loader */
.no-js #loader { display: none; }
.js #loader { display: block; position: absolute; left: 100px; top: 0; }
</style>
<script src="jquery-1.5.2.min.js"></script>
<script src="modernizr.min.js"></script>
<script src="phaser.min.js"></script>
<script>
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
var platforms;
var player;
var cursors;
var tehla1;
var tehla2;
var tehla3;
var tehla4;
var tehla5;
var poc=0;
var text=null;
var style=null;
var delta = 25;
var postext = 150;
var rychlost=1;
var text2;
var trafil1=false;var trafil2=false;var trafil3=false;var trafil4=false;var trafil5=false;
function preload() {
game.load.image('sky', 'assets/sky.png');
game.load.image('wheelbarrow', 'assets/wheelbarrow.png');
game.load.image('brick', 'assets/brick.png');
game.load.image('ground', 'assets/ground.png');
game.load.audio('boden', ['assets/sound.wav']);
}
function create() {
text2 = game.add.text(32, 32, 'Loading...', { fill: '#ffffff' });
music = game.add.audio('boden');
//music.play();
sounds = [music];
game.sound.setDecodedCallback(sounds, start, this);
game.world.setBounds(0, 0, 800, 600);
cursors = game.input.keyboard.createCursorKeys();
// We're going to be using physics, so enable the Arcade Physics system
game.physics.startSystem(Phaser.Physics.ARCADE);
// A simple background for our game
game.add.sprite(0, 0, 'sky');
//var tehla = game.add.sprite(3, 3, 'brick');
tehla1 = game.add.sprite((Math.random() * 800), 0.2*game.world.randomY, 'brick');
tehla2 = game.add.sprite((Math.random() * 800), 0.2*game.world.randomY, 'brick');
tehla3 = game.add.sprite((Math.random() * 800), 0.2*game.world.randomY, 'brick');
tehla4 = game.add.sprite((Math.random() * 800), 0.2*game.world.randomY, 'brick');
tehla5 = game.add.sprite((Math.random() * 800), 0.2*game.world.randomY, 'brick');
//game.add.sprite(0, 0, 'wheelbarrow');
// The platforms group contains the ground and the 2 ledges we can jump on
platforms = game.add.group();
// We will enable physics for any object that is created in this group
platforms.enableBody = true;
// Here we create the ground.
var ground = platforms.create(0, game.world.height - 64, 'ground');
// Scale it to fit the width of the game (the original sprite is 400x32 in size)
//ground.scale.setTo(2, 2);
// This stops it from falling away when you jump on it
ground.body.immovable = true;
// Now let's create two ledges
//var ledge = platforms.create(400, 400, 'ground');
//ledge.body.immovable = true;
//ledge = platforms.create(-150, 250, 'ground');
//ledge.body.immovable = true;
player = game.add.sprite(32, game.world.height - 120, 'wheelbarrow');
//player.body.bounce.y = 0.2;
//player.body.gravity.y = 300;
//player.body.collideWorldBounds = true;
style = { font: "25px Arial", fill: "#ff0044", align: "center" };
text = game.add.text(125, 25, "Trafil roznych tehiel: ", style);
text.anchor.set(0.5);
game.load.onLoadStart.add(loadStart, this);
game.load.onFileComplete.add(fileComplete, this);
game.load.onLoadComplete.add(loadComplete, this);
}
function start() {
music.loopFull(1.0);
}
function cikoniec(){
if(poc==5){
alert('Uz si trafil/a vsetky tehly. Spustam hru znova!');
location.reload();
}
}
function update() {
//if(tehla1.y<game.height) game.add.tween(tehla1).to({ y: game.height*1.1 }, 1000, Phaser.Easing.Linear.None, true);
if(tehla1.y<game.height) tehla1.y+=rychlost;
if(tehla1.y>=game.height) {tehla1.y=game.rnd.integerInRange(20, 200);tehla1.x=game.rnd.integerInRange(20, 500);}
if(Math.abs(tehla1.y-player.y)<delta && Math.abs(tehla1.x-player.x)<delta && trafil1==false ){
poc=poc+1;
postext+=50;
tehla1.destroy();
text = game.add.text(postext, 35, "1", style);
trafil1 = true;
}
//if(tehla2.y<game.height) game.add.tween(tehla2).to({ y: game.height*1.1 }, 1000, Phaser.Easing.Linear.None, true);
if(tehla2.y<game.height) tehla2.y+=rychlost;
if(tehla2.y>=game.height) {tehla2.y=game.rnd.integerInRange(20, 200);tehla2.x=game.rnd.integerInRange(20, 500);}
if(Math.abs(tehla2.y-player.y)<delta && Math.abs(tehla2.x-player.x)<delta && trafil2==false ){
poc=poc+1;
postext+=50;
tehla2.destroy();
text = game.add.text(postext, 35, "2", style);
trafil2 = true;
}
//if(tehla3.y<game.height) game.add.tween(tehla3).to({ y: game.height*1.1 }, 1000, Phaser.Easing.Linear.None, true);
if(tehla3.y<game.height) tehla3.y+=rychlost;
if(tehla3.y>=game.height) {tehla3.y=game.rnd.integerInRange(20, 200);tehla3.x=game.rnd.integerInRange(20, 500);}
if(Math.abs(tehla3.y-player.y)<delta && Math.abs(tehla3.x-player.x)<delta && trafil3==false ){
poc=poc+1;
postext+=50;
tehla3.destroy();
text = game.add.text(postext, 35, "3", style);
trafil3 = true;
}
//if(tehla4.y<game.height) game.add.tween(tehla4).to({ y: game.height*1.1 }, 1000, Phaser.Easing.Linear.None, true);
if(tehla4.y<game.height) tehla4.y+=rychlost;
if(tehla4.y>=game.height) {tehla4.y=game.rnd.integerInRange(20, 200);tehla4.x=game.rnd.integerInRange(20, 500);}
if(Math.abs(tehla4.y-player.y)<delta && Math.abs(tehla4.x-player.x)<delta && trafil4==false ){
poc=poc+1;
postext+=50;
tehla4.destroy();
text = game.add.text(postext, 35, "4", style);
trafil4 = true;
}
//if(tehla5.y<game.height) game.add.tween(tehla5).to({ y: game.height*1.1 }, 1000, Phaser.Easing.Linear.None, true);
if(tehla5.y<game.height) tehla5.y+=rychlost;
if(tehla5.y>=game.height) {tehla5.y=game.rnd.integerInRange(20, 200);tehla5.x=game.rnd.integerInRange(20, 500);}
if(Math.abs(tehla5.y-player.y)<delta && Math.abs(tehla5.x-player.x)<delta && trafil5==false ){
poc=poc+1;
postext+=50;
tehla5.destroy();
text = game.add.text(postext, 35, "5", style);
trafil5 = true;
}
if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
if(player.x>0) player.x -= 15;
cikoniec();
}
else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
if(player.x<660) player.x += 15;
cikoniec();
}
game.physics.arcade.collide(player, platforms);
}
function render() {
game.debug.text('Hold left/right to move the player.');
}
</script>
<script>
// Wait for window load
$(window).load(function() {
// Animate loader off screen
$("#loader").animate({
top: -200
}, 1500);
});
</script>
</head>
<body>
<img src="assets/loader.gif" id="loader">
<noscript>Sorry, your browser does not support JavaScript!</noscript>
</body>
</html>
Related
I have a html canvas that I draw a rect on, when I clear the canvas the screen clears but when you move the mouse the rect reappears. I stretch the rect vertically. Here is a code pen example of what is happening, you have to double click on the canvas for the rect to appear. https://codepen.io/tjquinn/pen/BYZQqo
HTML
<div id="app">
<div class="cv">
<canvas v-on:mousedown="mouseDown" v-on:mousemove="mouseMove" v-on:mouseup="mouseUp" #dblclick="dclick" id="rect" class="rect" width="150" height="700"></canvas>
<button v-on:click="clear">
Clear
</button>
</div>
</div>
JS
methods: {
checkCloseEnough: function (p1, p2) {
return Math.abs(p1 - p2) < this.closeEnough;
},
getVal: function (x) {
this.canvas2 = document.getElementById('rect');
this.ctx2 = this.canvas2.getContext('2d');
this.st = this.canvas2.height;
this.ic = (this.st / x);
},
draw: function () {
this.ctx2.fillStyle = "#222222";
this.ctx2.fillRect(this.ctx2.rect.startX, this.ctx2.rect.startY, this.ctx2.rect.w, this.ctx2.rect.h);
this.drawHandles();
},
drawHandles: function () {
this.drawCircle(this.ctx2.rect.startX + this.ctx2.rect.w/2, this.ctx2.rect.startY, this.closeEnough); //top left corner
//drawCircle(rect.startX + rect.w, rect.startY, closeEnough);
//drawCircle(rect.startX + rect.w, rect.startY + rect.h, closeEnough);
this.drawCircle(this.ctx2.rect.startX + this.ctx2.rect.w/2, this.ctx2.rect.startY + this.ctx2.rect.h, this.closeEnough);
},
drawCircle: function (x, y, radius) {
this.ctx2.fillStyle = "#FF0000";
this.ctx2.beginPath();
this.ctx2.arc(x, y, radius, 0, 2 * Math.PI);
this.ctx2.closePath();
this.ctx2.fill();
},
checkCloseEnough: function (p1, p2) {
return Math.abs(p1 - p2) < this.closeEnough;
},
mouseDown: function (event) {
this.mouseX = event.pageX - this.canvas2.offsetLeft;
this.mouseY = event.pageY - this.canvas2.offsetTop;
// if there isn't a rect yet
if (this.ctx2.rect.w === undefined) {
this.ctx2.rect.startX = this.mouseY;
this.ctx2.rect.startY = this.mouseX;
this.dragBR = true;
}
if (this.checkCloseEnough(this.mouseX, this.ctx2.rect.startX + this.ctx2.rect.w/2) && this.checkCloseEnough(this.mouseY, this.ctx2.rect.startY)) {
this.dragTL = true;
}
else if (this.checkCloseEnough(this.mouseX, this.ctx2.rect.startX + this.ctx2.rect.w/2) && this.checkCloseEnough(this.mouseY, this.ctx2.rect.startY + this.ctx2.rect.h)) {
this.dragBR = true;
}
else {
// handle not resizing
}
this.ctx2.clearRect(0, 0, this.canvas2.width, this.canvas2.height);
this.draw();
},
mouseMove: function (event) {
this.mouseX = event.pageX - this.canvas2.offsetLeft;
this.mouseY = event.pageY - this.canvas2.offsetTop;
if (this.dragTL) {
//rect.w += rect.startX - mouseX;
this.ctx2.rect.h += this.ctx2.rect.startY - this.mouseY;
//rect.startX = mouseX;
this.ctx2.rect.startY = this.mouseY;
}
else if (this.dragBR) {
//rect.w = Math.abs(rect.startX - mouseX);
this.ctx2.rect.h = Math.abs(this.ctx2.rect.startY - this.mouseY);
}
this.ctx2.clearRect(0, 0, this.canvas2.width, this.canvas2.height);
this.draw();
},
mouseUp: function () {
this.dragTL = false;
this.dragTR = false;
this.dragBL = false;
this.dragBR = false;
},
dclick: function (e) {
console.log("Fires");
e.preventDefault();
this.ctx2.rect = {
startX: 25,
startY: 100,
w: (this.canvas2.width - 50),
h: 300,
}
this.draw();
this. ln = this.lines;
this.getVal(10);
},
clear: function () {
this.cv2 = 'rect';
this.canvas2 = document.getElementById(this.cv2);
this.ctx2 = this.canvas2.getContext('2d');
console.log(this.ctx2.clearRect(0, 0, this.canvas2.width, this.canvas2.height));
console.log("Clear should run");
},
}
})
It turns out the error was in my logic that was pointed out by Kamal Singh, I needed to add clear flags to my methods so that they do not run if the screen has been cleared.
<html>
<head>
<title>Test</title>
<script src="vue.min.js"></script>
</head>
<body>
<div id="app">
<div class="cv">
<canvas style='border:1px solid;' v-on:mousedown="mouseDown" v-on:mousemove="mouseMove" v-on:mouseup="mouseUp" #dblclick="dclick" id="rect" class="rect" width="150" height="700"></canvas>
<button v-on:click="clear">
Clear
</button>
</div>
</div>
<script>
new Vue({
el: '#app',
data: function() {
return {
rect : {},
drag : false,
closeEnough : 10,
st : 0,
ic : 0,
mouseX : 0,
mouseY : 0,
dragTL : false,
dragBL : false,
dragTR : false,
dragBR : false,
cv2: '',
ln: 0,
cleared: true
}
},
mounted: function () {
this.getVal(10);
this.draw();
},
methods: {
checkCloseEnough: function (p1, p2) {
return Math.abs(p1 - p2) < this.closeEnough;
},
getVal: function (x) {
this.canvas2 = document.getElementById('rect');
this.ctx2 = this.canvas2.getContext('2d');
this.st = this.canvas2.height;
this.ic = (this.st / x);
},
draw: function () {
this.ctx2.fillStyle = "#222222";
this.ctx2.fillRect(this.ctx2.rect.startX, this.ctx2.rect.startY, this.ctx2.rect.w, this.ctx2.rect.h);
this.drawHandles();
},
drawHandles: function () {
this.drawCircle(this.ctx2.rect.startX + this.ctx2.rect.w/2, this.ctx2.rect.startY, this.closeEnough); //top left corner
//drawCircle(rect.startX + rect.w, rect.startY, closeEnough);
//drawCircle(rect.startX + rect.w, rect.startY + rect.h, closeEnough);
this.drawCircle(this.ctx2.rect.startX + this.ctx2.rect.w/2, this.ctx2.rect.startY + this.ctx2.rect.h, this.closeEnough);
},
drawCircle: function (x, y, radius) {
this.ctx2.fillStyle = "#FF0000";
this.ctx2.beginPath();
this.ctx2.arc(x, y, radius, 0, 2 * Math.PI);
this.ctx2.closePath();
this.ctx2.fill();
},
checkCloseEnough: function (p1, p2) {
return Math.abs(p1 - p2) < this.closeEnough;
},
mouseDown: function (event) {
if(this.cleared) return;
this.mouseX = event.pageX - this.canvas2.offsetLeft;
this.mouseY = event.pageY - this.canvas2.offsetTop;
// if there isn't a rect yet
if (this.ctx2.rect.w === undefined) {
this.ctx2.rect.startX = this.mouseY;
this.ctx2.rect.startY = this.mouseX;
this.dragBR = true;
}
if (this.checkCloseEnough(this.mouseX, this.ctx2.rect.startX + this.ctx2.rect.w/2) && this.checkCloseEnough(this.mouseY, this.ctx2.rect.startY)) {
this.dragTL = true;
}
else if (this.checkCloseEnough(this.mouseX, this.ctx2.rect.startX + this.ctx2.rect.w/2) && this.checkCloseEnough(this.mouseY, this.ctx2.rect.startY + this.ctx2.rect.h)) {
this.dragBR = true;
}
else {
// handle not resizing
}
I need some help with my code. I want to make the str sprite invisible after 10 seconds.
I'm using this link for help: http://phaser.io/examples/v2/time/basic-timed-event
var game = new Phaser.Game(500, 550, Phaser.AUTO);
//var picture;
var Pacman = function (game) {
this.map = null;
this.layer = null;
this.pacman = null;
this.safetile = 14;
this.gridsize = 16;
this.speed = 100;
this.threshold = 3;
this.turnSpeed = 200;
this.marker = new Phaser.Point();
this.turnPoint = new Phaser.Point();
this.directions = [ null, null, null, null, null ];
this.opposites = [ Phaser.NONE, Phaser.RIGHT, Phaser.LEFT, Phaser.DOWN, Phaser.UP ];
this.current = Phaser.NONE;
this.turning = Phaser.NONE;
this.score=0;
this.scoreText='';
this.bonus=0;
this.bonusText='';
};
Pacman.prototype = {
init: function () {
this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.scale.pageAlignHorizontally = true;
this.scale.pageAlignVertically = true;
Phaser.Canvas.setImageRenderingCrisp(this.game.canvas);
this.physics.startSystem(Phaser.Physics.ARCADE);
},
preload: function () {
// We need this because the assets are on github pages
// Remove the next 2 lines if running locally
this.load.baseURL = 'https://nikosdaskalos.github.io/pacman/';
this.load.crossOrigin = 'anonymous';
this.load.image('str', 'assets/str.png');
this.load.image('dot', 'assets/dot.jpg');
this.load.image('coin', 'assets/coin.jpg');
this.load.image('tiles', 'assets/pacman-tiles.png');
this.load.spritesheet('pacman', 'assets/pacman.png');
this.load.tilemap('map', 'assets/pacman-map.json', null, Phaser.Tilemap.TILED_JSON);
// Needless to say, graphics (C)opyright Namco
},
create: function () {
this.map = this.add.tilemap('map');
this.map.addTilesetImage('pacman-tiles', 'tiles');
this.layer = this.map.createLayer('Pacman');
//picture = game.add.sprite(game.world.centerX, game.world.centerY, 'str');
//picture.anchor.setTo(0.5, 0.5);
//game.time.events.add(Phaser.Timer.SECOND * 4, fadePicture, this);
this.dots = this.add.physicsGroup();
this.map.createFromTiles(36, this.safetile, 'str', this.layer, this.dots);
this.map.createFromTiles(7, this.safetile, 'dot', this.layer, this.dots);
this.map.createFromTiles(35, this.safetile, 'coin', this.layer, this.dots);
// The dots will need to be offset by 6px to put them back in the middle of the grid
this.dots.setAll('x', 6, false, false, 1);
this.dots.setAll('y', 6, false, false, 1);
// Pacman should collide with everything except the safe tile
this.map.setCollisionByExclusion([this.safetile], true, this.layer);
// Position Pacman at grid location 14x17 (the +8 accounts for his anchor)
this.pacman = this.add.sprite((14 * 16) + 8, (17 * 16) + 8, 'pacman', 0);
this.pacman.anchor.set(0.5);
//this.pacman.animations.add('munch', [0, 1, 2, 1], 20, true);
this.physics.arcade.enable(this.pacman);
this.pacman.body.setSize(16, 16, 0, 0);
this.cursors = this.input.keyboard.createCursorKeys();
//this.pacman.play('munch');
this.move(Phaser.LEFT);
this.scoreText = game.add.text(0, 500, 'Score: 0', { fontSize: '34px Arial', fill: 'white' });
lives = game.add.group();
game.add.text(game.world.width - 340, 500, 'Lives : ', { fontSize: '34px Arial', fill: 'white' });
this.bonusText = game.add.text(360, 500, 'Bonus: 0', { fontSize: '20px Arial', fill: 'white' });
for (var i = 0; i < 3; i++)
{
var pacman = lives.create(game.world.width - 235 + (30 * i), 517, 'pacman');
pacman.anchor.setTo(0.5, 0.5);
pacman.angle = 90;
pacman.alpha = 0.4;
}
},
//function fadePicture() {
//game.add.tween(picture).to( { alpha: 0 }, 2000, Phaser.Easing.Linear.None, true);
//},
checkKeys: function () {
if (this.cursors.left.isDown && this.current !== Phaser.LEFT)
{
this.checkDirection(Phaser.LEFT);
}
else if (this.cursors.right.isDown && this.current !== Phaser.RIGHT)
{
this.checkDirection(Phaser.RIGHT);
}
else if (this.cursors.up.isDown && this.current !== Phaser.UP)
{
this.checkDirection(Phaser.UP);
}
else if (this.cursors.down.isDown && this.current !== Phaser.DOWN)
{
this.checkDirection(Phaser.DOWN);
}
else
{
// This forces them to hold the key down to turn the corner
this.turning = Phaser.NONE;
}
},
checkDirection: function (turnTo) {
if (this.turning === turnTo || this.directions[turnTo] === null || this.directions[turnTo].index !== this.safetile)
{
// Invalid direction if they're already set to turn that way
// Or there is no tile there, or the tile isn't index 1 (a floor tile)
return;
}
// Check if they want to turn around and can
if (this.current === this.opposites[turnTo])
{
this.move(turnTo);
}
else
{
this.turning = turnTo;
this.turnPoint.x = (this.marker.x * this.gridsize) + (this.gridsize / 2);
this.turnPoint.y = (this.marker.y * this.gridsize) + (this.gridsize / 2);
}
},
turn: function () {
var cx = Math.floor(this.pacman.x);
var cy = Math.floor(this.pacman.y);
// This needs a threshold, because at high speeds you can't turn because the coordinates skip past
if (!this.math.fuzzyEqual(cx, this.turnPoint.x, this.threshold) || !this.math.fuzzyEqual(cy, this.turnPoint.y, this.threshold))
{
return false;
}
// Grid align before turning
this.pacman.x = this.turnPoint.x;
this.pacman.y = this.turnPoint.y;
this.pacman.body.reset(this.turnPoint.x, this.turnPoint.y);
this.move(this.turning);
this.turning = Phaser.NONE;
return true;
},
move: function (direction) {
var speed = this.speed;
if (direction === Phaser.LEFT || direction === Phaser.UP)
{
speed = -speed;
}
if (direction === Phaser.LEFT || direction === Phaser.RIGHT)
{
this.pacman.body.velocity.x = speed;
}
else
{
this.pacman.body.velocity.y = speed;
}
// Reset the scale and angle (Pacman is facing to the right in the sprite sheet)
/* this.pacman.scale.x = 1;
this.pacman.angle = 0;
if (direction === Phaser.LEFT)
{
this.pacman.scale.x = -1;
}
else if (direction === Phaser.UP)
{
this.pacman.angle = 270;
}
else if (direction === Phaser.DOWN)
{
this.pacman.angle = 90;
}
this.current = direction;
},*/
this.add.tween(this.pacman).to( { angle: this.getAngle(direction) }, this.turnSpeed, "Linear", true);
this.current = direction;
},
getAngle: function (to) {
// About-face?
if (this.current === this.opposites[to])
{
return "180";
}
if ((this.current === Phaser.UP && to === Phaser.LEFT) ||
(this.current === Phaser.DOWN && to === Phaser.RIGHT) ||
(this.current === Phaser.LEFT && to === Phaser.DOWN) ||
(this.current === Phaser.RIGHT && to === Phaser.UP))
{
return "-90";
}
return "90";
},
eatDot: function (pacman, dot) {
dot.kill();
var audio = new Audio('assets/pacman_chomp.wav');
audio.play()
this.score+=10;
this.scoreText.text= 'Score: ' + this.score;
//setTimeout(audio.play(),2000);
if (this.dots.total === 0)
{
this.dots.callAll('revive');
}
},
/*function muteAudio() {
var audio = document.getElementById('audioPlayer');
if (audio.mute = false) {
document.getElementById('audioPlayer').muted = true;
}
else {
audio.mute = true
document.getElementById('audioPlayer').muted = false;
}
}*/
eatCoin: function(pacman,coin){//pente
coin.kill();
this.score+=20;
this.scoreText.text= 'Score: ' + this.score;
var audio = new Audio('assets/pacman_eatfruit.wav');
audio.play()
if(this.coins.total===0)
{
this.coins.callAll('revive');
}
},
eatStr: function(pacman,str){//pente
str.kill();
this.bonus+=100;
this.bonusText.text= 'Bonus: ' + this.bonus;
var audio = new Audio('assets/pacman_eatfruit.wav');
audio.play()
if(this.strs.total===0)
{
this.strs.callAll('revive');
}
},
update: function () {
this.physics.arcade.collide(this.pacman, this.layer);
this.physics.arcade.overlap(this.pacman, this.dots, this.eatDot, null, this);
this.physics.arcade.overlap(this.pacman, this.dots, this.eatCoin, null, this);
this.physics.arcade.overlap(this.pacman, this.dots, this.eatStr, null, this);
this.marker.x = this.math.snapToFloor(Math.floor(this.pacman.x), this.gridsize) / this.gridsize;
this.marker.y = this.math.snapToFloor(Math.floor(this.pacman.y), this.gridsize) / this.gridsize;
// Update our grid sensors
this.directions[1] = this.map.getTileLeft(this.layer.index, this.marker.x, this.marker.y);
this.directions[2] = this.map.getTileRight(this.layer.index, this.marker.x, this.marker.y);
this.directions[3] = this.map.getTileAbove(this.layer.index, this.marker.x, this.marker.y);
this.directions[4] = this.map.getTileBelow(this.layer.index, this.marker.x, this.marker.y);
this.checkKeys();
if (this.turning !== Phaser.NONE)
{
this.turn();
}
}
};
game.state.add('Game', Pacman, true);
</script>
</body>
</html>
So, can anyone help me with making the str invisible after 10 seconds?
You were pretty close.
I'm going to use pacman as an example, since I'm not 100% sure how you were going to fade out the coins. When Pacman eats them?
First, you want the following fadePicture function:
fadePicture: function() {
game.add.tween(this.pacman).to( { alpha: 0 }, 2000, Phaser.Easing.Linear.None, true);
},
Note how that was changed from function fadePicture().
Next, in your create function you can refer to it:
this.game.time.events.add(Phaser.Timer.SECOND * 4, this.fadePicture, this);
That replaces the following:
//game.time.events.add(Phaser.Timer.SECOND * 4, fadePicture, this);
I've created a JSFiddle with the relevant changes.
If you do want your coins to fade then I would try updating fadePicture to accept a dot/str parameter and then game.add.tween on that.
I am trying to pause between levels in this game but the pause feature wont work. Any help would be great. Currently the code just keeps getting stuck in a loop and prints out Next Level.
The level system is supposed to work when this.p.levelData.nextLevel is true but it keeps looping.
Any help would be great.
Quintus.ZombiesGameplay = function(Q) {
//game level
Q.Sprite.extend('Level', {
init: function(p) {
this._super(p, {
asset: '/assets/images/background.png',
type: Q.SPRITE_GROUND,
x: 90 + 1024/2,
y: 768/2,
w: 1024,
h: 768,
sunFrequency: {min: 3,max: 10}, //min and max number of seconds for sun to appear
});
this.timeNextSun = this.getTimeNextSun(); //time for the next sun to appear
//level data
this.zombieIndex = 0; //current index from zombies array
this.numZombies = this.p.levelData.zombies.length;
this.levelTime = 0; //keep track of the level duration
//save the position of each plant in a grid
this.plantsGrid = new Array(new Array(7), new Array(7), new Array(7), new Array(7), new Array(7), new Array(7));
this.on('touch');
Q.audio.play('/assets/audio/ZombiesOnYourLawn.mp3');
},
step: function(dt) {
//update level duration
this.levelTime += dt;
//check for level passed
if(this.p.levelData.duration < this.levelTime) {
if(this.p.levelData.nextLevel) {
// Q.stageScene("level", {levelData: Q.assets[this.p.levelData.nextLevel]});
// Q.stage().pause();
// Q.stage().unpause();
// debugger;
nextLevel();
// pauseGame();
// unPauseGame();
}else {
endGame();
// Q.stageScene('level', {levelData: Q.assets['/assets/data/level1.json']});
// Q.stage().pause();
// Q.stage().unpause();
}
}
//create zombies at the defined times
if(this.zombieIndex < this.numZombies) {
var currentZombie = this.p.levelData.zombies[this.zombieIndex];
if(this.levelTime >= currentZombie.time) {
var zombieData = Q.zombieTypes[currentZombie.type];
var newZombie = new Q.Zombie(
Q._extend(zombieData, {y: currentZombie.row * 120 + 60})
);
this.stage.insert(newZombie);
this.zombieIndex++;
}
}
//update sun generation timing
this.timeNextSun -= dt;
if(this.timeNextSun <= 0) {
this.timeNextSun = this.getTimeNextSun();
//create sun in the sun stage
Q.stage(1).insert(new Q.Sun());
}
},
touch: function(touch) {
//if a plant is selected
if(Q.state.get('currentPlant')) {
//get plantsGrid coordinates
var row = Math.floor((touch.y)/120);
var col = Math.floor((touch.x - 240)/120);
if(row >= 0 && row < this.plantsGrid.length && col >= 0 && col < this.plantsGrid[0].length) {
if(!this.plantsGrid[row][col] && Q.state.get('sun') >= Q.state.get('currentPlant').cost) {
Q.state.dec('sun', Q.state.get('currentPlant').cost);
var newPlant = new Q.Plant(Q._extend({x: 240 + 60 + col*120, y: 60 + row*120}, Q.state.get('currentPlant')));
this.stage.insert(newPlant);
this.plantsGrid[row][col] = newPlant;
newPlant.p.gridRow = row;
newPlant.p.gridCol = col;
}
}
}
},
getTimeNextSun: function() {
return this.p.sunFrequency.min + Math.random()*(this.p.sunFrequency.max - this.p.sunFrequency.min);
},
});
}
function nextLevel(){
console.log('NEXT LEVEL');
Q.stageScene("nextLevel",1, { label: "LEVEL COMPLETED!" });
Q.scene('nextLevel',function(stage) {
var container = stage.insert(new Q.UI.Container({
x: Q.width/2, y: Q.height/2, fill: "rgba(0,0,0,0.5)"
}));
var nextLevelButton = container.insert(new Q.UI.Button({ x: 0, y: 0, fill: "#CCCCCC",
label: "Next Level" }))
var label = container.insert(new Q.UI.Text({x:10, y: -10 - nextLevelButton.p.h, fill: "#FFFFFF",
label: stage.options.label }));
nextLevelButton.on("click",function() {
alert("test");
Q.stageScene("level", {levelData: Q.assets[this.p.levelData.nextLevel] });
});
container.fit(20);
});
pauseGame();
};
function endGame(){
console.log('YOU WON!');
Q.stageScene("endGame",1, { label: "You Have Won The Game!" });
Q.scene('endGame',function(stage) {
var container = stage.insert(new Q.UI.Container({
x: Q.width/2, y: Q.height/2, fill: "rgba(0,0,0,0.5)"
}));
var button = container.insert(new Q.UI.Button({ x: 0, y: 0, fill: "#CCCCCC",
label: "Play Again" }))
var label = container.insert(new Q.UI.Text({x:10, y: -10 - button.p.h, fill: "#FFFFFF",
label: stage.options.label }));
button.on("click",function() {
Q.clearStages();
Q.stageScene('level', {levelData: Q.assets['/assets/data/level1.json']});
});
container.fit(20);
});
// pauseGame();
};
function pauseGame(){
console.log("Game Paused");
Q.stage().pause()
};
function unPauseGame(){
Q.stage().unpause()
};
I've converted a skinned.dae mesh to JSON using this loader. I'm now loading it up in a scene and - since its animations are not intended as actual animation, but ranges of motion for model posing, I am attempting to map those animations to sliders. Relevant code:
var loader = new THREE.JSONLoader();
var animation;
loader.load('phases/1/1.json', function(geometry, materials) {
var mesh = new THREE.SkinnedMesh(geometry, new THREE.MeshFaceMaterial(materials));
scene.add(mesh);
console.log(mesh.geometry);
mesh.scale.set(1, 1, 1);
materials.forEach(function(i) { i.skinning = true });
var clip = mesh.geometry.animations[0];
var clip2 = mesh.geometry.animations[1];
var clip3 = mesh.geometry.animations[2];
var clip4 = mesh.geometry.animations[3];
var clip5 = mesh.geometry.animations[4];
mixer = new THREE.AnimationMixer(mesh);
action = mixer.clipAction(clip);
action2 = mixer.clipAction(clip2);
action3 = mixer.clipAction(clip3);
action4 = mixer.clipAction(clip4);
I then initialize them:
action.play();
action.paused = true;
action2.play();
action2.paused = true;
action3.play();
action3.paused = true;
action4.play();
action4.paused = true;
And then in an IIFE create sliders and map said animations:
(function() {
var container = document.querySelector('div#sliders'),
slider = document.createElement('input'),
attrs = { 'type': 'range', 'min': 0, 'max': 1, 'step': 0.01 };
slider2 = document.createElement('input'),
attrs2 = { 'type': 'range', 'min': 0, 'max': 1, 'step': 0.01 };
slider3 = document.createElement('input'),
attrs3 = { 'type': 'range', 'min': 0, 'max': 1, 'step': 0.01 };
slider4 = document.createElement('input'),
attrs4 = { 'type': 'range', 'min': 0, 'max': 1, 'step': 0.01 };
Object.keys(attrs).forEach(function(i) { slider.setAttribute(i, attrs[i]);});
Object.keys(attrs2).forEach(function(i) { slider2.setAttribute(i, attrs2[i]) });
Object.keys(attrs3).forEach(function(i) { slider3.setAttribute(i, attrs3[i]) });
Object.keys(attrs4).forEach(function(i) { slider4.setAttribute(i, attrs4[i]) });
container.style.position = 'absolute';
container.style.top = '0';
container.style.left = '0';
slider.addEventListener('input', function(evt) {
action.time = parseFloat(this.value * action.getClip().duration);
console.log(action.time);
});
slider2.addEventListener('input', function(evt) {
action2.time = parseFloat(this.value * action2.getClip().duration);
});
slider3.addEventListener('input', function(evt) {
action3.time = parseFloat(this.value * action3.getClip().duration);
});
slider4.addEventListener('input', function(evt) {
action4.time = parseFloat(this.value * action4.getClip().duration);
});
container.appendChild(slider);
container.appendChild(slider2);
container.appendChild(slider3);
container.appendChild(slider4);
}());
This works but gives me a surprisingly limited range of motion in each animation - which is to say the animation doesn't play out fully (i.e all keyframes), just tiny movements.
Any ideas why that might be happening? I'm at my wits end.
You can find the live code here.
Any/all help would be much appreciated - thanks!
Have you set materials after loading to morph yet?
for (var m=0; m<materials.length; m++){
var material = materials[ m ];
material.morphTargets = true;
}
I've gotten this from the json loader example in three.js website and modified it slightly.
hope this helps,
A newb
I am developing a web application.
In my guest registration page I need to access web cam for taking images of guests.
The image which I take could be able to stored in a specified location.
Which will be the best way to perform this.
Methods using java, JSP, html, java script or any other methods are welcomed.
Answering own question, as there is a better way using HTML5 is available.
Option 1, Accessing default camera from the system
HTML
Video Tag
<br/>
<div class="camera">
<video id="video">Video stream not available.</video>
<button id="startbutton">Take photo</button>
</div>
<br/>
Canvas
<br/>
<canvas id="canvas"></canvas>
Script
var width = 320;
var height = 0;
var streaming = false;
navigator.mediaDevices.getUserMedia({video: true, audio: false})
.then(function (stream) {
video.srcObject = stream;
video.play();
})
.catch(function (err) {
console.log("An error occured! " + err);
});
video.addEventListener('canplay', function (ev) {
if (!streaming) {
height = video.videoHeight / (video.videoWidth / width);
video.setAttribute('width', width);
video.setAttribute('height', height);
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
streaming = true;
}
}, false);
startbutton.addEventListener('click', function (ev) {
takepicture();
ev.preventDefault();
}, false);
clearphoto();
function clearphoto() {
var context = canvas.getContext('2d');
context.fillStyle = "#AAA";
context.fillRect(0, 0, canvas.width, canvas.height);
}
function takepicture() {
var context = canvas.getContext('2d');
if (width && height) {
canvas.width = width;
canvas.height = height;
context.drawImage(video, 0, 0, width, height);
var dataURL = canvas.toDataURL("image/jpeg", 0.95);
if (dataURL && dataURL != "data:,") {
var fileName = generateImageName();
uploadimage(dataURL, fileName);
} else {
alert("Image not available");
}
} else {
clearphoto();
}
}
function generateImageName() {
... generate image name logic here ...
return imageName;
}
function uploadimage(dataurl, filename) {
... upload logic here ...
}
Screen shot
Option 2, Provide a list of available cameras in the system, and let user select the camera.
HTML
<select id="videoSelect"></select>
<button id="startCameraButton">Start Camera</button>
<br/>
Video Tag
<br/>
<div class="camera">
<video id="video">Video stream not available.</video>
<button id="takePictureButton">Take photo</button>
</div>
<br/>
Canvas
<br/>
<canvas id="canvas">
</canvas>
Script
var width = 320;
var height = 0;
var streaming = false;
var localstream = null;
startCameraButton.onclick = start;
takePictureButton.onclick = takepicture;
navigator.mediaDevices.enumerateDevices()
.then(gotDevices)
.catch(function (err) {
console.log("An error occured while getting device list! " + err);
});
function gotDevices(deviceInfos) {
while (videoSelect.firstChild) {
videoSelect.removeChild(videoSelect.firstChild);
}
for (var i = 0; i !== deviceInfos.length; ++i) {
var deviceInfo = deviceInfos[i];
var option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label || 'Camera ' + (videoSelect.length + 1);
videoSelect.appendChild(option);
}
}
}
function start() {
stopVideo();
clearphoto();
var videoSource = videoSelect.value;
var constraints = {
audio: false,
video: {deviceId: videoSource ? {exact: videoSource} : undefined}
};
navigator.mediaDevices.getUserMedia(constraints).
then(gotStream).then(gotDevices).catch(handleError);
}
function gotStream(stream) {
localstream = stream;
video.srcObject = stream;
video.play();
// Refresh button list in case labels have become available
return navigator.mediaDevices.enumerateDevices();
}
function handleError(error) {
console.log('navigator.getUserMedia error: ', error);
}
video.addEventListener('canplay', function (ev) {
if (!streaming) {
height = video.videoHeight / (video.videoWidth / width);
video.setAttribute('width', width);
video.setAttribute('height', height);
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
streaming = true;
}
}, false);
clearphoto();
function clearphoto() {
var context = canvas.getContext('2d');
context.fillStyle = "#AAA";
context.fillRect(0, 0, canvas.width, canvas.height);
}
function takepicture() {
var context = canvas.getContext('2d');
if (width && height) {
canvas.width = width;
canvas.height = height;
context.drawImage(video, 0, 0, width, height);
var dataURL = canvas.toDataURL("image/jpeg", 0.95);
if (dataURL && dataURL != "data:,") {
var fileName = generateImageName();
fileName = fileName + ".txt"
uploadimage(dataURL, fileName);
} else {
console.log("Image not available");
}
} else {
clearphoto();
}
}
function generateImageName() {
... generate image name logic here ...
return imageName;
}
function uploadimage(dataurl, filename) {
... upload logic here ...
}
function stopVideo() {
if (localstream) {
localstream.getTracks().forEach(function (track) {
track.stop();
localstream = null;
});
}
}
Screen Shot
Option 3, let user select audio and video sources and audio output
In option 2, user can select any particular camera. On top of that if user want to select audio source and audio output source also, modify the above code with below changes.
HTML
audioInputSelect
<br/>
<select id="audioInputSelect"></select>
<br/>
audioOutputSelect
<select id="audioOutputSelect"></select>
Script
function gotDevices(deviceInfos) {
while (videoSelect.firstChild) {
videoSelect.removeChild(videoSelect.firstChild);
}
for (var i = 0; i !== deviceInfos.length; ++i) {
var deviceInfo = deviceInfos[i];
var option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'audioinput') {
option.text = deviceInfo.label || 'Microphone ' + (audioInputSelect.length + 1);
audioInputSelect.appendChild(option);
} else if (deviceInfo.kind === 'audiooutput') {
option.text = deviceInfo.label || 'Speaker ' + (audioOutputSelect.length + 1);
audioOutputSelect.appendChild(option);
} else if (deviceInfo.kind === 'videoinput') {
option.text = deviceInfo.label || 'Camera ' + (videoSelect.length + 1);
videoSelect.appendChild(option);
}
}
}
function start() {
stopVideo();
clearphoto();
var audioSource = audioInputSelect.value;
var videoSource = videoSelect.value;
var constraints = {
audio: {deviceId: audioSource ? {exact: audioSource} : undefined},
video: {deviceId: videoSource ? {exact: videoSource} : undefined}
};
navigator.mediaDevices.getUserMedia(constraints).
then(gotStream).then(gotDevices).catch(handleError);
}
jQuery Webcam Plugin does the hard work for you:
http://www.xarg.org/project/jquery-webcam-plugin/