Flutter, paint free hand point header position got misplaced - flutter

I am developing a flutter application. In that am using Paint to draw lines. In free hand line the point header is correctly displaying when we draw a straight line. But when we rotate the line, the point header position got misplaced.
case PaintMode.freeStyleArrow:
for (var i = 0; i < _offset!.length - 1; i++) {
if (_offset[i] != null && _offset[i + 1] != null) {
final _path = Path()
..moveTo(_offset[i]!.dx, _offset[i]!.dy)
..lineTo(_offset[i + 1]!.dx, _offset[i + 1]!.dy);
canvas.drawPath(_path, _painter!..strokeCap = StrokeCap.round);
paintsFreestyleArrow(canvas,_offset[0]!, _offset[_offset.length - 2]!, _painter, size);
}
else if (_offset[i] != null && _offset[i + 1] == null) {
canvas.drawPoints(PointMode.points, [_offset[i]!],
_painter!);
}}
break;

Related

Unity Path Generation On 2D Grid

roadTopStartX = Random.Range(5, 10); // Path's x position which creation begins
roadTopStartY = Random.Range(8, 12); // Path's y position which creation begins
roadTopLength = Random.Range(4, 9); // Path's length
for (int i = 0; i < roadTopLength; i++)
{
GameObject tile = GameObject.Find("Tile" + (roadTopStartX + i) + " " + roadTopStartY); //I created grid whose tile's name Tile X Y like Tile 0 0
GameObject road = Instantiate(roadPrefab, tile.transform.position, tile.transform.rotation);
road.name = "Road"+ " " + (roadTopStartX + i) + " " + roadTopStartY;
roads.Add(road);
}
It is how i create random path on 2d grid, do you know better solution because when thinks become more complex gameobject.find becomes suffer for me
i found a more reliable solution: (thanks to derHugo)
public GameObject findTile(int x,int y)
{
GameObject findTilex = GameObject.Find("Tile" + (tileX + x) + " " +
(tileY + y));
return findTilex;
}
Example how i get neighbour tiles
public void getNeighbours()
{
if (findTile(0, 1) != null)
{
upper = findTile(0, 1);
}
if (findTile(0, -1) != null)
{
below = findTile(0, -1);
}
if (findTile(1, 0) != null)
{
right = findTile(1, 0);
}
if (findTile(-1, 0) != null)
{
left = findTile(-1, 0);
}
if (findTile(1, 1) != null)
{
rightCrossTop = findTile(1, 1);
}
if (findTile(1, -1) != null)
{
rightCrossUnder = findTile(1, -1);
}
if (findTile(-1, 1) != null)
{
leftCrossTop = findTile(-1, 1);
}
if (findTile(-1, -1) != null)
{
leftCrossBottom = findTile(-1, -1);
}
}

flutter painting on canvas and erase drawing

i am working on a canvas drawing module in to it i need to erase user drawing
basic funda is
adding image in canvas
user can draw on image using pencil (i.e black color) now user can erase this black color on erase function (i.e clear user drawing )
my try is :
case PaintMode.eraser:
print('eraser**** _image Painter!!!*'); // print(_painter.color)
// canvas.saveLayer(Offset.zero & size, Paint());1
var _painterTemp = _painter!
// ..color = Colors.transparent.withOpacity(0.8)//also tried it
..strokeCap = StrokeCap.round
..blendMode = BlendMode.clear;
for (var i = 0; i < _offset!.length - 1; i++) {
if (_offset[i] != null && _offset[i + 1] != null) {
final _path = Path()
..moveTo(_offset[i]!.dx, _offset[i]!.dy)
..lineTo(_offset[i + 1]!.dx, _offset[i + 1]!.dy);
} else if (_offset[i] != null && _offset[i + 1] == null) {
canvas.drawPoints(PointMode.points, [_offset[i]!], _painterTemp);
}
}
// canvas.restore();//1
break
but i am getting black lines only
took reference from
https://github.com/yellowQ-software/yellowQ-Flutter-Image-Painter
edit-----
i've edited like
case PaintMode.eraser:
print('eraser**** _image Painter!!!*');
var _painterTemp = _painter!
..color = Colors.transparent
..blendMode = BlendMode.clear; //srcOver
for (var i = 0; i < _offset!.length - 1; i++) {
if (_offset[i] != null && _offset[i + 1] != null) {
final _path = Path()
..moveTo(_offset[i]!.dx, _offset[i]!.dy)
..lineTo(_offset[i + 1]!.dx, _offset[i + 1]!.dy);
canvas.drawPath(_path, _painter);
canvas.drawPath(_path, _painterTemp);
canvas.saveLayer(Offset.zero & size, Paint());
} else if (_offset[i] != null && _offset[i + 1] == null) {
canvas.drawPoints(PointMode.points, [_offset[i]!], _painter);
canvas.drawPoints(PointMode.points, [_offset[i]!], _painterTemp);
}
// canvas.saveLayer(Offset.zero & size, Paint()); //1
}
// canvas.restore();//1
break;
but not working but getting custom painter called canvas.save() or canvas.saveLayer() at least 773 more times than it called canvas.restore().
any help?

