Applying double color transform in AS3 - actionscript-3

Simply put, I would like to set several movieclips to different specific colors and then apply a tint over them.
var color1 = new ColorTransform(); color1.color = 0x0000FF;
var color2 = new ColorTransform(); color2.color = 0x00FF00;
var color3 = new ColorTransform(); color3.color = 0xFFFF00;
thing1.transform.colorTransform = color1;
thing2.transform.colorTransform = color2;
thing3.transform.colorTransform = color3;
thing1.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0);
thing2.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0);
thing3.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0);
unfortunately the colortransform resets the value. Any way to keep the value of the first color transform?

You should be able to do that with the ColorTransform.concat() function.
var color1 = new ColorTransform(); color1.color = 0x0000FF;
var color2 = new ColorTransform(); color2.color = 0x00FF00;
var color3 = new ColorTransform(); color3.color = 0xFFFF00;
color1.concat( new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0) );
color2.concat( new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0) );
color3.concat( new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0) );
thing1.transform.colorTransform = color1;
thing2.transform.colorTransform = color2;
thing3.transform.colorTransform = color3;
Which essentially is the same as (clamping offset values to 255 using Math.min):
thing1.transform.colorTransform = new ColorTransform(1*1, 1*1, 1*1, 1*1, Math.min(0x00+0, 0xFF), Math.min(0x00+200, 0xFF), Math.min(0xFF+150, 0xFF), Math.min(0x00+0, 0xFF));
thing2.transform.colorTransform = new ColorTransform(1*1, 1*1, 1*1, 1*1, Math.min(0x00+0, 0xFF), Math.min(0xFF+200, 0xFF), Math.min(0x00+150, 0xFF), Math.min(0x00+0, 0xFF));
thing3.transform.colorTransform = new ColorTransform(1*1, 1*1, 1*1, 1*1, Math.min(0xFF+0, 0xFF), Math.min(0xFF+200, 0xFF), Math.min(0x00+150, 0xFF), Math.min(0x00+0, 0xFF));
Or:
thing1.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0x00, 0xC8, 0xFF, 0x00);
thing2.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0x00, 0xFF, 0x96, 0x00);
thing3.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0xFF, 0xFF, 0x96, 0x00);

I've found a solution to this problem.
If I set an object to a color
var color1 = new ColorTransform(); color1.color = 0x0000FF;
thing1.transform.colorTransform = color1;
I can then edit the blue and green values as so to get my desired tint
color1.blueOffset+=200;
color1.greenOffset+=150;
And then use colortransform on the object to set the new color
thing1.transform.colorTransform = color1;

Related

Three.js THREE.DeviceOrientationControls is not a constructor

