Turning Issue With Vex Robot C++ - c++

When we use the joystick with axises 1 and 2 to turn, when we turn left the robot turns right and when we turn right the robot turns left. We've tried switching different values to make some negative to reverse this but nothing seems to work. We've also tried making the left motor reversed instead of the right motor and it corrected the problem but the forward and backward are switched.
while (true) {
int rightSpeed= (Controller1.Axis3.position(vex::pct) +
(Controller1.Axis1.position(vex::pct) + Controller1.Axis4.position(vex::pct)));
int leftSpeed= (Controller1.Axis1.position(vex::pct) -
(Controller1.Axis2.position(vex::pct) + Controller1.Axis3.position(vex::pct)));
if (leftSpeed>15||leftSpeed<-15){
RightMotor.spin(vex::directionType::fwd, leftSpeed, vex::velocityUnits::pct);
}
if (rightSpeed>15||rightSpeed<-15){
LeftMotor.spin(vex::directionType::fwd, rightSpeed, vex::velocityUnits::pct);
RightMotor.spin(vex::directionType::fwd, -leftSpeed, vex::velocityUnits::pct);
}
}

Related

Box2d Detect when a body is fully inside another body and which side it came in from

I need to detect when a body is fully inside another body and which side it came in from.
I have balls that bounce around the screen, and can enter the space of other square bodies. I need to know when the ball is fully inside the box, and from which side it came in on. This is NOT just collision detection on a side of the box, as the ball needs to be fully inside the box before anything triggers. I'm using b2FixtureDef::filter::maskBits and b2FixtureDef::filter::categoryBits to allow balls and boxes to not collide with each other.
I'm new to box2d, but not to C++, so I may be missing some functions that could make this easier for me. I started writing the following code, which works when a ball passes the correct edge, but also when it passes other edges.
Is there a way to do this without copying the ball into another data structure that keeps track of where it first contacts the box?
NOTE: This code is an example. It may not actually compile or do exactly what I say it does.
void CBox::captureBalls(std::list<CBall> &balls)
{
std::list<CBall> capturedBalls;
std::list<CBall>::iterator ball = balls.begin();
while (ball != balls.end()) {
bool capture = false;
int ballMinX = ball->getX() - ball->getRadius();
int ballMaxX = ball->getX() + ball->getRadius();
int ballMinY = ball->getY() - ball->getRadius();
int ballMaxY = ball->getY() + ball->getRadius();
switch (this->captureSide) {
case Top:
if ((ballMinX >= this->x) &&
(ballMaxX < (this->x + this->width)) &&
//(ballMinY >= this->y) &&
(ballMaxY < (this->y + this->height)))
capture = true;
break;
case Right:
if (//(ballMinX >= this->x) &&
(ballMaxX < (this->x + this->width)) &&
(ballMinY >= this->y) &&
(ballMaxY < (this->y + this->height)))
capture = true;
break;
case Bottom:
if ((ballMinX >= this->x) &&
(ballMaxX < (this->x + this->width)) &&
(ballMinY >= this->y) /*&&
(ballMaxY < (this->y + this->height))*/)
capture = true;
break;
case Left:
if ((ballMinX >= this->x) &&
//(ballMaxX < (this->x + this->width)) &&
(ballMinY >= this->y) &&
(ballMaxY < (this->y + this->height)))
capture = true;
break;
}
if (capture) {
capturedBalls.push_back(ball);
balls.erase(ball++);
}
else {
++ball;
}
}
}
To detect when a ball is fully inside the box, you could use a sensor fixture inside the box, that is smaller than the box by the diameter of the ball. In the diagram below the black rectangle is the box and the red dashed rectangle is the sensor. (If the balls all have different diameters this would not work.)
As to "which side it came in", I think you need to define what you mean by that, before anyone could help. I mean, look at the possible cases you are dealing with. The blue ball is the most straight-forward in that it approaches on one side in a constant direction. When you detect that it touches the sensor, you could use the direction of travel as suggested by sp2danny, to do a raycast from outside the box to the current position of the ball, and the side it entered is pretty obvious. But this would not work for the green or pink balls. For the pink ball in particular, what side would you consider it entered from?
Now I am assuming that the balls are free to enter the boxes from any angle. But if they had a solid obstruction at their corners, it might be clearer to define which side they came in. You could use four sensors around the exterior, and detect when a ball finishes touching these.
However, it would not be bullet-proof because in rare cases a ball could go from touching one side sensor to another in one time step, without touching nothing in between (green ball). For really fast balls, they could also potentially go from touching one side sensor, to completely inside without ever touching the sensor for the side they "came in" (pink ball). On the plus side though, this would handle the case when you have many different sizes of ball.
Ok... now that I've written up a whole post saying how it can't be done easily, I had a good idea, although it would only work when all balls are the same size. You could use two sensors inside the box, one inset by the radius of the balls, and one inset by the diameter of the balls. When the ball first touches the outer of these sensors, it means the center of the ball has crossed from being outside, to inside the box (but the ball as a whole may not be fully inside). At this point, take a raycast between the previous and current positions, and note which side it intersected. Continue on until the ball also touches the inner sensor, then you know it is fully inside, and you have already noted which side it originally came in from. If the ball stops touching the outer sensor at any point, reset to the starting state.
Note that it is still possible for a ball to first touch the box from one side, then move so that the first time its center is inside the box is from a different side (orange ball). But I am assuming you would not count a mere touch as "came in".

