Program built using Unity3D Freezing PC - Sporadic - loops

My program that I built using Unity3D sporadically freezes, and this action freezes my computer. I'm unable to pinpoint the root cause. I had placed logs all over my project, but the game failed to freeze.
Has any Unity3D developer experience their apps sporadically freeze in the manner in which I am describing? Does anyone have any ideas or suggestions?
Due to a 30K character limit, the below object has been modified slightly. This is the object I believe contains a flaw, but I am unable to identify this flaw.
public class gamePlayController : MonoBehaviour {
void Start () {
int i = 0;
int selectedPlayers = PlayerPrefs.GetInt("TotalPlayers");
foreach( GameObject touchable in GameObject.FindGameObjectsWithTag("Touchable") )
{
touchable.SetActive(false);
touchable.AddComponent(typeof(PlayerCollisionDispatcher));
PlayerCollisionDispatcher nextDispatcher = touchable.GetComponent<PlayerCollisionDispatcher>();
nextDispatcher.currentGameObject = touchable;
nextDispatcher.gameObject.AddComponent("AudioSource");
for(i = 0; i < this.m_Players.Count; i++)
{
if(string.Compare(touchable.name, this.m_Players[i].name) < 0)
{
break;
}
}
if(i < this.m_Players.Count)
{
this.m_Players.Insert(i, touchable);
}
else
{
this.m_Players.Add(touchable);
}
}
while(this.m_Players.Count > selectedPlayers)
{
this.m_Players.RemoveRange(selectedPlayers, this.m_Players.Count - selectedPlayers);
}
this.restartGame();
}
void OnGameTimer(object sender, ElapsedEventArgs e)
{
}
void Update() {
Vector3 vector = m_ArialCamera.camera.transform.position;
vector.x = Mathf.Abs((1500 * this.m_ArialView.x) - 1500) + 250;
vector.y = (600 * this.m_ArialView.y) + 100;
vector.z = (1500 * this.m_ArialView.z) + 250;
m_ArialCamera.camera.transform.position = vector;
if(this.m_IsGameOver)
{
Application.LoadLevel("Replay Screen");
}
else if(this.m_SimulateCamera)
{
this.SimulateCamera();
}
else if(m_AutoPluck)
{
this.AutoPluck();
}
else if(Time.timeScale != 0.0f && this.m_Dispatcher && this.m_Dispatcher.didObjectStop)
{
this.determineTurnOutcome();
}
else if(Time.timeScale != 0.0f && this.m_Dispatcher && this.m_Dispatcher.didObjectMove)
{
this.m_Dispatcher.trackMovementProgress();
}
else if(Time.timeScale != 0.0f && this.m_Dispatcher
&& this.m_Players[this.m_PlayerIndex].rigidbody.velocity.magnitude > 15.0f
&& this.m_Dispatcher.didPluck)
{
this.m_Dispatcher.didObjectMove = true;
}
}
void restartGame()
{
this.m_PlayerIndex = -1;
foreach( GameObject touchable in this.m_Players)
{
GameObject startField = GameObject.FindWithTag ("StartField");
touchable.SetActive(false);
touchable.rigidbody.useGravity = false;
touchable.rigidbody.velocity = Vector3.zero;
touchable.rigidbody.AddForce(Vector3.zero);
touchable.rigidbody.AddTorque(Vector3.zero);
if(startField)
{
Vector3 nextPoint = startField.renderer.bounds.center;
nextPoint.y = 11.0f;
touchable.transform.position = nextPoint;
}
touchable.rigidbody.useGravity = true;
}
this.startNextPlayer();
}
void startNextPlayer()
{
bool isActivePlayerReady = true;
do{
if(this.m_PlayerIndex != -1)
{
audioPlayer.PlayAudio("Audio/Next Player");
}
this.m_PlayerIndex = (this.m_PlayerIndex + 1)%this.m_Players.Count;
this.m_Dispatcher = this.m_Players[this.m_PlayerIndex].GetComponent<PlayerCollisionDispatcher>();
if(this.m_Dispatcher && !this.m_Dispatcher.isGameOver && !this.m_Dispatcher.didEnterMud)
{
if(!this.m_Players[this.m_PlayerIndex].activeSelf)
{
this.m_Dispatcher.startGame();
this.m_Players[this.m_PlayerIndex].SetActive(true);
}
this.m_Dispatcher.startTurn();
}
}
while(!isActivePlayerReady);
Vector3 vector = this.m_Players[this.m_PlayerIndex].transform.position;
vector.x = (1500 * this.m_ArialView.x) + 250;
vector.y = 300;
vector.z = (1500 * this.m_ArialView.z) + 250;
m_ArialCamera.camera.transform.position = vector;
this.setAnnouncement("Player " + this.m_Players[this.m_PlayerIndex].name + "'s Turn");
if(this.m_PlayerIndex != 0)
{
this.m_IsSimulating = PlayerPrefs.GetInt("SimulatePlayer" + this.m_Players[this.m_PlayerIndex].name);
this.m_IsSimulating = 1;
}
else
{
this.m_IsSimulating = 0;
}
GameObject mainCamera = GameObject.FindWithTag ("MainCamera");
MouseOrbit mo = null;
if(mainCamera)
{
mo = mainCamera.GetComponent<MouseOrbit>();
}
if(this.m_IsSimulating >= 1)
{
this.StartSimulation();
if(mo)
{
mo.DoFreeze = true;
}
}
else
{
if(mo)
{
mo.DoFreeze = false;
}
}
}
void StartSimulation()
{
System.Random random = new System.Random();
StringBuilder sb = new StringBuilder();
int randomNumber = 0;
//determine either the player object or the next block
if(this.m_Dispatcher.isKiller)
{
m_SimulateToObject = this.m_Players[randomNumber%this.m_Players.Count];
randomNumber = random.Next(0, 100);
}
else
{
sb.AppendFormat("{0:D2}", this.m_Dispatcher.targetScore);
Debug.Log("target score=" + sb.ToString());
foreach(GameObject scoreField in GameObject.FindGameObjectsWithTag("ScoreField"))
{
if(scoreField.name == sb.ToString())
{
m_SimulateToObject = scoreField;
break;
}
}
}
this.m_IsTargetInitiallyVisible = false;
this.m_SimulationTimer = new System.Timers.Timer();
this.m_SimulationTimer.Elapsed+=new ElapsedEventHandler(TriggerCameraSimulation);
this.m_SimulationTimer.Interval=2500;
this.m_SimulationTimer.Enabled=true;
}
void TriggerCameraSimulation(object sender, ElapsedEventArgs e)
{
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
this.m_SimulateCamera = true;
}
void SimulateCamera()
{
GameObject mainCamera = GameObject.FindWithTag ("MainCamera");
MouseOrbit mo = null;
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
if(mainCamera)
{
mo = mainCamera.GetComponent<MouseOrbit>();
if(!this.m_IsTargetInitiallyVisible)
{
mo.IsManualMove = true;
mainCamera.transform.position = this.m_Players[this.m_PlayerIndex].transform.position;
mainCamera.transform.LookAt(this.m_SimulateToObject.transform, Vector3.up);
this.m_IsTargetInitiallyVisible = true;
}
else if(this.m_SimulateCamera)
{
if(mo.getDistance() >= 10.0f)
{
this.m_SimulateCamera = false;
}
mo.setDistance(-0.001f);
}
}
if(!this.m_SimulateCamera)
{
this.m_SimulationTimer = new System.Timers.Timer();
this.m_SimulationTimer.Elapsed+=new ElapsedEventHandler(TriggerSimulatedPluck);
this.m_SimulationTimer.Interval=2000;
this.m_SimulationTimer.Enabled=true;
}
}
void TriggerSimulatedPluck(object sender, ElapsedEventArgs e)
{
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
this.m_AutoPluck = true;
}
void AutoPluck()
{
System.Random random = new System.Random();
GameObject mainCamera = GameObject.FindWithTag ("MainCamera");
MouseOrbit mo = null;
float applyForce = 0.0f;
float slope = 0.00028648399272739457f;
float y_int = 0.2908366193449838f;
Vector3 vTorque = Vector3.zero;
int simulateId = PlayerPrefs.GetInt("SimulatePlayer" + this.m_Players[this.m_PlayerIndex].name);
int seed = (5 * ((int)(SimulationOptions.Pro) - simulateId));
int xSeed = 0;
int ySeed = 0;
int zSeed = 0;
int sign = random.Next(1, 1000)%2;
int range = random.Next(1, 1000)%seed;
int myValue = 0;
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
if(mainCamera)
{
mo = mainCamera.GetComponent<MouseOrbit>();
mo.IsManualMove = false;
}
this.m_AutoPluck = false;
if(simulateId >= 1)
{
float distance = Vector3.Distance(this.m_Players[this.m_PlayerIndex].transform.position,
this.m_SimulateToObject.transform.position);
if(simulateId != (int)(SimulationOptions.Pro))
{
myValue = random.Next(1, 6);
seed = (int)(myValue * ((int)(SimulationOptions.Pro) - simulateId));
sign = random.Next(1, 2);
range = random.Next(1, seed);
if(random.Next(1, 1000)%3 == 0)
{
distance += (sign == 1 ? range : -range);
}
}
vTorque.x = (float)(random.Next(1, 90));
vTorque.y = (float)(random.Next(1, 90));
vTorque.z = (float)(random.Next(1, 90));
applyForce = (slope * distance) + y_int;
this.m_Dispatcher.pluckObject(applyForce, vTorque);
}
}
void determineTurnOutcome()
{
int number = -1;
bool canActivePlayerContinue = false;
bool isAutoReward = false;
bool didElinimatePlayer = false;
foreach(GameObject nextObject in this.m_Players)
{
PlayerCollisionDispatcher nextDispatcher = nextObject.GetComponent<PlayerCollisionDispatcher>();
if(nextObject.activeSelf && !nextDispatcher.isGameOver && !nextDispatcher.isActive)
{
if(nextDispatcher.currentScore == nextDispatcher.targetScore)
{
nextDispatcher.totalScore = nextDispatcher.targetScore;
int.TryParse(nextDispatcher.name, out number);
nextDispatcher.targetScore++;
if(nextDispatcher.totalScore >= 13 || nextDispatcher.targetScore > 13)
{
nextDispatcher.totalScore = 13;
nextDispatcher.targetScore = 13;
nextDispatcher.isKiller = true;
this.setMaterial(nextDispatcher.renderer, "killers", nextDispatcher.name);
}
else
{
this.setMaterial(nextDispatcher.renderer, "numbers", nextDispatcher.name);
}
}
else if(nextDispatcher.didKillerCollide && (nextDispatcher.didLeaveBoard || nextDispatcher.didLeaveBounds))
{
this.setMaterial(nextDispatcher.renderer, "eliminated", nextDispatcher.name);
nextDispatcher.isGameOver = true;
didElinimatePlayer = true;
}
else if(nextDispatcher.didPlayerCollide && (nextDispatcher.didLeaveBoard || nextDispatcher.didLeaveBounds))
{
if(int.TryParse(nextDispatcher.name, out number))
{
nextDispatcher.targetScore = 1;
nextDispatcher.totalScore = 0;
}
}
else if(nextDispatcher.didEnterMud)
{
this.setMaterial(nextDispatcher.renderer, "mudd", nextDispatcher.name);
nextDispatcher.isKiller = false;
}
else if(nextDispatcher.isInMud && !nextDispatcher.didEnterMud)
{
isAutoReward = true;
}
else
{
this.setMaterial(nextDispatcher.renderer, "numbers", nextDispatcher.name);
}
}
nextDispatcher.transferStates();
}
if(this.m_Dispatcher.isKiller && !didElinimatePlayer)
{
this.setMaterial(this.m_Dispatcher.renderer, "numbers", this.m_Dispatcher.name);
this.m_Dispatcher.totalScore = 0;
this.m_Dispatcher.targetScore = 1;
this.m_Dispatcher.isKiller = false;
}
else if(this.m_Dispatcher.didEnterMud)
{
this.setMaterial(this.m_Dispatcher.renderer, "mud", this.m_Dispatcher.name);
}
else if(this.m_Dispatcher.currentScore == this.m_Dispatcher.targetScore || isAutoReward)
{
this.m_Dispatcher.totalScore = this.m_Dispatcher.targetScore;
canActivePlayerContinue = true;
this.m_Dispatcher.consecutivePops++;
int.TryParse(this.m_Dispatcher.name, out number);
this.m_Dispatcher.targetScore++;
this.setMaterial(this.m_Dispatcher.renderer, "numbers", this.m_Dispatcher.name);
}
else
{
this.setMaterial(this.m_Dispatcher.renderer, "numbers", this.m_Dispatcher.name);
}
this.isWinnerAnnounced();
if(!this.m_IsGameOver && !canActivePlayerContinue)
{
this.m_Dispatcher.endTurn();
this.startNextPlayer();
}
else if(canActivePlayerContinue)
{
this.m_Dispatcher.transferStates();
this.m_Dispatcher.isActive = true;
this.m_Dispatcher.didObjectMove = false;
this.m_Dispatcher.didObjectStop = false;
if(this.m_IsSimulating >= 1)
{
this.StartSimulation();
}
}
this.m_ForceValue = 0.0f;
}
void isWinnerAnnounced()
{
StringBuilder sb = new StringBuilder();
int totalPlayers = 0;
string winner = string.Empty;
int number = -1;
int totalPlayersInMud = 0;
foreach(GameObject nextObject in this.m_Players)
{
PlayerCollisionDispatcher nextDispatcher = nextObject.GetComponent<PlayerCollisionDispatcher>();
if(!nextDispatcher.isGameOver)
{
totalPlayers++;
winner = nextObject.name;
}
if(nextDispatcher.isInMud)
{
totalPlayersInMud++;
}
}
if(totalPlayers == 1)
{
if(winner != string.Empty && int.TryParse(winner, out number))
{
sb.AppendFormat("Congratulations Player {0}", number);
PlayerPrefs.SetString("WinningPlayer", sb.ToString());
}
else
{
PlayerPrefs.SetString("WinningPlayer", "Congratulations");
}
this.m_IsGameOver = true;
}
else if(totalPlayersInMud == this.m_Players.Count)
{
PlayerPrefs.SetString("WinningPlayer", "All players are stuck in the mud!");
this.m_IsGameOver = true;
}
}
void setMaterial(Renderer renderer, string state, string playerId)
{
StringBuilder sbNextImage = new StringBuilder();
sbNextImage.AppendFormat("Materials/playerObjects/{0}/{1}", state, playerId);
Material newMat = Resources.Load(sbNextImage.ToString(), typeof(Material)) as Material;
if(newMat)
{
renderer.material = newMat;
}
else
{
Debug.Log("FAILED to set material: " + sbNextImage.ToString());
}
}
void setAnnouncement(string text)
{
this.m_IsAnnouncement = true;
this.m_AnnouncementHeight = (int)(Screen.height * 0.5);
this.m_AnnouncementText = text;
}
void OnGUI() {
GUIStyle labelStyle = GUI.skin.label;
int number = -1;
StringBuilder scoreDetails = new StringBuilder();
StringBuilder turnDetails = new StringBuilder();
float x = 0;
float y = 0;
float w = 64.0f;
float h = 32.0f;
float alpha = 1.0f;
if(this.m_IsAnnouncement)
{
this.displayAnnouncement();
}
labelStyle.normal.textColor = new Color(1.0f, 1.0f, 1.0f, alpha);
Texture2D texture = new Texture2D(32, 32, TextureFormat.ARGB32, false);
for(int i = 0; i < 32; i++)
{
for(int j = 0; j < 32; j++)
{
texture.SetPixel(i, j, new Color(0.0f, 0.0f, 0.0f, 0.25f));
}
}
texture.Apply();
labelStyle.normal.background = texture;
if(this.m_DoShowScore)
{
foreach(GameObject nextObject in this.m_Players)
{
PlayerCollisionDispatcher nextDispatcher = nextObject.GetComponent<PlayerCollisionDispatcher>();
int.TryParse(nextDispatcher.name, out number);
if(nextDispatcher.isGameOver)
{
scoreDetails.AppendFormat("\tPlayer {0}: Game Over\n", number);
}
else if(nextDispatcher.didEnterMud)
{
scoreDetails.AppendFormat("\tPlayer {0}: In The Mudd\n", number);
}
else if(nextDispatcher.isKiller)
{
scoreDetails.AppendFormat("\tPlayer {0}: Killer\n", number);
}
else
{
scoreDetails.AppendFormat("\tPlayer {0}: {1}\n", number, nextDispatcher.totalScore);
}
}
GUI.Label (new Rect (0, 0, 225, 100), scoreDetails.ToString());
}
w = 64.0f;
h = 32.0f;
x = Screen.width - w;
y = Screen.height - h;
if(GUI.Button (new Rect (x, y, w, h), "Menu"))
{
audioPlayer.PlayAudio("Audio/Click");
this.m_IsMenuShowing = !this.m_IsMenuShowing;
}
if(this.m_IsMenuShowing)
{
w = (64.0f * this.m_MenuText.Length);
h = 32.0f;
x = Screen.width - w - 64.0f;
y = Screen.height - h;
int selOption = GUI.Toolbar(new Rect(x, y, w, h), this.m_MenuOption, this.m_MenuText);
if(selOption != this.m_MenuOption)
{
audioPlayer.PlayAudio("Audio/Click");
this.m_MenuOption = -1;
this.m_IsMenuShowing = !this.m_IsMenuShowing;
switch(selOption)
{
case (int)(MenuOptions.ArialViewOption): //arial
this.m_ArialCamera.SetActive(!this.m_ArialCamera.activeSelf);
break;
case (int)(MenuOptions.VolumeOption): //mute
int muteVolume = PlayerPrefs.GetInt("MuteVolume");
muteVolume = (muteVolume + 1)%2;
PlayerPrefs.SetInt("MuteVolume", muteVolume);
if(muteVolume == 0)
{
this.m_MenuText[(int)(MenuOptions.VolumeOption)] = "Mute";
}
else
{
this.m_MenuText[(int)(MenuOptions.VolumeOption)] = "Volume";
}
break;
case (int)(MenuOptions.PauseOption): //pause
if(Time.timeScale == 0.0f)
{
this.setAnnouncement("Continuing Game Play");
Time.timeScale = this.m_Speed;
this.m_MenuText[(int)(MenuOptions.PauseOption)] = "Pause";
}
else
{
this.setAnnouncement("Game Is Paused");
Time.timeScale = 0.0f;
this.m_MenuText[(int)(MenuOptions.PauseOption)] = "Play";
}
break;
case (int)(MenuOptions.ScoresOption): //scores
this.m_DoShowScore = !this.m_DoShowScore;
break;
case (int)(MenuOptions.RestartOption): //restart
Time.timeScale = this.m_Speed;
this.restartGame();
break;
case (int)(MenuOptions.QuitOption): //quit
Application.LoadLevel("Opening Screen");
break;
default:
break;
}
}
}
if(this.m_ArialCamera.activeSelf)
{
x = Screen.width * 0.7f - 10.0f;
y = 0;
w = 10.0f;
h = Screen.height * 0.3f;
this.m_ArialView.z = GUI.VerticalSlider (new Rect(x, y, w, h), this.m_ArialView.z, 1.0f, 0.0f);
x = Screen.width * 0.7f;
y = Screen.height * 0.3f;
w = Screen.width * 0.3f;
h = 10.0f;
this.m_ArialView.x = GUI.HorizontalSlider (new Rect(x, y, w, h), this.m_ArialView.x, 1.0f, 0.0f);
x = Screen.width * 0.7f;
y = Screen.height * 0.3f + 12.0f;
w = Screen.width * 0.3f;
h = 10.0f;
this.m_ArialView.y = GUI.HorizontalSlider (new Rect(x, y, w, h), this.m_ArialView.y, 1.0f, 0.0f);
}
int.TryParse(this.m_Players[this.m_PlayerIndex].name, out number);
turnDetails.AppendFormat("\tPlayer {0}'s Turn\n", number);
turnDetails.AppendFormat("\tNext Goal: {0}\n", this.m_Dispatcher.targetScore);
GUI.Label (new Rect (0, Screen.height - 100, 225, 100), turnDetails.ToString());
if(!this.m_Dispatcher.didObjectMove && m_IsSimulating == 0)
{
x = 250.0f;
y = Screen.height - 190.0f;
w = 30.0f;
h = 150.0f;
this.m_ForceValue = GUI.VerticalSlider (new Rect(x, y, w, h), m_ForceValue, 1.0f, 0.0f);
x = 250.0f;
y = Screen.height - 30.0f;
w = 100.0f;
h = 30.0f;
if(GUI.Button (new Rect(x, y, w, h), "Pluck!"))
{
System.Random random = new System.Random();
Vector3 vTorque = Vector3.zero;
int xSeed = 0;
int ySeed = 0;
int zSeed = 0;
xSeed = (random.Next(1, 45));
ySeed = (random.Next(1, 45));
zSeed = (random.Next(1, 45));
vTorque = new Vector3(xSeed, ySeed, zSeed);
this.m_Dispatcher.pluckObject(this.m_ForceValue, vTorque);
}
}
}
void displayAnnouncement()
{
float x = 0;
float y = 0;
float w = 0;
float h = 0;
float alpha = 1.0f;
GUIStyle announcementStyle = null;
GUIStyle labelStyle = null;
announcementStyle = new GUIStyle();
labelStyle = GUI.skin.label;
labelStyle.normal.textColor = new Color(1.0f, 1.0f, 1.0f, alpha);
x = (int)(Screen.width * 0.25);
y = (int)m_AnnouncementHeight;
w = (int)(Screen.width * 0.5);
h = 100;
alpha = (float)m_AnnouncementHeight/(float)(Screen.height * 0.5);
announcementStyle.fontSize = 32;
announcementStyle.alignment = TextAnchor.MiddleCenter;
announcementStyle.fontStyle = FontStyle.BoldAndItalic;
announcementStyle.normal.textColor = new Color(1.0f, 1.0f, 1.0f, alpha);
GUI.Label (new Rect (x, y, w, h), this.m_AnnouncementText, announcementStyle);
if(Time.timeScale != 0.0f)
{
if((this.m_AnnouncementHeight + h) <= 0)
{
this.m_IsAnnouncement = false;
this.m_AnnouncementHeight = (int)(Screen.height * 0.5);
}
else
{
this.m_AnnouncementHeight -= 1;
}
}
}
}
-----------

