Object does not return to original position when released cs4 - drag-and-drop

I am making a drag and drop activity where multiple items are to be placed at the same target. I have action code on the main time line and then code attached to a sprite.
Problems:
When I release the object if it is correct it should snap to the top of that section. If it is incorrect it should return to its original orientation to be picked up again. Unfortunately it stays where I placed it, and does not move back to original place when it is incorrect. I have fixed other issues with this flash file as to if code is supposed to be on the main time line or in the sprite, but this does not seem to have an effect after the object is released. Near the end of the script there is _root.rlamp1.gotoAndPlay(1) this is a buzzer that goes off if the answer is incorrect. This is working correctly.
I do not know if these are related Items but if the correct placement is given I want the next item to start in the original position, but it is starting where my mouse is instead of the original position. I am relatively new to coding and am trying to make an activity for my science class to get instant feedback to see if they understand to concept.
Thanks for your help.
// [Action in Frame 1]
answername = Array();
answerdest = Array();
answername[0] = "gravel";
answerdest[0] = "1";
answername[1] = "nuts and bolts";
answerdest[1] = "1";
answername[2] = "oxygen";
answerdest[2] = "2";
answername[3] = "helium";
answerdest[3] = "2";
answername[4] = "gold";
answerdest[4] = "2";
dbCount = 0;
dbutton.duplicateMovieClip("dbutton" + dbCount,dbCount * 100);
dbutton.visible = false;
dbutton0.answer = answerdest[dbCount];
dbutton0.theText.text = answername[dbCount];
// This code is on the sprite and not on the main actionscript
onClipEvent (load)
{
this.defx = _x;
this.defy = _y;
if (this.theText.text.length > 20)
{
this.theText._height = 31;
this.theBox._height = 27;
}
else
{
this.theText._height = 19;
this.theBox._height = 19;
} // end else if
}
on (press)
{
if (this.noDrag !=true)
{
startDrag (this,false);
}
}
on (release)
{
if (this.noDrag != true)
{
stopDrag ();
if(this.hitTest(_root["dz" + this.answer]))
{
totalHeight = 0;
for (v = 0; v < _root.dbCount; v++)
{
if (_root["dbutton" + v].answer == this.answer)
{
totalHeight = totalHeight + _root["button" + v].theBox._height ;
} // end if
} // end of for
++_root.dbCount;
this .duplicateMovieClip("dbutton" + _root.dbCount, _root.dbCount * 100);
_root["dbutton" + _root.dbCount]._x = this.defX;
_root["dbutton" + _root.dbCount]._y = this.defY;
_root["dbutton" + _root.dbCount].answer = _root.answerdest[_root.dbCount + 1];
_root["dbutton" + _root.dbCount].theText.text = _root.answername[_root.dbCount +1];
if (_root["dbutton" + _root.dbCount].theText.text == "undefined")
{
_root["dbutton" + _root.dbCount].theText.text = "Finished!";
_root["dbutton" + _root.dbCount].noDrag = true;
} // end if
this.noDrag = true;
this._y = _root["dz" + this.answer]._y + totalHeight;
this._x = _root["dz" + this.answer]._x - _root["dz" + this.answer]._width / 2;
++_root["dz" + this.answer].numItems;
_root.glamp1.gotoAndPlay (1);
}
else
{
this.X = this.defX;
this._Y = this.defY;
_root.rlamp1.gotoAndPlay(1);
} // end if
} // end else if
}

The problem is that there are misspelled variable names and properties in the sprite code.
Replace these lines
this.X = this.defX;
this._Y = this.defY;
with those lines
this._x = this.defx;
this._y = this.defy;
and your code should work.

Related

Holes in Mesh only showing from one side

