i'm a newbie and i'm terrible at english but hopefully you can understand my problem
i create a simple space shooting game with easeljs, when i tried to create multiple bullets and assign an onTick handle to each one, i relize just one bullet fire out. Here is the code:
//handle fire(shooting)
if(fire && cd === 0){
for(var i=0; i<5; i++){
//codartjs.Bullet is a class extend createjs.Bitmap
var b = new codartjs.Bullet(bullet_img);
b.x = 200;
b.y = 200;
stage.addChild(b);
b.onTick = function(){
//this event handler work for only first instance
b.y -= 10;
};
}
cd = 100;
setTimeout(function(){
cd = 0;
},100);
}
What you can also try is having a central ticker and loop through each bullet element and update its position that way. Here is quick demo that will illustrate my point.
<script>
var canvas, stage;
var bullets;
var speed;
function init() {
stage = new createjs.Stage("test");
bullets = [];
var bg = new createjs.Shape();
bg.graphics.beginFill("#FFFFFF").drawRect(0, 0, stage.canvas.width, stage.canvas.height).endFill();
bg.cache(0, 0, stage.canvas.width, stage.canvas.height);
speed = 15;
stage.onClick = handleClick;
stage.mouseEnabled = true;
stage.enableMouseOver(10);
createjs.Ticker.setFPS(24);
stage.addChild(bg);
createjs.Ticker.addListener(window);
}
function getSprite() {
var s = new createjs.Shape();
s.graphics.beginFill("#000000").drawCircle(0, 0, 10).endFill();
return s;
}
function tick() {
for(var i=0;i<bullets.length;i++) {
var s = bullets[i];
s.x += speed;
}
stage.update();
}
function handleClick(event) {
var s = getSprite();
s.x = event.stageX;
s.y = event.stageY;
bullets.push(s);
stage.addChild(s);
}
</script>
Hope this helps.
Related
I have a script that spawns endless tiles (3D) and i want it to stop at after a certain number (e.g. 100) and at the end of the last tile (the 100th) i want to spawn an other prefab like a portal.
I have no clue how to do that.
Any answer i have found on google couldnt help.
Any help is much appreciated.
void Start()
{
nextTileLocation = startPoint;
nextTileRotation = Quaternion.identity;
for (int i = 0; i < initSpawnNum; ++i)
{
SpawnNextTile (i >= initNoObstacles);
}
}
public void SpawnNextTile(bool spawnObstacles = true)
{
var newTile = Instantiate (tile, nextTileLocation, nextTileRotation);
var nextTile = newTile.Find ("Next Spawn Point");
nextTileLocation = nextTile.position;
nextTileRotation = nextTile.rotation;
if (!spawnObstacles)
return;
var obstacleSpawnPoints = new List<GameObject> ();
foreach (Transform child in newTile) {
if (child.CompareTag ("ObstacleSpawn")) {
obstacleSpawnPoints.Add (child.gameObject);
}
}
if (obstacleSpawnPoints.Count > 0) {
var spawnPoint = obstacleSpawnPoints [Random.Range (0, obstacleSpawnPoints.Count)];
var spawnPos = spawnPoint.transform.position;
var newObstacle = Instantiate (obstacle, spawnPos, Quaternion.identity);
newObstacle.SetParent (spawnPoint.transform);
}
}
You could do something like pass in a bool to tell the function to spawn a portal.
void Start()
{
nextTileLocation = startPoint;
nextTileRotation = Quaternion.identity;
for (int i = 0; i < initSpawnNum; ++i)
{
// Pass in true for the last tile
SpawnNextTile (i >= initNoObstacles, i == initSpawnNum - 1);
}
}
public void SpawnNextTile(bool spawnObstacles = true, bool shouldSpawnPortal = false)
{
//
}
Edit to show adding the tiles to a list:
class YourScript : MonoBehaviour
{
private List<GameObject> tiles = new List<GameObject>();
private void SpawnNextTile(bool spawnObstacles = true, bool shouldSpawnPortal = false)
{
var newTile = Instantiate (tile, nextTileLocation, nextTileRotation);
tiles.Add(newTile);
// The rest of your code
}
}
I have some error related to IndexOutOfRangeException. The number of errors is over 200 and the error comes up when I play the game.
Error shown like this:
IndexOutOfRangeException: Array index is out of range. GameController.OnGUI () (at Assets/MicroRacers Assets/Scripts/GameController.js:67)
Here is the code of my game controller.
var CheckPoints:Transform[];
var LapsToWin:int = 5;
var PointsPerPlace:Array = new Array(8,4,2,1);
var CountDownToStart:float = 5;
var Items:Transform[];
var ItemCopy:Object;
var SpawnTime:Vector2 = Vector2(5,10);
private var SpawnTimeCount:float = 0;
var MaximumItems:int = 5;
private var ItemCount:int = 0;
private var FinishPlace:int = 0;
private var Players:int = 1;
var RaceEndDelay:float = 5;
//~ function Awake()
//~ {
//~ Application.targetFrameRate = 30;
//~ }
function Start()
{
SpawnTimeCount = Random.Range(SpawnTime.x, SpawnTime.y);
}
function Update ()
{
if ( SpawnTimeCount > 0 )
{
SpawnTimeCount -= Time.deltaTime;
}
else if ( ItemCount < MaximumItems )
{
SpawnTimeCount = Random.Range(SpawnTime.x, SpawnTime.y);
ItemCount++;
ItemCopy = Instantiate(Items[Mathf.Floor(Random.Range(0, Items.length - 1))], CheckPoints[Mathf.Floor(Random.Range(0, CheckPoints.length - 1))].position + Vector3.up * 0.3, Quaternion.identity);
ItemCopy.transform.Translate(Vector3.right * Random.Range(-3,3), Space.Self);
}
if ( Players == 0 )
{
RaceEndDelay -= Time.deltaTime;
if ( RaceEndDelay <= 0 )
{
Application.LoadLevel("end");
}
}
}
//This script displays the HUD, with current weapon, ammo left, Health, Shield, and score
var GUIskin:GUISkin; //The skin gui we'll use
var CountdownTextures:Texture2D[];
private var CountdownTextureIndex:int = 0;
function OnGUI()
{
GUI.skin = GUIskin; //The skin gui we'll use
if ( CountDownToStart > Time.timeSinceLevelLoad )
{
GUI.DrawTexture(Rect( (Screen.width - CountdownTextures[Mathf.Round(Time.timeSinceLevelLoad)].width) * 0.5, (Screen.height - CountdownTextures[Mathf.Round(Time.timeSinceLevelLoad)].height) * 0.5, CountdownTextures[Mathf.Round(Time.timeSinceLevelLoad)].width, CountdownTextures[Mathf.Round(Time.timeSinceLevelLoad)].height), CountdownTextures[Mathf.Round(Time.timeSinceLevelLoad)]); //Draw the HUD texture
}
}
Mathf.Round(Time.timeSinceLevelLoad) is just bigger CountdownTextures array size.
Maybe try adding this:
Debug.Log("Index: "+Mathf.Round(Time.timeSinceLevelLoad)+", Array size: "+ CountdownTextures.Length);
And you should see that index is bigger than size.
You can also add kind of safety check inside if, something like this:
if(Mathf.Round(Time.timeSinceLevelLoad) < CountdownTextures.Length && <your second statement>)
I have this code (not originally my invention) that is working fine, but I have hit upon a problem with it. I can't seem to render the second submesh, with another material.
I can't figure out the problem lies in [renderer] part or the 2nd "submesh" that is perhaps never combining.
#script RequireComponent(MeshFilter)
#script RequireComponent(MeshRenderer)
private var matarray : Material[] = new Material[2];
var mat : Material;
var mat2 : Material;
function Start () {
matarray[0] = mat;
matarray[1] = mat2;
for (var child in transform)
child.position += transform.position;
transform.position = Vector3.zero;
transform.rotation = Quaternion.identity;
var meshFilters = GetComponentsInChildren(MeshFilter);
var combine : CombineInstance[] = new CombineInstance[meshFilters.Length-1];
var index = 0;
for (var i = 0; i < meshFilters.Length; i++) {
if (meshFilters[i].sharedMesh == null)
continue;
combine[index].mesh = meshFilters[i].sharedMesh;
combine[index++].transform = meshFilters[i].transform.localToWorldMatrix;
renderer.sharedMaterials = matarray;
meshFilters[i].active = false;
}
GetComponent(MeshFilter).mesh = new Mesh();
GetComponent(MeshFilter).mesh.CombineMeshes(combine);
renderer.active = true;
//here seems to be the trouble.
renderer.sharedMaterials = matarray;
}
Alternatively I have tried,
renderer.sharedMaterials[1] = matarray[1];
In short, I'm in trouble. I have to save few draw calls, which is not looking good unless this gets fixed.
I have created a game that has 16 spheres in it and they are swapping on mouse click. But I want to have 15 spheres and one empty gameobject, so as to make them slide with the help of an empty gameobject.and i also want to shuffle the spheres when game starts each time. How is it possible?
I follow this tutorial
After that I tried to make it, but my cubes get overlapped on one another while changing their position on start.
var xtemp ;
var ytemp ;
var slot : Transform;
var cubesPosition : Vector3[] = new Vector3[16];
var cubeGameObjects: GameObject[] = new GameObject[16];
function Start ()
{
ChangePosition();
AssignPositions();
}
function ChangePosition()
{
for(var i=0;i<cubeGameObjects.length;i++)
{
cubeGameObjects[i].transform.position;
}
slot.transform.position = new Vector3(Random.Range (1,4),Random.Range (1,4),10);
}
function AssignPositions()
{
for (var i = 0; i < cubesPosition.length; ++i)
cubeGameObjects[i].transform.position = cubesPosition[i];
}
function OnMouseUp() {
if(Vector3.Distance(transform.position,slot.position)==1)
{
xtemp = transform.position.x;
ytemp = transform.position.y;
transform.position.x=slot.position.x;
transform.position.y=slot.position.y;
slot.position.x = xtemp;
slot.position.y = ytemp;
}
OVERALL GOAL: Have the camera change target to the selected car
I'm new to the unity game engine and got a bit of a problem.
So, I have a successful car selector which changes between cars and starts the match with that car. Everything there works. The only issue is that my "CarCameraScript" has a transform variable which is always 1 of the 3 cars. I want it to change dependant on the selected car.
Here is the look at the code of the CarCameraScript
#pragma strict
var car : Transform;
var distance: float = 6.4;
var height: float = 1.4;
var rotationDamping : float = 3.0;
var heightDamping: float = 2.0;
var zoomRatio : float = 0.5;
var DefaultFOV : float = 60;
private var rotationVector : Vector3;
function Start () {
}
function LateUpdate () {
var wantedAngel = rotationVector.y;
var wantedHeight = car.position.y + height;
var myAngel = transform.eulerAngles.y;
var myHeight = transform.position.y;
myAngel = Mathf.LerpAngle(myAngel,wantedAngel,rotationDamping*Time.deltaTime);
myHeight = Mathf.Lerp(myHeight,wantedHeight,heightDamping*Time.deltaTime);
var currentRotation = Quaternion.Euler(0,myAngel,0);
transform.position = car.position;
transform.position -= currentRotation*Vector3.forward*distance;
transform.position.y = myHeight;
transform.LookAt(car);
}
function FixedUpdate () {
var localVilocity = car.InverseTransformDirection(car.rigidbody.velocity);
if (localVilocity.z<-0.5) {
rotationVector.y = car.eulerAngles.y + 180;
} else {
rotationVector.y = car.eulerAngles.y;
}
var acc = car.rigidbody.velocity.magnitude;
camera.fieldOfView = DefaultFOV + acc*zoomRatio;
}
This is what it looks like on the side panel.
http://i.stack.imgur.com/lYJP7.jpg
The area that says none (transform) is the place that should be variable dependant on the currently selected car.
Now, Here is my other script being the CharacterSelectScript
#pragma strict
//this is the currently selected Player. Also the one that will be saved to PlayerPrefs
var selectedPlayer : int = 0;
function Update()
{
if (Input.GetMouseButtonUp (0)) {
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit, 100))
{
// The pink text is where you would put the name of the object you want to click on (has attached collider).
if(hit.collider.name == "Player1")
SelectedCharacter1(); //Sends this click down to a function called "SelectedCharacter1(). Which is where all of our stuff happens.
if(hit.collider.name == "Player2")
SelectedCharacter2();
if(hit.collider.name == "Player3")
SelectedCharacter3();
}
else
{
return;
}
}
}
function SelectedCharacter1() {
Debug.Log ("Character 1 SELECTED"); //Print out in the Unity console which character was selected.
selectedPlayer = 1;
PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
}
function SelectedCharacter2() {
Debug.Log ("Character 2 SELECTED");
selectedPlayer = 2;
PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
}
function SelectedCharacter3() {
Debug.Log ("Character 3 SELECTED");
selectedPlayer = 3;
PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
}
How would I get it so that the SelectedPlayer changes the transform in the first script?
Any ideas?
I also have the prefab script which probably isnt important.
Also, should I join both scripts into one?
OVERALL GOAL: Have the camera change target to the selected car