Detect if all objects between two points are of same tag in Unity

I am making a game where the floor consists of individual live and dead pixels. If a line of live pixels are drawn between the two points, you pass. If the line is broken, you cannot pass.
I would like to detect wether all objects between two points are of the same Tag. Here is a drawing to try and illustrate this:
At the moment, I have the following code that checks if the next "pixel" is live or dead using RayCasts:
function Update () {
var pixfwd = transform.TransformDirection (Vector3.up * Reach);
var pixbwd = transform.TransformDirection (Vector3.down * Reach);
var pixleft = transform.TransformDirection (Vector3.left * Reach);
var pixright = transform.TransformDirection (Vector3.right * Reach);
Debug.DrawRay(transform.position, pixfwd * Reach, Color.red, 0.1f);
Debug.DrawRay(transform.position, pixbwd * Reach, Color.green, 0.1f);
Debug.DrawRay(transform.position, pixleft * Reach, Color.yellow, 0.1f);
Debug.DrawRay(transform.position, pixright * Reach, Color.blue, 0.1f);
Physics.Raycast (transform.position, pixfwd, pixhit);
Physics.Raycast (transform.position, pixbwd, pixhit2);
Physics.Raycast (transform.position, pixleft, pixhit3);
Physics.Raycast (transform.position, pixright, pixhit4);
if ( checkVision(pixhit) || checkVision(pixhit2) || checkVision(pixhit3) || checkVision(pixhit4) ) {
nextisLive = true;
}
else
{
nextisLive=false;
}
}
function checkVision(pixhit:RaycastHit):boolean
{
if ( pixhit != null && pixhit.collider != null && pixhit.collider.tag == "Live" )
{
return true;
}
return false;
if ( pixhit2 != null && pixhit2.collider != null && pixhit2.collider.tag == "Live" )
{
return true;
}
return false;
if ( pixhit3 != null && pixhit3.collider != null && pixhit3.collider.tag == "Live" )
{
return true;
}
return false;
if ( pixhit4 != null && pixhit4.collider != null && pixhit4.collider.tag == "Live" )
{
return true;
}
return false;
}
An approach to this problem which doesn't rely on Unity's physics system is to store your "pixel" objects in a 2D array, and iterate through the array to evaluate whether or not the live pixels form a continuous path from one side to the other.
Note: This assumes that when you create/initialize your game, you store your pixel objects in the array correctly, reflective of their in-game arrangement. (ie. Representative of the rows and columns of the grid they form.)
Here's an idea of how your path validation algorithm might look:
var pixels : GameObject[,];
function Start()
{
// Populate pixels array in here, or when you create the grid if the pixels are
// created dynamically.
//
// Array should be initialized to new GameObject[GRID_WIDTH, GRID_HEIGHT];
//
// For this approach, it can be helpful if you group your pixel GameObjects under
// empty GameObjects that match the structure of the array, as this will make it
// easier to populate.
// (Only really applies if you the pixels are not created dynamically.)
}
// Accepts two parameters, which provide the top and bottom of the generator at each
// point.
//
// (For example, a generator spanning between pixels 0 and 2 in width would be
// represented by new int[]{0, 2})
function CheckForClearPath(startPoint : int[], endPoint : int[])
{
// For tracking live pixels in last and current column
var prevColumn : boolean[] = new boolean[pixels[0].length];
var currColumn : boolean[] = new boolean[pixels[0].length];
InitializeArray(prevColumn);
// Iterating through each column of grid
var x : int = 0;
for (x = 0; x < pixels.length; x++)
{
// Special cases for first and last column
var isFirstColumn : boolean = (x == 0);
var isLastColumn : boolean = (x == pixels.length - 1);
// Iterating through each row of grid column, first to identify live pixels
// adjacent to previous column's live pixels
var y : int = 0;
for (y = 0; y < pixels[x].length; y++)
{
if (prevColumn[x]) {
currColumn[y] = (pixels[x][y].tag == "Live");
}
else {
currColumn[y] = false;
}
}
// Next, iterating through each row of grid column, to identify live pixels
// adjacent to current column's live pixels
//
// This is done by checking whether current pixel is live, then checking whether
// next pixel has live tag
for (y = 0; y < pixels[x].length - 1; y++)
{
if (currColumn[y]){
currColumn[y + 1] = (pixels[x][y].tag == "Live");
}
}
// Check if any pixels are recorded as alive in column - if not, it means that no
// live pixels were adjacent to last columns live pixels, and path is broken.
if (AreAllPixelsDead(currColumn)) {
return false;
}
// If first column, check if pixels next to start point are live.
if (isFirstColumn) {
if (!DoesPathMeetPoint(startPoint, currColumn)) {
return false;
}
}
// If last column, check if pixels next to end point are live.
if (isLastColumn) {
if (!DoesPathMeetPoint(endPoint, currColumn)) {
return false;
}
}
// Saving current column results in last column results
for (x = 0; x < pixels.length; x++)
{
prevColumn[x] = currColumn[x];
}
}
// If all goes well, path is valid
return true;
}
function InitializeArray(arrayRef : boolean[]) {
for (var i : int = 0; i < arrayRef.length; i++)
{
arrayRef[i] = true;
}
}
function AreAllPixelsDead(arrayRef : boolean[]) {
for (var i : int = 0; i < arrayRef.length; i++)
{
if (arrayRef[i]) {
return false;
}
}
return true;
}
function DoesPathMeetPoint(point : int[], columnPixels : boolean[]) {
for (var i : int = 0; i < columnPixels.length; i++)
{
if (columnPixels[i] && i >= point[0] && i <= point[1]) {
return true;
}
}
return false;
}
Basically, the algorithm goes through each column of the grid, and determines whether there are live pixels adjacent to the previous column's live pixels, and live pixels adjacent to those. Successfully passing this test means that the live pixels in the grid form at least one continuous path from one end to the other. (Then there are the couple special checks to make sure the path connects to the start and end points.)
Hope this helps! Let me know if you have any questions.
Disclaimer: Code not tested, but the logic of the algorithm is there.