For a sailing game I'm working on, I've added functionality to programmatically create damage holes in a mesh (e.g. cannonball holes in a sail). This is largely based on the method here (link to the example code here)
private void MessWithMesh() {
filter = this.transform.parent.gameObject.GetComponent<MeshFilter>();
mesh = filter.mesh;
filter.mesh = GenerateMeshWithHoles();
}
private IEnumerator GenerateTrisWithVertex() {
// Destroying the sail won't work until this has finished, but it only takes a second or two so I don't think anybody will notice.
trisWithVertex = new List<int>[origvertices.Length];
for (int i = 0; i <origvertices.Length; ++i)
{
trisWithVertex[i] = ArrayHelper.IndexOf(origtriangles, i);
yield return null;
}
yield return null;
}
Mesh GenerateMeshWithHoles()
{
float damageRadius = 1f;
Transform parentTransform = this.transform.parent.transform;
Hole[] holes = this.GetComponentsInChildren<Hole>();
foreach (Hole hole in holes) {
Vector3 trackPos = hole.transform.position;
float closest = float.MaxValue;
int closestIndex = -1;
int countDisabled = 0;
damageRadius = hole.diameter;
for (int i = 0; i <origvertices.Length; ++i)
{
Vector3 v = new Vector3(origvertices[i].x * parentTransform.localScale.x, origvertices[i].y * parentTransform.localScale.y, origvertices[i].z * parentTransform.localScale.z) + parentTransform.position;
Vector3 difference = v - trackPos;
if (difference.magnitude < closest)
{
closest = difference.magnitude;
closestIndex = i;
}
if (difference.magnitude < damageRadius)
{
for (int j = 0; j <trisWithVertex[i].Count; ++j)
{
int value = trisWithVertex[i][j];
int remainder = value % 3;
trianglesDisabled[value - remainder] = true;
trianglesDisabled[value - remainder + 1] = true;
trianglesDisabled[value - remainder + 2] = true;
countDisabled++;
}
}
}
// If no triangles were removed, then we'll just remove the one that was closest to the hole.
// This shouldn't really happen, but in case the hole is off by a bit from where it should have hit the mesh, we'll do this to make sure there's at least a hole.
if (countDisabled == 0 && closestIndex > -1) {
Debug.Log("Removing closest vertex: " + closestIndex);
for (int j = 0; j < trisWithVertex[closestIndex].Count; ++j)
{
int value = trisWithVertex[closestIndex][j];
int remainder = value % 3;
trianglesDisabled[value - remainder] = true;
trianglesDisabled[value - remainder + 1] = true;
trianglesDisabled[value - remainder + 2] = true;
}
}
}
triangles = ArrayHelper.RemoveAllSpecifiedIndicesFromArray(origtriangles, trianglesDisabled).ToArray();
mesh.SetTriangles(triangles, 0);
for (int i = 0; i <trianglesDisabled.Length; ++i)
trianglesDisabled[i] = false;
return mesh;
}
When a cannonball hits the sail, I add a Hole object at the location of the impact, and I call MessWithMesh. The holes are often generated correctly, but many times they're only visible from one side of the sail (it looks fully intact from the other side). It's often visible from the opposite side of the sail that the cannonball impacted (the far side, not the near side), if that's at all helpful. The ship I'm using is this free asset.
I'm not really familiar with meshes, so I don't really understand what's going on.

IndexOutOfRangeException: Can't figure out why index out of bound

