So I'm playing around with the BouncyGame. I made it so that when you start the game you need to press the screen for it to start. I would like to implement this whenever you play a new round as well. I tried to reuse this att the bottom of my code but it made it extremely laggy.
// Register for touch events
var touchListener = new CCEventListenerTouchAllAtOnce();
touchListener.OnTouchesEnded = OnTouchesEnded;
touchListener.OnTouchesMoved = OnTouchesEnded;
AddEventListener(touchListener, this);
}
void OnTouchesEnded(List<CCTouch> touches, CCEvent touchEvent)
{
if (touches.Count > 0)
{
Schedule(RunGameLogic);
scoreLabel.Text = "Score: 0";
paddleSprite.RunAction(new CCMoveTo(.1f, new CCPoint(touches[0].Location.X, paddleSprite.PositionY)));
}
}
I have no idea how to do this, tried for 2 hours with 0 results. Any suggestions are welcome.
Here's the full code.
using System;
using System.Collections.Generic;
using CocosSharp;
using Microsoft.Xna.Framework;
namespace CocosSharpGameTest
{
public class IntroLayer : CCLayerColor
{
// Define a label variable
CCLabel scoreLabel;
CCSprite paddleSprite, ballSprite;
public IntroLayer() : base(CCColor4B.Black)
{
// create and initialize a Label
scoreLabel = new CCLabel("Tap to GO!", "Arial", 80, CCLabelFormat.SystemFont);
// add the label as a child to this Layer
scoreLabel.PositionX = 50;
scoreLabel.PositionY = 1000;
scoreLabel.AnchorPoint = CCPoint.AnchorUpperLeft;
AddChild(scoreLabel);
paddleSprite = new CCSprite("paddle.png");
AddChild(paddleSprite);
ballSprite = new CCSprite("ball.png");
AddChild(ballSprite);
}
protected override void AddedToScene()
{
base.AddedToScene();
// Use the bounds to layout the positioning of our drawable assets
CCRect bounds = VisibleBoundsWorldspace;
// position the label on the center of the screen
paddleSprite.PositionX = 100;
paddleSprite.PositionY = 100;
ballSprite.PositionX = 320;
ballSprite.PositionY = 640;
// Register for touch events
var touchListener = new CCEventListenerTouchAllAtOnce();
touchListener.OnTouchesEnded = OnTouchesEnded;
touchListener.OnTouchesMoved = OnTouchesEnded;
AddEventListener(touchListener, this);
}
void OnTouchesEnded(List<CCTouch> touches, CCEvent touchEvent)
{
if (touches.Count > 0)
{
Schedule(RunGameLogic);
scoreLabel.Text = "Score: 0";
paddleSprite.RunAction(new CCMoveTo(.1f, new CCPoint(touches[0].Location.X, paddleSprite.PositionY)));
}
}
float ballXVelocity;
float ballYVelocity;
// How much to modify the ball's y velocity per second:
const float gravity = 140;
int score = 0;
void RunGameLogic(float frameTimeInSeconds)
{
// This is a linear approximation, so not 100% accurate
ballYVelocity += frameTimeInSeconds * -gravity;
ballSprite.PositionX += ballXVelocity * frameTimeInSeconds;
ballSprite.PositionY += ballYVelocity * frameTimeInSeconds;
bool overlap = ballSprite.BoundingBoxTransformedToParent.IntersectsRect(paddleSprite.BoundingBoxTransformedToParent);
bool movingDown = ballYVelocity < 0;
if (overlap && movingDown)
{
ballYVelocity *= -1;
const float minXVelocity = -300;
const float maxXVelocity = 300;
ballXVelocity = CCRandom.GetRandomFloat(minXVelocity, maxXVelocity);
score++;
scoreLabel.Text = "Score: " + score;
}
float ballRight = ballSprite.BoundingBoxTransformedToParent.MaxX;
float ballLeft = ballSprite.BoundingBoxTransformedToParent.MinX;
float screenRight = VisibleBoundsWorldspace.MaxX;
float screenLeft = VisibleBoundsWorldspace.MinX;
bool shouldReflectXVelocity =
(ballRight > screenRight && ballXVelocity > 0) ||
(ballLeft < screenLeft && ballXVelocity < 0);
if (shouldReflectXVelocity)
{
ballXVelocity *= -1;
}
if (ballSprite.PositionY < VisibleBoundsWorldspace.MinY)
{
ballSprite.PositionX = 320;
ballSprite.PositionY = 640;
ballXVelocity = 0;
ballYVelocity = 0;
ballYVelocity *= -1;
scoreLabel.Text = "Score: 0";
score = 0;
}
}
}
}
Thanks in advance!
Figured it out!
There is an "Unschedule" Method built into Cocossharp.
Ref. https://developer.xamarin.com/api/namespace/CocosSharp/
I just added
Unschedule(RunGameLogic);
at the very en of my RunGameLogic method under
if (ballSprite.PositionY < VisibleBoundsWorldspace.MinY)
So once the ballSprite is out of bounds it will Unschedule what i Scheduled in my OntouchesEnded method. That means the code goes back to listening for touches.
Might have made some errors, but this is as best I could figure it out and it works!
Related
I am so confessed right now I don't even know how to properly form this question.
I have some code (as shown below) that is run on a different thread with the variable i not being referenced anywhere else that could interfere with it here. I just don't understand what is happening to cause this error, I put some watchers down with visual studio code and the values all seem to be fine and in range but almost randomly out of nowhere I will get this error.
Is it possible that this is caused by another section of code despite to my best knowledge being completely isolated from it? I even went as far to rename all other uses of i to different letters and I still get this problem.
Is it just something with for loops?
Am I somehow modifying i without even know it?
I just don't even know what to ask.
Here is the full code
`
using SFML.Graphics;
using SFML.Window;
using System.Diagnostics;
using System.Numerics;
namespace RenderEngine
{
public class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
PhysicsEngine re = new PhysicsEngine();
for (int i = 0; i < 100; i++)
{
Debug.WriteLine(i);
}
}
}
public class PhysicsEngine
{
Solver solver = new Solver();
public void RenderEngine2()
{
ContextSettings settings = new ContextSettings();
settings.AntialiasingLevel = 8;
RenderWindow window = new RenderWindow(new VideoMode(2000, 1000), "Poop", Styles.Default, settings);
SFML.Graphics.Color color = new SFML.Graphics.Color(0, 0, 0, 0);
window.SetVerticalSyncEnabled(true);
CircleShape shape = new CircleShape(5);
shape.FillColor = new SFML.Graphics.Color(0, 0, 255, 255);
window.Closed += handelclose;
int drawcount = 0;
while (window.IsOpen)
{
window.Clear(color);
window.DispatchEvents();
try
{
foreach (Partical partical in solver.Particals)
{
shape.Position = new SFML.System.Vector2f((partical.position.X), (partical.position.Y));
window.Draw(shape);
drawcount++;
}
drawcount = 0;
}
catch
{
Debug.WriteLine("notready yet");
}
window.Display();
}
void handelclose(object sender, EventArgs e)
{
window.Close();
Environment.Exit(Environment.ExitCode);
}
}
List<Partical> todraw = new List<Partical>();
void EngineLoop()
{
while (true)
{
foreach (Partical partical in solver.Particals)
{
int x = (int)Math.Round(partical.position.X/10);
int y = (int)Math.Round(partical.position.Y/10);
List<int> ts = solver.Grid[x, y];
if (ts != null)
{
for (int brokenint = 0; brokenint < ts.Count; brokenint++)
{
Debug.WriteLine(partical.ID);
Debug.WriteLine(ts[brokenint]);
if (partical.ID != ts[brokenint])
{
Vector2 pos = new Vector2(partical.ID, ts[brokenint]);
if (solver.Collision.Count > 0)
{
if (!solver.Collision.Contains(pos))
solver.Collision.Add(pos);
}
else
{
solver.Collision.Add(pos);
}
}
}
}
}
}
}
private int particalcount = 10;
bool canstart = false;
public PhysicsEngine()
{
Parallel.Invoke(() =>
{
while (!canstart) { Thread.Sleep(100); }
Debug.WriteLine("third thread");
RenderEngine2();
},
() =>
{
while (!canstart) { Thread.Sleep(100); }
Debug.WriteLine("engine started");
EngineLoop();
},
() =>
{
Debug.WriteLine("first thread");
PhysicsLoop(this);
}
);
}
void PhysicsLoop(PhysicsEngine PhyEng)
{
int frames = 0;
long second = 0;
PhysicsStart(PhyEng);
Thread.Sleep(1000);
Stopwatch sw = Stopwatch.StartNew();
solver.startupdate();
while (true)
{
sw.Start();
todraw = solver.Particals;
solver.update();
frames++;
if (second != (Stopwatch.GetTimestamp() / Stopwatch.Frequency))
{
second = (Stopwatch.GetTimestamp() / Stopwatch.Frequency);
Debug.WriteLine(frames);
frames = 0;
}
sw.Stop();
sw.Reset();
if (sw.ElapsedMilliseconds < 15)
Thread.Sleep(15 - (int)sw.ElapsedMilliseconds);
}
}
void PhysicsStart(PhysicsEngine phyeng)
{
for (int i = 0; i < 210; i++)
{
for (int j = 0; j < 110; j++)
{
solver.Grid[i,j] = new List<int>();
}
}
Random rand = new Random();
for (int i = 0; i < particalcount; i++)
{
Partical partical = new Partical();
partical.position = new Vector2(rand.Next(0, 2000), rand.Next(0, 1000));
partical.oldposition = partical.position;
partical.ID = i;
int x1 = (int)Math.Round((partical.position.X + 5) / 10);
int y1 = (int)Math.Round((partical.position.Y + 5) / 10);
int x2 = (int)Math.Round((partical.position.X - 5) / 10);
int y2 = (int)Math.Round((partical.position.Y - 5) / 10);
solver.Grid[x1, y1].Add(partical.ID);
solver.Grid[x2, y1].Add(partical.ID);
solver.Grid[x1, y2].Add(partical.ID);
solver.Grid[x2, y2].Add(partical.ID);
solver.Particals.Add(partical);
}
canstart = true;
}
}
public class Partical
{
public Vector2 position = new Vector2(0, 0);
public Vector2 oldposition = new Vector2(0, 0);
public Vector2 acceleration = new Vector2(0, 0);
Vector2 zero = new Vector2(0, 0);
public int ID = new int();
public void updatePosition(float sub)
{
Vector2 velocity = position - oldposition;
oldposition = position;
position = position + (velocity * 0.9f) + acceleration * sub;
acceleration = zero;
}
public void accelerate(Vector2 accel)
{
acceleration = acceleration + accel;
}
}
public class Solver
{
public List<Partical> Particals = new List<Partical>();
public List<Vector2> Collision = new List<Vector2>();
public List<int>[,] Grid = new List<int>[2100,1100];
public void update()
{
int subcount = 8;
float sub = 1f / (float)subcount;
for (int i = 0; i < subcount; i++)
{
applyGravity(sub);
updatePositions(sub);
for (int j = 0; j < Collision.Count; j++)
{
solvecolisions((int)Collision[j].X, (int)Collision[j].Y);
}
Collision.Clear();
}
}
public void startupdate()
{
applyGravity(0.5f);
updatePositions(0.5f);
applyGravity(0.5f);
updatePositions(0.5f);
}
void updatePositions(float sub)
{
foreach (Partical partical in Particals)
{
partical.updatePosition(sub);
int x1 = (int)Math.Round((partical.oldposition.X + 5) / 10);
int y1 = (int)Math.Round((partical.oldposition.Y + 5) / 10);
int x2 = (int)Math.Round((partical.oldposition.X - 5) / 10);
int y2 = (int)Math.Round((partical.oldposition.Y - 5) / 10);
Grid[x1,y1].Remove(partical.ID);
Grid[x2,y1].Remove(partical.ID);
Grid[x1,y2].Remove(partical.ID);
Grid[x2,y2].Remove(partical.ID);
x1 = (int)Math.Round((partical.position.X + 5) / 10);
y1 = (int)Math.Round((partical.position.Y + 5) / 10);
x2 = (int)Math.Round((partical.position.X - 5) / 10);
y2 = (int)Math.Round((partical.position.Y - 5) / 10);
Grid[x1,y1].Add(partical.ID);
Grid[x2,y1].Add(partical.ID);
Grid[x1,y2].Add(partical.ID);
Grid[x2,y2].Add(partical.ID);
}
}
void applyGravity(float sub)
{
float gravitystrangth = -0.1f;
foreach (Partical partical in Particals)
{
float a = partical.position.Y;
float b = partical.position.X;
b -= 1000;
a -= 500;
double angle = Math.Atan2(a, b);
float newA = gravitystrangth * (float)(Math.Sin(angle));
float newB = gravitystrangth * (float)(Math.Sin((Math.PI / 180) * 90 - angle));
Vector2 gravity = new Vector2(newB, newA);
partical.accelerate(gravity);
}
}
void solvecolisions(int id1, int id2)
{
Partical part = Particals[id1];
Partical part2 = Particals[id2];
if (part != part2)
{
Vector2 colisionaxis = part.position - part2.position;
float dist = colisionaxis.Length();
if (dist < 10)
{
Vector2 n = colisionaxis / dist;
float delta = 10 - dist;
part.position += 0.5f * delta * n;
part2.position -= 0.5f * delta * n;
}
}
}
public List<Partical> GetParticals()
{
return Particals;
}
}
}
`
You ts list depends on solver.Grid[x,y]. I am sure that some of your code that is not visible on the screen makes some changes of solver.Grid, probably deletes some times, or replaces them. This is what causing the error.
I am very new to unity and I made a snake game. However, the apple can sometimes spawn inside the snake. I'm assuming that this needs an if statement like if CreateRandomApple = TailNode then try again but I'm not sure how to code that. Here is my code for the snake and the apple.
void PlacePlayer()
{
playerObj = new GameObject("Player");
SpriteRenderer playerRender = playerObj.AddComponent<SpriteRenderer>();
playerSprite = CreateSprite(playerColor);
playerRender.sprite = (playerSprite);
playerRender.sortingOrder = 1;
playerNode = GetNode(3, 3);
PlacePlayerObject(playerObj, playerNode.worldPosition);
playerObj.transform.localScale = Vector3.one * 1.2f;
tailParent = new GameObject("tailParent");
}
void CreateApple()
{
appleObj = new GameObject("Apple");
SpriteRenderer appleRenderer = appleObj.AddComponent<SpriteRenderer>();
appleRenderer.sprite = CreateSprite(appleColor);
appleRenderer.sortingOrder = 1;
RandomlyPlacedApple();
}
#endregion
#region Update
void MoveTail()
{
Node prevNode = null;
for (int i = 0; i < tail.Count; i++)
{
SpecialNode p = tail[i];
availbleNodes.Add(p.node);
if (i == 0)
{
prevNode = p.node;
p.node = playerNode;
}
else
{
Node prev = p.node;
p.node = prevNode;
prevNode = prev;
}
availbleNodes.Remove(p.node);
PlacePlayerObject(p.obj, p.node.worldPosition);
}
}
#endregion
#region Utilities
bool isTailNode(Node n)
{
for (int i = 0; i < tail.Count; i++)
{
if(tail[i].node == n)
{
return true;
}
}
return false;
}
void PlacePlayerObject(GameObject obj, Vector3 pos)
{
pos += Vector3.one * .5f;
obj.transform.position = pos;
}
void RandomlyPlacedApple()
{
int ran = Random.Range(0, availbleNodes.Count);
Node n = availbleNodes[ran];
PlacePlayerObject(appleObj, n.worldPosition);
appleNode = n;
}
Node GetNode(int x, int y)
{
if (x < 0 || x > MaxWidth - 1 || y < 0 || y > MaxHeight - 1)
return null;
return grid[x, y];
}
SpecialNode CreateTailNode(int x, int y)
{
SpecialNode s = new SpecialNode();
s.node = GetNode(x, y);
s.obj = new GameObject();
s.obj.transform.parent = tailParent.transform;
s.obj.transform.position = s.node.worldPosition;
s.obj.transform.localScale = Vector3.one * .95f;
SpriteRenderer r = s.obj.AddComponent<SpriteRenderer>();
r.sprite = (playerSprite);
r.sortingOrder = 1;
return s;
}
#endregion
}`
This is a simplified version of the script.
Thanks
Since you have an isTailNode function you should be able to continuously generate new apple nodes and check if they are tail nodes. If they are you generate new ones. This can be achieved using a while loop.
void RandomlyPlacedApple()
{
int ran = Random.Range(0, availbleNodes.Count);
while(isTailNode(availbleNodes[ran]))
{
ran = Random.Range(0, availbleNodes.Count);
}
PlacePlayerObject(appleObj, availbleNodes[ran].worldPosition);
appleNode = availbleNodes[ran];
}
Check if it's inside ez
if(apple.location == snake.location){ changeAppleLocation() }
I am learning C #, and I am creating a hypothetical game for me to understand the language. I want several bots to follow the Player who is moving the rectangle, but I can only move the player, but the automatic bots do not move.
I really researched what I could do to move these bots. And I came to the conclusion that I would have to understand Threads, which simply causes the program not to crash.
I leave here the full code of what I am trying.
public partial class Form1 : Form
{
public enum Direction { Up, Down, Left, Right }
private Player player;
private List<Bot> bots;
public Form1()
{
InitializeComponent();
this.Paint += Form1_Paint;
this.KeyPreview = true;
this.KeyDown += Form1_KeyDown;
this.player = new Player(new Size(8, 8));
this.bots = new List<Bot>();
for (int i = 0; i < 30; i++)
{
Bot bot = new Bot(player, new Size(8, 8));
bot.Follow();
this.bots.Add(bot);
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Up:
player.Move(Direction.Up);
break;
case Keys.Down:
player.Move(Direction.Down);
break;
case Keys.Left:
player.Move(Direction.Left);
break;
case Keys.Right:
player.Move(Direction.Right);
break;
}
this.Invalidate();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
List<Rectangle> rs = new List<Rectangle>();
rs = this.bots.Select(x => x.Rectangle).ToList();
rs.Add(player.Rectangle);
if (rs.Count > 0)
{
e.Graphics.FillRectangles(new SolidBrush(Color.Red), rs.ToArray());
}
}
}
public class Player
{
private Rectangle rectangle;
public Rectangle Rectangle { get => rectangle; }
public Player(Size size)
{
this.rectangle = new Rectangle() { Size = size };
}
public void Move(Direction direction)
{
switch (direction)
{
case Direction.Up:
this.rectangle.Y -= 3;
break;
case Direction.Down:
this.rectangle.Y += 3;
break;
case Direction.Left:
this.rectangle.X -= 3;
break;
case Direction.Right:
this.rectangle.X += 3;
break;
default:
break;
}
}
}
public class Bot
{
private Rectangle rectangle;
private Player player;
public Rectangle Rectangle { get => rectangle; }
public Bot(Player player, Size size)
{
this.player = player;
this.rectangle = new Rectangle() { Size = size };
}
public void Follow()
{
Task.Run(() =>
{
while (true)
{
Point p = player.Rectangle.Location;
Point bot = rectangle.Location;
for (int i = bot.X; i < p.X; i += 2)
{
Thread.Sleep(100);
bot.X = i;
}
for (int i = bot.X; i > p.X; i -= 2)
{
Thread.Sleep(100);
bot.X = i;
}
for (int i = bot.Y; i < p.Y; i += 2)
{
Thread.Sleep(100);
bot.Y = i;
}
for (int i = bot.Y; i > p.Y; i -= 2)
{
Thread.Sleep(100);
bot.Y = i;
}
}
});
}
}
As you can see, I can only move the player, but the bots don't move what can I do to move the bots?
I think a Timer would work better here and remove the requirement for you to fully understanding threading at this point, as it will handle the details for you. I'm assuming you actually want the bots to "follow" instead of only moving when the Player moves and will fall behind if the player is moving quickly.
So to use a Timer, I would adjust your Bot class as below, to remove your usage of threads and only allow it to take a single step towards the player in the Follow method which will be called every 100ms. Note Rectangle is a struct, so it is not mutable - that is why your bots do not move - if you do the following:
Point bot = Rectangle.Location;
bot.X = 5;
You're probably thinking Rectangle.Location.X is now 5; but it is not. So we create a new rectangle using the new position.
public class Bot
{
private Player player;
public Rectangle Rectangle { get; set; }
public Bot(Player player, Size size)
{
this.player = player;
this.Rectangle = new Rectangle() { Size = size };
}
public void Follow()
{
Point p = player.Rectangle.Location;
Point bot = Rectangle.Location;
for (int i = bot.X + 2; i < p.X;)
{
bot.X = i;
break;
}
for (int i = bot.X - 2; i > p.X;)
{
bot.X = i;
break;
}
for (int i = bot.Y + 2; i < p.Y;)
{
bot.Y = i;
break;
}
for (int i = bot.Y - 2; i > p.Y;)
{
bot.Y = i;
break;
}
Rectangle = new Rectangle(bot, player.Rectangle.Size);
}
}
And add the following code to replace your existing constructor and add another method to handle the Timer tick.
private Timer timer;
public Form1()
{
InitializeComponent();
this.Paint += Form1_Paint;
this.KeyPreview = true;
this.KeyDown += Form1_KeyDown;
// setup a timer which will call Timer_Tick every 100ms
timer = new System.Windows.Forms.Timer();
timer.Interval = 100;
timer.Tick += Timer_Tick;
timer.Start();
this.player = new Player(new Size(8, 8));
this.bots = new List<Bot>();
for (int i = 0; i < 30; i++)
{
Bot bot = new Bot(player, new Size(8, 8));
bot.Follow();
this.bots.Add(bot);
}
}
private void Timer_Tick(object sender, System.EventArgs e)
{
foreach (var bot in bots)
bot.Follow();
this.Invalidate();
}
Point is a value type (a struct). (Read more about this at What's the difference between struct and class in .NET?)
When you did this:
Point bot = Rectangle.Location;
bot.X = i;
...you created a local Point and modified it. This doesn't change the Location of the Rectangle of the Bot. Also, Rectangles are structs too, so you have to modify the original Bot's Rectangle, or assign a new Rectangle to the Bot.
To fix, you could replace:
bot.X = i;
...with...
this.rectangle.X = i;
And make the similar change for .Y (in all your for loop locations)
Spelling it all out:
public void Follow()
{
Task.Run(() =>
{
while (true) {
Point p = player.Rectangle.Location;
Point bot = rectangle.Location;
for (int i = bot.X; i < p.X; i += 2) {
Thread.Sleep(100);
this.rectangle.X = i;
}
for (int i = bot.X; i > p.X; i -= 2) {
Thread.Sleep(100);
this.rectangle.X = i;
}
for (int i = bot.Y; i < p.Y; i += 2) {
Thread.Sleep(100);
this.rectangle.Y = i;
}
for (int i = bot.Y; i > p.Y; i -= 2) {
Thread.Sleep(100);
this.rectangle.Y = i;
}
}
});
}
How do I close a GUI-menue when clicking outside of it?
What would be the smartest way to do it?
Here a picture of a two-stage GUI example:
And the belonging code, feel free to use it for your own purpose:
using UnityEngine;
using System.Data;
using Mono.Data.SqliteClient;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using UnityEngine.EventSystems;
public class menue2 : MonoBehaviour
{
private Vector2 scrollViewVector = Vector2.zero;
static int menueWidth = 125;
static int menueHeight = 25;
Rect dropDownRect1 = new Rect(0,0,menueWidth,menueHeight);
Rect dropDownRect2 = new Rect (menueWidth, menueHeight, 170, menueHeight);
// Menue Level 1
public static string[] list = {"Navigation","Setup Ordner", "Optionen Ordner", "Setup Dateien", "Optionen Dateien", "blabla"};
// Menue Level 2
public static string[] camSetup = {"Kamera Zoom Min.", "Kamera Zoom Max.", "Kamera Geschw. Normal", "Kamera Geschw. Schnell"};
public static string[] setupOrdner = {"Farbe = ","Höhe = ","setupFolder3","setupFolder4","setupFolder5","setupFolder6"};
public static string[] optionenOrdner = {"setupFolder1","setupFolder2","setupFolder3","setupFolder4","setupFolder5","set upFolder6"};
public static string[] setupDatei = {"oooooo","ppp","üüüüüüüüü","qqqqqq","nnnnnnn","mmmm"};
public static string[] optionenDatei = {"wwwww","eeeee","rrrrr","tttt","zzzzzzz","uuuuuu"};
public static string[] blabla = {"aaaaa","ssssss","gggg","ddddd","jjjjjj","hhhhh"};
public static string[][] listCollection = {camSetup, setupOrdner, optionenOrdner, setupDatei, optionenDatei, blabla};
int indexNumber;
int indexNumber2;
int level = 0;
string lastClicked = null;
public GameObject other;
void OnGUI()
{
if (GUI.Button (new Rect ((dropDownRect1.x), dropDownRect1.y, dropDownRect1.width, dropDownRect1.height), "Setup")) {
if (level == 0) {
level = 1;
lastClicked = "Setup";
} else if (level > 0)
level = 0;
}
if (level >= 1) {
for (int index = 0; index < list.Length; index++) {
if (GUI.Button (new Rect (0, (index * 25 + dropDownRect1.height), dropDownRect1.width, dropDownRect1.height), list [index])) {
indexNumber = index;
level = 2;
lastClicked = (list [index]);
}
}
if (level == 2 || level == 3) {
for (int index = 0; index < camSetup.Length; index++) {
if (GUI.Button (new Rect (menueWidth, ((indexNumber * menueHeight) + (index * menueHeight) + menueHeight), menueWidth, menueHeight), listCollection [indexNumber] [index])) {
indexNumber2 = index;
level = 3;;
lastClicked = (listCollection [indexNumber] [index]);
}
}
}
}
if (Input.GetMouseButtonUp (0)) {
print (lastClicked);
}
}
}
Thanks a lot for any help!
I stayed with scripting my GUI in the end and found a quite simple solution.
void closeMenue()
{
Vector2 mousePosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
if (Input.GetMouseButtonDown (0) && mousePosition.x > Screen.width/2 || Input.GetMouseButtonDown (0) && mousePosition.y < Screen.height/2)
{
level = 0; // closing everything
}
}
So I simply check for the cursor position.. here adjusted to a menue on the top left.
But the allowed area can easily be changed to the personal situation of course.
Problem
I'm using a C# application to record keyboard and mouse movement, processing that movement and sending serial data out to a micro-controller that interpreters that data and moves a set of servos. In the past I had created a box or image that was the resolution(number of steps) my servos were capable of, clipped the mouse to that box or image, and processed where the cursor was in that box and sent data to my servos to move to that position.
This worked fine and dandy till I needed to move a greater amount of steps than my monitor has resolution.
So my question is what options are available to me for tracking mouse movement up to 10,000 steps/resolution in the X and Y axis?
Possible solution route
Thinking outside the box I think I could hide and center the mouse on the screen, record how much the mouse moved on mousemoved events, process that data, then recenter the mouse on the screen to give me unlimited movement in each axis.
Enclosed below is my PIC18F2420 code. Currently it is fed x and y positions via serial communications from my C# application. Data is stored in a ring buffer as it is received and processed as soon as possible.
PIC CODE
#include <p18f2420.h>
#include <cType.h>
#include <usart.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <timers.h>
#include <delays.h>
/**********************************************************************************************/
//DEFINES
#define switch_0 PORTCbits.RC4
#define switch_1 PORTCbits.RC5
#define bufferSize 48
/**********************************************************************************************/
/**********************************************************************************************/
//Function prototypes
void high_isr(void);
void int2ASCII(unsigned int output);
void UART_putChar(unsigned char value);
char readBuffer();
char emptyBuffer();
char peekBuffer();
void limitServo0(); //limit movement via predetermined min/max
void limitServo1();
/**********************************************************************************************/
unsigned char hertz = 75; //value to generate 5-=60 hertz wave default value 75
unsigned int timer0, servo0Min, servo0Max;
unsigned int timer1, servo1Min, servo1Max;
unsigned char servo0Rate = 10;
unsigned char ByteOut;
char array[bufferSize]; //input rs-232 buffer
char valueArray[bufferSize];
char dataArray[bufferSize];
char tempArray[bufferSize];
unsigned char tempIndex;
unsigned char head = 0;
unsigned char tail = 0;
//variables used to disect the comma delimited string
char CVdata; //do we have a command and value?
char CVvalue; //bool value like above
//BOOLEAN IF values
/**********************************************************************************************/
//Interrupt Service Routine
#pragma code high_vector=0x08
void interrupt_at_high_vector (void)
{
_asm GOTO high_isr _endasm
}
#pragma code /* return to the default code section */
#pragma interrupt high_isr
void high_isr (void)
{
if(PIR1bits.TMR2IF == 1)
{
//T0CONbits.TMR0ON = 0;
//T1CONbits.TMR1ON = 0;
INTCONbits.TMR0IF = 0; //Turn off Int Flag
PIR1bits.TMR1IF = 0;
PIR1bits.TMR2IF = 0; //Turn off Int Flag
LATCbits.LATC3 = 1; //Turn on data line
TMR0H = timer0/256; //Extract HIGH byte always do Hbyte first
TMR0L = timer0; //Extract LOW byte
}
if(PIR1bits.TMR1IF == 1)
{
PIR1bits.TMR1IF = 0;
//T1CONbits.TMR1ON = 0;
//PIR1bits.TMR2IF = 0; //Turn off Int Flag
INTCONbits.TMR0IF = 0; //Turn off Int Flag
LATCbits.LATC2 = 0;
PR2 = hertz; //Generate 50-60hertz pulse
}
if(INTCONbits.TMR0IF == 1)
{
LATCbits.LATC2 = 1;
//PIR1bits.TMR1IF = 0;
//PIR1bits.TMR2IF = 0; //Turn off Int Flag
//T0CONbits.TMR0ON = 0;
//T1CONbits.TMR1ON = 1;
INTCONbits.TMR0IF = 0; //Turn off Int Flag
LATCbits.LATC3 = 0;
TMR1H = timer1/256;
TMR1L = timer1;
}
if(PIR1bits.RCIF == 1)
{
PIR1bits.RCIF = 0;
array[tail] = RCREG;
//array[tail] = ReadUSART();
tail++;
if(tail == bufferSize)
{
tail = 0;
}
/* Clear the interrupt flag */
}
}
/**********************************************************************************************/
void main(void)
{
/**********************************************************************************************/
//Initialize
memset(array, '\0' , bufferSize);
memset(tempArray, '\0' , bufferSize);
memset(dataArray, '\0' , bufferSize);
memset(valueArray, '\0' , bufferSize);
TRISC = 0b10110000;//RC4 and RC5 inputs for switches
servo0Max = 65000; //Max value allowed PAN 65000
servo0Min = 62000; //Min value allowed 63500
servo1Max = 65000; //Tilt 64138
servo1Min = 62000; //TILT 63864
timer0 = 64250; //Initial position
timer1 = 64200;
CVdata = 0;
CVvalue = 0;
tempIndex = 0;
LATCbits.LATC0 = 0;
/**********************************************************************************************/
//USART
OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_CONT_RX &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_BRGH_HIGH
, 16);//change back to 16 for 57.6 103 for 9.6
RCSTAbits.ADDEN = 0;//Testing this out might not help with overflow
TXSTAbits.SYNC = 0;
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
TXSTAbits.BRGH = 1;
BAUDCONbits.BRG16 = 1;
/**********************************************************************************************/
//Initialize Timer0
OpenTimer0(TIMER_INT_ON &
T0_SOURCE_INT &
T0_16BIT);
T0CONbits.PSA = 1;
INTCONbits.TMR0IF = 0;
/**********************************************************************************************/
/**********************************************************************************************/
//Initialize Timer1
OpenTimer1(TIMER_INT_ON &
T1_16BIT_RW &
T1_SOURCE_INT &
T1_PS_1_1);
T1CONbits.T1CKPS1 = 0; // bits 5-4 Prescaler Rate Select bits
T1CONbits.T1CKPS0 = 0; // bit 4
T1CONbits.T1OSCEN = 1; // bit 3 Timer1 Oscillator Enable Control bit 1 = on
T1CONbits.T1SYNC = 1; // bit 2 Timer1 External Clock Input Synchronization Control bit...1 = Do not synchronize external clock input
T1CONbits.TMR1CS = 0; // bit 1 Timer1 Clock Source Select bit...0 = Internal clock (FOSC/4)
T1CONbits.TMR1ON = 1; // bit 0 enables timer
/**********************************************************************************************/
/**********************************************************************************************/
//Initialize Timer2
OpenTimer2( TIMER_INT_ON &
T2_PS_1_16 &
T2_POST_1_16);
PR2 = hertz;
PIE1bits.TMR2IE = 1;
IPR1bits.TMR2IP = 1;
INTCONbits.GIEH = 1; //enable global interrupts
INTCONbits.GIEL = 1;
/**********************************************************************************************/
while(1)
{
while(emptyBuffer());
if(CVdata == 0 && CVvalue == 1)
{
//ERROR THIS SHOULDN't HAPPEN! FLUSH BUFFER
CVdata = 0;
CVvalue = 0;
}
if(CVdata == 0 && CVvalue == 0)
{
if(peekBuffer() != ',')
{
tempArray[tempIndex] = readBuffer();
tempIndex++;
}
else
{
readBuffer();//if comma sent first read it and throw away
if(tempIndex > 0) //comma read and data in buffer
{
memcpy(dataArray, tempArray, tempIndex);
tempIndex = 0;
CVdata = 1;
memset(tempArray, 'a' , bufferSize);
}
}
}
if(CVdata ==1 && CVvalue == 0)
{
if(peekBuffer() != ',')
{
if(isdigit(peekBuffer()))
{
tempArray[tempIndex] = readBuffer();
tempIndex++;
}
else
readBuffer();
}
else
{
//readBuffer();
if(tempIndex > 0)
{
memcpy(valueArray, tempArray, tempIndex);
tempIndex = 0;
CVvalue = 1;
memset(tempArray, 'a', bufferSize);
}
}
}
if(CVdata == 1 && CVvalue == 1)
{
switch(dataArray[0])
{
case 'x':
case 'X':
{
//timer0 = current = atof(valueArray);//ISSUE HERE first char null
timer0 = (unsigned int)atoi(valueArray);
break;
}
case 'y':
case 'Y':
{
timer1 = (unsigned int)atoi(valueArray);
break;
}
}
CVdata = 0;
CVvalue = 0;
memset(dataArray, 'a' , bufferSize);
memset(valueArray, 'a' , bufferSize);
}
limitServo0();
limitServo1();
}
}
/**********************************************************************************************/
//Functions
void int2ASCII(unsigned int output)
{
unsigned char digit = 0;
while (output >= 10000) { output -= 10000; digit++; } UART_putChar(digit + 0x30); digit = 0;
while (output >= 1000) { output -= 1000; digit++; } UART_putChar(digit + 0x30); digit = 0;
while (output >= 100) { output -= 100; digit++; } UART_putChar(digit + 0x30); digit = 0;
while (output >= 10) { output -= 10; digit++; } UART_putChar(digit + 0x30); digit = 0;
while (output >= 1) { output -= 1; digit++; } UART_putChar(digit + 0x30);
}
void UART_putChar(unsigned char value)
{
while(PIR1bits.TXIF == 0);
TXREG = value;
}
char readBuffer()
{
if(tail != head)
{
ByteOut = array[head];
head++;
if(head == bufferSize)
{
head = 0;
}
return ByteOut;
}
//LATCbits.LATC0 = 1;
}
char peekBuffer()
{
return array[head];
}
char emptyBuffer()
{
if(tail == head)
return 1;
else
return 0;
}
void limitServo0()
{
if(timer0 > servo0Max)
{
timer0 = servo0Max;
}
if(timer0 < servo0Min)
{
timer0 = servo0Min;
}
}
void limitServo1()
{
if(timer1 > servo1Max)
{
timer1 = servo1Max;
}
if(timer1 < servo1Min)
{
timer1 = servo1Min;
}
}
An Example of my previous tracking via bitmap can be viewed on my youtube channel at: http://www.youtube.com/watch?v=rBhkV3dnyiU&list=UULGlw5rGZfETaiPs49JBEuA&index=41
UPDATE
After some research it seems I can write a XNA application, capture mouse movement, and output serial communications. I would really really like a windows forms solution but I do have XNA experience so guess I'll work on converting my application until another solution presents itself.
My initial purposed solution did the trick. On trackingEnabled I center the mouse and check how much it has moved every 100ms, after that I recenter it and send the data to my controller.
using System;
using System.Timers;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PIC18F_Servo_Control_V2;
namespace FSI_Grid1
{
public partial class Form1 : Form
{
TabControl LeftControlTab;
System.Timers.Timer myTimer;
public delegate void UpdateStatusBarDelegate();
TabPage myTabPage;
Grid myGrid;
serialConnection myConnection;
int timerDelay = 100;
int initialX, initialY, currentX, currentY, minX, minY, maxX, maxY;
int MouseCurrentX, MouseCurrentY, MouseMovedX, MouseMovedY;//tracking mousemovement
int offsetX, offsetY;//how much each arrow click moves the servos
bool trackingActive;//are we in tracking mode?
bool MouseMovedFlag;
int YOffsetValue;//used to offset dynamically generated buttons in tab groups
int XCenter, YCenter;
enum States { Startup, MouseTracking, KeyboardTracking, Script, Idle };//state engine
States CurrentState;
public Form1()
{
currentX = initialX = 63503;
currentY = initialY = 64012;
minX = 62000;
maxX = 65000;
minY = 62000;
maxY = 65000;
offsetX = 10;
offsetY = 10;
trackingActive = false;
YOffsetValue = 0;
CurrentState = States.Startup;
MouseMovedFlag = false;
myTimer = new System.Timers.Timer(timerDelay);
myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
myTimer.Elapsed += new ElapsedEventHandler(TrackMouse);
myTimer.Enabled = false;
InitializeComponent();
InitializeGrid();
InitializeLeftControlTab();
InitializeSerial();
//Initialize StatusBar
RadioButton button = (RadioButton)this.Controls.Find("SelectKeyboardRadioButton", true)[0];
button.Checked = true;
activeStatus.Text = "Keyboard Tracking DEACTIVATED";
activeStatus.BackColor = Color.Red;
ConnectionStatus.Text = "Disconnected!";
xOffsetStatus.Text = "X offset value " + offsetX.ToString();
yOffsetStatus.Text = "Y offset value " + offsetY.ToString();
//this.MouseMove += new MouseEventHandler(Form_MouseMove);
XCenter = this.Location.X + this.Width / 2;
YCenter = this.Location.Y + this.Height / 2;
}
~Form1()
{
if (myConnection.connected)
myConnection.disconnect();
}
private void widthTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
}
private void widthTextBox_KeyUp(object sender, KeyEventArgs e)
{
TextBox text = (TextBox)this.Controls.Find("widthTextBox", true)[0];
xOffsetStatus.Text = text.Text;
offsetX = Convert.ToInt16(text.Text);
}
private void heightTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
}
private void heightTextBox_KeyUp(object sender, KeyEventArgs e)
{
TextBox text = (TextBox)this.Controls.Find("heightTextBox", true)[0];
yOffsetStatus.Text = text.Text;
offsetY = Convert.ToInt16(text.Text);
}
private void LeftControlTab_DrawItem(object sender, DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Brush _textBrush;
// Get the item from the collection.
TabPage _tabPage = LeftControlTab.TabPages[e.Index];
// Get the real bounds for the tab rectangle.
Rectangle _tabBounds = LeftControlTab.GetTabRect(e.Index);
if (e.State == DrawItemState.Selected)
{
// Draw a different background color, and don't paint a focus rectangle.
_textBrush = new SolidBrush(Color.Red);
g.FillRectangle(Brushes.White, e.Bounds);
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
g.FillRectangle(Brushes.LightGray, e.Bounds);
//e.DrawBackground();
}
// Use our own font.
Font _tabFont = new Font("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel);
// Draw string. Center the text.
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Center;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
}
private void InitializeLeftControlTab()
{
LeftControlTab = new TabControl();
LeftControlTab.Location = new Point(10, 30);
LeftControlTab.Size = new Size(300, 500);
LeftControlTab.Alignment = TabAlignment.Left;
LeftControlTab.SizeMode = TabSizeMode.Fixed;
LeftControlTab.ItemSize = new Size(30, 90);
LeftControlTab.DrawMode = TabDrawMode.OwnerDrawFixed;
/*EVENT HANDLER*/
LeftControlTab.DrawItem += new DrawItemEventHandler(LeftControlTab_DrawItem);
/*TABS*/
int offset = 100; //how far to the right the edit boxes are
myTabPage = new TabPage();
myTabPage.Text = "Appearance";
LeftControlTab.Controls.Add(myTabPage);
myTabPage = new TabPage();
myTabPage.Text = "Settings";
/*LABEL*/
Label OffsetLabel = new Label();
OffsetLabel.Text = "Step resolution";
OffsetLabel.Location = new Point(0,YOffset());
myTabPage.Controls.Add(OffsetLabel);
/*WIDTH LABEL*/
Label widthLabel = new Label();
widthLabel.Text = "Width";
widthLabel.Location = new Point(0, YOffset());
myTabPage.Controls.Add(widthLabel);
/*WIDTH TEXTBOX*/
TextBox widthTextBox = new TextBox();
widthTextBox.Name = "widthTextBox";
widthTextBox.Text = myGrid.Width.ToString();
widthTextBox.Location = new Point(widthLabel.Location.X + offset, widthLabel.Location.Y);
myTabPage.Controls.Add(widthTextBox);
widthTextBox.KeyPress += new KeyPressEventHandler(widthTextBox_KeyPress); //EVENT HANDLER
widthTextBox.KeyUp += new KeyEventHandler(widthTextBox_KeyUp); //EVENT HANDLER
/*HEIGHT LABEL*/
Label heightLabel = new Label();
heightLabel.Text = "Height";
heightLabel.Location = new Point(0, YOffset());
myTabPage.Controls.Add(heightLabel);
/*HEIGHT TEXTBOX*/
TextBox heightTextBox = new TextBox();
heightTextBox.Name = "heightTextBox";
heightTextBox.Text = myGrid.Height.ToString();
heightTextBox.Location = new Point(heightLabel.Location.X + offset, heightLabel.Location.Y);
myTabPage.Controls.Add(heightTextBox);
/*RADIOBUTTON LABEL*/
GroupBox RadioLabel = new GroupBox();
RadioLabel.Text = "Tracking Style";
RadioLabel.Location = new Point(0, YOffset());
myTabPage.Controls.Add(RadioLabel);
/*RADIO BUTTONS*/
RadioButton SelectMouse = new RadioButton();
SelectMouse.Location = new Point(10, 20);
SelectMouse.Text = "Mouse";
SelectMouse.Name = "SelectMouseRadioButton";
SelectMouse.CheckedChanged += new EventHandler(RadioButtons_CheckedChanged);
RadioLabel.Controls.Add(SelectMouse);
RadioButton SelectKeyboard = new RadioButton();
SelectKeyboard.Location = new Point(10, 42);
SelectKeyboard.Text = "Keyboard";
SelectKeyboard.Name = "SelectKeyboardRadioButton";
SelectKeyboard.CheckedChanged += new EventHandler(RadioButtons_CheckedChanged);
RadioLabel.Controls.Add(SelectKeyboard);
heightTextBox.KeyPress += new KeyPressEventHandler(heightTextBox_KeyPress); //EVENT HANDLER
heightTextBox.KeyUp += new KeyEventHandler(heightTextBox_KeyUp); //EVENT HANDLER
//EVENT HANDLER
LeftControlTab.Controls.Add(myTabPage);
Controls.Add(LeftControlTab);
}
private void InitializeGrid()
{
myGrid = new Grid(offsetX, offsetY);
}
private void connectToolStripMenuItem_Click(object sender, EventArgs e)
{
serialConnectionDialogBox serialBox = new serialConnectionDialogBox();
Point temp = this.Location;
temp.X += 30;
temp.Y += 70;
serialBox.Location = temp;
DialogResult results = serialBox.ShowDialog();
if (results == DialogResult.Yes && !myConnection.connected)
{
myConnection.setCOMMPort(serialBox.commPortComboBox.Text);
myConnection.setBaudRate(Convert.ToInt32(serialBox.baudRateComboBox.Text));
myConnection.connect();
}
if (myConnection.connected)
{
ConnectionStatus.Text = "X " + currentX.ToString() + "Y " + currentY.ToString();
}
}
private void InitializeSerial()
{
myConnection = new serialConnection();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
bool updatePos = false;
switch (keyData)
{
case Keys.Left:
currentX += offsetX;
updatePos = true;
break;
case Keys.Right:
currentX -= offsetX;
updatePos = true;
break;
case Keys.Up:
currentY += offsetY;
updatePos = true;
break;
case Keys.Down:
currentY -= offsetY;
updatePos = true;
break;
case Keys.F5:
if (trackingActive)
{
trackingActive = false;
LeftControlTab.Enabled = true;
if(CurrentState == States.KeyboardTracking)
activeStatus.Text = "Keyboard Tracking DEACTIVATED";
if (CurrentState == States.MouseTracking)
activeStatus.Text = "Mouse Tracking DEACTIVATED";
activeStatus.BackColor = Color.Red;
myTimer.Enabled = false;
}
else
{
trackingActive = true;
LeftControlTab.Enabled = false;
if (CurrentState == States.KeyboardTracking)
activeStatus.Text = "Keyboard Tracking ACTIVATED";
if (CurrentState == States.MouseTracking)
activeStatus.Text = "Mouse Tracking ACTIVATED";
activeStatus.BackColor = Color.Green;
myTimer.Enabled = true;
}
break;
}
if (updatePos == true)
{
updatePos = false;
Point temp = new Point();
temp.X = currentX = clipX(currentX);
temp.Y = currentY = clipY(currentY);
String tx = "x," + Convert.ToString(temp.X) + ",y," + Convert.ToString(temp.Y) + ",";
myConnection.sendData(tx);
ConnectionStatus.Text = "X " + currentX.ToString() + "Y " + currentY.ToString();
}
return base.ProcessCmdKey(ref msg, keyData);
}
private void disconnectToolStripMenuItem_Click_1(object sender, EventArgs e)
{
if (myConnection.connected)
{
myConnection.disconnect();
ConnectionStatus.Text = "Disconnected!";
}
}
private void RadioButtons_CheckedChanged(object sender, EventArgs e)
{
if (sender == (RadioButton)this.Controls.Find("SelectMouseRadioButton", true)[0])
{
CurrentState = States.MouseTracking;
activeStatus.Text = "Mouse Tracking ";
}
if (sender == (RadioButton)this.Controls.Find("SelectKeyboardRadioButton", true)[0])
{
CurrentState = States.KeyboardTracking;
activeStatus.Text = "Keyboard Tracking ";
}
if (trackingActive)
activeStatus.Text += "ACTIVATED";
else
activeStatus.Text += "DEACTIVATED";
}
private void TrackMouse(object source, ElapsedEventArgs e)
{
if (trackingActive && CurrentState == States.MouseTracking)
{
MouseMovedFlag = true;
MouseMovedX = -1 * (Cursor.Position.X - XCenter);
MouseMovedY = -1 * (Cursor.Position.Y - YCenter);
currentX += MouseMovedX;
currentX = clipX(currentX);
currentY += MouseMovedY;
currentY = clipY(currentY);
statusStrip1.Invoke(new UpdateStatusBarDelegate(this.UpdateStatusBar), null);
Cursor.Position = new Point(XCenter, YCenter);
}
}
private int clipX(int tempX)
{
if(tempX < minX)
tempX = minX;
if(tempX > maxX)
tempX = maxX;
return tempX;
}
private int clipY(int tempY)
{
if(tempY < minY)
tempY = minY;
if (tempY > maxY)
tempY = maxY;
return tempY;
}
private int YOffset()
{
int tempValue = YOffsetValue;
if (tempValue == 0)
{
YOffsetValue += 22;
return tempValue;
}
else
{
YOffsetValue += 22;
return tempValue;
}
}
void OnTimedEvent(object source, ElapsedEventArgs e)
{
if (true)
{
if (MouseMovedFlag || trackingActive)
{
Point temp = new Point();
temp.X = currentX;
temp.Y = currentY;
String tx = "x," + Convert.ToString(temp.X) + ",y," + Convert.ToString(temp.Y) + ",";
myConnection.sendData(tx);
}
}
}
void UpdateStatusBar()
{
ConnectionStatus.Text = "X " + currentX.ToString() + "Y " + currentY.ToString();
ConnectionStatus.Invalidate();
this.Update();
}
}
}