8. Keyboard Interaction (To move the camera)
In this tutorial I'm going to cover keyboard interaction.
(use W,A,S and D)
The very first thing we need to do before we start is to go right back and edit the base class. We're going to make it accept more than one camera, then we can dynamically select the camera, scene and viewport to use.
Open up PaperBase.as (Double click on it in the project tree, under PaperBase). Insert the following lines just below the line "public var default_camera:Camera3D;":
-
public var current_scene:Scene3D;
-
public var current_camera:CameraObject3D;
-
public var current_viewport:Viewport3D;
These three variables will store the camera, scene and viewport to use in the render. We need to make the default camera, scene and viewport be stored in these variables when we initiate our project, so in the initPapervision function, right at the end, add the following lines:
-
current_camera = default_camera;
-
current_scene = default_scene;
-
current_viewport = viewport;
The final little edit that we need to make is to render from the current objects.
Change the line "renderer.renderScene(default_scene, default_camera, viewport);" to:
-
renderer.renderScene(current_scene, current_camera, current_viewport);
Done. You can download the NEW version of the base class by clicking here!
Now that we've got the base class edited, we can start editing Main.as.
Copy and paste this code into Main.as, make sure you have the papervision library, and the PaperBase class imported in your project's classpaths.
-
package {
-
-
import PaperBase;
-
import flash.events.KeyboardEvent;
-
import org.papervision3d.cameras.FreeCamera3D;
-
import org.papervision3d.objects.primitives.Plane;
-
import org.papervision3d.materials.BitmapFileMaterial;
-
-
public class Main extends PaperBase {
-
-
public var wdown:Boolean = false;
-
public var adown:Boolean = false;
-
public var sdown:Boolean = false;
-
public var ddown:Boolean = false;
-
public var camera:FreeCamera3D;
-
-
public function Main() {
-
init();
-
}
-
-
override protected function init3d():void {
-
// Initiate 3d
-
}
-
override protected function processFrame():void {
-
// Process Frame Here
-
}
-
}
-
}
I've put in all the imports that you'll need for the project. Let's set up the event listeners which will listen for when we press or release a key. Change the code in the Main() function so it looks like this:
-
public function Main() {
-
init();
-
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
-
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
-
}
This sets up the two event listeners. Now the functions "onKeyDown" then "onKeyUp" will be triggered when you press a key down, then release it.
If you look at the code, you'll notice that I've declared four boolean values, Wdown, Adown, Sdown and Ddown.
-
public var Wdown:Boolean = false;
-
public var Adown:Boolean = false;
-
public var Sdown:Boolean = false;
-
public var Ddown:Boolean = false;
I like to use the W A S and D keys for movement, so each of these boolean values will hold whether W,A,S or D is down.
We'll now set up our onKey functions, which will set the above variables to the correct value. Add this code to your project:
-
public function onKeyDown( event:KeyboardEvent ):void {
-
// The keycodes for the W,A,S & D keys are:
-
// W: 87
-
// A: 65
-
// S: 83
-
// D: 68
-
// -------
-
switch(event.keyCode) {
-
case 87:
-
wdown = true;
-
break;
-
case 65:
-
adown = true;
-
break;
-
case 83:
-
sdown = true;
-
break;
-
case 68:
-
ddown = true;
-
break;
-
}
-
}
-
-
public function onKeyUp( event:KeyboardEvent ):void {
-
switch(event.keyCode) {
-
case 87:
-
wdown = false;
-
break;
-
case 65:
-
adown = false;
-
break;
-
case 83:
-
sdown = false;
-
break;
-
case 68:
-
ddown = false;
-
break;
-
}
-
}
Pretty simple stuff - Just sets the needed variable to true.
Now we've set that all up, we need to set up our scene. Add the following function to your code:
-
override protected function init3d():void {
-
camera = new FreeCamera3D(1, 500);
-
camera.moveUp(400);
-
current_camera = camera;
-
for (var x:Number = 0; x <4; x++) {
-
for (var y:Number = 0; y <4; y++) {
-
var p:Plane = new Plane(new BitmapFileMaterial("http://papervision2.com/wp-content/downloads/concretetex.jpg"), 1000, 1000, 8, 8);
-
p.pitch(90);
-
p.x = (x * 1000)-2000;
-
p.z = (y * 1000)-2000;
-
default_scene.addChild(p);
-
}
-
}
-
}
Notice that we initiate our "camera" variable here. We then set the current_camera to the camera that we just made. After the line "current_camera = camera", the baseclass will render the scene looking through "camera" instead of "default_camera". The rest of the code in this function just adds a big flat area to the scene which will be our "floor"
Now we can use the boolean variables to move our camera in the processframe function. Add this code to your project:
-
override protected function processFrame():void {
-
if (wdown) {
-
camera.moveForward(60);
-
}
-
if (sdown) {
-
camera.moveBackward(60);
-
}
-
if (adown) {
-
camera.yaw( -8);
-
}
-
if (ddown) {
-
camera.yaw( 8);
-
}
-
}
This just moves the camera forward or back, or rotates it left/right, depending on which key has been pressed.
Your project is now ready to be run. Here is my final code:
-
package {
-
-
import PaperBase;
-
import flash.events.KeyboardEvent;
-
import org.papervision3d.cameras.FreeCamera3D;
-
import org.papervision3d.objects.primitives.Plane;
-
import org.papervision3d.materials.BitmapFileMaterial;
-
-
public class Main extends PaperBase {
-
-
public var wdown:Boolean = false;
-
public var adown:Boolean = false;
-
public var sdown:Boolean = false;
-
public var ddown:Boolean = false;
-
public var camera:FreeCamera3D;
-
-
public function Main() {
-
init();
-
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
-
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
-
}
-
-
public function onKeyDown( event:KeyboardEvent ):void {
-
// The keycodes for the W,A,S & D keys are:
-
// W: 87
-
// A: 65
-
// S: 83
-
// D: 68
-
// -------
-
switch(event.keyCode) {
-
case 87:
-
wdown = true;
-
break;
-
case 65:
-
adown = true;
-
break;
-
case 83:
-
sdown = true;
-
break;
-
case 68:
-
ddown = true;
-
break;
-
}
-
}
-
-
public function onKeyUp( event:KeyboardEvent ):void {
-
switch(event.keyCode) {
-
case 87:
-
wdown = false;
-
break;
-
case 65:
-
adown = false;
-
break;
-
case 83:
-
sdown = false;
-
break;
-
case 68:
-
ddown = false;
-
break;
-
}
-
}
-
-
override protected function init3d():void {
-
camera = new FreeCamera3D(1, 500);
-
camera.moveUp(400);
-
current_camera = camera;
-
for (var x:Number = 0; x <4; x++) {
-
for (var y:Number = 0; y <4; y++) {
-
var p:Plane = new Plane(new BitmapFileMaterial("http://papervision2.com/wp-content/downloads/concretetex.jpg"), 1000, 1000, 8, 8);
-
p.pitch(90);
-
p.x = (x * 1000)-2000;
-
p.z = (y * 1000)-2000;
-
default_scene.addChild(p);
-
}
-
}
-
}
-
override protected function processFrame():void {
-
if (wdown) {
-
camera.moveForward(60);
-
}
-
if (sdown) {
-
camera.moveBackward(60);
-
}
-
if (adown) {
-
camera.yaw( -8);
-
}
-
if (ddown) {
-
camera.yaw( 8);
-
}
-
}
-
}
-
}




