we have following function to create object wall:
function placeWorkareaWithSlope(points, waDetail, drawLine = true) {
const workareaHeight = Number(waDetail.WorkareaHeight) || 10;
const workareaParapet = Number(waDetail.WorkareaParapet) || 3;
// Different color wall for workarea
drawWallForWorkareaWithSlope(points, workareaHeight, waDetail);
drawWallBoxForWorkareaWithSlope(points, workareaHeight, waDetail);
// Convert points array to accrding to 3D space Quadrant
const convertedPoints = convertTo3dQuadrant(points);
const shape = [];
for (let i = 0; i < convertedPoints.length; i++) {
const e = convertedPoints[i];
shape.push(new THREE.Vector2(e.x, e.y));
}
const workareaShape = new THREE.Shape(shape);
const extrusionSettings = {
steps: 1,
depth: workareaHeight,
bevelEnabled: false,
};
const workareaGeometry = new THREE.ExtrudeGeometry(workareaShape, extrusionSettings);
workareaGeometry.computeVertexNormals();
workareaGeometry.computeFaceNormals();
const workarea = new THREE.Mesh(workareaGeometry, workareaMaterial);
workarea.rotation.x = -THREE.Math.degToRad(90);
//added by kd to define slope angle
objRotation(points, waDetail, workarea);
//end kd
workarea.receiveShadow = isRenderShaodw;
workarea.castShadow = isRenderWorkareaShadow;
scene.add(workarea);
// DrawLines
if (drawLine && workarea && workarea.geometry) {
const lineGeo = new THREE.EdgesGeometry(workarea.geometry);
const wireframe = new THREE.LineSegments(lineGeo, workareaLineMaterial);
wireframe.renderOrder = 1;
workarea.add(wireframe);
}
}
once we create wall over scene after that we rotate it base on slope provided with objRotation function with obj.rotation.y but when we rotate it at that movement object change its place, basically we require object should be there with world axis
following is object rotation function :
function objRotation(points, waDetail, obj) {
const Point1 = points[0];
const Point2 = points[1];
const Point3 = points[2];
const Point4 = points[3];
const slopeAngle = Number(waDetail.Angle) || 0;
if (waDetail.SlopeDirection == "P1 to P2") {
xDiff = Point1.x - Point2.x;
yDiff = Point1.y - Point2.y;
}
if (waDetail.SlopeDirection == "P2 to P3") {
xDiff = Point2.x - Point3.x;
yDiff = Point2.y - Point3.y;
}
if (waDetail.SlopeDirection == "P3 to P4") {
xDiff = Point3.x - Point4.x;
yDiff = Point3.y - Point4.y;
}
if (waDetail.SlopeDirection == "P4 to P1") {
xDiff = Point4.x - Point1.x;
yDiff = Point4.y - Point1.y;
}
if (Math.abs(xDiff) > Math.abs(yDiff)) {
if (obj.rotation.x > 0) {
if (xDiff > 0)
obj.rotation.y += THREE.Math.degToRad(slopeAngle);
else
obj.rotation.y -= THREE.Math.degToRad(slopeAngle);
}
else {
if (xDiff > 0)
obj.rotation.y -= THREE.Math.degToRad(slopeAngle);
else
obj.rotation.y += THREE.Math.degToRad(slopeAngle);
}
} else {
if (yDiff<0)
obj.rotation.x += THREE.Math.degToRad(slopeAngle);
else
obj.rotation.x -= THREE.Math.degToRad(slopeAngle);
}
}
So for the above issue, can someone guide me?
The wall created by the code with height and width provided by system and it rotates 90 degrees to setup over map surface but after that we have a requirement to slope its base on an angle so we added one more rotation there with provided slope angle by user. But when this slope angle rotation applied to object the object change its height base on camera left or right distance. We require the object should be same place there as before after rotation.
i have created wall using path in three js. I want change the color option buttion automatically need to change the color onclick event.
Below my color any one help me.
// wall 1 inside
item_count = 1;
var wall_x1 = 69;
var wall_y1 = 55;
var wall_x2 = 366;
var wall_y2 = 52;
var wall_z = 0;
var wall_width = 5;
var wall_height = default_height;
var wall_wall_width = 5;
if(!wall_wall_width) { wall_wall_width = 5; }
var wall_wall_elevation = planner_default_height;
if(!wall_wall_elevation) { wall_wall_elevation = default_height; }
var wall_top_filltype = 'texture';
var wall_top_fill = 'default_wall.jpg';
var wall_side_filltype = 'texture';
var wall_side_fill = 'wall5.jpg';
if ( item_count == 0 )
{
starting_x_value = wall_x1;
starting_y_value = wall_y1;
}
path = generate_path_byline(wall_x1,wall_y1,wall_x2,wall_y2,default_depth);
path_type ="wall";
x=starting_x_value-wall_x1; y=starting_y_value-wall_y1;
// z=default_height/2;
path_transform = transformSVGPath(path);
create_surface(1,1,path_type,path_transform,starting_x_value,starting_y_value,x,y,z,default_height,wall_wall_elevation,wall_top_filltype,wall_top_fill,wall_side_filltype,wall_side_fill);
I see no clear way of defining the material at your sample code, or at least the way three.js does it:
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
If you use as a material a texture with an image, you have many ways to change its color... one easy trick could be to change the light color that lightens the scene or this object.
I'm importing .3DS models into Blender 2.72b, then exporting them with the Three.js import/export addon. The models have multiple geometry 'islands' (separate groups of connected faces and vertices), each with its own material. I'd like to be able to pair each material with its corresponding island, without having to create separate THREE.Geometry objects. After some digging, I found this question which suggests using a THREE.MeshFaceMaterial to achieve multiple materials for one object. The only problem is that the geometry in that example is a simple cube, whereas my models have hundreds of faces spread across 2-5 islands.
Does Three.js have functionality for identifying geometry 'islands' in a mesh?
No. three.js does not have functionality for identifying geometry 'islands' in a mesh.
When using MeshFaceMaterial, WebGLRenderer breaks the geometry into chunks anyway -- one chunk for each material. It does that because WebGL supports one shader per geometry.
I would not merge all your geometries, and then use MeshFaceMaterial, only to have the renderer break the single geometry apart.
You can merge geometries that share a single material if you wish.
three.js r.69
I tried with a function but still is not accurate, it produce more geometries than non connected geometries:
If somebody could have a look on it, it would be grate.
function groupGeometryIntoNonConnectedGeometries(geometry) {
const material = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
vertexColors: THREE.VertexColors
});
let geometryArray = [];
const indexArray = geometry.index.array;
const positionArray = geometry.attributes.position.array;
const positionCount = geometry.attributes.position.count;
const color = new THREE.Vector3(geometry.attributes.color.array[0], geometry.attributes.color.array[1], geometry.attributes.color.array[2]);
const totalTriangles = indexArray.length / 3;
let geometryCount = 0;
let indexValueAlreadyVisited = new Uint8Array(indexArray.length);
let structure = [];
/*
* indexValue: {
* child: [ [indexval0, indexval1], [] ],
* parent: null
* }
*/
// Initialize Structure:
for (var vextexIdx=0; vextexIdx<positionCount; vextexIdx++) {
structure[vextexIdx] = {
child: [],
parent: null
}
}
for (idx=0; idx<totalTriangles; idx++) {
const geoIndex1 = indexArray[idx*3];
const geoIndex2 = indexArray[idx*3+1];
const geoIndex3 = indexArray[idx*3+2];
const triangleIndexVertexArray = [ geoIndex1, geoIndex2, geoIndex3 ].sort(function(a, b) {
return a - b;
});
structure[ triangleIndexVertexArray[0] ].child.push(triangleIndexVertexArray[1], triangleIndexVertexArray[2]);
structure[ triangleIndexVertexArray[1] ].parent = triangleIndexVertexArray[0];
structure[ triangleIndexVertexArray[2] ].parent = triangleIndexVertexArray[0];
}
let count = 0;
let currentCount = 0;
let geometryStructureArray = [];
for (let strIdx=0; strIdx<structure.length; strIdx++) {
if (structure[strIdx].parent == null) {
currentCount = count;
geometryStructureArray[currentCount] = {
name: "G_" + currentCount,
indexMap: {},
currentIndex: 0,
indexArray: [],
positionArray: [],
colorArray: []
};
count += 1;
}
if (structure[strIdx].child.length > 0) {
const childLen = structure[strIdx].child.length / 2;
for (let childIdx=0; childIdx<childLen; childIdx++) {
const vertexIndex0 = strIdx;
const vertexIndex1 = structure[strIdx].child[childIdx*2];
const vertexIndex2 = structure[strIdx].child[childIdx*2+1];
const v0 = new THREE.Vector3( positionArray[strIdx*3], positionArray[strIdx*3+1], positionArray[strIdx*3+2] );
const v1 = new THREE.Vector3( positionArray[vertexIndex1*3], positionArray[vertexIndex1*3+1], positionArray[vertexIndex1*3+2] );
const v2 = new THREE.Vector3( positionArray[vertexIndex2*3], positionArray[vertexIndex2*3+1], positionArray[vertexIndex2*3+2] );
// check vertex0
if (geometryStructureArray[currentCount].indexMap[vertexIndex0] == undefined) {
geometryStructureArray[currentCount].indexMap[vertexIndex0] = geometryStructureArray[currentCount].currentIndex;
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
geometryStructureArray[currentCount].positionArray.push(v0.x, v0.y, v0.z);
geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
geometryStructureArray[currentCount].currentIndex += 1;
} else {
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex0]);
}
// check vertex1
if (geometryStructureArray[currentCount].indexMap[vertexIndex1] == undefined) {
geometryStructureArray[currentCount].indexMap[vertexIndex1] = geometryStructureArray[currentCount].currentIndex;
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
geometryStructureArray[currentCount].positionArray.push(v1.x, v1.y, v1.z);
geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
geometryStructureArray[currentCount].currentIndex += 1;
} else {
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex1]);
}
// check vertex1
if (geometryStructureArray[currentCount].indexMap[vertexIndex2] == undefined) {
geometryStructureArray[currentCount].indexMap[vertexIndex2] = geometryStructureArray[currentCount].currentIndex;
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
geometryStructureArray[currentCount].positionArray.push(v2.x, v2.y, v2.z);
geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
geometryStructureArray[currentCount].currentIndex += 1;
} else {
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex2]);
}
}
}
}
// Convert to geometryArray:
const geometryStructureArrayLen = geometryStructureArray.length;
const object3d = new THREE.Object3D();
for (let geoIdx=0; geoIdx<geometryStructureArrayLen; geoIdx++) {
const geo = new THREE.BufferGeometry();
geo.name = "G_" + geoIdx;
const geoPositions = new Float32Array(geometryStructureArray[geoIdx].positionArray);
const geoColors = new Float32Array(geometryStructureArray[geoIdx].colorArray);
const geoIndices = new Uint32Array(geometryStructureArray[geoIdx].indexArray);
//console.log(geoIdx, "geoPositions: ", geoPositions);
//console.log(geoIdx, "geoColors: ", geoColors);
//console.log(geoIdx, "geoIndices: ", geoIndices);
geo.index = new THREE.BufferAttribute(geoIndices, 1, false);
geo.attributes.position = new THREE.BufferAttribute(geoPositions, 3, false);
geo.attributes.color = new THREE.BufferAttribute(geoColors, 3, true);
geo.computeBoundingSphere();
geo.computeBoundingBox();
const mesh = new THREE.Mesh(geo, material);
mesh.name = "M_" + geoIdx;
object3d.add(mesh);
}
//return [structure, geometryStructureArray, object3d, count];
return object3d;
}
Best regards
This is I think the correct way:
function unmergeGeometryArray(geometry) {
// Asumptions:
// geometry is BufferGeometry
// The geometry has no index duplicates (2 equal positions with different index) neither empty triangles, the geometry has been processed with mergeVertices function
// normal attribute is discarded, can be recomputed after, only color and position attributes are taken into account
const material = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
vertexColors: THREE.VertexColors
});
const indexArray = geometry.index.array;
const positionArray = geometry.attributes.position.array;
const positionCount = geometry.attributes.position.count;
const totalTriangles = indexArray.length / 3;
let triangleVisitedArray = new Uint8Array(totalTriangles);
let indexVisitedArray = new Uint8Array(positionCount);
let indexToTriangleIndexMap = [];
let missingVertices = positionCount;
let missingTriangles = totalTriangles;
// Functions:
function computeTrianglesRecursive(index, out){
//console.log("- start of computeTriangles with index:", index);
if (indexVisitedArray[index] === 1 || missingVertices === 0 || missingTriangles === 0) {
return;
}
indexVisitedArray[index] = 1;
missingVertices -= 1;
let triangleIndexArray = indexToTriangleIndexMap[index];
for(let i=0; i<indexToTriangleIndexMap[index].length; i++) {
let triangleIndex = indexToTriangleIndexMap[index][i];
if (triangleVisitedArray[triangleIndex] === 0) {
triangleVisitedArray[triangleIndex] = 1
missingTriangles -= 1;
//console.log("-- index: ", index, "; i: ", i, "; triangleIndex: ", triangleIndex);
out.push(triangleIndex);
childIndex1 = indexArray[triangleIndex*3+1];
computeTriangles(childIndex1, out);
childIndex2 = indexArray[triangleIndex*3+2];
computeTriangles(childIndex2, out);
}
}
}
function computeTriangles(indexTocheck){
let out = [];
let startIndex = indexTocheck;
let indexToCheckArray = [indexTocheck];
let i = 0;
while (i<indexToCheckArray.length) {
let index = indexToCheckArray[i];
if (indexVisitedArray[index] == 0) {
indexVisitedArray[index] = 1;
missingVertices -= 1;
let triangleIndexArray = indexToTriangleIndexMap[index];
for(let j=0; j<indexToTriangleIndexMap[index].length; j++) {
let triangleIndex = indexToTriangleIndexMap[index][j];
if (triangleVisitedArray[triangleIndex] === 0) {
triangleVisitedArray[triangleIndex] = 1;
missingTriangles -= 1;
out.push(triangleIndex);
let rootIndex = indexArray[triangleIndex*3];
let child1Index = indexArray[triangleIndex*3+1];
let child2Index = indexArray[triangleIndex*3+2];
if (indexToCheckArray.indexOf(rootIndex) === -1) {
indexToCheckArray.push(rootIndex);
}
if (indexToCheckArray.indexOf(child1Index) === -1) {
indexToCheckArray.push(child1Index);
}
if (indexToCheckArray.indexOf(child2Index) === -1) {
indexToCheckArray.push(child2Index);
}
}
}
}
i +=1;
}
return out;
}
// In the first loop we reorder indices asc order + generate map
for (triangleIndex=0; triangleIndex<totalTriangles; triangleIndex++) {
const geoIndex1 = indexArray[triangleIndex*3];
const geoIndex2 = indexArray[triangleIndex*3+1];
const geoIndex3 = indexArray[triangleIndex*3+2];
const triangleIndexVertexArray = [ geoIndex1, geoIndex2, geoIndex3 ].sort(function(a, b) {
return a - b;
});
if (indexToTriangleIndexMap[geoIndex1] === undefined) {
indexToTriangleIndexMap[geoIndex1] = [triangleIndex];
} else {
indexToTriangleIndexMap[geoIndex1].push(triangleIndex);
}
if (indexToTriangleIndexMap[geoIndex2] === undefined) {
indexToTriangleIndexMap[geoIndex2] = [triangleIndex];
} else {
indexToTriangleIndexMap[geoIndex2].push(triangleIndex);
}
if (indexToTriangleIndexMap[geoIndex3] === undefined) {
indexToTriangleIndexMap[geoIndex3] = [triangleIndex];
} else {
indexToTriangleIndexMap[geoIndex3].push(triangleIndex);
}
//indexArray[triangleIndex*3] = triangleIndexVertexArray[0];
//indexArray[triangleIndex*3+1] = triangleIndexVertexArray[1];
//indexArray[triangleIndex*3+2] = triangleIndexVertexArray[2];
}
let geometryTriangleArray = [];
let index = 0;
while (index<indexToTriangleIndexMap.length && missingVertices>0 && missingTriangles>0){
let out = [];
if (indexVisitedArray[index] === 0) {
out = computeTriangles(index);
}
if (out.length > 0) {
geometryTriangleArray.push(out);
}
index += 1;
}
let geometryArray = [];
for (let i=0; i<geometryTriangleArray.length; i++) {
let out = {
positionArray: [],
colorArray: [],
indexArray: [],
indexMap: [],
currentIndex: 0
}
let triangleArray = geometryTriangleArray[i];
for (let j=0; j<triangleArray.length; j++) {
let triangleIndex = triangleArray[j];
let rootIndex = indexArray[triangleIndex*3];
if (out.indexMap[rootIndex] === undefined) {
out.indexMap[rootIndex] = out.currentIndex;
// add vertex position and color
out.positionArray.push(
geometry.attributes.position.array[rootIndex*3],
geometry.attributes.position.array[rootIndex*3+1],
geometry.attributes.position.array[rootIndex*3+2]
);
if (geometry.attributes.color != undefined) {
out.colorArray.push(
geometry.attributes.color.array[rootIndex*3],
geometry.attributes.color.array[rootIndex*3+1],
geometry.attributes.color.array[rootIndex*3+2]
);
}
out.currentIndex += 1;
}
let child1Index = indexArray[triangleIndex*3+1];
if (out.indexMap[child1Index] === undefined) {
out.indexMap[child1Index] = out.currentIndex;
// add vertex position and color
out.positionArray.push(
geometry.attributes.position.array[child1Index*3],
geometry.attributes.position.array[child1Index*3+1],
geometry.attributes.position.array[child1Index*3+2]
);
if (geometry.attributes.color != undefined) {
out.colorArray.push(
geometry.attributes.color.array[child1Index*3],
geometry.attributes.color.array[child1Index*3+1],
geometry.attributes.color.array[child1Index*3+2]
);
}
out.currentIndex += 1;
}
let child2Index = indexArray[triangleIndex*3+2];
if (out.indexMap[child2Index] === undefined) {
out.indexMap[child2Index] = out.currentIndex;
// add vertex position and color
out.positionArray.push(
geometry.attributes.position.array[child2Index*3],
geometry.attributes.position.array[child2Index*3+1],
geometry.attributes.position.array[child2Index*3+2]
);
if (geometry.attributes.color != undefined) {
out.colorArray.push(
geometry.attributes.color.array[child2Index*3],
geometry.attributes.color.array[child2Index*3+1],
geometry.attributes.color.array[child2Index*3+2]
);
}
out.currentIndex += 1;
}
// Add indices:
out.indexArray.push(out.indexMap[rootIndex], out.indexMap[child1Index], out.indexMap[child2Index]);
}
const geoPositions = new Float32Array(out.positionArray);
const geoColors = new Float32Array(out.colorArray);
const geoIndices = new Uint32Array(out.indexArray);
const geo = new THREE.BufferGeometry();
geo.name = "G_" + i;
geo.index = new THREE.BufferAttribute(geoIndices, 1, false);
geo.attributes.position = new THREE.BufferAttribute(geoPositions, 3, false);
geo.attributes.color = new THREE.BufferAttribute(geoColors, 3, true);
geo.computeBoundingSphere();
geo.computeBoundingBox();
geometryArray.push(geo);
}
return geometryArray;
}
So I have a Flash ActionScript 2 code, which creates a preset amount of enemies, gives enemies stats, and makes them move around randomly. Code:
//Settings
var mapWidth:Number = 550;
var mapHeight:Number = 400;
var enemiesArray:Array = new Array();
var totalEnemies:Number;
var eClip:MovieClip;
//Math functions
function getdistance(x, y, x1, y1)
{
run = x1-x;
rise = y1-y;
return (hyp(run, rise));
}
function hyp(a, b)
{
return (Math.sqrt(a*a+b*b));
}
function resetDirection(mc:MovieClip)
{
mc.roamTime = random(50);
mc.t = mc.roamTime;
mc.roamDistance = random(60)+25;
mc.randomRoamDistanceX = (Math.random()*mc.roamDistance)+mc.xx-(mc.roamDistance/2);
mc.randomRoamDistanceY = (Math.random()*mc.roamDistance)+mc.yy-(mc.roamDistance/2);
mc.newRoamDistance = getdistance(mc._x, mc._y, mc.randomRoamDistanceX, mc.randomRoamDistanceY);
mc.norm = mc.roamSpeed/mc.newRoamDistance;
mc.finalRoamDistanceX = (mc.randomRoamDistanceX-mc.xx)*mc.norm;
mc.finalRoamDistanceY = (mc.randomRoamDistanceY-mc.yy)*mc.norm;
}
//function to move enemies
function moveIt(mc:MovieClip)
{
//reduce roamTime;
mc.t--;
//move enemy to new position
if (getdistance(mc._x, mc._y, mc.randomRoamDistanceX, mc.randomRoamDistanceY)>mc.roamSpeed) {
mc._x += mc.finalRoamDistanceX;
mc._y += mc.finalRoamDistanceY;
}
//rotate enemy
XXXdiff = mc.xx-mc.randomRoamDistanceX;
YYYdiff = -(mc.yy-mc.randomRoamDistanceY);
rrradAngle = Math.atan(YYYdiff/XXXdiff);
if (XXXdiff<0) {
cccorrFactor = 270;
} else {
cccorrFactor = 90;
}
//
mc.ship_mc._rotation = -(rrradAngle*360/(2*Math.PI)+cccorrFactor);
//check if time to reset, based on roamTime
if (mc.t<=0) {
resetDirection(mc);
}
}
//
// Generate Enemies
//
// set and save enemy stats
//
//
// createEnemies(number of enemies you want, movieclip where you want to create the enemies);
//
function createEnemies(amount:Number, targetLocation:MovieClip) {
trace("createEnemies: "+amount);
for (var i = 0; i<amount; i++) {
randomXpos = Math.round(Math.random()*mapWidth);
randomYpos = Math.round(Math.random()*mapHeight);
//add new enemy to map
var newEnemy:MovieClip = targetLocation.attachMovie("enemy1", "enemy1_"+i, targetLocation.getNextHighestDepth());
enemiesArray.push(newEnemy);
//
//set enemy stats
newEnemy.id = i;
newEnemy._x = randomXpos;
newEnemy._y = randomYpos;
//save x and y position
newEnemy.xx = newEnemy._x;
newEnemy.yy = newEnemy._y;
//
newEnemy.roamSpeed = 2
newEnemy.roamTime = random(50);
newEnemy.roamDistance = random(60)+25;
newEnemy.t = 0;
//
newEnemy.myHealth = 10;
newEnemy.myName = "Small Scout";
//
resetDirection(newEnemy);
//target enemy
newEnemy.onPress = function() {
trace("Enemy: "+this.tName+" "+this.id);
target_txt.text = this.myName+": "+this.id+" Health: "+this.myHealth;
};
newEnemy.onEnterFrame = function() {
moveIt(this);
};
}
}
start_btn.onRelease = function() {
if (start_txt.text == "Start") {
//run the create enemies function to start the engine
createEnemies(box_mc.numberOfEnemies.text, map_mc);
//hide start button
start_txt._visible =false;
this._visible = false;
box_mc._visible = false;
}
};
I want program enemies to be grouped (based on fireflies algorithm). My idea is write for loop to define attractiveness, but I don't know how to make my objects move to the most attractiveness. Maybe someone would help me with this problem?
I change this line:
newEnemy.myHealth = 10;
on this
newEnemy.myHealth = Math.round(random(9)+1);
myHealth would be responsible for attractiveness. I try to use code from this site and modificate code to let objects with low attractiveness follow objects with large attractiveness. Also, I want to stop algorith, when they are in the groups.
I am making a missile defense type of game and am trying to get the missiles to fall at random angles. I also need the bullet image to turn at the angle I am shooting at. I am very unfamiliar with angles in AS3 so I need some help.
Code:
import spark.components.Image;
public var missiles:Array;
public var bullets:Array;
public var playerLife:Number;
public var targetX:Number;
public var targetY:Number;
public function init():void {
startGame();
}
public function onEnterFrame(e:Event):void {
if(Math.random() <.05 ){
//make a new missle
var newMissile:Image = new Image();
//draw to is
newMissile.source = "assets/missileDown.jpg";
//position it
newMissile.x = Math.random() * stage.stageWidth;
//animate it
newMissile.addEventListener(Event.ENTER_FRAME, onMissileEnterFrame);
//add it to missle array
missiles.push(newMissile);
//add it to the screen
gameGroup.addElement(newMissile);
}
}
public function startGame():void {
//makes new arrays
//gets rid of old arrays
missiles = new Array();
bullets = new Array();
//set player life
playerLife = 5;
//show player life
playerHealth.text = String(playerLife);
//add animation and mouse interation
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(MouseEvent.CLICK, fireWeapon);
//set game over alpha
gameEnd.alpha = 0;
reset.alpha = 0;
//set game start alpha
playerHealth.alpha = 1;
healthLabel.alpha = 1;
}
//updates the missle
public function onMissileEnterFrame(e:Event):void {
//reference to target
var targetMissile:Image = Image(e.currentTarget);
//move missle down
targetMissile.y += 10;
//if missle has gone too far, remove it and player loses life
if(targetMissile.y > stage.stageHeight) {
playerLife --;
removeMissile(targetMissile);
//show player life
playerHealth.text = String(playerLife);
}
//if player is dead, game over
if(playerLife <= 0) {
gameOver();
}
}
//update bullet
public function onBulletEnterFrame(e:Event):void {
//get reference to bullet
var thisBullet:Bullet = Bullet(e.currentTarget);
//animate towards point..
//calculate difference between current position and desired position
var diffX:Number = thisBullet.targX - thisBullet.x;
var diffY:Number = thisBullet.targY - thisBullet.y;
//move 10% of difference closer
thisBullet.x += diffX * .1;
thisBullet.y += diffY * .1;
//chekc for overlap between bullet and missles
for(var i:Number = 0; i < missiles.length; i++) {
//if they do overlap, remove missle
if( thisBullet.hitTestObject(missiles[i]) ) {
removeMissile(missiles[i]);
removeBullet(thisBullet);
break;
}
}
//if we're 'close enough' to the target position, remove bullet
if(Math.abs(diffX) < 10 && Math.abs(diffY) < 10) {
removeBullet(thisBullet);
}
}
//gets rid of a missle
public function removeMissile(targetMissile:Image):void {
//removes the missle from the missiles array
for(var i:Number = missiles.length - 1; i >= 0; i--) {
if(missiles[i] == targetMissile) {
missiles.splice(i,1);
break;
}
}
//don't animate anymore
targetMissile.removeEventListener(Event.ENTER_FRAME, onMissileEnterFrame);
//remove from stage
gameGroup.removeElement(targetMissile);
}
//removes bullet from stage
public function removeBullet(targetBullet:Bullet):void {
//stop animation
targetBullet.removeEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
//remove from stage
gameGroup.removeElement(targetBullet);
}
//shoot a bullet at the mouse position
public function fireWeapon(e:MouseEvent):void {
//make a new bullet
var newBullet:Bullet = new Bullet();
newBullet.addEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
//position near the earth in the center
var halfStage:Number = stage.stageWidth / 2;
newBullet.x = halfStage;
newBullet.y = 500;
//set target
newBullet.targX = stage.mouseX;
newBullet.targY = stage.mouseY;
//add it to the stage
gameGroup.addElement(newBullet);
}
//you lose
public function gameOver():void {
//remove missles
for(var i:Number = 0; i < missiles.length; i++) {
removeMissile(missiles[i]);
}
//stop interaction
stage.removeEventListener(MouseEvent.CLICK, fireWeapon);
//stop animation
this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
//set game start alpha
playerHealth.alpha = 0;
healthLabel.alpha = 0;
//set game end alpha
gameEnd.alpha = 1;
reset.alpha = 1;
}
]]>
</fx:Script>
onEnterFrame
...
//position it
newMissile.x = Math.random() * stage.stageWidth;
//rotate it
newMissile.rotation = - (Math.random() * 60 - 30);
onMissileEnterFrame
...
//move missle down
//targetMissile.y += 10;
targetMissile.x -= 10 * Math.sin(targetMissile.rotation * Math.PI/180);
targetMissile.y += 10 * Math.cos(targetMissile.rotation * Math.PI/180);
fireWeapon
...
//set target
newBullet.targX = stage.mouseX;
newBullet.targY = stage.mouseY;
newBullet.rotation = - Math.atan((newBullet.x - newBullet.targX) / (newBullet.y - newBullet.targY)) * 180/Math.PI;