Tank movement seen from above

Hello,
Im new to processing and coding in general. Im trying to code a “tank” move around (seen from above). I want to have a tank rotate left when pressing keyboard “A” and right when pressing “D”. And I want it to drive forwards and backwards when pressing “W” and “S”.

I have a hard time finding any code from somebody else who have done the same thing. Its really annoying because it feels like it would be a really simple thing but I admit I really need some help. I have tried multiple things using vectors, trigonometry and 2D transformation.

I should also probably mention that my intention is to have a “tank-like” robot send its driving distance to processing via serial. And plot that information in that top view so that I can kind of see a navigation map of the robot.

I would really appriciate some help.

Here is the code that I have now. (Dont mind the created lines, its just so that I can see where the translate function is atm)

``````float x,y;
float angle;

void setup() {
size(600, 600);
x = 0;
y = 0;
angle = 0;
noFill();
stroke(0);
strokeWeight(1);
}

void draw() {
background(255);
translate(width/2,height/2);
line(0,0,0,-20);
line(-10,0,10,0);

//pushMatrix();

//popMatrix();

translate(x,y);

line(0,0,0,-20);
line(-10,0,10,0);

translate(x,y);
line(0,0,0,-20);
line(-10,0,10,0);

point(0,0);
rectMode(CENTER);
rect(0,0, 20, 40);

update();

}

void update() {
if(keyPressed) {
print(angle + "    ");
println(key);
if(key == 'w' || key =='W') {
y = y - 1;
}
if(key == 'a' || key =='A') {
angle = angle - 1;
}
}
}
``````

A question that describes the problem? Posted code that is formatted properly? Shown effort?

Amazing! You win a solution:

``````float x, y;
float angle;

void setup() {
size(600, 600);
x = width/2;
y = height/2;
angle = 0;
noFill();
stroke(0);
strokeWeight(1);
rectMode(CENTER);
}

void draw() {
background(255);
update();
translate(x,y);
rotate(angle);
line(0, 0, 0, -20);
line(-10, 0, 10, 0);
rect(0, 0, 20, 40);
}

void update() {
if (keyPressed) {
if (key == 'w' || key =='W') {
x+=4*cos(angle-HALF_PI);
y+=4*sin(angle-HALF_PI);
}
if (key == 's' || key =='S') {
x-=4*cos(angle-HALF_PI);
y-=4*sin(angle-HALF_PI);
}
if (key == 'a' || key =='A') {
}
if (key == 'd' || key =='D') {
}
}
}
``````

You could also create a `Tank` object if you are familiar with object-oriented programming :

``````class Tank{
float x,y,angle;

Tank(float xx,float yy,float a){
x = xx;
y = yy;
angle = a;
}

void update(){
if (key == 'w' || key =='W') {
x+=4*cos(angle-HALF_PI);
y+=4*sin(angle-HALF_PI);
}
if (key == 's' || key =='S') {
x-=4*cos(angle-HALF_PI);
y-=4*sin(angle-HALF_PI);
}
if (key == 'a' || key =='A') {
}
if (key == 'd' || key =='D') {
}
}

void display(){
translate(x,y);
rotate(angle);
line(0, 0, 0, -20);
line(-10, 0, 10, 0);
rect(0, 0, 20, 40);
}
}
``````

Thank you, that was perfect, I really needed the help. Now I understand quite a bit more as well. Thanks to both of you, I will take a further look at object-oriented programming in the near future.

Actually, do you think you can give me a brief description of what is happening in this piece of code?

``````    if (key == 'w' || key =='W') {
x+=4*cos(angle-HALF_PI);
y+=4*sin(angle-HALF_PI);
}
``````

I understand that it is the same as this, but I don’t understand quite what it does. For example where does the “4” come from? Thank you.

``````      x = x + 4*cos(angle-HALF_PI)
y = y + 4*sin(angle-HALF_PI)
``````

Ah ha, this is where it gets fun! Try out some variations of it to see what you get for example, try the following:

``````   x = x + 24*cos(angle-HALF_PI);
y = y + 24*sin(angle-HALF_PI);
``````

FAST TANK!

``````   x = x + 4*cos(angle);
y = y + 4*sin(angle);
``````

JANKY DIRECTION TANK!

If you have some trigonometry under your belt (and you should, if not, go get gud at learnin’ da maths), you’ll know that if you have a vector of length L that makes an angle of A with horizontal, then the vertical and horizontal components of that vector are `L * cos(A)` and `L * sin(A)`, respectively. That should look familiar…

