We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
Glitchy... (Read 1664 times)
Glitchy...
Apr 18th, 2009, 5:04pm
 
Hello
I am attempting to make a program that will shoot a bullet from a "gun" (just a line) and accurately simulate the trajectory (just gravity and the power from the gun). I did this using vectors. I also added a couple of features: a "power bar" that increases the power of the shot if you hold down the firing button, a keyboard interface, and some debug stuff. However, the gun does not fire properly.

Here is the code, commented heavily:
Quote:
float angle, a, b, c, d, xco, yco;    // Declaring variables
boolean throwvar, start, started;
PVector gravity, launch, sum;
String[] tex = new String[4];

void setup()
{
 background(255, 255, 255);    // Setting up backgroung, line width, and screen size
 strokeWeight(5);
 size(500, 500);
 throwvar = false;    // Initializing some important variables
 angle = 0;
}

void draw()
{
 background(255, 255, 255);    // Clearing the screen
 rect(50, 425, 400, 25);    // Power bar (outline part)
 fill(200, 255, 200);    // Making non-outline portion of power bar green
 rect(50, 425, 400*(d/10), 25);    // Power bar (non-outline part)
 noFill();    // Reversing color change
 rotate(angle);    // Rotating gun/aimer based on user-inputted angle
 line(0, 0, 0, -50);    // Making gun/aimer
 start = true;    // Telling the next "if" that the first frame has already occurred
 if(start && !started) {    // If statement to rotate aimer to 45 degrees on the first frame
   angle += PI*0.75;    // Indirect rotation
   started = true;    // Making this if statement invalid for subsequent executions of draw
 }
 if(throwvar && xco < 500 && yco > -500) {    // If statement to launch pellet/bullet (also prevents pellet from going off screen)
   gravity = new PVector(a, PI);    // Initializing vectors
   launch = new PVector(d, angle);
   sum = PVector.add(gravity, launch);
   xco = sum.x*cos(sum.y);    // Converting the vectors (polar) to x/y coordinates
   yco = sum.x*sin(sum.y);
   tex[0] = str(xco);    // Debug stuff
   tex[1] = str(yco);
   tex[2] = str(mouseX);
   tex[3] = str(mouseY);
   println(join(tex, ", "));
   point(xco, yco);    // Drawing bullet
   a += 0.98;    // Increasing velocity downwards (gravity is acceleration)
   if(d >= 0) {    // Making bullet speed decay over time
     d -= 0.1;
   }
 }
 if(xco >= 500 && yco <= -500) {    // Resetting program when pellet hits the edge of screen
   a = 0;
   d = 0;
   throwvar = false;
 }
}

void keyPressed()    // Stuff to make aimer change angle when you pres arrow keys as well as firing machanism
{
 if(key == CODED && !throwvar) {
   if(keyCode == UP && angle > PI/2) {
     angle -= 0.01;
   }
   if(keyCode == DOWN && angle < PI) {
     angle += 0.01;
   }
 }
 if((key == ENTER || key == RETURN) && d < 10) {
   d += 0.1;
 }
}

void keyReleased()    // Pretty self explanatory
{
 if(key == ENTER || key == RETURN) {
   throwvar = true;
 }
 else if(key == BACKSPACE || key == DELETE) {
   throwvar = false;
 }
}

Please copy and paste this into a processing sketch to see what I mean. To fire, press and hold enter until the desired power level is reached (think gunbound-style firing). Change the angle of the gun using the up and down arrow keys. IMPORTANT: try adjusting the firing angle to see just how glitchy this code is. You have to restart the program to fire again. Please look over my code, although I don't see any problems with it, you might. Thank you in advance.
Re: Glitchy...
Reply #1 - Apr 19th, 2009, 10:28am
 
PVectors are not polars.

(sorry for short post, would be longer but am having trouble with posting)
Re: Glitchy...
Reply #2 - Apr 19th, 2009, 1:54pm
 
Huh...  Huh

I thought that a PVector could be anything you want it to be, as long as it is defined using 2 or 3 numbers (similar to an array except specialized). I was under the impression that a PVector was just a way of containing numbers for use in vector math.
Re: Glitchy...
Reply #3 - Apr 20th, 2009, 2:47am
 
interesting point...

that said, looking at the methods, they do all seem to be skewed towards the cartesian.

http://dev.processing.org/reference/core/javadoc/processing/core/PVector.html

that said, you aren't using any of them 8)

actually, you are - add().

Re: Glitchy...
Reply #4 - Apr 20th, 2009, 7:43am
 
