Processing与Arduino互动编程 10. 4 摇杆控制坦克移动错误纠正
原书内容运行后无法显示坦克,可能作者并没有实际运行其代码,原代码如下:
import processing.serial.*;
Serial myPort;
public static final char HEADER = 'M'; //数据 帧 头( 起始 位)
public static final short LF = 10; //数据 帧 尾( 结束 位)
public static final short portIndex = 2;
public static final short centerX= 527; //摇杆 静止 时 X 轴 的 中点 值( 由于 不同 摇杆 的 中点 值 不同, 建议 读者 自行 测试 出 静止 的 中点 值, 并修 改)
public static final short centerY= 507; //摇杆 静止 时 Y 轴 的 中点 值
int x= 300, y= 200; //坦克 起始 位置
int speed= 3; // 坦克 移动 的 速度, 读者 可自 行 修改
char Direction; // 方向 判断
class Tank
{
Tank() { }
void DisplayTank( int px, int py, char direction)
{ background(204); switch(direction) { case 'F': //前行 fill( 255, 255, 0);rect( px-10, py, 20, 40); rect( px+30, py, 20, 40); ellipse( px+ 20, py+ 20, 20, 25);rect( px+17, py-10, 6, 19); break; case 'B': // 后退 fill( 255, 255, 0);rect( px-10, py, 20, 40);rect( px+30, py, 20, 40); ellipse( px+20, py+20, 20, 25); rect( px+ 17, py+ 30, 6, 19); break;
case 'L': //往左 行驶
fill( 255, 255, 0);
rect( px, py-10, 40, 20);
rect( px, py+30, 40, 20);
ellipse( px+20, py+ 20, 25, 20);
rect( px-10, py+17, 19, 6);
break;
case 'R': //往右 行驶
fill( 255, 255, 0);
rect( px, py-10, 40, 20);
rect( px, py+30, 40, 20);
ellipse( px+20, py+20, 25, 20);
rect( px+30, py+17, 19, 6);
break;
default:
break;
}
}
void boundary( int px, int py){ if (px< 10) x= 10; if (py< 10) y= 10;
if (px>( width- 50)) x= width- 50;
if (py>( height- 50)) y= height- 50;
}
char tankDirection( int px, int py) //判断 坦克 移动 的 方向
{ if ((px<(centerX-30))&&(abs( px- centerX)> abs(py- centerY))) Direction='L'; //往左 移动
if ((px>( centerX+ 30))&&( abs( px- centerX)> abs( py- centerY))) Direction='R'; //往右 移动
if ((py<( centerY- 30))&&( abs( px- centerX)< abs( py- centerY))) Direction='F'; //往前 移动
if ((py>( centerY+ 30))&&( abs( px- centerX)< abs( py- centerY))) Direction='B'; //往后 移动
if(( px>=( centerX- 30))&&( px<=( centerX+ 30))&&( py>=( centerY- 30))&&( py<= (centerY+ 30))) Direction='S'; //停止
return Direction; //返回 方向
}
}
Tank tank;
void setup()
{size( 640, 480);
tank= new Tank();
tank.DisplayTank(x,y,'F');
myPort= new Serial(this,"COM13",9600);
myPort.clear();
}
void draw() {
}
void serialEvent(Serial myPort)
{ String message = myPort. readStringUntil( LF); //返回 一个 字符串 缓冲区, 并 包括 一个 特殊 字符 char direction; if (message != null) { print( message); String []data = message. split(","); //返回 带有 特殊 字符 的 字符串 println( data[1]); println( data[2]); if (data[0]. charAt(0) == HEADER) //读取 到 帧 头{ if (data.length > 2) { int tempX = Integer.parseInt(data[1]); //把 整型 对象 转换 成 基本 数据 类型 int int tempY = Integer.parseInt(data[2]); print("x = "+tempX ); print(", y = "+tempY ); direction= tank.tankDirection(tempX,tempY);//print(direction);switch(direction) { case 'F': y= y- speed; tank.boundary(x,y);tank.DisplayTank(x,y,'F');break; case 'B':y= y+speed;
tank.boundary(x,y); tank.DisplayTank(x,y,'B');break; case 'L':x= x- speed; tank.boundary(x,y); tank.DisplayTank(x,y,'L');break; case 'R': x= x+speed;tank.boundary(x,y); tank.DisplayTank(x,y,'R');break; case 'S': break;default: break; }}}}}
修改后的内容如下:
- 为了能够画出坦克,在draw()函数内加如下语句:
void draw() {tank.DisplayTank(x,y,Direction);
}
2.为了能够使坦克在停止时不会消失,在串口函数中的 case’s’后加如下语句:
case 'S': tank.boundary(x,y); tank.DisplayTank(x,y,'S');break;
3.为了能够使坦克在停止时不会消失,还要在Tank类定义内 case’s’后加如下语句:
case 'S': fill( 255, 255, 0);rect( px-10, py, 20, 40); rect( px+30, py, 20, 40); ellipse( px+ 20, py+ 20, 20, 25);rect( px+17, py-10, 6, 19);
default:
这样修改后,坦克停止后不会消失,且炮管向上。
本打算使坦克停止后炮管与运动方向一致,学艺不精,没想到方法。
下面是改正后的完整代码
import processing.serial.*;
Serial myPort;
public static final char HEADER = 'M'; //数据 帧 头( 起始 位)
public static final short LF = 10; //数据 帧 尾( 结束 位)
public static final short portIndex = 2;
public static final short centerX= 527; //摇杆 静止 时 X 轴 的 中点 值( 由于 不同 摇杆 的 中点 值 不同, 建议 读者 自行 测试 出 静止 的 中点 值, 并修 改)
public static final short centerY= 507; //摇杆 静止 时 Y 轴 的 中点 值
int x= 300, y= 200; //坦克 起始 位置
int speed= 3; // 坦克 移动 的 速度, 读者 可自 行 修改
char Direction; // 方向 判断
class Tank
{
Tank() { }
void DisplayTank( int px, int py, char direction)
{ background(204); switch(direction) { case 'F': //前行 fill( 255, 255, 0);rect( px-10, py, 20, 40); rect( px+30, py, 20, 40); ellipse( px+ 20, py+ 20, 20, 25);rect( px+17, py-10, 6, 19); break; case 'B': // 后退 fill( 255, 255, 0);rect( px-10, py, 20, 40);rect( px+30, py, 20, 40); ellipse( px+20, py+20, 20, 25); rect( px+ 17, py+ 30, 6, 19); break;
case 'L': //往左 行驶
fill( 255, 255, 0);
rect( px, py-10, 40, 20);
rect( px, py+30, 40, 20);
ellipse( px+20, py+ 20, 25, 20);
rect( px-10, py+17, 19, 6);
break;
case 'R': //往右 行驶
fill( 255, 255, 0);
rect( px, py-10, 40, 20);
rect( px, py+30, 40, 20);
ellipse( px+20, py+20, 25, 20);
rect( px+30, py+17, 19, 6);
break;
case 'S': fill( 255, 255, 0);rect( px-10, py, 20, 40); rect( px+30, py, 20, 40); ellipse( px+ 20, py+ 20, 20, 25);rect( px+17, py-10, 6, 19);
default:
break;
}
}
void boundary( int px, int py){ if (px< 10) x= 10; if (py< 10) y= 10;
if (px>( width- 50)) x= width- 50;
if (py>( height- 50)) y= height- 50;
}
char tankDirection( int px, int py) //判断 坦克 移动 的 方向
{ if ((px<(centerX-30))&&(abs( px- centerX)> abs(py- centerY))) Direction='L'; //往左 移动
if ((px>( centerX+ 30))&&( abs( px- centerX)> abs( py- centerY))) Direction='R'; //往右 移动
if ((py<( centerY- 30))&&( abs( px- centerX)< abs( py- centerY))) Direction='F'; //往前 移动
if ((py>( centerY+ 30))&&( abs( px- centerX)< abs( py- centerY))) Direction='B'; //往后 移动
if(( px>=( centerX- 30))&&( px<=( centerX+ 30))&&( py>=( centerY- 30))&&( py<= (centerY+ 30))) Direction='S'; //停止
return Direction; //返回 方向
}
}
Tank tank;
void setup()
{size( 640, 480);
tank= new Tank();
tank.DisplayTank(x,y,'F');
myPort= new Serial(this,"COM13",9600);
myPort.clear();
}
void draw() {tank.DisplayTank(x,y,Direction);
}
void serialEvent(Serial myPort)
{ String message = myPort. readStringUntil( LF); //返回 一个 字符串 缓冲区, 并 包括 一个 特殊 字符 char direction; if (message != null) { print( message); String []data = message. split(","); //返回 带有 特殊 字符 的 字符串 println( data[1]); println( data[2]); if (data[0]. charAt(0) == HEADER) //读取 到 帧 头{ if (data.length > 2) { int tempX = Integer.parseInt(data[1]); //把 整型 对象 转换 成 基本 数据 类型 int int tempY = Integer.parseInt(data[2]); print("x = "+tempX ); print(", y = "+tempY ); direction= tank.tankDirection(tempX,tempY);//print(direction);switch(direction) { case 'F': y= y- speed; tank.boundary(x,y);tank.DisplayTank(x,y,'F');break; case 'B':y= y+speed;
tank.boundary(x,y); tank.DisplayTank(x,y,'B');break; case 'L':x= x- speed; tank.boundary(x,y); tank.DisplayTank(x,y,'L');break; case 'R': x= x+speed;tank.boundary(x,y); tank.DisplayTank(x,y,'R');break; case 'S': tank.boundary(x,y); tank.DisplayTank(x,y,'S');break;default: break; }}}}}
Arduino部分就不用修改了,按原书内容即可,代码如下:
int potXPin =A0;
int potYPin =A1;
char HEADER ='M'; void setup()
{Serial.begin(9600);
}void loop()
{int x =analogRead(potXPin); //读取摇杆X轴数据int y =analogRead(potYPin); //读取摇杆Y轴数据Serial.print(HEADER); //输出数据帧头Serial.print(","); //逗号分隔符Serial.print(x,DEC); //X轴数据Serial.print(","); //逗号分隔符Serial.print(y,DEC); //Y轴数据Serial.print(","); //逗号分隔符Serial.println(); //输出换行符作为帧尾delay(50);
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