I have a problem with ThreeJS giving me this error message. I included all the necessary ThreeJS files but still this message appears. My intention is to have a mobile device navigating with DeviceOrientationControl.js. Mousemove works very well, but I can't get this to work. Any ideas?
Uncaught TypeError: THREE.DeviceOrientationControls is not a constructor
at init ((index):201)
at (index):193
Error Message
<script type="module">
import * as THREE from '/bftest/three/build/three.module.js';
import {OrbitControls} from '/bftest/three/examples/jsm/controls/OrbitControls.js';
import {GLTFLoader} from '/bftest/three/examples/jsm/loaders/GLTFLoader.js';
import {DeviceOrientationControls} from '/bftest/three/examples/jsm/controls/DeviceOrientationControls.js';
var camera, scene, renderer, stats, controls, windowHalfX = window.innerWidth / 2,
windowHalfY = window.innerHeight / 2,
mouseX = 0,
mouseY = 0;
var renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.shadowMapSoft = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
var width = window.innerWidth;
var height = window.innerHeight;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
controls = new THREE.DeviceOrientationControls(camera);
camera.position.set(0, 0, 8);
scene = new THREE.Scene();
var directionalLight = new THREE.DirectionalLight(0xffffff, 5);
directionalLight.color.setHSL(0.1, 1, 0.95);
directionalLight.position.set(0, 1, 1);
directionalLight.position.multiplyScalar(10);
scene.add(directionalLight);
directionalLight.shadow.mapSize.width = 2048;
directionalLight.shadow.mapSize.height = 2048;
directionalLight.shadow.camera.left = -20;
directionalLight.shadow.camera.right = 20;
directionalLight.shadow.camera.top = 20;
directionalLight.shadow.camera.bottom = -20;
directionalLight.shadow.camera.near = 1;
directionalLight.shadow.camera.far = 200;
directionalLight.shadowCameraVisible = true;
var spotLight1 = new THREE.DirectionalLight( 0xff4000 );
spotLight1.position.set( -15, 3, -4 );
spotLight1.target.position.set( 0, 1, 0 );
spotLight1.intensity = 1.2;
spotLight1.shadowDarkness = 0.5;
spotLight1.shadowcameranear = 0;
spotLight1.shadowcamerafar = 15;
spotLight1.shadowcameraleft = -5;
spotLight1.shadowcameraright = 5;
spotLight1.shadowcameratop = 5;
spotLight1.shadowcamerabottom = -5;
spotLight1.castShadow = true;
scene.add( spotLight1 );
var spotLight2 = new THREE.DirectionalLight( 0xff0aea );
spotLight2.position.set( 15, 3, -4 );
spotLight2.target.position.set( 0, 1, 0 );
spotLight2.intensity = 1.2;
spotLight2.castShadow = true;
scene.add( spotLight2 );
var hemisphereLight = new THREE.HemisphereLight(0xffffff,0x000000, .5)
var shadowLight = new THREE.DirectionalLight(0xff8f16, .4);
shadowLight.position.set(50, 0, 22);
shadowLight.target.position.set(50, 50, 0);
shadowLight.rotation.set(Math.PI / -2, 0, 0);
shadowLight.shadow.camera.near = 0.5;
shadowLight.shadow.camera.far = 5000;
shadowLight.shadow.camera.left = -500;
shadowLight.shadow.camera.bottom = -500;
shadowLight.shadow.camera.right = 500;
shadowLight.shadow.camera.top = 500;
scene.add(shadowLight);
var light2 = new THREE.DirectionalLight(0xfff150, .25);
light2.position.set(-600, 350, 350);
var light3 = new THREE.DirectionalLight(0xfff150, .15);
light3.position.set(0, -250, 300);
scene.add(hemisphereLight);
scene.add(shadowLight);
const gltfLoader = new GLTFLoader();
gltfLoader.load('./3D/Bobby.glb', (gltf) => {
const root = gltf.scene;
root.rotateY(-89.55);
root.position.set(0, -0.7, 0);
root.castShadow = true;
gltf.scene.traverse(function(node) {
if (node instanceof THREE.Mesh) {
node.castShadow = true;
}
});
scene.add(root);//default is false
// compute the box that contains all the stuff
// from root and below
const box = new THREE.Box3().setFromObject(root);
const boxSize = box.getSize(new THREE.Vector3()).length();
const boxCenter = box.getCenter(new THREE.Vector3());
// set the camera to frame the box
frameArea(boxSize * 0.7, boxSize, boxCenter, camera);
box.castShadow = true;
// update the Trackball controls to handle the new size
controls.maxDistance = boxSize * 10;
controls.target.copy(boxCenter);
});
renderer = new THREE.WebGLRenderer({ antialias: true, canvas: document.querySelector('canvas'), alpha: true, });
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
window.addEventListener( 'resize', onWindowResize, false );
window.addEventListener('mousemove', onDocumentMouseMove, false);
}
function onDocumentMouseMove(event) {
mouseX = - (event.clientX - windowHalfX) /150;
mouseY = - (event.clientY - windowHalfY) /150;
}
function animate() {
requestAnimationFrame(animate);
render(scene,camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function render() {
camera.position.x += (mouseX - camera.position.x)*0.9;
camera.position.y += (-mouseY - camera.position.y)*0.9;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
</script>
When importing examples files like DeviceOrientationControls via ES6 modules, using the THREE namespace is not necessary anymore. So instead of
controls = new THREE.DeviceOrientationControls(camera);
use
controls = new DeviceOrientationControls(camera);

How to use Matrix3D.appendTranslation()?

With stage 3d I set up a basic triangle, and I can use append rotation and append scale and everything works, but using append translation on the z axis, the triangle will dissapear with the translation being 1 or higher. With other shapes it would dissapear with only 3 or higher. And it doesn't look like the triangle is getting any smaller/farther away between 0 and 0.9 translation. The translation on the x and y axis do work though.
Here are my shader codes:
private static const VERTEX_SHADER_SOURCE:String = "m44 op, va0, vc1";
private static const FRAGMENT_SHADER_SOURCE:String = "mov oc, fc0";
my render loop:
addEventListener(Event.ENTER_FRAME, enter);
var t:Number=0;
function enter():void {
context3D.clear();
context3D.setProgram(program);
var m:Matrix3D = new Matrix3D;
m.appendTranslation(0, 0, t);
t+=0.01;
context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 1, m, true);
context3D.setVertexBufferAt(0, buffer, 0, Context3DVertexBufferFormat.FLOAT_3);
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, color);
context3D.drawTriangles(indexBuffer);
context3D.present();
}
my full code:
var assembler:AGALMiniAssembler = new AGALMiniAssembler();
assembler.assemble(Context3DProgramType.VERTEX, VERTEX_SHADER_SOURCE);
if (assembler.error) {
trace("vertex shader error " +assembler.error);
return;
}
var vertexShaderByteCode:ByteArray = assembler.agalcode;
assembler.assemble(Context3DProgramType.FRAGMENT, FRAGMENT_SHADER_SOURCE);
if (assembler.error) {
trace("fragment shader error " + assembler.error);
return;
}
var fragmentShaderByteCode:ByteArray = assembler.agalcode;
var program:Program3D = context3D.createProgram();
try {
program.upload(vertexShaderByteCode, fragmentShaderByteCode);
}
catch (err:Error) {
trace("couldnt upload shader program" + err);
return;
}
color = new <Number>[0.9296875, 0.9140625, 0.84765625, 1];
var verts:Vector.<Number> = Vector.<Number>([
0.5, 0, 0,
-0.5, 0, 0,
0, 0.5, 0
]);
var buffer:VertexBuffer3D = context3D.createVertexBuffer(3, 3);
buffer.uploadFromVector(verts, 0, 3);
var indices:Vector.<uint> = Vector.<uint>([0, 1, 2])
var indexBuffer:IndexBuffer3D = context3D.createIndexBuffer(3);
indexBuffer.uploadFromVector(indices, 0, 3);
addEventListener(Event.ENTER_FRAME, enter);
var t:Number=0;
function enter():void {
context3D.clear();
context3D.setProgram(program);
var m:Matrix3D = new Matrix3D;
m.appendTranslation(0, 0, t);
t+=0.01;
context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 1, m, true);
context3D.setVertexBufferAt(0, buffer, 0, Context3DVertexBufferFormat.FLOAT_3);
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, color);
context3D.drawTriangles(indexBuffer);
context3D.present();
}