I believe I have narrowed the freezing down. Simulated testing results is leading me to believe that my problem is inside the OnGUI() method. I have commented that method out all together, and my app is operating smoothly. I'll figure this out, unless someone beats me to the root cause and solution.

I solved it...
My initial suspicions were correct: the problem did lie within the OnGUI() method. I moved the following source code to the Start() method. It made sense, since I'm only building a transparent background texture once.:
Texture2D texture = new Texture2D(32, 32, TextureFormat.ARGB32, false);
for(int i = 0; i < 32; i++)
{
for(int j = 0; j < 32; j++)
{
texture.SetPixel(i, j, new Color(0.0f, 0.0f, 0.0f, 0.25f));
}
}
texture.Apply();

Related

glutWarpPointer with first person camera

I'm trying to do a first person camera with GLUT, I have my get mouse speed x/y code here..
X_mouse = mousex;
Y_mouse = mousey;
current_t = static_cast<double>(glutGet(GLUT_ELAPSED_TIME));
delta_t = (current_t - previous_t)/CLOCKS_PER_SEC;
diffX = (X_mouse - Xpre);
diffY = (Y_mouse - Ypre);
if ( diffX != 0)
{
if (delta_t == 0) delta_t = 1;
Vx = diffX / delta_t;
MouseXSpd = Vx/1000.0;
}
if ( diffY != 0)
{
if (delta_t == 0) delta_t = 1;
Vx = diffY / delta_t;
MouseXSpd = Vy/1000.0;
}
glutSwapBuffers(); //<-- not sure if this is needed
previous_t = current_t;
Xpre = X_mouse;
Ypre = Y_mouse;
Then in my glutMotionFunc is just this code
void MousePosition(int x, int y) {
mousex = x;
mousey = y;
}
but having trouble with warping the mouse pointer when it gets to the edge of the window.

