I am trying to have an object collide with any of the two obstacles and set its position, however it is registering a collision whenever I pass either of them and in all honesty I am confusing myself a lot and don't know what is wrong at this point. This is the code I am using broken off from everything else:
int[] player1;
int[] player2;
int p1width = 50;
int p1height = 50;
int sandbagwidth = 30;
int sandbagheight = 200;
int sand11 =200;
int sand12 = 0;
int sand21 =200;
int sand22 = 400;
void setup(){
size(1200, 600);
player1= new int[] {250, 250};
}
void draw(){
//draw players
fill(0);
rect(0,0,width/2,height);
fill(255,0,0);
rect(600,0,width/2,height);
//move players
fill(255);
rect(player1[0], player1[1], p1width, p1height);
if (keyPressed) {
switch(keyCode) {
case LEFT:
player1[0] -=10;
break;
case RIGHT:
player1[0] +=10;
break;
case UP:
player1[1] -=10;
break;
case DOWN:
player1[1] +=10;
break;
}
}
if(player1[0]+25>1150){
player1[0]-=25;
}
if(player1[0]-25<0){
player1[0]+=50;
}
if(player1[1]+25>550){
player1[1]-=25;
}
if(player1[1]-25<0){
player1[1]+=50;
}
//COLLISION
fill(0,255,0);
rect(sand11, sand12, sandbagwidth, sandbagheight);
fill(0,255,0);
rect(sand21, sand22, sandbagwidth, sandbagheight);
if(player1[0] + p1width/2 > sand11 - sandbagwidth/2
&& player1[0] - p1width/2 < sand11 + sandbagwidth/2
&& player1[1] + p1height/2 > sand12 - sandbagheight/2
&& player1[1] - p1height/2 < sand12 + sandbagheight/2){
player1[0]=220;
player1[1]=250;
}
if(player1[0] + p1width/2 > sand21 - sandbagwidth-25
&& player1[0] - p1width/2 < sand21 + sandbagwidth-25
&& player1[1] + p1height/2 > sand22 - sandbagheight-25
&& player1[1] - p1height/2 < sand22 + sandbagheight-25){
player1[0]=50;
player1[1]=50;
}
}
It looks to me like you're using player1, sandXX, etc. as the top-left corners when drawing, but as the centre when calculating collisions (unless you have a rectMode call in the code you haven't included). This could easily cause your bug - try to pass the bottom sandbag at the bottom, even though there is no visible gap there.
Nitpick: you also switch between constants and calculated values; this is going to bite you in the long run, even if it works here. For example, rect(600,0,width/2,height) should probably be rect(width/2,0,width/2,height). player1[0]=220 in the collision response code is an even better candidate for being replaced with calculations based on your variables.
Related
I wanted to make a servomotor oscilate between 0-90 degrees when i push a button, but when i push another one, it stops oscillating and then remains in its latest position.
i started with this:
#include <Servo.h>
Servo myservo;
int pos = 0;
const int button1 = 5;
const int button2 = 6;
int lastpos = pos;
void setup() {
myservo.attach(3);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
}
void loop() {
if(digitalRead(button1) == HIGH)
{for(pos = 0; pos <= 90; pos += 1)
{myservo.write(pos);
for(pos = 90; pos >= 0; pos -= 1)
{myservo.write(pos);
delay(36);
} } if(digitalRead(button2) == HIGH){ myservo.write(lastpos);}}}
To start, take a look at how to format code inside a question. It makes it a lot easier to read and help you out. See below for how I formatted for the site, but also readability.
Servo myservo;
int pos = 0;
const int button1 = 5;
const int button2 = 6;
int lastpos = pos;
void setup() {
myservo.attach(3);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
}
void loop() {
if(digitalRead(button1) == HIGH) {
for(pos = 0; pos <= 90; pos += 1) {
myservo.write(pos);
for(pos = 90; pos >= 0; pos -= 1) {
myservo.write(pos);
delay(36);
}
}
if(digitalRead(button2) == HIGH) {
myservo.write(lastpos);
}
}
}
There are several issues with your code based on your description of what you are trying to achieve. First, let's start with the button presses. You are ready the button state, but your code will only detect the button if it is pressed at the exact moment you are doing the digital read. Here's a good resource for reading up on how to properly implement buttons on Arduino: https://www.logiqbit.com/perfect-arduino-button-presses
The second objective is to have the servo sweep back and forth, but stop when you press a button. Your for loops won't let that happen. As currently written, you will always do a sweep to one end and back and then check the next button.
You should update the position of the servo once each time through the loop so you can check on the status of the buttons. In pseudo-code, what I suggest you do is:
void loop() {
//Check button statuses
if(button1), start sweep
if(button2), stop sweep
//Update sweep position
if(ascending && pos < 90) {
//You should be increasing in angle and you haven't reached 90 yet
ascending = TRUE;
pos += 1
myservo.write(pos);
delay(36); //Or whatever delay you need for the servo
} else if(pos > 0) {
//You already reached 90 and are coming back down to 0
ascending = FALSE;
pos -= 1;
delay(36);
}
I'm stuck at the solution of a problem.
Problem =>
You are given a square grid with some cells open (.) and some blocked (X). Your playing piece can move along any row or column until it reaches the edge of the grid or a blocked cell. Given a grid, a start and a goal, determine the minimum number of moves to get to the goal.
Example =>
...
.X.
...
The starting position (0,0) so start in the top left corner. The goal is (1,2) The path is (0,0)->(0,2)->(1,2). It takes moves to reach the goal.
Output = 2
Solution=>
BFS using Queue.
But how BFS can get to the minimum path for example if there is more than one path exist between starting and ending point then how BFS can get to the minimum one ?
Here is my solution for the above problem. But it doesn't work.
class Pair{
int x,y;
Pair(int a,int b){x=a;y=b;}
}
class Result {
public static int minimumMoves(List<String> grid, int startX, int startY, int goalX, int goalY)
{
int n=grid.get(0).length();
ArrayDeque<Pair> q=new ArrayDeque<Pair>();
Pair location[][]=new Pair[n][n];
char color[][]=new char[n][n];
//default color a mean it is neither in queue nor explore
//till now, b mean it is in queue, c means it already explore
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
color[i][j]='a';
}
}
q.addLast(new Pair(startX,startY));
int tempx,tempy,tempi,tempj;
while(!q.isEmpty()){
tempx=q.peekFirst().x;
tempy=q.peekFirst().y;
q.removeFirst();
color[tempx][tempy]='c';
tempj=tempy-1;
tempi=tempx;
//cheking unvisited node around -X axis
while(tempj>=0){
if(color[tempi][tempj]!='a' || grid.get(tempi).charAt(tempj)!='.'){
break;
}
q.addLast(new Pair(tempi,tempj));
color[tempi][tempj]='b';
location[tempi][tempj]=new Pair(tempx,tempy);
tempj--;
}
//checking unvisited node around +X axis
tempi=tempx;
tempj=tempy+1;
while(tempj<n){
if(color[tempi][tempj]!='a' || grid.get(tempi).charAt(tempj)!='.'){
break;
}
q.addLast(new Pair(tempi,tempj));
color[tempi][tempj]='b';
location[tempi][tempj]=new Pair(tempx,tempy);
tempj++;
}
//checking unvisited node around +Y axis
tempi=tempx-1;
tempj=tempy;
while(tempi>=0){
if(color[tempi][tempj]!='a' || grid.get(tempi).charAt(tempj)!='.'){
break;
}
q.addLast(new Pair(tempi,tempj));
color[tempi][tempj]='b';
location[tempi][tempj]=new Pair(tempx,tempy);
tempi--;
}
checking unvisited node around -Y axis
tempi=tempx+1;
tempj=tempy;
while(tempi<n){
if(color[tempi][tempj]!='a' || grid.get(tempi).charAt(tempj)!='.'){
break;
}
q.addLast(new Pair(tempi,tempj));
color[tempi][tempj]='b';
location[tempi][tempj]=new Pair(tempx,tempy);
tempi++;
}
}//end of main while
//for track the path
Stack<Pair> stack=new Stack<Pair>();
//If path doesn't exist
if(location[goalX][goalY]==null){
return -1;
}
boolean move=true;
stack.push(new Pair(goalX,goalY));
while(move){
tempi=stack.peek().x;
tempj=stack.peek().y;
stack.push(location[tempi][tempj]);
if(tempi==startX && tempj==startY){
move=false;
}
}
System.out.println(stack);
return stack.size()-2;
}
}
Here My algorithm only find the path. Not the minimum path. Can anyone suggest me how BFS finds the minimum path here and what should I change into my code ?
BFS finds the minimal path by concentric moving outward, so everything in round 1 is 1 away from start, all squares added there are then 2 away from start and so on. This means the basic idea of using BFS to find the path is good, unfortunately the implementation is a bit difficult and slow.
Another way of viewing it is to think about the grid as a graph, with all squares connected to all other squares up, down, left and right until they hit the edge or an obstacle.
A third way of thinking of it is like a flood fill, first round only start is filled, next round all that can be accessed from it is filled and so on.
The major thing is that you break when you see a b.
aabbaaaaaa
aabbbaaaaa
babbbaaaaa
babbbaaaaa
babbbaaaaa
babbbaaaaa
bbbbbaaaaa
bbbbbaaaaa
bCbbbAAAAA
cccccaaaaa
When processing the capital Cit stops because it is surrounded by bs and cs. And therefore you don't examine the As.
I have hacked the code a bit, note i'm not a java programmer ... my main problem when trying to solve it was timeouts. I believe this can be solved without the location array by recording how many generations of BFS we run, that should save a lot of memory and time.
class Pair{
int x,y;
Pair(int a,int b){x=a;y=b;}
public String toString() {
return "[" + x + "," + y + "]";
}
}
class Result {
/*
* Complete the 'minimumMoves' function below.
*
* The function is expected to return an INTEGER.
* The function accepts following parameters:
* 1. STRING_ARRAY grid
* 2. INTEGER startX
* 3. INTEGER startY
* 4. INTEGER goalX
* 5. INTEGER goalY
*/
public static int minimumMoves(List<String> grid, int startX, int startY, int goalX, int goalY) {
if (startX==goalX&&startY==goalY)
return 0;
startX += 1;
startY += 1;
goalX += 1;
goalY += 1;
int n=grid.get(0).length();
Pair dirs[] = {new Pair(-1,0), new Pair(+1,0), new Pair(0,-1), new Pair(0,+1)};
ArrayDeque<Pair> q=new ArrayDeque<Pair>();
Pair location[][]=new Pair[n+2][n+2];
char color[][]=new char[n+2][n+2];
//default color a mean it is neither in queue nor explore
//till now, b mean it is in queue, c means it already explore
for(int i=0;i<n+2;i++){
for(int j=0;j<n+2;j++){
if (i == 0 || i == n+1 ||j == 0 || j == n+1 || // boarder
grid.get(i-1).charAt(j-1)!='.')
color[i][j]='x';
else
color[i][j]='a';
}
}
q.addLast(new Pair(startX,startY));
int tempx,tempy,tempi,tempj;
while(!q.isEmpty()){
tempx=q.peekFirst().x;
tempy=q.peekFirst().y;
q.removeFirst();
if(location[goalX][goalY]!=null){
System.out.println("Goal reached");
break;
}
color[tempx][tempy]='c';
for (Pair dir : dirs ) {
tempi=tempx;
tempj=tempy;
while(true){
tempi+=dir.x;
tempj+=dir.y;
if (color[tempi][tempj]=='x') { // includes boarder
break;
}
if (color[tempi][tempj]>='b') {
continue;
}
q.addLast(new Pair(tempi,tempj));
color[tempi][tempj]='b';
location[tempi][tempj]=new Pair(tempx,tempy);
}
}
// System.out.println(location[goalX][goalY]);
// for(int i = 1; i < n+1; i++) {
// for(int j = 1; j < n+1; j++) {
// System.out.printf("%c", color[i][j]);
// }
// System.out.println();
// }
}//end of main while
//for track the path
Stack<Pair> stack=new Stack<Pair>();
//If path doesn't exist
if(location[goalX][goalY]==null){
System.out.printf("Gaol not reached %d %d", goalX, goalY);
System.out.println();
for(int i = 1; i < n+1; i++) {
for(int j = 1; j < n+1; j++) {
System.out.printf("%s", location[i][j]);
}
System.out.println();
}
return -1;
}
boolean move=true;
int moves = 0;
tempi = goalX;
tempj = goalY;
while(move){
System.out.println(String.valueOf(tempi)+" "+ String.valueOf(tempj));
moves = moves +1;
Pair cur = location[tempi][tempj];
tempi=cur.x;
tempj=cur.y;
if(tempi==startX && tempj==startY){
move=false;
}
}
System.out.println(moves);
return moves;
}
}
I am drawing a Pythagoras Tree using L-system and 2 production rules. I managed to use the first rule called “F-rule” to draw the right handside of the tree. I tried using the second rule “H-rule” to draw the left handside. NO matter what I change in the H-rule, it messes up the result of the right handside. Any idea how I can create the leftside similar to the right ? Many thanks.
int SZ = 800;
Tree tree;
void settings() {
size(SZ,SZ);
}
void setup() {
int d = 100;
int x = SZ/2;
int y = SZ/2;
float branchAngle = radians(180);
float branchAngle_Left = radians(-45);
float branchAngle_Right = radians(45);
float initOrientation = PI;
String state = "F"; // initiator
float scaleFactor = 0.8;
String F_rule = "F[+sH]s+F";
String H_rule = "";
String f_rule = "";
int numIterations = 6;
background(255);
noLoop();
tree = new Tree(d, x, y, branchAngle, branchAngle_Right, branchAngle_Left, initOrientation, state, scaleFactor, F_rule, H_rule, f_rule, numIterations);
}
void draw() {
tree.draw();
}
class Tree {
int m_lineLength; // turtle line length
int m_x; // initial x position
int m_y; // initial y position
float m_branchAngle_Right; // turtle rotation at branch
float m_branchAngle_Left; // turtle rotation at branch
float m_branchAngle;
float m_initOrientation; // initial orientation
String m_state; // initial state
float m_scaleFactor; // branch scale factor
String m_F_rule; // F-rule substitution
String m_H_rule; // H-rule substitution
String m_f_rule; // f-rule substitution
int m_numIterations; // number of times to substitute
// constructor
// (d = line length, x & y = start position of drawing)
Tree(int d, int x, int y, float branchAngle, float branchAngle_Right, float branchAngle_Left, float initOrientation, String state, float scaleFactor,
String F_rule, String H_rule, String f_rule, int numIterations) {
m_lineLength = d;
m_x = x;
m_y = y;
m_branchAngle= branchAngle;
m_branchAngle_Right = branchAngle_Right;
m_branchAngle_Left = branchAngle_Left;
m_initOrientation = initOrientation;
m_state = state;
m_scaleFactor = scaleFactor;
m_F_rule = F_rule;
m_H_rule = H_rule;
m_f_rule = f_rule;
m_numIterations = numIterations;
// Perform L rounds of substitutions on the initial state
for (int k=0; k < m_numIterations; k++) {
m_state = substitute(m_state);
}
}
void draw() {
pushMatrix();
pushStyle();
stroke(0);
translate(m_x, m_y); // initial position
rotate(m_initOrientation); // initial rotation
for (int i=0; i < m_state.length(); i++) {
turtle(m_state.charAt(i));
}
popStyle();
popMatrix();
}
void turtle(char c) {
switch(c) {
case 'F': // drop through to next case
case 'H':
//line (0, 0, 0, m_lineLength);
rect(0, 0, m_lineLength, m_lineLength);
translate(0, m_lineLength);
break;
case 'f':
translate(0, m_lineLength);
break;
case 't':
translate(0, -m_lineLength);
break;
case 's':
scale(m_scaleFactor);
break;
case '&':
rotate(m_branchAngle);
break;
case '-':
rotate(m_branchAngle_Left);
break;
case '+':
rotate(m_branchAngle_Right);
break;
case '[':
pushMatrix();
break;
case ']':
popMatrix();
break;
default:
println("Bad character: " + c);
exit();
}
}
// apply substitution rules to string s and return the resulting string
String substitute(String s) {
String newState = new String();
for (int j=0; j < s.length(); j++) {
switch (s.charAt(j)) {
case 'F':
newState += m_F_rule;
break;
case 'H':
newState += m_H_rule;
break;
case 'f':
newState += m_f_rule;
break;
default:
newState += s.charAt(j);
}
}
return newState;
}
}
After a bit of research (1, 2, 3, 4, 5) I have arrived to a few conclusions. However, I haven't been able to find the H and F rules anywhere.
First of all I wouldn't recomend you setting two different angles since they are dependant as they form a right triangle. branchAngle_Right = 90 - branchAngle_Left
Moreover, for 45º, the fact that the scale factor is √2/2 (and not 0,8) is not arbitrary. It's due to trygonometric consequences. If we wanted to generalize it would be something like this: m_scaleFactor_Right = cos(m_branchAngle_Right), and the same for left.
Finally, i would try to redo, the tree generation as it seems to me that it has been overcomplicated. The fourth and the fith (in the coments) references atached at the begining are example codes. See how, in the fith one, it is being calculated the position of the new square and not translating from the previous square, which may be the cause of your problems when doing the left side backwards.
However, i do thing your code could work, but the efford you would put into it would be much larger than doing it from the begining and not overcomplicating.
If you still want to continue that way, please attach some information about those rules you were saying so we can help you.
Im trying to add settings to a snake game made in processing. I want to have something like easy, normal and hard or something along the lines of that and change the speed and maybe size of the grid. If anyone coudl explain how to id greatly appreciate it!
ArrayList<Integer> x = new ArrayList<Integer>(), y = new ArrayList<Integer>();
int w = 30, h = 30, bs = 20, dir = 2, applex = 12, appley = 10;
int[] dx = {0,0,1,-1}, dy = {1,-1,0,0};
boolean gameover = false;
void setup() {
size(600,600);
x.add(5);
y.add(5);
}
void draw() {
background(255);
for(int i = 0 ; i < w; i++) line(i*bs, 0, i*bs, height); //Vertical line for grid
for(int i = 0 ; i < h; i++) line(0, i*bs, width, i*bs); //Horizontal line for grid
for(int i = 0 ; i < x.size(); i++) {
fill (0,255,0);
rect(x.get(i)*bs, y.get(i)*bs, bs, bs);
}
if(!gameover) {
fill(255,0,0);
rect(applex*bs, appley*bs, bs, bs);
if(frameCount%5==0) {
x.add(0,x.get(0) + dx[dir]);
y.add(0,y.get(0) + dy[dir]);
if(x.get(0) < 0 || y.get(0) < 0 || x.get(0) >= w || y.get(0) >= h) gameover = true;
for(int i = 1; i < x.size(); i++) if(x.get(0) == x.get(i) && y.get(0) == y.get(i)) gameover = true;
if(x.get(0)==applex && y.get(0)==appley) {
applex = (int)random(0,w);
appley = (int)random(0,h);
}else {
x.remove(x.size()-1);
y.remove(y.size()-1);
}
}
} else {
fill(0);
textSize(30);
text("GAME OVER. Press Space to Play Again", 20, height/2);
if(keyPressed && key == ' ') {
x.clear(); //Clear array list
y.clear(); //Clear array list
x.add(5);
y.add(5);
gameover = false;
}
}
if (keyPressed == true) {
int newdir = key=='s' ? 0 : (key=='w' ? 1 : (key=='d' ? 2 : (key=='a' ? 3 : -1)));
if(newdir != -1 && (x.size() <= 1 || !(x.get(1) ==x.get(0) + dx[newdir] && y.get (1) == y.get(0) + dy[newdir]))) dir = newdir;
}
}
You need to break your problem down into smaller steps:
Step one: Can you store the difficulty in a variable? This might be an int that keeps track of a level, or a boolean that switches between easy and hard. Just hardcode the value of that variable for now.
Step two: Can you write your code so it changes behavior based on the difficulty level? Use the variable you created in step one. You might use an if statement to check the difficulty level, or maybe the speed increases over time. It's completely up to you. Start out with a hard-coded value. Change the value to see different behaviors.
Step three: Can you programatically change that value? Maybe this requires a settings screen where the user chooses the difficulty, or maybe it gets more difficult over time. But you have to do the first two steps before you can start this step.
If you get stuck on a specific step, then post an MCVE and we'll go from there.
int x = 31;
int y = 31;
int x_dir = 4;
int y_dir = 0;
void setup ()
{
size (800, 800);
}
void draw ()
{
background (150);
ellipse (x,y,60, 60);
if (x+30>=width)
{
x_dir =-4;
y_dir = 4;
}
if (y+30>=height)
{
x_dir=4;
y_dir = 0;
}
if (x+30>=width)
{
x_dir = -4;
}
x+=x_dir;
y+=y_dir;
println(x,y);
}
Hi,
I have to create this program in processing which produces an animation of a ball going in a Z pattern (top left to top right, diagonal top right to bottom left, and then straight from bottom left to bottom right) which then goes backwards along the same path it came.
While I have the code written out for the forward direction, I don't know what 2 if or else statements I need to write for the program so that based on one condition it goes forwards, and based on another condition it will go backwards, and it will continue doing so until it terminates.
If I am able to figure out which two if statements I need to write, all I need to do is copy and reverse the x_dir and y_dir signs on the forward loop.
There are a ton of different ways you can do this.
One approach is to keep track of which "mode" you're in. You could do this using an int variable that's 0 when you're on the first part of the path, 1 when you're on the second part of the path, etc. Then just use an if statement to decide what to do, how to move the ball, etc.
Here's an example:
int x = 31;
int y = 31;
int mode = 0;
void setup ()
{
size (800, 800);
}
void draw ()
{
background (150);
ellipse (x, y, 60, 60);
if (mode == 0) {
x = x + 4;
if (x+30>=width) {
mode = 1;
}
} else if (mode == 1) {
x = x - 4;
y = y + 4;
if (y+30>=height) {
mode = 2;
}
} else if (mode == 2) {
x = x + 4;
if (x+30>=width) {
mode = 3;
}
} else if (mode == 3) {
x = x - 4;
y = y - 4;
if (y-30 < 0) {
mode = 2;
}
}
}
Like I said, this is only one way to approach the problem, and there are some obvious improvements you could make. For example, you could store the movement speeds and the conditions that change the mode in an array (or better yet, in objects) and get rid of all of the if statements.