Objects pass through each other

I've two objects, one is static and another one is dynamic. Fixtures of both of them created from ChainShape. The problem is that they pass through each other.
Screenshot :
Two ChainShapes dont collide with each other make one of them a PolygonShape.
This works for me:
BodyDef triangleDef = new BodyDef();
triangleDef.type = BodyDef.BodyType.DynamicBody;
triangleDef.position.set( 0, 0 );
Body triangleBody = this.world.createBody( triangleDef );
PolygonShape triangleShape = new PolygonShape();
triangleShape.set( new float[]{ 0, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f } );
triangleBody.createFixture( triangleShape, 1 );
triangleShape.dispose();
BodyDef groundDef = new BodyDef();
triangleDef.position.set( 0, 0 );
Body groundBody = this.world.createBody( groundDef );
ChainShape groundShape = new ChainShape();
groundShape.createLoop( new float[]{ -10, 10, -10, -10, 10, -10, 10, 10 } );
groundBody.createFixture( groundShape, 1 );
groundShape.dispose();

AS3: Tile based movement system

very new to as3 and using a tutorial found here to try my hand at tile based movement. However, i cant seem to get the code to work. I keep getting the error code:
"1046: Type was not found or was not a compile-time constant:hero."
The line it is reference is:
var character: hero = new hero();
My full code is:
package {
import flash.display.MovieClip;
import flash.events.*;
public class main2 extends MovieClip {
var hero;
public function main2() {
// Create map
var mapWidth = 10;
var mapHeight = 10;
var tileSide = 32;
var totalTiles = mapWidth * mapHeight;
var myMap: Array = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 1, 0, 0, 1],
[1, 0, 0, 1, 0, 0, 1, 0, 0, 1],
[1, 0, 0, 1, 1, 1, 1, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
];
for (var i: int = 0; i < mapHeight; i++) {
for (var u: int = 0; u < mapWidth; u++) {
var cell: MovieClip = new tile();
cell.gotoAndStop(myMap[i][u] + 1);
cell.x = tileSide * u;
cell.y = tileSide * i;
addChild(cell);
}
}
// Hero management
var heroSpawnX = 4;
var heroSpawnY = 2;
var character: hero = new hero();
addChild(character);
character.x = heroSpawnX * tileSide;
character.y = heroSpawnY * tileSide;
var heroX = heroSpawnX;
var heroY = heroSpawnY;
// Basic movement
stage.addEventListener(KeyboardEvent.KEY_DOWN, movement);
function movement(event: KeyboardEvent):void {
if (event.keyCode == 40 && myMap[heroY + 1][heroX] == 0) {
character.gfx.rotation = 0;
character.y += tileSide;
heroY++;
}
if (event.keyCode == 38 && myMap[heroY - 1][heroX] == 0) {
character.gfx.rotation = 180;
character.y -= tileSide;
heroY--;
}
if (event.keyCode == 39 && myMap[heroY][heroX + 1] == 0) {
character.gfx.rotation = 270;
character.x += tileSide;
heroX++;
}
if (event.keyCode == 37 && myMap[heroY][heroX - 1] == 0) {
character.gfx.rotation = 90;
character.x -= tileSide;
heroX--;
}
}
}
}
}
Any help on this issue would be great, been at it for an hour now.
also if you have any recommendations on as3 resources please let me know...specifically tiled based systems.
thanks is advanced.
That error means your class Hero is not found. you should put the hero.as file at where your main2.as file is(at same location as main2.as). and then import it:
import Hero;
 
