How to prevent "mouse object" from moving throgh rectangles? - xna

What am I trying to achieve?
I have a Sprite which is supposed to move with the mouse position (kinda like a cursor). In my case though I also have some other Textures (Obstacle-class). So if the mouse collides with such an obstacle I want the texture to stop moving in that direction.
What is the problem?
While the texture does follow the mouse and also does stop when the mouse "collides" with an obstacle, at some point the cursor is not within the Bounding Rectangle anymore, but on the other side of a wall for example. The consequence, the texture's position is updated to the mouse position and it suddenly appears behind the wall which is not a desired behavior.
My collision method.
private void CheckCollision(List<Obstacle> _obstacleList, MouseState mState)
{
int xOffset = oldMouseState.X - mState.X;
int yOffset = oldMouseState.Y - mState.Y;
Vector2 offsetPosition = new Vector2(oldMouseState.X + xOffset,oldMouseState.Y + yOffset);
bool collides = false;
foreach (Obstacle obstacle in _obstacleList)
{
if (obstacle.BoundRectangle.Contains(offsetPosition))
{
collides = true;
}
}
if (!collides)
{
position = offsetPosition;
}
}
Question
What be a way to prevent the sprite to move through walls in my case?
Thanks in advance.

As you know, you can read the the mouse position by calling Mouse.GetState(). But you can also set the mouse position to whatever you want through Mouse.SetPosition(X,Y) and the mouse will go there.
So, if you are up against, say, an X barrier (vertical barrier), simply call
Mouse.SetPosition(oldMouseState.X, mState.Y);
and your mouse will not change its X value even if pushing your mouse in that direction, it will not go through the wall at all but it is allowed to go up and down just fine.
If you back off from the wall, simply don't call this line and it will operate like befor.

You could store the last (valid) known position of the mouse and the current position of the mouse (valid means the mouse isn't in a rectangle where it shouldn't be). When you hit a rectangle that the mouse shouldn't pass through with your current mouse position, you iterate back to the last valid position in a while loop and check if the mouse is still in the blocking sprite every time you moved the mouse closer to the valid position. If the mouse is outside the forbidden zone, you just exit the while loop and the mouse is quite close to the border of the obstacle.

Related

What does mouse position argument signify in mouse.move command?

In this particular code if for mouse.move command I am giving argument 1100/500 it is moving toward right and if I am giving argument as 100/500 it is moving towards left doesn't matter where the target position is. Even for 500/500, it is moving toward the right, what does it mean?
keyboard ⋘WIN+D⋙
mouse.click 336⫽49 relative false type down
mouse.move 1100⫽500 wait 1000 relative false
mouse.click 1819⫽870 relative false type up
In this example mouse.move won't make a big difference to the whole automation because you have ordered a robot to press the left mouse button at the 336⫽49 position and then move somewhere randomly (to the 1100⫽500 position) and finally move to the 1819⫽870 position and unpress the left mouse button.

Making object locked to a circle "follow" mouse

I'm making a circle pong game (where there's only one paddle and you move in a circle with the ball spawning in the middle of the circle)
Currently, I've almost everything down but I feel like using the keyboard to move the paddle is too slow and I cannot find any "middle" value where it's not too fast or slow
I saw some other examples of this game using the mouse to control the paddle but I have no idea how to do such a thing.
This is my update function for the paddle (sorry if the way I handle updating is ugly):
pad:update(
function(dt,self)
local mouseX,mouseY=love.mouse.getPosition()
self.rot=math.atan2((400 - self.x), -(300 - self.y))
--self.rot=math.atan2((mouseX - self.x), -(mouseY - self.y))
self.x = circleRadius*math.cos(self.r) + self.orgX;
self.y = circleRadius*math.sin(self.r) + self.orgY;
if love.keyboard.isDown("a") then
self.r=self.r+4*dt
end
if love.keyboard.isDown("d") then
self.r=self.r-4*dt
end
end,
dt
)
The above code is inside love.update and sends a function as an argument to pads update function, which then calls that function, giving it the correct arguments like self and dt.
r is basically the position of the paddle on the circle
Got it by setting the current position on the circle (r) to the angle between mouse and the centre of the circle (which in my case is the centre of the window which is 800x600)
self.r=math.atan2((400-mouseX), -(300-mouseY))+math.rad(90)