hello, i get this error message when i run your code:
Error: a target file must be specified
Use 'mxmlc -help' for information about using the command line.
Build halted with errors (mxmlc).
what´s the problem? thanx
Hi,
Right click on the project in the Project Tree, click on Properties, then in the output file location box, type the name of the file that you want the project to be output to (I put movement1.swf)
Thanks, I hope this helps,
Luke.
[quote]
for (var x:Number = 0; x <4; x++) {
for (var y:Number = 0; y <4; y++) {
...
}
}
[/quote]
Luke, look at the "<" in FORs.
Good example!
Alek
OK thanks, i had already fixed that but forgot to tell. I hadnt checked the "always compile" option of the main.as. that was it, sorry to bother and thanks again
Thanks Alek!
That's wordpress turning them into html-safe values, I'll have to fix my syntax highlighter so that it shows them how they should be.
Luke.
hi,
I'm getting the following error:
D:\Eigene Dateien\webDesign\PV3d\ConeExample\Main.as(59): col: 4 Error: Zugriff auf eine nicht definierte Eigenschaft current_camera.
current_camera = camera;
^
If I change current_camera to default_camera I'm getting a type mismatch error!
thnx
Stefan
"Done. You can download the NEW version of the base class by clicking here!"
I should have read the whole thing first!
Replaced my BaseClass and everything runs now!
hi,
you have forget this line for PaperBase:
import org.papervision3d.core.proto.CameraObject3D;
Hello there guys , i just wanted to know if anyone knows how yo achieve the first person shooter effect for the camera. Imean how do you make the camera follow the mouse (having in mind that the camera should rotate and the mouse should stay in the middle).
Just like in every first person shooter W move forward S move backward A strafe left D strafe right and mouse for Look up down left and right. Also i think that when the camera is looking to the left when you press W it shouldnt look like strafe but move forward should always poin to the direction the camera is aimed at ?
I will be rly grateful if anyone can explain how this thing happens
FWIW: When I adapt this code to a project in Flex Builder, I get a null pointer exception at runtime at this line:
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
As a workaround, I modified the constructor like so:
public function Main()
{
init();
this.addEventListener("addedToStage", onAddedToStage);
}
And added the following function:
public function onAddedToStage(event:Event):void
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
}
This works fine, but if anyone has a better solution please share!
Are you using Flex 2? I just used with Flex3, no errors...
---------------------
Hello there guys , i just wanted to know if anyone knows how yo achieve the first person shooter effect for the camera. Imean how do you make the camera follow the mouse (having in mind that the camera should rotate and the mouse should stay in the middle).
Just like in every first person shooter W move forward S move backward A strafe left D strafe right and mouse for Look up down left and right. Also i think that when the camera is looking to the left when you press W it shouldnt look like strafe but move forward should always poin to the direction the camera is aimed at ?
I will be rly grateful if anyone can explain how this thing happens
-------------________________________
This lets you move the angle of look
camera.rotationX = -(viewport.mouseY - stage.height )/1.5 ;
camera.rotationY = (viewport.mouseX - stage.width )/1.5 ;
however you need to prevent the mouse from leaving the stage,anyoneknow how to do that?
I'm trying this one - I've had success with the previous tutorials, but this one has me stumped. I get an error in the Main.as file - line 62:
col: 36 Error: Type was not found or was not a compile-time constant: InteractiveScene3DEvent.
Here's the line.
private function onPress( e:InteractiveScene3DEvent ):void {
and then there's a bunch of errors on the PaperBase code, but I'm guessing they're occurring as a result of this error?
nevermind. I figured it out. I hadn't added the classpath to Greatwhite.
hallo everybody!
please could you give me a hint - i completed this tutorial and works flawless (thanks Luke!), with only one problem - when i load the flash movie in the html page and reviewing it in browser (no matter of what kind), i have to click the embedded flash to start interaction. usually it has been solved by using the swfobject (2.0) script for implementing the flash movie into the webpage, but it did not help this time. please help!
be good all, thanx
I've successfuly went through all of the tutorials, but this one is giving me an
issue. The problem that I noticed is coming from the the PaperBase.as file that I downloaded and used it for this project. I copied the text from this example and placed it in the Main.as file that I created.
Here is the code exception error-
Running process: C:\Documents and Settings\Administrator\Local Settings\Application Data\FlashDevelop\Tools\fdbuild\fdbuild.exe "C:\Documents and Settings\Administrator\My Documents\PaperBase6\PaperBase6.as2proj" -ipc 612563d0-248f-40bf-8a93-15fb544285fd -compiler "C:\Documents and Settings\Administrator\Local Settings\Application Data\FlashDevelop\tools\mtasc" -library "C:\Documents and Settings\Administrator\Local Settings\Application Data\FlashDevelop\Library" -cp "C:\Documents and Settings\Administrator\Local Settings\Application Data\Adobe\Flash CS3\en\Configuration\Classes"
Building PaperBase6
C:\Documents and Settings\Administrator\My Documents\PaperBase6/PaperBase.as:7: characters 0-7 : parse error Unexpected package
Build halted with errors (mtasc).
Done (1)
Issue Resolved for both PaperBase.as and Main.as in my project.
What happened was that my project was created with AS2 not with AS3.
Applied all the other settings and copied files and pasted code to the Main.as
and it worked like a charm.
Thanks Luke for the tutorials and all of you for posting your comments.
Small issue here, I think?:)
I am testing the .swf file and it works in the folder where it was compiled. But when I put the .swf file in another location and view it in flashplayer it show the 3d object but the image is not available.
Any suggestions welcome.
adapted this script and thought I would share the results. This adds a cube which gets moved around by the arrow keys with some friction. A camera then follows behind the cube with some delay so you can see it rotating. Adjust spring and friction vars for different effects
Hope it helps
package {
import PaperBase;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.display.MovieClip;
import flash.text.TextField;
import org.papervision3d.cameras.FreeCamera3D;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.materials.BitmapFileMaterial;
import org.papervision3d.materials.MovieMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
public class Main extends PaperBase {
public var updown:Boolean=false;
public var leftdown:Boolean=false;
public var downdown:Boolean=false;
public var rightdown:Boolean=false;
public var camera:FreeCamera3D;
public var cube:Cube;
//
private var xpos:Number=0;
private var zpos:Number=0;
private var vx:Number=0;
private var vz:Number=0;
private var vxcam:Number=0;
private var vzcam:Number=0;
private var spring:Number = 0.1;
private var friction:Number=.90;
private var frictioncam:Number=.60;
private var speed:Number=200;
private var spacer:Number=800;
//
// This is the movieclip that we'll use as the texture.
private var movie:MovieClip=new MovieClip;
private var movieFront:MovieClip=new MovieClip;
private var movieBack:MovieClip=new MovieClip;
public function Main() {
init();
stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP,onKeyUp);
trace('Use arrow keys');
}
override protected function init3d():void {
var light:PointLight3D=new PointLight3D(true);
light.y=400;
camera=new FreeCamera3D(1,500);
camera.moveUp(600);
current_camera=camera;
var sidemat:FlatShadeMaterial = new FlatShadeMaterial(light, 0xBBBBBB, 0x000000);
var p:Plane=new Plane(new BitmapFileMaterial("http://papervision2.com/wp-content/downloads/concretetex.jpg"),20000,20000,50,50);
p.pitch(90);
default_scene.addChild(p);
movie.graphics.beginFill(0xFFFFFF);
movie.graphics.drawRect(0,0,500,500);
movie.graphics.endFill();
movie.graphics.beginFill(0x000000);
movie.graphics.drawRect(0,0,10,500);
movie.graphics.drawRect(490,0,10,500);
movie.graphics.drawRect(0,0,500,10);
movie.graphics.drawRect(0,490,500,10);
movie.graphics.endFill();
var movieFrontText:TextField=new TextField;
movieFrontText.text='Front';
movieFront.addChild(movieFrontText);
var movieBackText:TextField=new TextField;
movieBackText.text='Back';
movieBack.addChild(movieBackText);
var mat:MovieMaterial=new MovieMaterial(movie,false,true);
var matFront:MovieMaterial=new MovieMaterial(movieFront,false,true);
var matBack:MovieMaterial=new MovieMaterial(movieBack,false,true);
cube=new Cube(new MaterialsList({all:sidemat,front:matFront,back:matBack}),500,500,500,1,1,1);
cube.y=255;
default_scene.addChild(cube);
}
override protected function processFrame():void {
var angle:Number=cube.rotationY-180;
angle=angle * Math.PI / 180;
if (updown) {
vx=- speed * Math.sin(angle);
vz=- speed * Math.cos(angle);
}
if (downdown) {
vx=speed * Math.sin(angle);
vz=speed * Math.cos(angle);
}
if (leftdown) {
cube.rotationY-= 5;
}
if (rightdown) {
cube.rotationY+= 5;
}
xpos+= vx;
zpos+= vz;
vx*= friction;
vz*= friction;
cube.x=xpos;
cube.z=zpos;
var camtargx:Number=cube.x+spacer*Math.sin(angle);
var camtargz:Number=cube.z+spacer*Math.cos(angle);
var dx:Number = camtargx - camera.x;
var dz:Number = camtargz - camera.z;
var ax:Number = dx * spring;
var az:Number = dz * spring;
vxcam += ax;
vzcam += az;
vxcam *= frictioncam;
vzcam *= frictioncam;
camera.x += vxcam;
camera.z += vzcam;
camera.lookAt(cube);
}
public function onKeyDown(event:KeyboardEvent):void {
//trace(angle)
switch (event.keyCode) {
case Keyboard.UP :
//vz += 3;
updown=true
;
break;
case Keyboard.DOWN :
//vz -= 3;
downdown=true;
break;
case Keyboard.LEFT :
leftdown=true;
break;
case Keyboard.RIGHT :
rightdown=true;
break;
default :
break;
}
}
public function onKeyUp(event:KeyboardEvent):void {
switch (event.keyCode) {
case Keyboard.UP :
updown=false
;
break;
case Keyboard.DOWN :
//vz -= 3;
downdown=false;
break;
case Keyboard.LEFT :
leftdown=false;
break;
case Keyboard.RIGHT :
rightdown=false;
break;
default :
break;
}
}
}
}
I dont know but it does not work for me. I compile the project and run it, but I only have a white screen. Any idea what could be wrong?
hi, there
as I follow all the step from your tutorial from tutorial 1...but and didn't install papervision1.5 b4 but download papervision 2 directly...
but i found the Greatwhite folder do not include CameraObject3D and FreeCamera3D there...and the output always tell me these classes are not included...
would you please tell me what's the matter...and how to solve these problem? as i have encounter this problem for many times...
I just start learning papervision...so please understand if this is a stupid question...:P
btw...your tutorials is do helpful!!!
hi there,
still me...and I have search online...and found this linkage
http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/cameras/
where i can find the FreeCamera3D as file...and add it into camera folder...but when i run the program...more file lost there...
so please suggest some solution for me ba...thx a lot~~
hi there,
btw...i am using flash cs3 IDE PC
Hi all,
I'm using flash CS3 and having difficulty with this particular class. I've done everything required and got everything else working up until now. Only difference is that I'm creating a seperate AS3 class called Interactivity which extends the PaperBase class, and then importing that class into my flash file.
When I run I get the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Interactivity$iinit()
at interactivity_fla::MainTimeline/interactivity_fla::frame1()
so there's a null object in there somewhere, I've a feeling it could be in the PaperBase class...
any suggestions?
Hi,
I'm having the same problem as Evian! Are you using the GreatWhite branch of Papervision! Because mine doesn't have FreeCamera in the cameras folder.
If i point my flash to a different version of Papervision, i get even more errors!
Please can you confirm the version i am meant to use for this tutorial
Thanks
Switching the FreeCamera3D for a Camera3D (import and instances) seems to fix the issue with the missing FreeCamera3D class.
How u do that?
# Comment by Brandon Bradley on July 30, 2008 2:36 am
Switching the FreeCamera3D for a Camera3D (import and instances) seems to fix the issue with the missing FreeCamera3D class.
I had the same problem as Peter. The solution was to switch the FreeCamera3D import and instances to Camera3D along with changing the instiantiation of the Camer3D object.
Change the following code
camera = new FreeCamera3D(1, 500);
to the following
camera = new Camera3D();
camera.zoom = 1;
camera.focus = 500;
ok
camera = new Camera3D();
camera.zoom = 1;
camera.focus = 500;
but there is an empty stage, texture booted that not doing so?
And Keyboard Interaction don't working (((
Cool. it's working)
And u must change the PaperBase...
change the folling code
default_camera = new FreeCamera3D();
to the following
default_camera = new Camera3D();
and
// -- Cameras --//
public var default_camera:FreeCamera3D; // A Camera
to this
// -- Cameras --//
public var default_camera:Camera3D; // A Camera
Hi
Great tuturials. I am learning a lot here thanks.
I notice this change I had to make to PaperBase in order to get the following line addition to be accepted at compilation time:
public var current_camera:CameraObject3D;
add
import org.papervision3d.core.proto.CameraObject3D; // CameraObject3D added
I keep getting this error:
Warning: 1090: Migration issue: The onKeyUp event handler is not triggered automatically by Flash Player at run time in ActionScript 3.0. You must first register this handler for the event using addEventListener ( 'keyUp', callback_handler).