原书内容运行后无法显示坦克,可能作者并没有实际运行其代码,原代码如下:
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);
}