How do i stop player from continuesly falling when i collide with top block?

I am using Windows Form Application and making a simple 2d platformer, with a picturebox that is the player and an array list of pictureboxes that are the blocks.
When i collide with Blocks[i].Top the "player" keeps falling into the top blocks. I think it is becuase
{player.Top += 3;}
is always happening.
How do i tell the player to stop falling when i collide with the top blocks?
private void timer1_Tick(object sender, EventArgs e)
{
for (int i = 0; i < blocks.Count; i++)
{
Rectangle playerRect = player.ClientRectangle;
playerRect.X = player.Location.X;
playerRect.Y = player.Location.Y;
Rectangle blockRect = blocks[i].ClientRectangle;
blockRect.X = blocks[i].Location.X;
blockRect.Y = blocks[i].Location.Y;
Rectangle Intersection = Rectangle.Intersect(playerRect, blockRect);
if (jump == true)
{
//hur snabbt spelaren faller
player.Top -= force;
force -= 1;
}
if (player.Top + player.Height >= screen.Height)
{
player.Top = screen.Height - player.Height;
if (jump == true)
{
player.Image = Image.FromFile("gubbe_still.png");
}
jump = false;
}
else
{
player.Top += 3;
}
//sid kollision
if (player.Right > blocks[i].Left &&
player.Left < blocks[i].Right - player.Width / 2 &&
player.Bottom > blocks[i].Top)
{
right = false;
}
//sid kollision
if (player.Left < blocks[i].Right &&
player.Right > blocks[i].Left + player.Width / 2 &&
player.Bottom > blocks[i].Top)
{
left = false;
}
// top kollision
if (player.Right - 5 > blocks[i].Left &&
player.Right + 5 < blocks[i].Left + blocks[i].Width + player.Width &&
player.Top + player.Height >= blocks[i].Top &&
player.Top < blocks[i].Top)
{
jump = false;
force = 0;
player.Top = blocks[i].Location.Y - player.Height;
}
}
You have some collision detection issues
// top kollision
if (player.Right - 5 > blocks[i].Left &&
player.Right + 5 < blocks[i].Left + blocks[i].Width + player.Width &&
player.Top + player.Height >= blocks[i].Top &&
player.Top < blocks[i].Top)
The first check (player.Right - 5 > blocks[i].Left) will fail if the player is standing off the left side of the block at all. You want something like:
// top kollision
if ((player.Left > blocks[i].Left &&
player.Left < blocks[i].Right) ||
(player.Right < blocks[i].Left &&
player.Right > blocks[i].Left) &&
player.Top + player.Height >= blocks[i].Top &&
player.Top < blocks[i].Top)

C# Quickly checking if two pictureboxes touch each other?

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