So, I have a list of Upgrade systems for my game but it has a bug on it when I press upgrade for a second time the index out of range then pressed for the third times the index out of range gone. this whole script.
void Start()
{
newSelectedIndex = previousSelectedIndex = PlayerPrefs.GetInt("currentPlayer");
btn = Select_Player[newSelectedIndex].GetComponent<Button>();
btn.interactable = false;
Coins = M_CoinManager.instance.Coins;
for (int i = 0; i < Select_Player.Length; i++)
{
priceText[i].text = Cost_Player[i].ToString();
value_player[i] = "" + i;
Select_Player[i].SetActive(false);
buyPlayer[i] = PlayerPrefs.GetInt(value_player[i]);
}
//if(PlayerPrefs.HasKey("currentPlayer")){
selectedVehicleIndex = PlayerPrefs.GetInt("currentPlayer");
theVehicles[selectedVehicleIndex].SetActive(true);
VehicleInfo();
UpgradeButtonStatus();
}
// Update is called once per frame
void Update()
{
for (int i = 0; i < Select_Player.Length; i++)
{
buyPlayer[i] = PlayerPrefs.GetInt(value_player[i]);
if (i == buyPlayer[i])
{
Select_Player[i].SetActive(true);
upgradeBtn[i].interactable = true;
UpgradeButtonStatus();
}
else
{
upgradeBtn[i].interactable = false;
}
}
}
public void BuyCharact(int id)
{
M_SoundManager.instance.playUIsfx();
if (Cost_Player[id] <= Coins)
{
M_CoinManager.instance.AddCoins(-Cost_Player[id]);
PlayerPrefs.SetInt(value_player[id], id);
}
else
{
_CoinShake.DoShake();
Debug.Log("Does have enough coin");
}
}
public void Reset()
{
for (int i = 0; i < Select_Player.Length; i++)
{
PlayerPrefs.SetInt(value_player[i], 0);
}
}
public void Select(int id)
{
previousSelectedIndex = newSelectedIndex;
newSelectedIndex = id;
newSelectedIndex = selectedVehicleIndex;
PlayerPrefs.SetInt("currentPlayer", newSelectedIndex);
Button newbtn = Select_Player[previousSelectedIndex].GetComponent<Button>();
btn = Select_Player[newSelectedIndex].GetComponent<Button>();
btn.interactable = false;
newbtn.interactable = true;
M_SoundManager.instance.playUIsfx();
Debug.Log("Selected TypeCar" + newSelectedIndex);
}
public void nextVehicle()
{
M_SoundManager.instance.playUIsfx();
theVehicles[selectedVehicleIndex].SetActive(false);
selectedVehicleIndex = (selectedVehicleIndex + 1) % theVehicles.Length;
theVehicles[selectedVehicleIndex].SetActive(true);
VehicleInfo();
UpgradeButtonStatus();
}
public void PreviousVehicle()
{
M_SoundManager.instance.playUIsfx();
theVehicles[selectedVehicleIndex].SetActive(false);
selectedVehicleIndex--;
if (selectedVehicleIndex < 0)
{
selectedVehicleIndex += theVehicles.Length;
}
theVehicles[selectedVehicleIndex].SetActive(true);
VehicleInfo();
UpgradeButtonStatus();
}
public void VehicleInfo()
{
currLevel = _VehicleStats[0].carItem[selectedVehicleIndex].unlockedLevel;
levelText[selectedVehicleIndex].text = "Level: " + (currLevel + 1);
powerText[selectedVehicleIndex].text = "Power: " + _VehicleStats[0].carItem[selectedVehicleIndex].vehicleLevel[currLevel].motorPower;
brakeText[selectedVehicleIndex].text = "Brake: " + _VehicleStats[0].carItem[selectedVehicleIndex].vehicleLevel[currLevel].brakePower;
Debug.Log(selectedVehicleIndex);
}
public void upgradeMethod()
{
nextLevelIndex = _VehicleStats[0].carItem[selectedVehicleIndex].unlockedLevel + 1;
if (Coins >= _VehicleStats[0].carItem[selectedVehicleIndex].vehicleLevel[nextLevelIndex].unlockCost)
{
Coins -= _VehicleStats[0].carItem[selectedVehicleIndex].vehicleLevel[nextLevelIndex].unlockCost;
_VehicleStats[0].carItem[selectedVehicleIndex].unlockedLevel++;
if (_VehicleStats[0].carItem[selectedVehicleIndex].unlockedLevel < _VehicleStats[0].carItem[selectedVehicleIndex].vehicleLevel.Length - 1)
{
upgradeBtnText[selectedVehicleIndex].text = "Upgrade Cost :" + _VehicleStats[0].carItem[selectedVehicleIndex].vehicleLevel[nextLevelIndex + 1].unlockCost;
}
else
{
upgradeBtn[selectedVehicleIndex].interactable = false;
upgradeBtnText[selectedVehicleIndex].text = "Max Level";
}
VehicleInfo();
}
}
private void UpgradeButtonStatus()
{
if (_VehicleStats[0].carItem[selectedVehicleIndex].unlockedLevel < _VehicleStats[0].carItem[selectedVehicleIndex].vehicleLevel.Length - 1)
{
upgradeBtn[selectedVehicleIndex].interactable = true;
nextLevelIndex = _VehicleStats[0].carItem[selectedVehicleIndex].unlockedLevel + 1;
upgradeBtnText[selectedVehicleIndex].text = "Upgrade Cost :" + _VehicleStats[0].carItem[selectedVehicleIndex].vehicleLevel[nextLevelIndex + 1].unlockCost;
}
else
{
upgradeBtn[selectedVehicleIndex].interactable = false;
upgradeBtnText[selectedVehicleIndex].text = "Max Level";
}
}
and the error reference to this method :
private void UpgradeButtonStatus()
{
if (_VehicleStats[0].carItem[selectedVehicleIndex].unlockedLevel < _VehicleStats[0].carItem[selectedVehicleIndex].vehicleLevel.Length - 1)
{
upgradeBtn[selectedVehicleIndex].interactable = true;
nextLevelIndex = _VehicleStats[0].carItem[selectedVehicleIndex].unlockedLevel + 1;
upgradeBtnText[selectedVehicleIndex].text = "Upgrade Cost :" + _VehicleStats[0].carItem[selectedVehicleIndex].vehicleLevel[nextLevelIndex + 1].unlockCost;
}
else
{
upgradeBtn[selectedVehicleIndex].interactable = false;
upgradeBtnText[selectedVehicleIndex].text = "Max Level";
}
}
as you can see on the update that's what I mean. after i press upgrade for third times the error stopped.
and this for the inpector
Arrays length is one higher than their highest index, but last iteration of "for" loops goes to array.length.
You need to make "for" loops to array.length-1.
I see you do "for" loops of up to array.length.
I haven't truly read thru your whole script so there might be more, but it's a typical error in my "for" loops so I think that is causing your error.

