I'm making a racing car game where my racing course is similar to a rectangular donut. In the middle of the rectangle I have another smaller rectangle which acts as a wall. I'm trying to add collision detection to my inside wall so that my cars will collide with the inside walls. Below are some basic measurements of the inside wall as well as a picture showing a concept of the track:
-Translated x from 14 to 18 units is the width of the rectangle.
-Translate y from -60 to 60 units is the total length of the rectangle.
My problem currently is if I try making the cars collide when the x position hits the wall at 14 units from the origin (or with y), it creates collision for the entire x or y line. So for example, once I hit the wall that's located 14 units in the x direction it doesn't let me pass if I were to reach that location at one of the turning points in the race course. I'm trying the following at the moment.
void checkColl(){
if (posX < -14){
velocityX *= -1 //bounce off the wall on the far left side of the picture
}
if (posX > 48){
velocityX *= -1 //bounce off wall on far right
}
if ((posY > 60 || posY < -60) && (posX > 14 && posX < 18)){ //bounce off the rectangle in middle of race course
velocityY = velocityY * -1;
velocityX = velocityX * -1;
}
}
The check for the y coordinate is broken. Try this:
if ((posY > -60 && posY < 60) && (posX > 14 && posX < 18)){
//bounce off the rectangle in middle of race course
This defines points within the black rectangle - the hole of the "doughnut".
Related
I'm working on a game for a game jam, and can't get my collision system to work. The way it's supposed to work is when an the player intersects with a wall hitbox it moves the player towards the last position until it no longer intersects. This doesn't work though, this is the code:`
while(worldBox.intersects((Rectangle2D) Player.entity)) {
if(offsetX - lastX > 0) offsetX --;
if(offsetX - lastX < 0) offsetX ++;
if(offsetY - lastY > 0) offsetY --;
if(offsetY - lastY < 0) offsetY ++;
makeWorldHitBox();
}
` and here is the link to the github repo: https://github.com/DJPretzel-bit64/LemonRunner.git
I tried changing sines and offsets, nothing worked
so recently, we've been assigned to code multiple circles that act like robots in a GUI interface. Basically, a robot simulator.
I've got the code to spawn in multiple circles that can act like robots.
This is my current code for detecting wall collision between the robot and the end of the square:
private void checkCollisions(double maxX, double maxY) {
for (ListIterator<Ball> slowIt = balls.listIterator(); slowIt.hasNext();) {
Ball b1 = slowIt.next();
// check wall collisions:
double xVel = b1.getXVelocity();
double yVel = b1.getYVelocity();
if ((b1.getCenterX() - b1.getRadius() <= 0 && xVel < 0)
|| (b1.getCenterX() + b1.getRadius() >= maxX && xVel > 0)) {
b1.setXVelocity(-xVel);
}
if ((b1.getCenterY() - b1.getRadius() <= 0 && yVel < 0)
|| (b1.getCenterY() + b1.getRadius() >= maxY && yVel > 0)) {
b1.setYVelocity(-yVel);
}
for (ListIterator<Ball> fastIt = balls.listIterator(slowIt.nextIndex()); fastIt.hasNext();) {
Ball b2 = fastIt.next();
final double deltaX = b2.getCenterX() - b1.getCenterX() ;
final double deltaY = b2.getCenterY() - b1.getCenterY() ;
if (colliding(b1, b2, deltaX, deltaY)) {
bounce(b1, b2, deltaX, deltaY);
}
}
}
}
The
b1.setXVelocity(-xVel);
b1.setYVelocity(-yVel);
are the main bits that make the circle bounce back from the wall. However, instead of this, I want the ball to detect the wall and rotate 90 degrees rather than bounce back form the wall like a bouncing ball.
Any help will be fully appreciated or a working piece of code that ca do this for me. I have an AraryList of all the balls called 'balls'.
If needed, I can give source code.
This is what I have so far. But I need each ball to have a sensor attached to them detecting if there a wall ahead.
https://i.stack.imgur.com/XsQvX.png
Assuming you have just square walls:
If the ball hits the right wall for example, you want to remove all x velocity, and then add either positive or negative velocity.
The issue with this is that the robot will end up just going around the outside edges of the map.
I have a rectangle which when I hold down the mouse button I want that rectangle to move to that point following a strait line 1 pixel at a time.
This is my code so far (I put comments in it so you can understand)
float distanceX = finalX - x; //the number of pixels needed to get to destination on the X axis
float distanceY = finalY - y; // same as above but Y axis
float moveX = distanceX > 0 ? 1 : -1; // I only want it to move 1 pixel per render
float moveY = distanceY > 0 ? 1 : -1; // same as above
Array<Stuff> collidedX = new Array<Stuff>(); //saves collisions seperately for x and y
Array<Stuff> collidedY = new Array<Stuff>(); //because I want the square to move where the mouse is pointing even if it means only aligning one axis
for (Stuff s : collidables) {
if (overlapsT(s, x + moveX, y)) {
collidedX.add(s);
}
}
if (collidedX.size < 1) {
if (distanceX != 0)
x += moveX;
}
for (Stuff s : collidables) {
if (overlapsT(s, x, y + moveY)) {
collidedY.add(s);
}
}
if (collidedY.size < 1) {
if (distanceY != 0)
y += moveY;
}
right now the problem is it goes perfectly diagonal until it lines up with one of the axis and then moves up down left or right to the destination.
I don't want to move fractions of pixels. The way my custom physics engine works is each pixel matters, fractional pixels are no good so I am trying to figure out how to smooth the path or rather how to decide when to add 1 to x and then y.
Currently I can't comment, so I have to answer. I think the Bresenham's line algorithm will help you out. It's for drawing rasterize lines.
Bresenham
I'm trying to implement a simple pong game. I want the ball to change X direction or Y direction depending what side of the ball was hit.
The ball moves at 3 pixels per second and has a width of 22 and height of 22. The paddles have a width and height of 32.
For collision detection on the ball, should I just create one rectangle and check for collision with the center point?
Alternatively I could create 4 rectangles around the ball to represent the sides, with an appropriate width, given that the ball moves at 3 pixels per frame.
Another option is to create a method that will check for collision at least 2 pixels in the direction of motion of the ball.
If the ball is moving to the right, and the x-position is 16, the next frame will be 19.
Should I create a method that will check x for 16, 17 and 18, to make sure if there is a collision it will hit the right side and not cause the ball to actually go inside the cube?
#Sig
I now have this as my collision detection
if(Rect.intersects(balls.get(j).ball, levelBlocks.blocks.get(i).rect))
{
//Bottom
if(balls.get(j).yPos <= levelBlocks.blocks.get(i).yPos - (32/2))
{
balls.get(j).ySpeed = balls.get(j).ySpeed * -1;
}
//Top
if(balls.get(j).yPos >= levelBlocks.blocks.get(i).yPos + (32/2))
{
balls.get(j).ySpeed = balls.get(j).ySpeed * -1;
}
//Left
if(balls.get(j).xPos < levelBlocks.blocks.get(i).xPos)
{
balls.get(j).xSpeed = balls.get(j).xSpeed * -1;
}
//Right
if(balls.get(j).xPos > levelBlocks.blocks.get(i).xPos)
{
balls.get(j).xSpeed = balls.get(j).xSpeed * -1;
}
This works, but not 100%, it still seems abit off. if the ball hits two blocks at the same time, it will invert the invert so the direction will go back again.
I then changed it to this
if(Rect.intersects(balls.get(j).ball, levelBlocks.blocks.get(i).rect))
{
//Bottom
if(balls.get(j).yPos <= levelBlocks.blocks.get(i).yPos - (32/2))
{
collision = 2;
}
//Top
if(balls.get(j).yPos >= levelBlocks.blocks.get(i).yPos + (32/2))
{
collision = 2;
}
//Left
if(balls.get(j).xPos <= levelBlocks.blocks.get(i).xPos + (32/2))
{
collision = 1;
}
//Right
if(balls.get(j).xPos >= levelBlocks.blocks.get(i).xPos + (32/2))
{
collision = 1;
}
temp = levelBlocks.blocks.get(i);
levelBlocks.blocks.remove(i);
combo.blocksDestroied += 1;
Assets.score += 10 * combo.comboMultiplier;
}
}
if(collision == 1)
{
balls.get(j).xSpeed = balls.get(j).xSpeed * -1;
collision = 0;
}
if(collision == 2)
{
balls.get(j).ySpeed = balls.get(j).ySpeed * -1;
collision = 0;
}
This does work, but every now and then the ball will just start randomly going through blocks, it is very odd to look at, really confused on why it is doing it, but I do feel it is because of the 3 pixels per frame
Because the shapes you're working with are so simple, why not be perfect? Use a rectangle for the paddles and a circle for the ball when performing hit detection. Start by checking for collisions on a frame-by-frame basis; at the speeds you're working with, you shouldn't need to "look into the future" for future collisions.
I wrote a program to solve the following:
Implement a diffusion limited aggregation simulation on a toroid plane where seeds are randomly created, and particles move randomly. they move if they particles do not land near a seed or a particle. where user inputs seeds (red pixels), particles (black pixels), steps (no or iterations), plane size.
My code is very slow. How can I make it faster?
I randomly created x and y coordinates and drew red pixels (seeds), then randomly created x and y for black pixels (particles), if a black pixel lands where there is a red or black pixel it can stay, otherwise it moves randomly again until there are no more particles . If the pixel lands out of borders like x > border then x=0; if x <1 then x= border. The same for y.
This just means that if it lands on the border I move it to the opposite border. Then checks for the neighboring pixels again. I have an outer loop to create the seeds, and inner loop for the particles. In the inner loop I check for the x,y positions:
//Place, move, and "stick" the particles; stop if either steps or particles = 0
for (int p = 0; p < particles; p++) {
for (int s = 0; s < steps; s++) {
if (xPos > image.getWidth() ) {
do something
}
else if (xPos < 1) {
do something
}
if (yPos > image.getHeight() - 2) {
do something
}
else if (yPos < 1) {
do something
}
else if (xPos > image.getWidth() && yPos > image.getHeight()) {
do something
}
else if (xPos < 1 && yPos < 1) {
do something
}
//If the surrounding pixels' color is not white, make that particle stick.
if (moveValid()) {
image.setRGB(xPos, yPos, 0xFF000000);
}
//Otherwise, move in a random direction
else {
if(xPos == 1 && image.getRGB(size - 2, yPos) != 0xFFFFFFFF){
draw(xPos,yPos);
}
else if(xPos == size - 2 && image.getRGB(1,yPos) != 0xFFFFFFFF){
draw(xPos,yPos);
}
if(yPos == 1 && image.getRGB(xPos, size - 2) != 0xFFFFFFFF){
draw(xPos,yPos);
}
else if(yPos == size - 2 && image.getRGB(xPos,1) != 0xFFFFFFFF){
draw(xPos,yPos);
}
else {
move();
}
}
}
//Regenerate random x and y positions for the next particle
xPos = random.nextInt(size);
yPos = random.nextInt(size);
}
Although the implementation of draw() is not shown, it looks like you're updating a BufferedImage and then rendering it.
The first step is always to profile your existing code, looking for easily implemented optimizations.
The second step is sometimes to set aside the existing code and try a different approach.
You may be able to leverage the Mode-View-Controller pattern, outlined here and discussed here. In particular, let your DLA model evolve on a background thread at full speed, while updating your view at a more sustainable rate. This article suggests several approaches to synchronization and includes a related example that uses javax.swing.Timer to pace the updates.