Boolean fuction to all the elements in an array processing 3.0

I'm trying to make a program which shows some circles, and when the user puts all the circles in one place, the background changes. The problem I have is that when one circle is moved to that place the background changes, but I need that to happened once all the elements of the array had changed position..
DragMe[] drags = new DragMe[15];
PGraphics topLayer;
PGraphics toperLayer;
color backgr;
void setup() {
size(500, 500);
for (int i = 0; i < drags.length; i++) {
drags[i] = new DragMe();
}
topLayer = createGraphics(width, height, g.getClass().getName());
}
void draw() {
background(backgr);
{
topLayer.beginDraw();
topLayer.noFill();
topLayer.stroke(0 );
if (mousePressed ==true) {
topLayer.line( pmouseX, pmouseY, mouseX, mouseY );
topLayer.endDraw();
}
image( topLayer, 0, 0 );
}
for (int i = 0; i < drags.length; i++) {
drags[i].display();
drags[i].update();
}
for (int i = 0; i < drags.length; i++) {
drags[i].fondo();
}
{
ellipse(width/2.5, height/2.5, 110, 110);
fill(255);
}
}
void mousePressed() {
for (int i = 0; i < drags.length; i++) {
if (!drags[i].isOver())
drags[i].dontMove = true;
drags[i].offset_x = mouseX - drags[i].pos_x;
drags[i].offset_y = mouseY - drags[i].pos_y;
}
}
void mouseReleased() {
for (int i = 0; i < drags.length; i++) {
drags[i].locked = false;
drags[i].dontMove = false;
}
}
class DragMe {
float pos_x, pos_y, SIZE = 25;
float prev_x, prev_y;
boolean locked;
boolean dontMove;
boolean all;
color c = color (255);
float offset_x, offset_y;
DragMe() {
pos_x = random(width-SIZE);
pos_y = random(height-SIZE);
}
void update() {
if (isOver() && !locked && !dontMove || locked && !dontMove )
c = color (255);
else
c = color (255);
if (isClicked()) {
locked = true;
}
if (isIn()) {
locked = false;
all = true;
}
if (locked && !dontMove) {
pos_x = mouseX - offset_x;
pos_y = mouseY - offset_y;
}
}
void display() {
fill(c);
ellipse(pos_x, pos_y, SIZE, SIZE);
ellipseMode(CORNER);
noStroke();
}
boolean isOver() {
float right_x = pos_x + SIZE;
float bottom_y = pos_y + SIZE;
return mouseX >= pos_x && mouseX <= right_x &&
mouseY >= pos_y && mouseY <= bottom_y;
}
boolean isClicked() {
return isOver() && mousePressed && !dontMove;
}
boolean isIn() {
float right_x = pos_x + SIZE;
float bottom_y = pos_y + SIZE;
return right_x >= width/2.5 + SIZE && right_x <= width/2.5 + 100 &&
bottom_y >= height/2.5 + SIZE && bottom_y <= height/2.5 + 100;
}
void fondo() {
if (all == true)
backgr= 255;
}
}
You have 15 instances of DragMe.
Each of those instances contains a variable named all.
When one instance's all is true, you set the background to white.
Specifically, this function:
void fondo() {
if (all == true)
backgr= 255;
}
Which you call from draw():
for (int i = 0; i < drags.length; i++) {
drags[i].fondo();
}
Instead, you need to check every instance's all variable, and only change the background if they are all true (in other words, if none of them are false):
boolean allIn = true;
for (int i = 0; i < drags.length; i++) {
if (!drags[i].all) {
allIn = false;
}
}
if (allIn) {
backgr= 255;
}
For future questions, please try to make sure your code is formatted. It might also be a good idea to use better variable names- naming a variable all is a bit hard to talk about. Maybe something like isInsideWhiteCircle would be better.