AddComponent("Rigidbody") or another component doesn't work

I am trying to program a very simple FPS game and I reached a point where I need to create a pickup weapon system. In order to finish that system, I am stuck on a point where I need to AddComponent("Rigidbody") and AddComponent("BoxCollider") and Unity3D throws that error:
'AddComponent is not a member of 'WeaponPickUp'
Where WeaponPickUp is my Javascript script file.
Below is my code:
#pragma strict
var pickup = false;
var check = 2;
function Update () {
if (Input.GetButtonDown("pickup") && check % 2 == 0){
GetObject();
pickup = true;
check = check + 1;
}
else if (Input.GetButtonDown("pickup") && (check % 2 == 1)){
pickup = false;
check = check - 1;
this.AddComponent("Rigidbody") as Rigidbody;
this.AddComponent("BoxCollider") as BoxCollider;
this.GetComponent(BoxCollider).enabled = true;
}
}
function GetObject(){
var position : GameObject = GameObject.Find("weaponPosition");
this.transform.position = position.transform.position;
Destroy(GetComponent(Rigidbody));
Destroy(GetComponent(BoxCollider));
this.transform.parent = GameObject.Find("FPSController").transform;
this.transform.parent = GameObject.Find("FirstPersonCharacter").transform;
// this.transform.parentposition
}
I've no idea why this happens. Anybody willing to help me out, I will appreciate it as always!
This
this.AddComponent("Rigidbody") as Rigidbody;
this.AddComponent("BoxCollider") as BoxCollider;
this.GetComponent(BoxCollider).enabled = true;
needs to be
gameObject.AddComponent("Rigidbody") as Rigidbody;
gameObject.AddComponent("BoxCollider") as BoxCollider;
gameObject.GetComponent(BoxCollider).enabled = true;
Same for the Destroy lines
AddComponent is part of GameObject, not your WeaponPickUp
Remove this keyword with gameObject then remove as Rigidbody and as BoxCollider
This is what it should look like:
gameObject.AddComponent("Rigidbody");
gameObject.AddComponent("BoxCollider");
gameObject.GetComponent("BoxCollider").enabled = true;
The syntax above should have worked but it is obsolete. It changed in Unity 5.
You will get error if you do it like that. Below is the new syntax and right way to do it now.
GetComponent.<Rigidbody>();
GetComponent.<BoxCollider>();
GetComponent.<BoxCollider>().enabled = true;
Your whole code:
#pragma strict
var pickup = false;
var check = 2;
function Update () {
if (Input.GetButtonDown("pickup") && check % 2 == 0){
GetObject();
pickup = true;
check = check + 1;
}
else if (Input.GetButtonDown("pickup") && (check % 2 == 1)){
pickup = false;
check = check - 1;
GetComponent.<Rigidbody>();
GetComponent.<BoxCollider>();
GetComponent.<BoxCollider>().enabled = true;
}
}
function GetObject(){
var position : GameObject = GameObject.Find("weaponPosition");
this.transform.position = position.transform.position;
Destroy(GetComponent(Rigidbody));
Destroy(GetComponent(BoxCollider));
this.transform.parent = GameObject.Find("FPSController").transform;
this.transform.parent = GameObject.Find("FirstPersonCharacter").transform;
// this.transform.parentposition
}