oooh...
EDIT
I see now!
I have to add the components of the vector by separating them into their components!
EDIT2
Hmm....
It still won't work.
Re: Glitchy...
Reply #5 - Apr 20th, 2009, 1:26pm
 
Quote:
float angle, a, b, c, d, xco, yco, launchcompx, launchcompy, gravitycompx, gravitycompy, sumx, sumy;    // Declaring variables
boolean throwvar, start, started, bar;
PVector gravity, launch, sum;
String[] tex = new String[4];

void setup()
{
  background(255, 255, 255);    // Setting up backgroung, line width, and screen size
  strokeWeight(5);
  size(500, 500);
  throwvar = false;    // Initializing some important variables
  angle = 0;
}

void draw()
{
  background(255, 255, 255);    // Clearing the screen
  if(!throwvar)
  {
    angle = atan2(mouseY, mouseX)+(PI/2);
  }
  rect(50, 425, 400, 25);    // Power bar (outline part)
  fill(200, 255, 200);    // Making non-outline portion of power bar green
  rect(50, 425, 400*(d/10), 25);    // Power bar (non-outline part)
  noFill();    // Reversing color change
  rotate(angle);    // Rotating gun/aimer based on user-inputted angle
  line(0, 0, 0, -50);    // Making gun/aimer
  start = true;    // Telling the next "if" that the first frame has already occurred
  if(bar && d < 10)
  {
    d += 0.1;
  }
  if(start && !started) {    // If statement to rotate aimer to 45 degrees on the first frame
    angle += PI*0.75;    // Indirect rotation
    started = true;    // Making this if statement invalid for subsequent executions of draw
  }
  if(throwvar && xco < 500 && yco < 500) {    // If statement to launch pellet/bullet (also prevents pellet from going off screen)
    gravity = new PVector(a, PI);    // Initializing vectors
    launch = new PVector(d, angle);
    launchcompx = launch.x*cos(launch.y);
    launchcompy = launch.x*sin(launch.y);
    gravitycompx = gravity.x*cos(gravity.y);
    gravitycompy = gravity.x*sin(gravity.y);
    sumx = gravitycompx + launchcompx;
    sumy = gravitycompy + launchcompy;
    sum = new PVector(sqrt(sumx*sumx + sumy*sumy), atan(sumy/sumx));
    xco = sum.x*cos(sum.y);
    yco = sum.x*sin(sum.y);
    point(xco, yco);    // Drawing bullet
    tex[0] = str(xco);    // Debug stuff
    tex[1] = str(yco);
    tex[2] = str(mouseX);
    tex[3] = str(mouseY);
    println(join(tex, ", "));
    a += 0.98;    // Increasing velocity downwards (gravity is acceleration)
    if(d > 0) {    // Making bullet speed decay over time
      d -= 0.1;
    }
  }
  if(xco >= 500 && yco >= 500) {    // Resetting program when pellet hits the edge of screen
    a = 0;
    d = 0;
    throwvar = false;
  }
}

void mousePressed()    // Stuff to make aimer change angle when you pres arrow keys as well as firing machanism
{
  if(mouseButton == LEFT)
  {
    bar = true;
  }
}

void mouseReleased()    // Pretty self explanatory
{
  bar = false;
  if(mouseButton == LEFT) {
    throwvar = true;
  }
  else if(mouseButton == RIGHT) {
    throwvar = false;
  }
}




Here is updated code.
It works slightly better
Re: Glitchy...
Reply #6 - Apr 21st, 2009, 4:36am
 
the overall clunkiness and lack of responsiveness of the code i'd blame on the following debug code:

Code:

   tex[0] = str(xco);    // Debug stuff
   tex[1] = str(yco);
   tex[2] = str(mouseX);
   tex[3] = str(mouseY);
   println(join(tex, ", "));


printing out this stuff, especially in this way (what's up with println(xco + ", " + yco); ?), is slowing the code down quite a bit.

and this bit here:
Code:

   sum = new PVector(sqrt(sumx*sumx + sumy*sumy), atan(sumy/sumx));
   xco = sum.x*cos(sum.y);
   yco = sum.x*sin(sum.y);


seems to be "convert c2p, convert p2c". doesn't xco = sumx and yco = sumy? you don't appear to use sum again so why bother with it?

will try running the new code when i get home tonight.
Re: Glitchy...
Reply #7 - Apr 21st, 2009, 1:23pm
 
ok, something:

Code:

launch = new PVector(d, angle);
launchcompx = launch.x*cos(launch.y);
launchcompy = launch.x*sin(launch.y);


your "launch" value gets calculated every time when really only the initial value is important. it depends on d. but d is being decremented on every loop

Code:

if(d > 0) { // Making bullet speed decay over time
d -= 0.1;
}


so this isn't only changing the current speed but also changing the 'launch' speed, is having double the effect.

your code is very confusing 8) i know it's because of the way that draw() operates but i think it could be clearer - have a single state flag and a switch statement in the draw loop. (also, gravity appears to be going from right to left as opposed to the usual downwards...)
Re: Glitchy...
Reply #8 - Apr 21st, 2009, 1:54pm
 