c++ Collision Detection for a turning rectangle

I have some collision detection working when my player hits an object. But this only works when my players x & y co-ordinates hit my marker (which is the centre of my character).
Would making a method returning a vector of all of the coordinates that the players texture cover work and what is the best way to implement this?
This is being done in c++ creating a top down game
There are many ways to do it, most simply is probably(depending on you use of classes etc).
This is the simplest, but no where near the best, or infact very good at all. This way means changing your "marker" to the bottom left of the rectangle.
void collisions()
{
//check if the x-coord is between the furthest left and furthest right x coords
if(rect.Getx() > someObject.Getx() && rect.Getx() < someObject.Getx() + someObject.GetWidth())
{
rect.SetMoveSpeed(0);
}
if(rect.Gety() > someObject.Gety() && rect.Gety() < someObject.Gety() + someObject.GetHeight())
{
rect.setMoveSpeed(0);
}
}
You would then have to set the move speed to normal when it is not colliding. That could be done with an else after each if, setting the move speed again. This is a quick fix and is not recommended for use in a game you plan to distribute anywhere.

C++ Collision Detection doesn't work on last check?

Over the last few days I have been trying to implement simple collision detection of objects drawn using OpenGL.
With the aid of the Pearson, Computer Graphics with OpenGL I have managed to write the following function:
void move(){
if(check_collision(sprite,platform1) || check_collision(sprite,platform2)){ //if colliding...
if (downKeyPressed ){ y_Vel += speed; downKeyPressed = false;} //going down
else if(upKeyPressed ){ y_Vel -= speed; upKeyPressed = false;} //going up
else if(rightKeyPressed){ x_Vel -= speed; rightKeyPressed = false;} //going right
else if(leftKeyPressed ){ x_Vel += speed; leftKeyPressed = false;} //going left
} // always glitches on whatever is last else if above?!?!
else{ glTranslatef(sprite.x+x_Vel, sprite.y+y_Vel, 0.0); }
}
My sprite moves in accordance to keyboard inputs (the arrow keys). If it collides with a stationary object it stops moving and stays in its position.
So far, it works when colliding with the top, left side and bottom of the stationary object. Unfortunately (even though I use the same logic) the right hand side doesn't work and upon a collision the sprite is redrawn at its original x/y coordinates. I'm baffled.
As it turns out, which-ever is the last check in the move() function (the last else-if) is the one that doesn't work... I have swapped the left with the right and sure enough when left is then the last one and the one that plays up :(
Any advice or ideas on how I can improve this and stop it glitching?
Please excuse my naivety and amateur coding. I'm merely a self-taught beginning. Thanks.
You should not use an else if. There is a possibility that it is hitting a side and the top or the bottom in the same frame. Trying changing those to all ifs because you want to check each one. or at the least change it to this.
if( /* check top */)
{
}
else if( /* check bot */)
{
}
if( /* check right */ )
{
}
else if( /* check left */)
{
}
Also, you should avoid declaring global variables like Y_VEL and X_VEL as this creates confusion. You may just be doing this to get your feet wet but I would avoid it. Create a class for each object and then have the velocities as members of that class.
Well, it seems to me that you have an issue when it comes to translating the actual object.
Your move code states
if(there is a collision)
{
//do stuff
}
else
{
glTranslateF( );
}
SO, whenever there is a collision, the translate function never gets called.
My opinion is that you should pull the glTranslateF() call out of the else {...}, just have it get called every time. However, it seems you're using the exact same 'draw' function for every rectangle, not just the player sprite. You'll probably have to ind a way to distinguish between regular rectangles (such as the platforms) and the player rectangle. Perhaps the simplest way for you to implement this, would be to have two different drawSprite functions: one for regular platforms, and the other for the player. Only call the move() function from within the player's draw function (perhaps called drawPlayer()?)
I don't quite have the time to look over all of your code to make a more educated and specific suggestion at the moment; however, I'll be free later this evening if this question is still open and needing help.
As you've already figured out, the problem is related to glTranslate(). Since you operate on both sprite's position and velocity, you should repeatedly update the positions using the velocities. That is:
sprite.x += x_vel;
sprite.y += y_vel;
and do it simply all the time (i.e. by some timer or every frame, if the scne is redrawn repeatedly). A collision then is equivalent to changing the velocity vector (x_vel, y_vel) in some way to simulate the collision effect: either zero it to stop any movement at all, or change the velocity component sign (x_vel = -x_vel) to make it rebound in an absolutely elastic manner, or do something else that fits.
What happens now with glTranslate() is that x_vel, y_vel actually hold offsets from the starting position, but not velocities of movement.