Processing - Flock Boids avoid draggable objects

I'm working on a boids flocking project.
My goal is to have several draggable objects which have to be avoided by the boids.
There are several different flocks with a different starting position.
I managed to get the boids to avoid one draggable object. But I can't seem to make them avoid all. (using a for loop)
I really can't figure out why this won't do the trick..
I hope you could give me some suggestions.
the code:
int initBoidNum = 100; //amount of boids to start the program with
BoidList flock1, flock2, flock3;
Draggable draggable;
NullDraggableObject nullDraggableObject;
ArrayList draggables;
int id;
float[] xposs= new float[10];
float[] yposs= new float[10];
String turn;
void setup() {
size(1000, 700);
//create and fill the list of boids
flock1 = new BoidList(150, 0, 10, 100);
flock2 = new BoidList(150, 255, 10, 200);
flock3 = new BoidList(150, 150, 10, 300);
turn = "turn";
nullDraggableObject = new NullDraggableObject();
draggables = new ArrayList();
for (int i = 0; i < 10; i++) {
draggables.add(new DraggableObject(random(width), random(height/2)));
}
}
void draw() {
background(100, 60);
flock1.run();
flock2.run();
flock3.run();
stroke(255);
noFill();
draggable = nullDraggableObject;
for (id = 0; id < draggables.size (); id++) {
Draggable d = (Draggable)draggables.get(id);
d.draw();
if (d.isBeingMouseHovered()) {
draggable = d;
}
}
}
void mousePressed() {
draggable.mousePressed();
}
void mouseDragged() {
draggable.mouseDragged();
}
void mouseReleased() {
draggable.mouseReleased();
}
interface Draggable {
boolean isBeingMouseHovered();
boolean inside(float ix, float iy);
void draw();
void mousePressed();
void mouseDragged();
void mouseReleased();
}
class NullDraggableObject implements Draggable {
boolean isBeingMouseHovered() {
return false;
}
boolean inside(float ix, float iy) {
return false;
}
void draw() {
}
void mousePressed() {
}
void mouseDragged() {
}
void mouseReleased() {
}
}
public class DraggableObject implements Draggable {
float XX, YY;
float radius;
boolean drag;
float dragX, dragY;
DraggableObject(float _x, float _y) {
XX = _x;
YY = _y;
radius = 50;
drag = false;
dragX = 0;
dragY = 0;
}
boolean isBeingMouseHovered() {
return inside(mouseX, mouseY);
}
boolean inside(float ix, float iy) {
return (dist(XX, YY, ix, iy) < radius);
}
void draw() {
ellipseMode(CENTER);
ellipse(XX, YY, 2*radius, 2*radius);
String space = "__";
println(id);
println(XX);
println(YY);
xposs[id] = XX;
yposs[id] = YY;
}
void mousePressed() {
drag = inside(mouseX, mouseY);
if (drag) {
dragX = mouseX - XX;
dragY = mouseY - YY;
}
}
void mouseDragged() {
if (drag) {
XX = mouseX - dragX;
YY = mouseY - dragY;
}
}
void mouseReleased() {
drag = false;
}
}
class Boid {
//fields
PVector pos, vel, acc, ali, coh, sep; //pos, velocity, and acceleration in a vector datatype
float neighborhoodRadius; //radius in which it looks for fellow boids
float maxSpeed = 1; //maximum magnitude for the velocity vector
float maxSteerForce = .05; //maximum magnitude of the steering vector
float sMod, aMod, cMod; //modifiers for the three forces on the boid
float h; //hue
Boid(PVector inPos) {
pos = new PVector();
pos.set(inPos);
vel = new PVector(random(-1, 1), random(-1, 1));
acc = new PVector(0, 0);
neighborhoodRadius = 20;
sMod = 1;
aMod = 1;
cMod = 4;
}
Boid(PVector inPos, PVector inVel, float r) {
pos = new PVector();
pos.set(inPos);
vel = new PVector();
vel.set(inVel);
acc = new PVector(0, 0);
neighborhoodRadius = r;
}
void run(ArrayList bl) {
for (int i =0; i < 10; i++) {
acc.add(attract(new PVector(width/2, height/2), true));
acc.add(avoid(new PVector(xposs[i], yposs[i]), true));
if (i == 10) i = 0;
}
if (pos.x>width-10)acc.add(bounce(new PVector(width, pos.y), true));
if (pos.x<10) acc.add(bounce(new PVector(0, pos.y), true));
if (pos.y>height-10) acc.add(bounce(new PVector(pos.x, height), true));
if (pos.y<10) acc.add(bounce(new PVector(pos.x, 0), true));
ali = alignment(bl);
coh = cohesion(bl);
sep = seperation(bl);
for (int i =0; i < 10; i++) {
if (PVector.dist(new PVector(xposs[i], yposs[i]), pos)>180) {
acc.add(PVector.mult(ali, aMod));
acc.add(PVector.mult(coh, cMod));
acc.add(PVector.mult(sep, sMod));
}
if (PVector.dist(new PVector(xposs[i], yposs[i]), pos)<80) maxSpeed = 1000;
if (i == 10) i = 0;
}
if (PVector.dist(new PVector(width, height), pos)<60) maxSpeed = 1000;
if (PVector.dist(new PVector(0, 0), pos)<50) {
maxSpeed = 1000;
} else {
maxSpeed = 1;
}
move();
checkBounds();
render();
}
void move() {
vel.add(acc); //add acceleration to velocity
vel.limit(maxSpeed); //make sure the velocity vector magnitude does not exceed maxSpeed
pos.add(vel); //add velocity to position
acc.mult(0); //reset acceleration
}
void checkBounds() {
}
void render() {
pushMatrix();
translate(pos.x, pos.y);
rotate(atan2(vel.y, vel.x)); //rotate drawing matrix to direction of velocity
stroke(0);
noFill();
ellipse(0, 0, neighborhoodRadius/2, neighborhoodRadius/2);
noStroke();
fill(h);
//draw triangle
beginShape(TRIANGLES);
rect(0, 0, 6, 2);
endShape();
popMatrix();
}
//steering. If arrival==true, the boid slows to meet the target. Credit to Craig Reynolds
PVector steer(PVector target, boolean arrival) {
PVector steer = new PVector(); //creates vector for steering
if (!arrival) {
steer.set(PVector.sub(target, pos)); //steering vector points towards target (switch target and pos for avoiding)
steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
} else {
PVector targetOffset = PVector.sub(target, pos);
float distance=targetOffset.mag();
float rampedSpeed = maxSpeed*(distance/100);
float clippedSpeed = min(rampedSpeed, maxSpeed);
PVector desiredVelocity = PVector.mult(targetOffset, (clippedSpeed/distance));
steer.set(PVector.sub(desiredVelocity, vel));
}
return steer;
}
//avoid. If weight == true avoidance vector is larger the closer the boid is to the target
PVector avoid(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(pos, target)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(pos, target)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector attract(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(target, pos)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(target, pos)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector bounce(PVector target, boolean weight) {
PVector steer = new PVector(); //creates vector for steering
steer.set(PVector.sub(pos, target)); //steering vector points away from target
if (weight) steer.mult(1/sq(PVector.dist(pos, target)));
//steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
return steer;
}
PVector seperation(ArrayList boids) {
PVector posSum = new PVector(0, 0);
PVector repulse;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = PVector.dist(pos, b.pos);
if (d>0&&d<=neighborhoodRadius) {
repulse = PVector.sub(pos, b.pos);
repulse.normalize();
repulse.div(d);
posSum.add(repulse);
}
}
return posSum;
}
PVector alignment(ArrayList boids) {
PVector velSum = new PVector(0, 0);
int count = 0;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = PVector.dist(pos, b.pos);
if (d>0&&d<=neighborhoodRadius) {
velSum.add(b.vel);
count++;
}
}
if (count>0) {
velSum.div((float)count);
velSum.limit(maxSteerForce);
}
return velSum;
}
PVector cohesion(ArrayList boids) {
PVector posSum = new PVector(0, 0);
PVector steer = new PVector(0, 0);
int count = 0;
for (int i=0; i<boids.size (); i++) {
Boid b = (Boid)boids.get(i);
float d = dist(pos.x, pos.y, b.pos.x, b.pos.y);
if (d>0&&d<=neighborhoodRadius) {
posSum.add(b.pos);
count++;
}
}
if (count>0) posSum.div((float)count);
steer = PVector.sub(posSum, pos);
steer.limit(maxSteerForce);
return steer;
}
}
class BoidList {
ArrayList boids; //will hold the boids in this BoidList
float h; //for color
BoidList(int n, float ih, int xstart, int ystart) {
boids = new ArrayList();
h = ih;
for (int i=0; i<n; i++) {
boids.add(new Boid(new PVector(xstart, ystart)));
}
}
void run() {
for (int i=0; i<boids.size (); i++) {
Boid tempBoid = (Boid)boids.get(i); //create a temporary boid to process and make it the current boid in the list
tempBoid.h = h;
tempBoid.run(boids); //tell the temporary boid to execute its run method
}
}
}