A drivable car. Not exactly a tank. But I guess it might help:
`http://Studio.ProcessingTogether.com/sp/pad/export/ro.9Nl\$898UQxW3Q`

Aaah, now I see!

The “4” is just a speed multiplier. If you can believe it I actually do have trigonometry experience, but for me finding angles and length on paper is a whole other world than to implement it into code. Thank you again for your help, I really appreciate it.

Hold on a second, this is interesting. Processing is based on Java and Java is an object oriented language, but when I try to add your Tank and instantiate it, it says something about nested and cant hide an enclosing type? What is that problem?

Hold on another second, I found the solution. I “hacked” at it until it worked.

``````float x, y;
float angle;
tank Tank;
void setup() {
size(600, 600);
//  Tank  = new tank();
x = width/2;
y = height/2;
angle = 0;
Tank  = new tank(x,y,angle);
noFill();
stroke(0);
strokeWeight(1);
rectMode(CENTER);
}

void draw() {
background(255);

Tank.display();
Tank.update();

}
class tank{
float x,y,angle;

tank(float xx,float yy,float a){
x = xx;
y = yy;
angle = a;
}
void update(){
if (keyPressed) {
if (key == 'w' || key =='W') {
x+=4*cos(angle-HALF_PI);
y+=4*sin(angle-HALF_PI);
}
if (key == 's' || key =='S') {
x-=4*cos(angle-HALF_PI);
y-=4*sin(angle-HALF_PI);
}
if (key == 'a' || key =='A') {
}
if (key == 'd' || key =='D') {
}
}
}

void display(){
translate(x,y);
rotate(angle);
line(0, 0, 0, -20);
line(-10, 0, 10, 0);
rect(0, 0, 20, 40);
}
}
``````

Without class

``````float x, y;
float angle;
boolean w, a, s, d;

void setup() {
size(600, 600);
x = width/2;
y = height/2;
angle = 0;
noFill();
stroke(0);
strokeWeight(1);
rectMode(CENTER);
}

void draw() {
background(255);
update();
translate(x, y);
rotate(angle);
line(0, 0, 0, -20);
line(-10, 0, 10, 0);
rect(0, 0, 20, 40);
}

void update() {
if (w) {
x+=4*cos(angle-HALF_PI);
y+=4*sin(angle-HALF_PI);
}
if (s) {
x-=4*cos(angle-HALF_PI);
y-=4*sin(angle-HALF_PI);
}
if (a) {
}
if (d) {
}
}

void keyPressed() {
if (key == 'w' || key =='W') {
w=true;
}
if (key == 's' || key =='S') {
s=true;
}
if (key == 'a' || key =='A') {
a=true;
}
if (key == 'd' || key =='D') {
d=true;
}
}

void keyReleased() {
if (key == 'w' || key =='W') {
w=false;
}
if (key == 's' || key =='S') {
s=false;
}
if (key == 'a' || key =='A') {
a=false;
}
if (key == 'd' || key =='D') {
d=false;
}
}

``````

With class

``````Tank tank;

void setup() {
size(600, 600);
tank = new Tank(width/2, height/2, 0);
noFill();
stroke(0);
strokeWeight(1);
rectMode(CENTER);
}

void draw() {
background(255);
tank.update();
tank.display();
}

class Tank {
float x, y, angle;
boolean w, a, s, d;
//
Tank(int x, int y, int angle) {
this.x=x;
this.y=y;
this.angle=angle;
}
//
void update() {
if (w) {
x+=4*cos(angle-HALF_PI);
y+=4*sin(angle-HALF_PI);
}
if (s) {
x-=4*cos(angle-HALF_PI);
y-=4*sin(angle-HALF_PI);
}
if (a) {
}
if (d) {
}
}
//
void display() {
translate(x, y);
rotate(angle);
line(0, 0, 0, -20);
line(-10, 0, 10, 0);
rect(0, 0, 20, 40);
}
}

void keyPressed() {
if (key == 'w' || key =='W') {
tank.w=true;
}
if (key == 's' || key =='S') {
tank.s=true;
}
if (key == 'a' || key =='A') {
tank.a=true;
}
if (key == 'd' || key =='D') {
tank.d=true;
}
}

void keyReleased() {
if (key == 'w' || key =='W') {
tank.w=false;
}
if (key == 's' || key =='S') {
tank.s=false;
}
if (key == 'a' || key =='A') {
tank.a=false;
}
if (key == 'd' || key =='D') {
tank.d=false;
}
}

``````
1 Like

That is very interesting, I hacked at it and you applied concepts of object oriented programming. I know which is more powerful in the long run.