Reverse animation direction when hitting the side of the screen

I am creating a space invaders game for my university assignment. I am breaking the parts down on paper, I thought a good place to start would be to move the sprites across the screen. The issue I have at the moment is this, when the sprite his the right hand side of the screen it would just carry on moving, so I added this code:
if (invadersSprite.getPosition().x > 650)
{
std::cout << "WIDTH_END" << std::endl;
}
I basically used this for debugging for future reference. The output popped up into the console so I knew I was onto something. So, I started moving on from the output to actually moving the sprites back to the left hand side of the screen. I am now having more issues then expected.
I declared some ints for up, left, right and down just for easability when it comes to reading the code.
int spriteWalkSpeed = 50;
int up=-spriteWalkSpeed, down=spriteWalkSpeed, left=-spriteWalkSpeed, right=spriteWalkSpeed;
I've tried using the SFML move commands and also setPosition, but none of them really work as I thought they should.
move:
The issue I have had with this one is it basically stops in the middle of the screen. It still animates the leg movement and such, but it doesn't move left or right.
if (invadersSprite.getPosition().x > 650)
{
invadersSprite.move(left, 00);
}
setPosition:
This is a little closer to what I am after, but still no cigar. The movement pauses for around a second and then pops up at the left hand side of the screen. What I need is to move back down the screen.
if (invadersSprite.getPosition().x > 650)
{
invadersSprite.setPosition(left, 00);
}
I haven't been using SFML for very long so I am a little puzzled by this.
EDIT
At the moment the sprite is moving to the right of the screen, as needed:
if(spriteTimer>delay)
{
invadersSprite.setTextureRect(area);
++count;
invadersSprite.move(right,0);
if(count==SPRITECOLS) //WE HAVE MOVED OFF THE RIGHT OF THE IMAGE
{
area.left=0; //reset texture rect at left
count=0; //reset count
}
else
{
area.left+=spaceWidth; //move texture rect right
}
spriteTimer=0; //we have made one move in the sprite tile - start timing for the next move
}
Your current logic will only move the sprite left once if the x-coord is greater than 650 - but that's not exactly what you want. What you want is for the sprite to continuously move left after reaching the edge.
To do this you'll need to keep track of a current velocity for your sprite. For example, when your sprite starts, it will be moving right:
xVelocity = right;
Then you can have 2 conditions that will switch direction (when hitting edges of screen):
if (invaderSprite.getPosition().x >= screenWidth) {
// hit the right side of screen
xVelocity = left;
} else if (invaderSprite.getPosition().x <= 0) {
// hit the left side of screen
xVelocity = right;
}
Now, on ever game tick, you simply move your sprite according to its current velocity:
invaderSprite.move(xVelocity, yVelocity);
There are some other things that will need to be fixed, like taking the width of the sprite into consideration, changing the y velocity, etc., but this is the main idea.