Dynamically removing movieclips

First time poster, long time reader.
I've been having a problem with figuring this out. I've been stuck in my game for 4 hours now, googling and trying to figure out how to do it.
I have a game where i add some cartoonish ants, that when they are clicked, they need to be removed from stage. There are 4 differend kinds of ants, so im doing a Math.random for picking which one to add. (ant 1+2+3 have 50% chance to spawn and 4th 50%)
rnd_nbr = (Math.random() * 5)+1;
I have a timer doing 10 tick, and i reset the timer to make neverending.
Then i have a math random and if sentences adding mc' to the stage with movement from Tweener, and event listeners for clicks.
But i cant figure out how to remove them when clicked.
I have done alot of failed tries right inside the click_candy_anty function.
I've left them commented out.
I apologize for abit messy coding, but it will be cleaned up when(hopefully) it gets working.
Help is highly appreciated.
import caurina.transitions.Tweener;
var ant_index:Array = new Array(10); //index for ants
var ant_number:int;
var ant_temp:int;
var rnd_nbr:int; //var for rnd number
var score:int = 0;
var score_update:String;
var reset_timer:Boolean = false;
var antTimer:Timer = new Timer(800,10); //timer
antTimer.addEventListener(TimerEvent.TIMER, create_ant);
var anty0_:anty_0; //creating ant vars for all 5 kind
var anty1_:anty_1;
var anty2_:anty_2;
var anty3_:anty_3;
var anty4_:anty_4;
var screen_number:int = 0;
var antyArray:Array = new Array(10);
var main:main_mc = new main_mc;
main.x = 0; //0,0
main.y = 0;
addChild(main);
var score_format:TextFormat = new TextFormat();
score_format.size = 25;
score_format.align = TextFormatAlign.CENTER;
var score_txt:TextField = new TextField();
score_txt.defaultTextFormat = score_format;
score_txt.text = "" + score;
score_txt.x = 600;
score_txt.y = 20;
score_txt.border = true;
score_txt.autoSize = TextFieldAutoSize.LEFT ;
score_txt.height = 40;
addChild(score_txt);
var score_txt_update:TextField = new TextField();
score_txt_update.defaultTextFormat = score_format;
score_txt_update.text = "0";
score_txt_update.x = 550;
score_txt_update.y = 20;
score_txt_update.border = true;
score_txt_update.autoSize = TextFieldAutoSize.LEFT ;
score_txt_update.height = 40;
score_txt_update.alpha = 0;
addChild(score_txt_update);
function click_candy_anty(event:MouseEvent):void{
if (score < 20){
//trace("evt: " + evt);
//this.removeChild();
//this.removeChild(this);
//removeChild(evt.currentTarget);
//removeChild(evt.target.name.substr(7));
//removeChild(this);
//removeChild(evt.currentTarget.name);
// trace("The " + evt.target.label + " button was clicked");
// trace(evt.type)
score++;
score_txt.text = "" + score;
//score_update = "+1";
score_txt_update.text = "+1";
//ori position x:570 y:20
score_txt_update.y = -30;
Tweener.addTween(score_txt_update, {y: 20, alpha: 1, time: 0.8, transition:"linear", onComplete:score_txt_update_fade});
}
else {
stop_game();
trace("48");
}
}
function score_txt_update_fade(Event = null){
Tweener.addTween(score_txt_update, {y: 50, alpha: 0, time: 0.4, transition:"linear"});
}
function click_leaf_anty(Event = null):void{
if (score > 0 && score < 20){
score--;
score_txt.text = "" + score;
score_txt_update.text = "-1";
score_txt_update.y = 50;
Tweener.addTween(score_txt_update, {y: 20, alpha: 1, time: 0.4, transition:"linear", onComplete:score_txt_update_fade_neg});
trace("12 wrong");
}
/* else {
stop_game();
trace("12");
trace("score: " + score + ", ");
}*/
}
function score_txt_update_fade_neg(Event = null){
Tweener.addTween(score_txt_update, {y: -30, alpha: -1, time: 0.8, transition:"linear"});
}
//screen1();
start_timer();
function screen1(Event = null):void {
screen_number = 2;//slet når event listener til scr1 kommer
if (screen_number == 2){
}
else {
screen_number = 2;
}
}
function screen2(Event = null):void {
if (screen_number == 3){
}
else {
screen_number = 3;
}
start_timer();
}
function start_timer(Event = null):void {
if (score < 20) {
if (reset_timer == false){
antTimer.start();
//trace("antTimer initialized");
}
if (reset_timer == true){
antTimer.reset();
antTimer.start();
//trace("antTimer RESETTED & initialized");
}
}
else {
stop_game();
trace("57");
}
}
function stop_game(Event = null):void {
if (screen_number != 2){
screen_number = 2;
trace("Game completed - launching end screen");
// move to next screen
for (var i:Number=0; i<=9;i++){
ant_temp = ant_number;
if (ant_temp < 9) {
//trace("ant_temp er lavere end 9::: " + ant_temp );
ant_temp++;
}
else if (ant_temp == 9) {
//trace("ant_temp lig med 9::: " + ant_temp );
ant_temp = 0;
}
if (ant_index[ant_temp] == 1){
//removeChild(anty1_);
if ("anty1_" + ant_temp != null){
removeChild(getChildByName("anty1_" + (ant_temp)));
}
}
if (ant_index[ant_temp] == 2){
//removeChild(anty2_);
if ("anty2_" + ant_temp != null){
removeChild(getChildByName("anty2_" + (ant_temp)));
}
}
if (ant_index[ant_temp] == 3){
//removeChild(anty3_);
if ("anty3_" + ant_temp != null){
removeChild(getChildByName("anty3_" + (ant_temp)));
}
}
else if (ant_index[ant_temp] == 4){
//removeChild(anty4_);
if ("anty4_" + ant_temp != null){
removeChild(getChildByName("anty4_" + (ant_temp)));
}
}
}//for loop end
screen3();
}
}
function screen3 (Event = null):void{
var end:end_mc = new end_mc;
end.x = 0; //0,0
end.y = 0; //
addChild(end);
}
function create_ant(Event = null):void {
//trace("antTimer triggered");
if (score < 20) {
rnd_nbr = (Math.random() * 5)+1;
ant_index[ant_number] = rnd_nbr;
trace("ant_number" + ant_number);
//trace("ant_index[" + ant_number + "]: " + ant_index[ant_number]);
if (ant_index[ant_number] == 1){
anty1_ = new anty_1();
anty1_.name = "anty1_" + (ant_number);
anty1_.height = 118;
anty1_.width = 102;
anty1_.x = 100;
anty1_.y = 300;
addChild(anty1_);
Tweener.addTween(anty1_, {x: 541, time: 3, transition:"linear"});
anty1_.addEventListener(MouseEvent.MOUSE_DOWN, click_candy_anty);
//trace("anty1_" + ant_number);
//trace("" + anty_1[ant_number].name);
}
if (ant_index[ant_number] == 2){
anty2_ = new anty_2();
anty2_.name = "anty2_" + (ant_number);
anty2_.height = 118;
anty2_.width = 102;
anty2_.x = 100;
anty2_.y = 300;
addChild(anty2_);
Tweener.addTween(anty2_, {x: 541, time: 3, transition:"linear"});
anty2_.addEventListener(MouseEvent.MOUSE_DOWN, click_candy_anty);
//trace("anty2_" + ant_number);
}
if (ant_index[ant_number] == 3){
anty3_ = new anty_3();
anty3_.name = "anty3_" + (ant_number);
anty3_.height = 118;
anty3_.width = 102;
anty3_.x = 100;
anty3_.y = 300;
addChild(anty3_);
Tweener.addTween(anty3_, {x: 541, time: 3, transition:"linear"});
anty3_.addEventListener(MouseEvent.MOUSE_DOWN, click_candy_anty);
//trace("anty3_" + ant_number);
}
else if (ant_index[ant_number] > 3 && ant_index[ant_number] < 7){
anty4_ = new anty_4();
anty4_.name = "anty4_" + (ant_number);
anty4_.height = 118;
anty4_.width = 102;
anty4_.x = 100;
anty4_.y = 300;
addChild(anty4_);
Tweener.addTween(anty4_, {x: 541, time: 3, transition:"linear"});
anty4_.addEventListener(MouseEvent.MOUSE_DOWN, click_leaf_anty);
//trace("anty4_" + ant_number);
}
ant_temp = ant_number;
if (ant_temp < 9) {
//trace("ant_temp er lavere end 9::: " + ant_temp );
ant_temp++;
}
else if (ant_temp == 9) {
//trace("ant_temp lig med 9::: " + ant_temp );
ant_temp = 0;
}
if (ant_index[ant_temp] == 1){
//removeChild(anty1_);
removeChild(getChildByName("anty1_" + (ant_temp)));
}
if (ant_index[ant_temp] == 2){
//removeChild(anty2_);
removeChild(getChildByName("anty2_" + (ant_temp)));
}
if (ant_index[ant_temp] == 3){
//removeChild(anty3_);
removeChild(getChildByName("anty3_" + (ant_temp)));
}
else if (ant_index[ant_temp] == 4){
//removeChild(anty4_);
removeChild(getChildByName("anty4_" + (ant_temp)));
}
/* if (ant_number == 9) { //resets the ant_number - being the end of the 10th ant
ant_number = 0;
start_timer(); // launches the timer again
trace("Timer resetted");
for (var i:Number=0; i<=9;i++){
if (ant_index[i] == 1){
//removeChild(anty1_);
removeChild(getChildByName("anty1_" + (i)));
}
if (ant_index[i] == 2){
//removeChild(anty2_);
removeChild(getChildByName("anty2_" + (i)));
}
if (ant_index[i] == 3){
//removeChild(anty3_);
removeChild(getChildByName("anty3_" + (i)));
}
else if (ant_index[i] == 4){
//removeChild(anty4_);
removeChild(getChildByName("anty4_" + (i)));
}
}//for loop end
}//ends if=9 reset*/
if (ant_number == 9) { //resets the ant_number at 10th ant, and restarts the timer
ant_number = 0;
reset_timer = true;
start_timer();
}
else {
ant_number++;
}
/*else {
ant_number++;
}*/
}
else if (score >= 20 && screen_number != 2){
stop_game();
trace("14");
}
} //create_ant func end
You can also use:
removeChild( evt.currentTarget as DisplayObject );
Or
var clicked_ant:DisplayObject = evt.currentTarget as DisplayObject;
removeChild( clicked_ant );
Let's say that you've created a Ant class, you could have something like this
private function init():void
{
this.addEventListener( MouseEvent.CLICK , clickHandler );
}
private function clickHandler( event:MouseEvent ):void
{
this.removeEventListener( MouseEvent.CLICK , clickHandler );
if( this.parent != null )
this.parent.removeChild( this );
}

