topical media & game development
mobile-query-three-plugins-ogsworkshop-slides-index.htm / htm
<!DOCTYPE html>
<html>
<head>
<title>Three.js workshop</title>
<base target=”_blank” />
<meta charset='utf-8'/>
<script src="vendor/jquery-1.7.2.min.js"></script>
<script src='slides.js'></script>
</head>
<body style='display: none'>
<style>
article[data-markdown] em {
color : orange;
font-style : normal;
font-weight : bolder;
}
article[data-markdown] h3 {
font-size : 180%;
}
span.orange {
color : orange;
}
span.larger {
font-weight : bolder;
font-size : 120%;
}
</style>
<section class='slides layout-regular template-default'>
<!-- *****************************************************************************
STAGE 0
****************************************************************************** -->
<article data-markdown>
# 3D Game with tQuery API
</article>
<article data-markdown>
# You know jQuery ?
## you know enougth to make a 3d game!
</article>
<article data-markdown>
# Stage 0
</article>
<article data-markdown>
# Install three.js + tQuery
## Have to start somewhere
</article>
<article data-markdown>
Links
three.js in tQuery repo
[tquery's repo](
http://jeromeetienne.github.com/tquery)
info on distribs
*tquery.js* : core aka tquery only
*tquery-bundle.js* : tquery core + three.js + boilerplate
*tquery-bundle-require.js* : tquery bundle + require.js
usefull to easily get plugins
</article>
<!-- *****************************************************************************
STAGE 1
****************************************************************************** -->
<article data-markdown>
# Stage 1
</article>
<article data-markdown>
# Boilerplate
## What is the boilerplate
</article>
<article data-markdown>
First the code
<pre>
<!doctype html><title>Minimal tQuery Page</title>
<script src="../../build/tquery-bundle.js"></script>
<body><script>
var world = tQuery.createWorld().boilerplate().start();
var object = tQuery.createTorus().addTo(world);
</script></body>
</pre>
Only *6 lines*
Valid html5 page
# Web can be nice !
</article>
<article data-markdown>
Second the show
<iframe src='../examples/stage010.html'>
</iframe>
</article>
<article data-markdown>
What is the world
```
var world = tQuery.createWorld().boilerplate().start();
```
scene
renderer
camera + its controls
rendering loop
</article>
<article data-markdown>
What is the boilerplate
```
var world = tQuery.createWorld().boilerplate().start();
```
include three.js boilerplate
easy way to get you started
# includes
full screen view
window resize
press 'p' for screenshot
press 'f' for fullscreen
</article>
<article data-markdown>
## Nice blank screen!
</article>
<article data-markdown>
Lets add an object
```
var object = tQuery.createTorus().addTo(world);
```
Create an object torus
creator for each included geometry
Sphere, Cube, cylinder and others
Objects creators use 'normalMaterial'
weird blueish thing
nice to debug
Then add it to the world
</article>
<article data-markdown>
So end up with that
<iframe src='../examples/stage010.html'>
</iframe>
</article>
<article data-markdown>
## So only a torus in the middle of the screen ?
</article>
<!-- *****************************************************************************
STAGE 2
***************************************************************************** -->
<article data-markdown>
# Stage 2
</article>
<article data-markdown>
# Minecraft character
## Lets add that :)
</article>
<article data-markdown>
First require.js
```
require([], function(){
// create the world, add the boilerplate and start
var world = tQuery.createWorld().boilerplate().start();
// create a torus and add it to the world
tQuery.createTorus().addTo(world);
});
```
# Why require.js
easy download of plugins
load files in proper orders
May pack+minify with r.js for prod
Load only what is needed
</article>
<article data-markdown>
Include minecraft plugin
```
require(['tquery.minecraft'], function(){
// create the world, add the boilerplate and start
var world = tQuery.createWorld().boilerplate().start();
// create a torus and add it to the world
tQuery.createTorus().addTo(world);
});
```
# Possibilities
multiple skins
create characters
animate them
control them with keyboard
</article>
<article data-markdown>
Use minecraft plugin
# Add default character [See More](../../minecraft/examples/char.html)
```
tQuery.createMinecraftChar().addTo(world);
```
# Add Agent smith
skin compatible with minecraft ones
15 available already. [See more](../../minecraft/examples/index.html)
```
tQuery.createMinecraftChar({
skinUrl : '../../minecraft/examples/images/agentsmith.png'
}).addTo(world);
```
</article>
<!-- ****************************************************************************
Put a world around it
********************************************************************************* -->
<article data-markdown>
# Stage 3
</article>
<article data-markdown>
# Put a world around
## no more flying in ether :)
</article>
<article data-markdown>
Notes on designing scenes
# Principle *Make the space visible*
or "antimatter via nutra sweet"!
reveal the void
# Techniques
lights good
moving ones better
shadows casting
skymap cool
fog, god ray
</article>
<article data-markdown>
First the sky
define skymap
create a infinitly huge square
appears as sphere via gpu tricks
# Several maps already available
7 of them
list with following line in jsconsole
```
Object.keys(tQuery.TextureCube.WellKnownUrls)
```
</article>
<article data-markdown>
skymap for sky
```
tQuery.createSkymap('skybox').addTo(world);
```
</article>
<article data-markdown>
skymap for reflection
define [reflection](
http://en.wikipedia.org/wiki/Reflection_mapping)
```
var material = tQuery.createMaterial({
envMap : tQuery.createCubeTexture('skybox')
});
tQuery.createCube().material(material).addTo(world)
```
* good trick for a material
* examples of [car](../../car/examples/)
* look at the arches
* look at the engines (swedish castle :)
</article>
<article data-markdown>
skymap for refraction
TODO link to definition
TODO get code
link to gello drop
</article>
<article data-markdown>
# a ground to stand on
## light on your feet
</article>
<article data-markdown>
Grass on the ground
Nature is healthy. [See More](../../grassground/examples)
similar a checkerboard [See More](../../checkerboard/examples)
```
require(['tquery.grassground'], function(){
// ...
var ground = tQuery.createGrassGround({
textureRepeatX : 20,
textureRepeatY : 20,
}).addTo(world)
})
```
# anisotropy is funny - looks cool even at a distance
```
ground.get(0).material.map.anisotropy = 16;
```
</article>
<!-- ****************************************************************************
Put a world around it
********************************************************************************* -->
<article data-markdown>
# Stage 4
</article>
<article data-markdown>
# Make it move
</article>
<article data-markdown>
Rendering loop
# What is it ?
part of the tQuery.World
use requestanimationframe()
called only when anims are ok
visible
use submillisecond timer
ms time unsuitable at 60fps
# Notify 2 times
*delta* aka nb seconds since last iteration
*now* aka nb seconds in absolute time
</article>
<article data-markdown>
Rendering loop
# how to hook it
```
world.loop().hook(function(delta, now){
// your stuff here
});
```
# in action
```
world.loop().hook(function(delta, now){
var mesh = character.object3D('root');
mesh.rotateY(delta * Math.PI*2)
});
```
* [See More](../examples/stage040.html)
</article>
<article data-markdown>
keyboard controls
# What is it ?
read and store keyboard state
Must be available during rendering loop
cant be done via event
</article>
<article data-markdown>
keyboard controls
# How to code it
```
world.loop().hook(function(delta, now){
var mesh = character.object3D('root');
var keyboard = tQuery.keyboard();
if( keyboard.pressed('left') ) mesh.translateX(-1 * delta)
if( keyboard.pressed('right') ) mesh.translateX(+1 * delta)
if( keyboard.pressed('up') ) mesh.translateZ(-1 * delta)
if( keyboard.pressed('down') ) mesh.translateZ(+1 * delta)
});
```
* depends on **delta**
* Thus same move no matter the fps
* [See It](../examples/stage041.html)
</article>
<article data-markdown>
character animation
# Pick a body part
armR/armL/legR/legL/body/head
say right arm
```
var mesh = character.object3D('armR');
```
# Make it move [action](../examples/stage042.html)
```
world.loop().hook(function(delta, now){
var mesh = character.object3D('armR');
var angle = now * Math.PI * 2;
mesh.rotationX(Math.sin(angle));
});
```
</article>
<article data-markdown>
Make it move baby
# animating of the character
use generic system based on keyframe
tweening from one to another
# what is an animation
succession of keyframes with a name
move properties, any property
position, rotation, scale whatever
generic
</article>
<article data-markdown>
Move your body miner
*rigging:* can move head/arms/legs/body
several animations already done [see here](../../minecraft/examples/animation.html)
run/walk/stand
wave/hiwave
# 3 for the head
yes/no/still
</article>
<!-- ****************************************************************************
Lets give it a weapon
******************************************************************************** -->
<article data-markdown>
# Stage 5
</article>
<article data-markdown>
# Lets give a weapon
## fighting time!
</article>
<article data-markdown>
Get the weapon
# extruding spritesheet
scary words
what does this means
show it [here](../../minecraft/examples/items.html)
from [that](../../minecraft/examples/images/items/items.png)
# One can even animate it
show it [here](../../minecraft/examples/spritesheet.html)
</article>
<article data-markdown>
Create a sword
# Initiation
```
var spritesheet = tQuery.createSpritesheet({
url : 'images/items/items.png',
imgW : 256,
imgH : 256,
spriteW : 16,
spriteH : 16
});
```
# Usage
```
spritesheet.createMesh(2,4).addTo(world);
```
</article>
<article data-markdown>
Sword in minecraft hand
```
var sword = items.createMesh(2, 4)
.addTo(character.parts.armR)
.position(0,-10/35,8/35)
.rotation(Math.PI/2,Math.PI/2,Math.PI/4)
.scaleBy(1/2)
```
what is ```.scaleBy()``` ?
what is ```.position()``` ?
what is ```.rotation()``` ?
# noticed ```.addTo(armR)``` ?
</article>
<article data-markdown>
A word on scenegraph
# principles
3d objects are in a scene
scene is a tree
features are inherited from parents
# consequences
change parent scale =>
it change children scale
</article>
<article data-markdown>
Lets play with that
* see [running code](../examples/stage050.html)
* copy that in live editor
* change scale
</article>
<!-- ****************************************************************************
Stage 6
********************************************************************************* -->
<article data-markdown>
# Stage 6
</article>
<article data-markdown>
# Sound with WebAudioAPI
## Crack boom hue
</article>
<article data-markdown>
Web Audio API
# What is it
new audio api
efficient, flexible
based on OpenAL
my [slidedeck on webaudio](
http://jeromeetienne.github.com/slides/webaudioapi)
Availability
chrome, safari and iOS
firefox implementing it
</article>
<article data-markdown>
#
Sound in modern browsers !
## First time in history!!
</article>
<article data-markdown>
Web Audio API
# Super cool for 3d
directional sound
sound for 3d position/velocity
dopler!
listener follows camera!!!
</article>
<article data-markdown>
Webaudio.js
# motivation
web audio api is verbose
kinda like webgl
little lib to make it easier to use
# Info
mit license
[homepage](
http://jeromeetienne.github.com/webaudio.js)
* [github](
github.com/jeromeetienne/webaudio.js/)
</article>
<article data-markdown>
Webaudio.js
# some Examples
real time sound analysis [here](
http://jeromeetienne.github.com/webaudio.js/examples/histotquery.html)
* directional sound [here](
http://jeromeetienne.github.com/webaudio.js/examples/sample-tquery.html)
* procedural sound generation with jsfx
[here](
http://jeromeetienne.github.com/webaudio.js/examples/jsfx/)
* playground to test [here](
http://jeromeetienne.github.com/webaudio.js/examples/playground/)
>
<article data-markdown>
Webaudio.js basic
# enable it
```
world.enableWebAudio();
```
setup a typical node chain
based on [html5rocks advices](http://www.html5rocks.com/en/tutorials/webaudio/games/)
* configure listener on camera
</article>
<article data-markdown>
Webaudio.js basic
# load a sound
```
var sound = tQuery.createSound().load('../sounds/checkpoint.wav');
```
# play it
```
sound.play()
```
# What about the 3d ?
```
sound.follow(mesh)
```
* blah!! got localisation + dopler!
* not too hard hey ? :)
</article>
<!-- ****************************************************************************
Stage 7
********************************************************************************* -->
<article data-markdown>
# Stage 7
</article>
<article data-markdown>
# Multiplayer!!
</article>
<article data-markdown>
Intro
not an easy problem
fighting latency is hard
various strategy are possible
[good intro](
http://buildnewgames.com/real-time-multiplayer/)
>
<article data-markdown>
Could that be easy ?
# tried with [easywebsocket](http://easywebsocket.org)
* service which only echo packets
up to the users to define protocols
# above and beyond with [simplemmoserver](
github.com/jeromeetienne/SimpleMMOServer)
the brand new attempt :)
less raw/more cooked
</article>
<article data-markdown>
SimpleMMOServer
# Feature
handle userlist for you
measure latency
allow echo/broadcast
broadcast = send to all others
echo = send to everybody (even me)
# info
mit license
repo [here](
github.com/jeromeetienne/SimpleMMOServer)
</article>
<article data-markdown>
more cooked ?
# not so cooked
server: 60lines + node.js
client: 130lines
# Still rawish :)
## *very naive* tho :)
</article>
<article data-markdown>
on the server
```
open -a "/Applications/Google Chrome.app" --args --disable-web-security --allow-file-access-from-file
setTimeout(function(){
location.href.match(/^file:/) && jQuery('a').add('iframe').each(function(index, element){
var attrNames = {
'A' : 'href',
'IFRAME': 'src'
};
var attrName = attrNames[element.nodeName];
var url = jQuery(element).attr(attrName);
url = url.replace(/^http:\/\/jeromeetienne.github.com\/tquery\// , 'file://localhost/Users/jerome/webwork/tquery/')
url = url.replace(/^http:\/\/jeromeetienne.github.com\/augmentedgesture.js\// , 'file://localhost/Users/jerome/webwork/augmentedgesture.js/')
url = url.replace(/^http:\/\/jeromeetienne.github.com\/webaudio.js\// , 'file://localhost/Users/jerome/webwork/webaudio.js/')
url = url.replace(/^http:\/\/jeromeetienne.github.com\/pongGL\//, 'file://localhost/Users/jerome/webwork/pongGL/')
url = url.replace(/^http:\/\/jeromeetienne.github.com\/threex\//, 'file://localhost/Users/jerome/webwork/threex/')
url = url.replace(/^http:\/\/learningthreejs.com\//, 'file://localhost/Users/jerome/webwork/learningthreejs.com/')
url = url.replace(/\/
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-2780434-1";
urchinTracker();
</script>