and my recommendation on as3 resources:
1.http://republicofcode.com:I think best site for starting as3.I started from it.
2.http://kirupa.com: a good site with a lot of articles
3.http://flashandmath.com: for professionals
and don't forget Adobe ActionScript-3 API reference:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/
I   H☺ P E   this helps !

What are width and height supposed to represent for a sprite?

I'm working with a Sprite in AS3. Initially, width,height are 0,0 as expected.
After this:
var tf : TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 48;
tf.bold = true;
text = new TextField();
text.text = "A";
text.x = 30;
text.y = 16;
text.selectable = false;
text.setTextFormat(tf);
addChild(text);
they are 100,100 (even if I shrink the text size).
After this
graphics.beginFill(0xffffff, 1);
graphics.drawRect(0, 0, 99, 99);
graphics.endFill();
graphics.beginFill(color, 1);
graphics.drawRoundRect(6, 6, 84, 84, 8, 8);
graphics.endFill();
They are 130,116. I would expect them to end up at 99,99, what am I missing?
Modification: here's the code from the first answer, but modified to use a single sprite:
var s = new Sprite();
trace("1:", s.width, ", ", s.height) // <-- 0 , 0
var tf : TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 48;
tf.bold = true;
var text = new TextField();
text.text = "A";
text.x = 30;
text.y = 16;
text.selectable = false;
text.setTextFormat(tf);
s.addChild(text);
trace("2:", s.width, ", ", s.height) //<-- 100, 100
s.graphics.beginFill(0xffffff, 1);
s.graphics.drawRect(0, 0, 99, 99);
s.graphics.endFill();
s.graphics.beginFill(0x000fff, 1);
s.graphics.drawRoundRect(6, 6, 84, 84, 8, 8);
s.graphics.endFill();
trace("3:", s.width, ", ", s.height) //<-- 130,116
Can anyone explain why these 2 behave differently?
Cheers,
Charlie.
I don't know what you're doing elsewhere, but your code is right.
import flash.display.Sprite;
var s = new Sprite();
trace(s.width, ", ", s.height) // <-- 0 , 0
var tf : TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 48;
tf.bold = true;
var text = new TextField();
text.text = "A";
text.x = 30;
text.y = 16;
text.selectable = false;
text.setTextFormat(tf);
s.addChild(text);
trace(s.width, ", ", s.height) //<-- 100, 100
var s2 = new Sprite();
with(s2) {
graphics.beginFill(0xffffff, 1);
graphics.drawRect(0, 0, 99, 99);
graphics.endFill();
graphics.beginFill(0x000fff, 1);
graphics.drawRoundRect(6, 6, 84, 84, 8, 8);
graphics.endFill();
}
trace(s2.width, ", ", s2.height) //<-- 99, 99
Are the results I get. Is something else in your code scaling objects?
the width and height attribute for a textfield returns the width and height of the textfield boarder, which by default is 100 x 100
try this to see what I'm talking about
text.border = true;
if you want the actual size of the text in the textfield you need
trace(text.textWidth);
trace(text.textHeight);