Collision Detection Between Rectangles - Resulting Angles

Basically I have a bunch of rectangles floating around at 8 different angles (45 degrees, 90 degrees etc). I have collision detection going on between all of them, but one thing still doesn't work as it should. I don't know if I'm just not thinking or what, but I can't seem to get the resulting angles right. I've also tried searching multiple places, but haven't really gained anything from what I've found.
NOTE: the angle system here starts at 0 at the top and increases clockwise.
NOTE: all rectangles have the same mass
Say one rectangle going straight right (90 degrees) hits another going straight left (270 degrees). They will hit off of each other just fine.
Now say one going left gets hit by one going up. Here I can't simply reverse the angles or anything.
If you have more than one way, consider the following: unless I rearrange the CD so it spreads into the other code, I have the positions of all of the rectangles. The CD checks by seeing if two are overlapping, not by comparing where they are going.
As I've been working on pretty much everything except for the collision detection until now, I only have tonight left to get it working and add a few other small things before I'm done.
If you know of a way to make the angles come out right without hardcoding, great. At this point I'm ready to hardcode it (not too much really) if all I have is which rectangle hits the other (ex 2), or if they both do (ex 1). Either one is really helpful.
I think you mean something like this...
Each Rectangle has this functionality, testing against, say an array of other objects.
Obstacle* obstacle = new Obstacle;
Obstacle** obstacles = obstacle*[];
For(int i = 0; i <3; i++)
{
obstacles[0] = New Obstacle(x,y, etc...);
etc...
}
Or something similar... this is a little rusty
void collision(obstacles)
{
for(int i = 0; i < obstacles.sizeOf();i++)
{
//bottom y
if((this.ypos + this.height) > (obstacles[i].ypos - obstacles[i].height))
obstacles[i].doYCollision(this);
//top y
if((this.ypos - this.height) < (obstacles[i].ypos + obstacles[i].height))
obstacles[i].doYCollision(this);
//right x
if((this.xpos + this.width) > (obstacles[i].xpos - obstacles[i].width))
obstacles[i].doXCollision(this);
//left x
if((this.xpos - this.width) < (obstacles[i].xpos + obstacles[i].width))
obstacles[i].doXCollision(this);
}
}
again im a little rusty but if you follow it you should be able to relaise what im doing.
then all you need is the resulting function calls.
void doYCollision(Obstacle obstacle)
{
// Whatever y direction they are going do the opposite
obstacle.yDir = obstacle.yDir * -1;
}
void doXCollision(Obstacle obstacle)
{
// Whatever x direction they are going do the opposite
obstacle.xDir = obstacle.xDir * -1;
}
where yDir, xDir is the x and y velocity of the current object.
i should point out again this is very rusty and without having some code from you this is the best ive got. but either way this should start you off into collision detection, the code above shoudl allow for all collisions with all obstacles/objects/pink flamingos/ whatever youve got. Im hoping also that itll do what you want when it comes to multiple collisions at the same time.
You shouldnt need to worry too much about the exact angle (unless you need it for something else), as velocity is a vector mass so has both speed and direction and you can get direction by treating x and y as two different elements. You can do this using the dot product method aswell => http://www.topcoder.com/tc?d1=tutorials&d2=geometry1&module=Static, but if they are just rectangles this should be fine.
Hopes this helps