how to get the visible area of canvas in wpf

I am creating an application just like a paint in WPF, and I want to add zoom functionality to it. I am taking canvas as a parent and writable bitmap on it as child on which I draw. When the size of the canvas is small, I am drawing on writable bitmap smoothly, but when the size of the canvas is large, and zoom it, canvas size will be large, problem occur to draw on this large area. So I want to find the visible region of the canvas so that I can draw on it smoothly.
Please give me a source code to find the visible region of the canvas.
I have create this application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Interop;
namespace MapDesigner.Controls
{
class MapCanvas : Canvas
{
#region Routed Events
public static readonly RoutedEvent SelectedColorChangeEvent = EventManager.RegisterRoutedEvent(
"SelectedColorChange", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ucToolBox));
public event RoutedEventHandler SelectedColorChange
{
add { AddHandler(SelectedColorChangeEvent, value); }
remove { RemoveHandler(SelectedColorChangeEvent, value); }
}
#endregion
#region Enums
public enum Tool
{
Pencil,
FloodFill,
Eraser,
RectSelect,
Brush,
Part
}
#endregion
WriteableBitmap _wBMP;
Image _dispImg = new Image();
ScaleTransform st = new ScaleTransform();
int canvasHeight, canvasWidth;
double zoomLevel = 1;
Border brdGrid = new Border();
Color cellColor = Colors.Black;
Tool currentTool = Tool.Pencil;
int[,] array;
bool drawing = false;
bool showGrids = true;
public TextBlock tbPos;
public Tool CurrentTool
{
get
{
return currentTool;
}
set
{
currentTool = value;
}
}
public Color CellColor
{
get
{
return cellColor;
}
set
{
cellColor = value;
}
}
public bool GridsVisible
{
get
{
return showGrids;
}
set
{
showGrids = value;
}
}
public MapCanvas()
{
this.Children.Clear();
this.Children.Add(_dispImg);
//st.ScaleX = 1;
//st.ScaleY = 1;
// this.LayoutTransform = st;
}
void Refresh()
{
//canvas = new MapCanvas();
this.Children.Clear();
this.Children.Add(_dispImg);
st.ScaleX = 1;
st.ScaleY = 1;
this.Height = 0;
this.Width = 0;
zoomLevel = 1;
drawing = false;
}
public void LoadBMP(Uri bmpUri)
{
Refresh();
BitmapImage bmi = new BitmapImage(bmpUri);
_wBMP = new WriteableBitmap(bmi);
_dispImg.Source = _wBMP;
this.Height = bmi.Height;
this.Width = bmi.Width;
ShowGrids();
}
public void CreateBMP(int width, int height)
{
Refresh();
_wBMP = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
_dispImg.Source = _wBMP;
this.Height = height;
this.Width = width;
ShowGrids();
}
public void CreateNewDesign(Size mapSize)
{
Refresh();
_wBMP = new WriteableBitmap((int)mapSize.Width, (int)mapSize.Width, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
_dispImg.Source = _wBMP;
array = new int[(_wBMP.PixelHeight + 1), (_wBMP.PixelWidth + 1)];
canvasWidth = (int)mapSize.Width;
canvasHeight = (int)mapSize.Height;
this.Height = mapSize.Height;
this.Width = mapSize.Width;
ShowGrids();
}
void ShowGrids()
{
return;
double width = 1;// _tileWidth + _tileMargin;
double height = 1;// _tileHeight + _tileMargin;
double numTileToAccumulate = 16;
Polyline gridCell = new Polyline();
gridCell.Margin = new Thickness(.5);
gridCell.Stroke = Brushes.LightBlue;
gridCell.StrokeThickness = 0.1;
gridCell.Points = new PointCollection(new Point[] { new Point(0, height-0.1),
new Point(width-0.1, height-0.1), new Point(width-0.1, 0) });
VisualBrush gridLines = new VisualBrush(gridCell);
gridLines.TileMode = TileMode.Tile;
gridLines.Viewport = new Rect(0, 0, 1.0 / numTileToAccumulate, 1.0 / numTileToAccumulate);
gridLines.AlignmentX = AlignmentX.Center;
gridLines.AlignmentY = AlignmentY.Center;
VisualBrush outerVB = new VisualBrush();
Rectangle outerRect = new Rectangle();
outerRect.Width = 10.0; //can be any size
outerRect.Height = 10.0;
outerRect.Fill = gridLines;
outerVB.Visual = outerRect;
outerVB.Viewport = new Rect(0, 0,
width * numTileToAccumulate, height * numTileToAccumulate);
outerVB.ViewportUnits = BrushMappingMode.Absolute;
outerVB.TileMode = TileMode.Tile;
this.Children.Remove(brdGrid);
brdGrid = new Border();
brdGrid.Height = this.Height;
brdGrid.Width = this.Width;
brdGrid.Background = outerVB;
this.Children.Add(brdGrid);
}
protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
{
base.OnMouseMove(e);
tbPos.Text = (_wBMP.PixelWidth / zoomLevel).ToString() + "," + (_wBMP.PixelHeight / zoomLevel).ToString() + " | " + Math.Ceiling((((Point)e.GetPosition(this)).X) / zoomLevel).ToString() + "," + Math.Ceiling((((Point)e.GetPosition(this)).Y / zoomLevel)).ToString();
if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
{
Point pos = e.GetPosition(this);
int xPos = (int)Math.Ceiling((pos.X) / zoomLevel);
int yPos = (int)Math.Ceiling((pos.Y) / zoomLevel);
int xDraw = (int)Math.Ceiling(pos.X);
int yDraw = (int)Math.Ceiling(pos.Y);
array[xPos, yPos] = 1;
drawing = true;
SetPixelsFromArray((int)zoomLevel);
//for (int i = 0; i < zoomLevel; i++)
//{
// for (int j = 0; j < zoomLevel; j++)
// {
// _wBMP.setPixel(xDraw, yDraw, cellColor);
// _dispImg.Source = _wBMP;
// }
//}
//_wBMP.setPixel(xPos, yPos, cellColor);
//_wBMP.setPixel((int)pos.X, (int)pos.Y, cellColor);
//_dispImg.Source = _wBMP;
}
}
private void SetPixelsFromArray(int ZoomLevel)
{
for (int i = 1; i < _wBMP.PixelWidth / ZoomLevel; i++)
{
for (int j = 1; j < _wBMP.PixelHeight / ZoomLevel; j++)
{
if (array[i, j] == 1)
{
for (int k = 0; k < ZoomLevel; k++)
{
for (int l = 0; l < ZoomLevel; l++)
{
_wBMP.setPixel((int)(i * ZoomLevel + k), (int)(j * ZoomLevel + l), cellColor);
_dispImg.Source = _wBMP;
}
}
}
}
}
}
protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e)
{
//double d= this.ActualHeight;
//Double t =(double) this.GetValue(Canvas.TopProperty);
//double i = Convert.ToDouble(top);
getScreenRect();
if (e.ChangedButton == System.Windows.Input.MouseButton.Right)
{
if (cellColor == Colors.Black)
{
cellColor = Colors.Red;
}
else
{
cellColor = Colors.Black;
}
}
else if (e.ChangedButton == System.Windows.Input.MouseButton.Left)
{
Point pos = e.GetPosition(this);
int xPos = (int)Math.Ceiling((pos.X) / zoomLevel);
int yPos = (int)Math.Ceiling((pos.Y) / zoomLevel);
array[xPos, yPos] = 1;
drawing = true;
SetPixelsFromArray((int)zoomLevel);
//_wBMP.setPixel((int)pos.X, (int)pos.Y, cellColor);
//_dispImg.Source = _wBMP;
}
}
private void getScreenRect()
{
Visual _rootVisual = HwndSource.FromVisual(this).RootVisual;
GeneralTransform transformToRoot = this.TransformToAncestor(_rootVisual);
Rect screenRect = new Rect(transformToRoot.Transform(new Point(0, 0)), transformToRoot.Transform(new Point(this.ActualWidth, this.ActualHeight)));
DependencyObject parent = VisualTreeHelper.GetParent(this);
while (parent != null)
{
Visual visual = parent as Visual;
System.Windows.Controls.Control control = parent as System.Windows.Controls.Control;
if (visual != null && control != null)
{
transformToRoot = visual.TransformToAncestor(_rootVisual);
Point pointAncestorTopLeft = transformToRoot.Transform(new Point(0, 0));
Point pointAncestorBottomRight = transformToRoot.Transform(new Point(control.ActualWidth, control.ActualHeight));
Rect ancestorRect = new Rect(pointAncestorTopLeft, pointAncestorBottomRight);
screenRect.Intersect(ancestorRect);
}
parent = VisualTreeHelper.GetParent(parent);
//}
// at this point screenRect is the bounding rectangle for the visible portion of "this" element
}
// return screenRect;
}
protected override void OnMouseWheel(System.Windows.Input.MouseWheelEventArgs e)
{
base.OnMouseWheel(e);
if (e.Delta > 0)
{
zoomLevel *= 2;
}
else
{
zoomLevel /= 2;
}
if (zoomLevel > 8)
{
zoomLevel = 8;
}
if (zoomLevel <= 1)
{
zoomLevel = 1;
// brdGrid.Visibility = Visibility.Collapsed;
}
else
{
//brdGrid.Visibility = Visibility.Visible;
}
_wBMP = new WriteableBitmap((int)zoomLevel * canvasWidth, (int)zoomLevel * canvasHeight, 96, 96, PixelFormats.Bgr32, BitmapPalettes.WebPalette);
_wBMP.setPixel(Colors.White);
this.Width = zoomLevel * canvasWidth;
this.Height = zoomLevel * canvasHeight;
if (drawing == true)
{
SetPixelsFromArray((int)zoomLevel);
}
//this.InvalidateVisual();
}
internal bool SaveAsBMP(string fileName)
{
return true;
}
}
public static class bitmapextensions
{
public static void setPixel(this WriteableBitmap wbm, Color c)
{
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return;
wbm.Lock();
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
int x = 0;
int y = 0;
for (x = 0; x < wbm.PixelWidth; x++)
{
for (y = 0; y < wbm.PixelHeight; y++)
{
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
pbuff[loc] = c.B;
pbuff[loc + 1] = c.G;
pbuff[loc + 2] = c.R;
//pbuff[loc + 3] = c.A;
}
}
}
wbm.AddDirtyRect(new Int32Rect(0, 0, x, y));
wbm.Unlock();
}
public static void setPixel(this WriteableBitmap wbm, int x, int y, Color c)
{
if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1)
return;
if (y < 0 || x < 0)
return;
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return;
wbm.Lock();
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
pbuff[loc] = c.B;
pbuff[loc + 1] = c.G;
pbuff[loc + 2] = c.R;
//pbuff[loc + 3] = c.A;
}
wbm.AddDirtyRect(new Int32Rect(x, y, 1, 1));
wbm.Unlock();
}
public static Color getPixel(this WriteableBitmap wbm, int x, int y)
{
if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1)
return Color.FromArgb(0, 0, 0, 0);
if (y < 0 || x < 0)
return Color.FromArgb(0, 0, 0, 0);
if (!wbm.Format.Equals(PixelFormats.Bgr32))
return Color.FromArgb(0, 0, 0, 0);
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
Color c;
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
c = Color.FromArgb(pbuff[loc + 3], pbuff[loc + 2], pbuff[loc + 1], pbuff[loc]);
}
return c;
}
}
}
You should implement IScrollInfo on your canvas (or actually, create a custom Panel that inherits from Canvas and implements IScrollInfo).
That interface holds all that is relevant to your situation:
http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.iscrollinfo.aspx
http://blogs.msdn.com/b/jgoldb/archive/2008/03/08/performant-virtualized-wpf-canvas.aspx

Resources