Merge Sort Iterative Implementation - Not working

I have the below merge sort iterative implementation, but somehow, it is not working. I debugged it, but couldn't find the cause.
Merge'ing function would remain the same as the recursive case, only the array dividing logic would be different, if I'm correct.
Please rectify, if I'm going in wrong direction.
I think you have a problem when you try to use the same object to represent different intervals:
At MergeSort_Iterative loop , when you are adding new elements to list1 you are using "info" object as temporal variable and then you add it to list1 collection.
In Java, all object variables are references so when you add the object to the collection you are not adding a copy of it but a reference which is being modified and inserted again.
info.left = left;
info.right = mid;
list1.add(info);
info.left = mid + 1;
info.right = right;
list1.add(info);
To fix that you should create two objects in order two perform the inserctions:
info = new MergePosInfo();
info.left = left;
info.right = mid;
list1.add(info);
info = new MergePosInfo();
info.left = mid + 1;
info.right = right;
list1.add(info);
On the other hand, once the problem described above is solved, you should iterate over list2 from shorter to wider intervals and from left to right positions and your algorithm is not generating list2 in that order.
You need to modify MergeSort_Iterative:
public static void MergeSort_Iterative(int[] numbers, int left, int right) {
int mid;
if (right <= left)
return;
LinkedList<MergePosInfo> list1 = new LinkedList<MergePosInfo>();
LinkedList<MergePosInfo> list2 = new LinkedList<MergePosInfo>();
for(int i = left; i <= right; i+=2)
{
MergePosInfo info = new MergePosInfo();
info.left = i;
info.right = (i+1<=right)?(i+1):i;
info.mid = -1;
list1.add(info);
list2.add(info);
}
int l = right-left+1;
for(int partsSize = 2; partsSize <= l/2; partsSize*=2)
{
int ll1 = list1.size();
for(int i = 0; i < ll1; i+=2)
{
MergePosInfo info2 = new MergePosInfo();
info2.left = list1.get(0).left;
info2.right = list1.get(1).right;
info2.mid = (info2.left+info2.right)/2;
list1.remove(0);
list1.remove(0);
list1.add(info2);
list2.addLast(info2);
}
}
for (int i = 0; i < list2.size(); i++) {
System.out.println("Merge [" + Integer.toString(list2.get(i).left) + " , " + Integer.toString(list2.get(i).right) + "]" );
DoMerge(numbers, list2.get(i).left, list2.get(i).mid+1,
list2.get(i).right);
}
}
As well as to add some lines to DoMerge:
public static void DoMerge(int[] numbers, int left, int mid, int right) {
int[] temp = new int[25];
int i, left_end, num_elements, tmp_pos;
left_end = (mid - 1);
tmp_pos = left;
num_elements = (right - left + 1);
if(num_elements == 2)
{
if(numbers[left]>numbers[right])
{
int buffer = numbers[left];
numbers[left] = numbers[right];
numbers[right] = buffer;
}
return;
}
...
As you can see the solution I provided only works when "numbers" length is 2^k. You can try to fix it by yourself and if you can't I will give you the last change.
I left
System.out.println("Merge [" + Integer.toString(list2.get(i).left) + " , " + Integer.toString(list2.get(i).right) + "]" );
line so you can understand how merge sort works.
info.left = left;
info.right = mid;
list1.add(info);
info.left = mid + 1;
info.right = right;
list1.add(info);
You are operating on the same object. Use a different object for each iteration, the same way you are doing with info2

C# Quickly checking if two pictureboxes touch each other?

I'm creating my first non-console game in Visual C#.
I have a player which is a picturebox, and obstacles which are also pictureboxes.
Now when I create an obstacle (picturebox) at a random position, I would like to check if it already touches an other obstacle.
Here's what I have now:
Picturebox obstacles = new Picturebox[20];
for (int i = 0; i < obstacles.Length; i++)
{
DateTime date = DateTime.Now;
Random randomNumber = new Random(date.Second * (date.Minute / 2) ^ 2 + date.Hour * 123 + (i ^ 9 + i / 2));
obstacles[i] = new PictureBox();
obstacles[i].Image = Properties.Resources.es;
obstacles[i].Size = new Size(25, 50);
obstacles[i].Location = new Point(randomNumber.Next(640 - obstacles[i].Image.Width), randomNumber.Next(topBar.Height, 480 - obstacles[i].Image.Height));
if (IsTouching(obstacles[i], player))
{
i--;
}
else
{
bool tmp = true;
for (int j = 0; j < obstacles.Length; j++)
{
if (obstacles[j] != null && j != i)
{
if (IsTouching(obstacles[j], obstacles[i]))
{
tmp = false;
break;
}
}
}
if (tmp)
{
Controls.Add(obstacles[i]);
}
else
{
i--;
}
}
}
So that's my way, but I know it's not really effective, so any better ideas, cause it takes a while (~5 seconds) to create those obstacles.
And here's my IsTouching method, which also kinda sucks, anyone have better ideas?
private bool IsTouching(PictureBox obj1, PictureBox obj2)
{
Point[] obj1Points = new Point[(obj1.Width * obj1.Height) - ((obj1.Width - 2) * (obj1.Height - 2))];
int count = 0;
for (int x = obj1.Left + 1; x < obj1.Left + obj1.Width - 1; x++)
{
obj1Points[count] = new Point(x, obj1.Top);
obj1Points[count + 1] = new Point(x, obj1.Top + obj1.Height);
count += 2;
}
for (int y = obj1.Top; y < obj1.Top + obj1.Height; y++)
{
obj1Points[count] = new Point(obj1.Left, y);
obj1Points[count + 1] = new Point(obj1.Left + obj1.Width, y);
count += 2;
}
Point[] obj2Points = new Point[(obj2.Width * obj2.Height) - ((obj2.Width - 2) * (obj2.Height - 2))];
count = 0;
for (int x = obj2.Left + 1; x < obj2.Left + obj2.Width - 1; x++)
{
obj2Points[count] = new Point(x, obj2.Top);
obj2Points[count + 1] = new Point(x, obj2.Top + obj2.Height);
count += 2;
}
for (int y = obj2.Top; y < obj2.Top + obj2.Height; y++)
{
obj2Points[count] = new Point(obj2.Left, y);
obj2Points[count + 1] = new Point(obj2.Left + obj2.Width, y);
count += 2;
}
for (int obj2Point = 0; obj2Point < obj2Points.Length; obj2Point++)
{
for (int obj1Point = 0; obj1Point < obj1Points.Length; obj1Point++)
{
if (obj2Points[obj2Point].X == obj1Points[obj1Point].X && obj2Points[obj2Point].Y == obj1Points[obj1Point].Y)
{
return true;
}
}
}
return false;
}
What it does: Checks if the given two parameters edges touch each other. So basically just a collision-detection, anyone have any ideas, cause I'm kinda new at this stuff?
If we assume that all the obstacles are solid (i.e. 2 obstacles touch if the other is inside the other), you can use the following method:
private bool IsTouching(PictureBox p1, PictureBox p2)
{
if (p1.Location.X + p1.Width < p2.Location.X)
return false;
if (p2.Location.X + p2.Width < p1.Location.X)
return false;
if (p1.Location.Y + p1.Height < p2.Location.Y)
return false;
if (p2.Location.Y + p2.Height < p1.Location.Y)
return false;
return true;
}
I tested your current IsTouching method and found out that it fails in some corner cases, such as in this one (it claims they are not touching although they are). My method works in these corner cases too.
There is one simple line of code for this but it might also fail for some corner pieces sometimes.
if(player1.Bounds.IntersectWith(player2.Bounds){
//Do something
}
Replace player1 with the name of the picture box and the same with player2 ofc.