I barely ever use switch(), so how would you do that "single state flag and a switch statement" thingy. I just wasn't very clear on what you were saying there.

Thank you very much for all the help.
Re: Glitchy...
Reply #9 - Apr 21st, 2009, 2:24pm
 
in your draw() you have various sections surrounded by conditions:

if(!throwvar)...
if(bar && d < 100)...
if(start && !started)...
if(throwvar && xco < 500 && yco < 500)...

but it's not obvious what gets run when and i just think it's clearer if you have a state flag and do something like:

PVector launch = null;
switch (state){
case AIMING:
 if (released()) {
   launch = new PVector(whatever);
   state = THROWN;
 }
 // bar stuff
 break;
case THROWN:
 move();
 if (hit_floor() || off_screen()) {
   state = FINISHED;
 }
 break;
case FINISHED:
...
}

etc. ie it's only ever in one state and only the code for that state gets runs on each draw loop. keeps it all separate.
Re: Glitchy...
Reply #10 - Apr 21st, 2009, 4:59pm
 
More updated code!
At least it displays the bullet correctly (ie: on the screen)
The power bar doesn't work anymore tho...

Quote:
float angle, a, b, c, d, xco, yco, launchcompx, launchcompy, gravitycompx, gravitycompy;    // Declaring variables
boolean throwvar, bar, launched;
PVector gravity, launch;
int state = 1;

void setup()
{
  background(255, 255, 255);    // Setting up background, line width, and screen size
  strokeWeight(5);
  size(500, 500);
  throwvar = false;    // Initializing some important variables
  angle = 0;
}

void draw()
{
  background(255, 255, 255);    // Clearing the screen
  if(launched)
  {
    c = d;
    launch = new PVector(c, angle);
    launched = false;
  }
  rect(50, 425, 400, 25);    // Power bar (outline part)
  rotate(angle);    // Rotating gun/aimer based on user-inputted angle
  line(0, 0, 0, -50);    // Making gun/aimer
  switch(state)
  {
  case 1:
    if(!throwvar)
    {
      angle = atan2(mouseY, mouseX)+(PI/2);
      b = d;
      fill(200, 255, 200);
      rect(50, 425, 400*(d/10), 25);
      noFill();
    } else {
      gravity = new PVector(a, PI+PI/2);
      launchcompx = launch.x*cos(launch.y);
      launchcompy = launch.x*sin(launch.y);
      gravitycompx = gravity.x*cos(gravity.y);
      gravitycompy = gravity.x*sin(gravity.y);
      xco = gravitycompx + launchcompx;
      yco = gravitycompy + launchcompy;
      point(xco, yco);    // Drawing bullet
      a += 0.98;
      if(launch.x > 0)
      {
        launch.x -= 0.001;
      }
    }
    state = 2;
    break;
  case 2:
    if(bar && d < 10)
    {
      d += 0.1;
    }
    state = 1;
    break;
  }
}

void mousePressed()    // Stuff to make aimer change angle
  if(mouseButton == LEFT && !throwvar)
  {
    bar = true;
  }
}

void mouseReleased()    // Pretty self explanatory
{
  bar = false;
  if(mouseButton == LEFT) {
    throwvar = true;
    launched = true;
  }
  else if(mouseButton == RIGHT) {
    throwvar = false;
    launched = false;
    launch = null;
    gravity = null;
    a = 0;
    b = 0;
    c = 0;
    d = 0;
    angle = 0;
    launchcompx = 0;
    launchcompy = 0;
    gravitycompx = 0;
    gravitycompy = 0;
    xco = 0;
    yco = 0;
    state = 1;
  }
}




Re: Glitchy...
Reply #11 - Apr 24th, 2009, 7:33am
 
Hmm....
My newest code works, but I don't think it accurately simulates a trajectory. I figured this out by commenting out "background(255, 255, 255);" and shooting the bullet at minimum power bar setting and at maximum. There was no difference between the two trajectories.

Why is this?
Re: Glitchy...
Reply #12 - Apr 24th, 2009, 9:44am
 
print out the value of c after this line.

launch = new PVector(c, angle);

they should be different in both cases.

if they are then print out

launchcompx and launchcompy
Page Index Toggle Pages: 1