SKLabelNode not displaying the right CGPoint

I have a problem in my game and i am trying to find out what it is and it is about the position of a SKSpriteNode and i made a SKLabelNode to display the position so i could see what is going wrong. I did:
testlable.text = "\(leftObstacle.position)"
testlable.zPosition = 50
testlable.fontSize = 60
It displays the position of (00,00) when it is in the top left corner or outside of the screen not ever the right position and it isn't ever at (00,00) so what should i do to make it display the right position?
The position parameter is the position of a node relative to its parent node - so if leftObstacle is a child of another node in the scene that would explain why it always looks like it is at 0,0. In this case report the position of its parent (or its grand-parent etc.) to get what you need.

Snake game movement issue Spritekit

I am trying to create a basic snake game using Swift and Spritekit. I have a sprite moving on the screen and when i swipe it starts moving in the swipe direction. I do this in the update method where I change the position of the sprite based on the swipe direction, a set speed and a fixed duration.
e.g. direction.x * blockMovePerSecond * CGFloat(actionDuration)
I have the sprites following each other, however, as soon as i swipe and the first sprite changes direction, the one following it moves diagonally instead of first on the x-axis and then the y-axis like a normal snakes game.
I tried the following options:
Tried keeping the distance that the sprite moves on each update equal
to the distance between the two sprites. However, the sprite runs off
the screen when i do that.
Made the first sprite create a path for the rest of the sprites to follow. However, the second sprite
runs off the screen and never shows up again. I think the problem is
because the path is open.
Here's my move method code for the sprites following the first sprite (snake head):
{
var temp:NSValue = lastNodeLocation // the lastnodelocation is from first sprite location
var tempNodeDirection = lastNodeDirection
let actionDuration = 1.0
let distanceToMoveThisFrame = tempNodeDirection.CGPointValue() * blockMovePerSecond * CGFloat(actionDuration)
var currentPosition = NSValue(CGPoint: blocksOfAlphabets[i].position)
let beforeDistance = CGPoint(x: temp.CGPointValue().x - currentPosition.CGPointValue().x, y: temp.CGPointValue().y - currentPosition.CGPointValue().y)
lastNodeLocation = NSValue(CGPoint: blocksOfAlphabets[i].position)
// move node to new location
var moveAction = SKAction.moveTo(temp.CGPointValue(), duration: 1.0)
node.runAction(moveAction)
}
Can somebody please help?
Thanks
Shuchi
Well your problem is that the runAction-methods don't wait to complete. So if you call another runAction-method while a sprite is already running an action, the new action will be started immediately.
You can work with sequences to finish the x-axis first: SKAction:sequence
I think the easiest thing to do here is to keep an array of snake sprite components (let's call these sprites a "Rib").
Every 5 seconds add a new Rib to the end of the array to make the snake grow.
Then, each half second in the update() method (or however long you want it to be):
check for any swipes that have happened since the last update and change direction of the first rib (the snake head) in the direction of the swipe.
now run through the snake array in reverse and set the location of node (n) to the node position of node (n-1).
There are other ways you could do it but I think this would be the easiest.

Xna 4.0 RTS camera

How do I make a RTS camera so that when the mouse is at the edge of the window, it will move either left/right/up/down. I been trying to create an invisible box at the side of the screen so that when the mouse is at the box it will move the camera, but it still doesn't work. Please help!
Building upon what #Davor Mlinaric said, using the mouses x and y coordinates (which can be gotten from Mouse.GetState()), and testing whether those coordinates come in contact with the top, bottom and sides of the screen.
It would be a good start to set where those boxes will be something along the lines of:
GraphicsDevice.Viewport.Width/Height -/+ offset
Where offset is the amount of distance from the top,bottom or side.
Then test where the mouse position is, with a boolean.
boolean inTheZone = false;
//Bottom Box
if(Mouse.GetState().Y > GraphicsDevice.Viewport.Height - offset)
{
//Move camera in the y axis downwards (+).
inTheZone = true;
}
else
{
inTheZone = false;
}
and then the same for the 4 remaining sides.
Notice ive also used Y here, depending on how you set up the camera this may change to Z.
I hope this helps

Resources