复古像素游戏《雷电》前传(红外遥控&16*16 LED点阵)

我看论坛上基本没有教1616LED点阵模块的....



这是之前为我们课程的作业写的,现在贴出来与大家分享~



因为这学期才开始接触Arduino和汇编语言,编的不能保证简练..

而且有不完善的地方,但我们作业的时间有限,实现功能就行了~

现在还在苦逼苦逼的做最终的大作业.....



有兴趣的童鞋可以下下来自己玩一玩~~

红外遥控器4,6控制飞机左右,2发射炮弹,0是reset

哭泣的表情需要摁reset来继续



视频地址:

http://v.youku.com/v_show/id_XNTM1NzcxNTgw.html





ARDUINO 代码复制打印

#include <IRremote.h>// 使用IRRemote函数库#define RowA 3 //行信号,驱动138#define RowB 4#define RowC 5#define RowD 6int hc138en=7; //138 使能//使用了硬件SPI,以下脚不能更改#define R1 11 //数据出 MOSI#define CLK 13 //时钟 SCK#define STB 10 //刷新显示 SS#define DATAIN 12 //数据入,读FLASH时有用 MISObyte dots[] ={//子弹0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01};byte plane2[] ={//飞机0xE0,0x00,0x40,0x00,0x70,0x00,0x20,0x00,0x38,0x00,0x10,0x00,0x1C,0x00,0x08,0x00,0x0E,0x00,0x04,0x00,0x07,0x00,0x02,0x00,0x03,0x80,0x01,0x00,0x01,0xC0,0x00,0x80,0x00,0xE0,0x00,0x40,0x00,0x70,0x00,0x20,0x00,0x38,0x00,0x10,0x00,0x1C,0x00,0x08,0x00,0x0E,0x00,0x04,0x00,0x07,0x00,0x02};byte cry[]={ //哭泣表情0x00,0x00,0x00,0x00,0xFC,0x3F,0xFC,0x3F,0x21,0x84,0x21,0x84,0x23,0xC4,0x26,0x64,0x24,0x24,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x00,0x00,0x00,0x00};//红外const int irReceiverPin = 2;// 红外接收器的 OUTPUT 引脚接在 PIN2 接口 定义irReceiverPin变量为PIN2接口IRrecv irrecv(irReceiverPin); // 设置irReceiverPin定义的端口为红外信号接收端口decode_results results;  // 定义results变量为红外结果存放位置long IRright=0x00FF5AA5;  //right 6long IRleft= 0x00FF10EF; //left 4long IRfire= 0x00FF18E7;   //fire 2long IRreset=0x00FF6897;  //reset 0void spi_transfer(volatile char data){SPDR = data; // Start the transmissionwhile (!(SPSR & (1<<SPIF))) // Wait the end of the transmission  //SPSR:程序状态保存寄存器{  ;}}//输出行void hc138sacn(byte r){ digitalWrite(RowA,!(r & 0x01));digitalWrite(RowB,!(r & 0x02));digitalWrite(RowC,!(r & 0x04));digitalWrite(RowD,!(r & 0x08));}void setup () {pinMode(RowA, OUTPUT);pinMode(RowB, OUTPUT);pinMode(RowC, OUTPUT);pinMode(RowD, OUTPUT); //138片选pinMode(hc138en, OUTPUT); //138 使能pinMode(R1, OUTPUT);//DIpinMode(CLK, OUTPUT); //时钟pinMode(STB, OUTPUT); //Latch锁存pinMode(DATAIN, INPUT); //无用,但SPI必须写Serial.begin(19200);//SPI硬件设置//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,//sample on leading edge of clk,system clock/4 rate (fastest)SPCR = (1<<SPE)|(1<<MSTR);delay(10);irrecv.enableIRIn(); // 启动红外解码}byte row;int count;//子弹部分byte rowb[6];//子弹所在行数int time[6];//计时int post[6];//position(column)int number;//计数int temp;//交换用//洞穴部分int timec; //计时int numberc;//计数byte cave[34]={ //洞穴初始化数据0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xFC,0x3F,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07};int fail=1;  void loop () {if(fail==1){  //哭泣表情  for(int i=15;i>=0;i--)  {  spi_transfer(~(cry[i2]));  spi_transfer(~(cry[i2+1]));  digitalWrite(hc138en, 1); //关闭显示  hc138sacn(15-i); //换行  digitalWrite(STB, 0); //595刷新  digitalWrite(STB, 1);  delayMicroseconds(500) ; //节电用,  digitalWrite(hc138en, 0); //开启显示  delayMicroseconds(500) ; //刷新频率调  }  if (irrecv.decode(&results)) { // 解码成功,把数据放入results变量中  // 把数据输入到串口  if (results.value ==IRreset ) //reset  {   fail=0;  //飞机部分  count=8;  //子弹部分  byte rowb[6]={    2,2,2,2,2,2  };//子弹所在行数  int time[6]={    0,0,0,0,0,0  };//计时  int post[6]={    0,0,0,0,0,0  };//position(column)  number=0;//计数  temp=0;//交换用  //洞穴部分  timec=0; //计时  numberc=0;//计数  byte cave[34]={ //洞穴初始化数据    0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,    0xE0,0x07,0xFC,0x3F,0xE0,0x07,0xE0,0x07,    0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,    0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07  };  }  irrecv.resume();  // 继续等待接收下一组信号  }}else{  int fire=0;  if (irrecv.decode(&results))  {     // 解碼成功,收到一組紅外線訊號  if (results.value ==IRright ) //right  {    count=count-1;     }  else if (results.value ==IRleft ) //left  {    count=count+1;     }  if (results.value ==IRfire ) //fire  {    fire=1;      }  if(count>14)  count=14;  if(count<1)  count=1;  irrecv.resume();  // 继续等待接收下一组信号  }  //飞机部分   for(row=1;row<3;row++)  {  if(row==1)   {  spi_transfer(~(plane2[count4-4]));   spi_transfer(~(plane2[count4-3]));   }  if(row==2)  {  spi_transfer(~(plane2[count4-2]));   spi_transfer(~(plane2[count4-1]));  }       digitalWrite(hc138en, 1); //关闭显示  hc138sacn(row); //换行  digitalWrite(STB, 0); //595刷新  digitalWrite(STB, 1);  delayMicroseconds(350) ; //节电用,  digitalWrite(hc138en, 0); //开启显示  delayMicroseconds(350) ; //  }  //多发炮弹部分  if(fire==1)  {  number=temp;  rowb[number]=3;  post[number]=count;  temp=number+1;  if(temp==6)  temp=0;  }  for(int i=0;i<=5;i++)  {  if(rowb[i]>=3)  {  spi_transfer(~(dots[post[i]2]));   spi_transfer(~(dots[post[i]2+1]));  time[i]++;  digitalWrite(hc138en, 1); //关闭显示  hc138sacn(rowb[i]); //换行  digitalWrite(STB, 0); //595刷新  digitalWrite(STB, 1);  delayMicroseconds(250) ; //节电用,  digitalWrite(hc138en, 0); //开启显示  delayMicroseconds(250) ; //刷新频率调,差不多120HZ,1/32间隔  if(time[i]==30)  {    rowb[i]=rowb[i]+1;    time[i]=0;  }  if(rowb[i]>15)    rowb[i]=2;  }  }  //洞穴部分  for(int i=0;i<=15;i++)  {  spi_transfer(~(cave[i2]));  spi_transfer(~(cave[i2+1]));  digitalWrite(hc138en, 1); //关闭显示  hc138sacn(i); //换行  digitalWrite(STB, 0); //595刷新  digitalWrite(STB, 1);  delayMicroseconds(100) ; //节电用,  digitalWrite(hc138en, 0); //开启显示  delayMicroseconds(100) ; //刷新频率调  if(i==0) {  timec=(timec+1)%100;  if(numberc<200){    cave[32]=(random(0,3)<<random(0,5)|0x80);    cave[33]=(random(0,3)<<random(1,6)|0x01);  }  else if(numberc<500){    cave[32]=(random(0,4)<<random(0,5)|0x80);    cave[33]=(random(0,4)<<random(1,6)|0x01);  }   else if(numberc<=900){    cave[32]=(random(0,8)<<random(0,4)|0x80);    cave[33]=(random(0,8)<<random(1,5)|0x01);  }   else{    numberc=900;    cave[32]=(random(0,8)<<random(0,4)|0x80);    cave[33]=(random(0,8)<<random(1,5)|0x01);  }      }  if(timec==0)  {   cave[i2]=cave[i2+2];  cave[i2+1]=cave[i2+3];  numberc++;  }  }  for(int j=0;j<=15;j++)  {  for(int k=0;k<=5;k++)  {  if(rowb[k]==j)  {    //用于判断子弹打下哪个B是子弹,C是目标 B^C 异或     if((dots[post[k]2]&cave[j2])||(dots[post[k]2+1]&cave[j2+1]))    {    cave[j2]=dots[post[k]2]^cave[j2];    cave[j2+1]=dots[post[k]2+1]^cave[j2+1];    rowb[k]=2;    }  }   }  //判断飞机是否接触洞穴   if(j==1)  if((plane2[count4-4]&cave[j2])||(plane2[count4-3]&cave[j2+1]))    fail=1;  if(j==2)  if((plane2[count4-2]&cave[j2])||(plane2[count4-1]&cave[j2+1]))     fail=1;  }}}
#include <IRremote.h>// 使用IRRemote函数库



#define RowA 3 //行信号,驱动138

#define RowB 4

#define RowC 5

#define RowD 6

int hc138en=7; //138 使能

//使用了硬件SPI,以下脚不能更改

#define R1 11 //数据出 MOSI

#define CLK 13 //时钟 SCK

#define STB 10 //刷新显示 SS

#define DATAIN 12 //数据入,读FLASH时有用 MISO



byte dots[] ={//子弹

0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,

0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,

0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x10,

0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01

};

byte plane2[] ={//飞机

0xE0,0x00,0x40,0x00,

0x70,0x00,0x20,0x00,

0x38,0x00,0x10,0x00,

0x1C,0x00,0x08,0x00,

0x0E,0x00,0x04,0x00,

0x07,0x00,0x02,0x00,

0x03,0x80,0x01,0x00,

0x01,0xC0,0x00,0x80,

0x00,0xE0,0x00,0x40,

0x00,0x70,0x00,0x20,

0x00,0x38,0x00,0x10,

0x00,0x1C,0x00,0x08,

0x00,0x0E,0x00,0x04,

0x00,0x07,0x00,0x02

};



byte cry[]={ //哭泣表情

0x00,0x00,0x00,0x00,0xFC,0x3F,0xFC,0x3F,

0x21,0x84,0x21,0x84,0x23,0xC4,0x26,0x64,

0x24,0x24,0x20,0x04,0x20,0x04,0x20,0x04,

0x20,0x04,0x20,0x04,0x00,0x00,0x00,0x00};







//红外

const int irReceiverPin = 2;// 红外接收器的 OUTPUT 引脚接在 PIN2 接口 定义irReceiverPin变量为PIN2接口

IRrecv irrecv(irReceiverPin); // 设置irReceiverPin定义的端口为红外信号接收端口

decode_results results; // 定义results变量为红外结果存放位置



long IRright=0x00FF5AA5; //right 6

long IRleft= 0x00FF10EF; //left 4

long IRfire= 0x00FF18E7; //fire 2

long IRreset=0x00FF6897; //reset 0



void spi_transfer(volatile char data)

{

SPDR = data; // Start the transmission

while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission

//SPSR:程序状态保存寄存器

{

;

}

}



//输出行

void hc138sacn(byte r){

digitalWrite(RowA,!(r & 0x01));

digitalWrite(RowB,!(r & 0x02));

digitalWrite(RowC,!(r & 0x04));

digitalWrite(RowD,!(r & 0x08));

}



void setup () {

pinMode(RowA, OUTPUT);

pinMode(RowB, OUTPUT);

pinMode(RowC, OUTPUT);

pinMode(RowD, OUTPUT); //138片选

pinMode(hc138en, OUTPUT); //138 使能

pinMode(R1, OUTPUT);//DI

pinMode(CLK, OUTPUT); //时钟

pinMode(STB, OUTPUT); //Latch锁存

pinMode(DATAIN, INPUT); //无用,但SPI必须写

Serial.begin(19200);

//SPI硬件设置

//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,

//sample on leading edge of clk,system clock/4 rate (fastest)

SPCR = (1<<SPE)|(1<<MSTR);

delay(10);



irrecv.enableIRIn(); // 启动红外解码

}



byte row;

int count;

//子弹部分

byte rowb[6];//子弹所在行数

int time[6];//计时

int post[6];//position(column)

int number;//计数

int temp;//交换用

//洞穴部分

int timec; //计时

int numberc;//计数

byte cave[34]={ //洞穴初始化数据

0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,

0xE0,0x07,0xFC,0x3F,0xE0,0x07,0xE0,0x07,

0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,

0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07};



int fail=1;

void loop () {

if(fail==1)

{ //哭泣表情

for(int i=15;i>=0;i--)

{

spi_transfer(~(cry[i
2]));

spi_transfer(~(cry[i2+1]));



digitalWrite(hc138en, 1); //关闭显示

hc138sacn(15-i); //换行

digitalWrite(STB, 0); //595刷新

digitalWrite(STB, 1);

delayMicroseconds(500) ; //节电用,

digitalWrite(hc138en, 0); //开启显示

delayMicroseconds(500) ; //刷新频率调

}

if (irrecv.decode(&results)) { // 解码成功,把数据放入results变量中

// 把数据输入到串口

if (results.value ==IRreset ) //reset

{

fail=0;

//飞机部分

count=8;

//子弹部分

byte rowb[6]={

2,2,2,2,2,2 };//子弹所在行数

int time[6]={

0,0,0,0,0,0 };//计时

int post[6]={

0,0,0,0,0,0 };//position(column)

number=0;//计数

temp=0;//交换用

//洞穴部分

timec=0; //计时

numberc=0;//计数

byte cave[34]={ //洞穴初始化数据

0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,

0xE0,0x07,0xFC,0x3F,0xE0,0x07,0xE0,0x07,

0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,

0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07 };



}

irrecv.resume(); // 继续等待接收下一组信号

}

}

else

{

int fire=0;

if (irrecv.decode(&results))

{

// 解碼成功,收到一組紅外線訊號

if (results.value ==IRright ) //right

{

count=count-1;

}

else if (results.value ==IRleft ) //left

{

count=count+1;

}

if (results.value ==IRfire ) //fire

{

fire=1;

}



if(count>14)

count=14;

if(count<1)

count=1;

irrecv.resume(); // 继续等待接收下一组信号

}

//飞机部分

for(row=1;row<3;row++)

{

if(row==1)

{

spi_transfer(~(plane2[count
4-4]));

spi_transfer(~(plane2[count4-3]));

}

if(row==2)

{

spi_transfer(~(plane2[count
4-2]));

spi_transfer(~(plane2[count4-1]));

}



digitalWrite(hc138en, 1); //关闭显示

hc138sacn(row); //换行

digitalWrite(STB, 0); //595刷新

digitalWrite(STB, 1);

delayMicroseconds(350) ; //节电用,

digitalWrite(hc138en, 0); //开启显示

delayMicroseconds(350) ; //

}



//多发炮弹部分

if(fire==1)

{

number=temp;

rowb[number]=3;

post[number]=count;

temp=number+1;

if(temp==6)

temp=0;

}

for(int i=0;i<=5;i++)

{

if(rowb[i]>=3)

{

spi_transfer(~(dots[post[i]
2]));

spi_transfer(~(dots[post[i]2+1]));

time[i]++;

digitalWrite(hc138en, 1); //关闭显示

hc138sacn(rowb[i]); //换行

digitalWrite(STB, 0); //595刷新

digitalWrite(STB, 1);

delayMicroseconds(250) ; //节电用,

digitalWrite(hc138en, 0); //开启显示

delayMicroseconds(250) ; //刷新频率调,差不多120HZ,1/32间隔



if(time[i]==30)

{

rowb[i]=rowb[i]+1;

time[i]=0;

}

if(rowb[i]>15)

rowb[i]=2;

}

}



//洞穴部分



for(int i=0;i<=15;i++)

{

spi_transfer(~(cave[i
2]));

spi_transfer(~(cave[i2+1]));



digitalWrite(hc138en, 1); //关闭显示

hc138sacn(i); //换行

digitalWrite(STB, 0); //595刷新

digitalWrite(STB, 1);

delayMicroseconds(100) ; //节电用,

digitalWrite(hc138en, 0); //开启显示

delayMicroseconds(100) ; //刷新频率调



if(i==0) {

timec=(timec+1)%100;

if(numberc<200){

cave[32]=(random(0,3)<<random(0,5)|0x80);

cave[33]=(random(0,3)<<random(1,6)|0x01);

}

else if(numberc<500){

cave[32]=(random(0,4)<<random(0,5)|0x80);

cave[33]=(random(0,4)<<random(1,6)|0x01);

}

else if(numberc<=900){

cave[32]=(random(0,8)<<random(0,4)|0x80);

cave[33]=(random(0,8)<<random(1,5)|0x01);

}

else{

numberc=900;

cave[32]=(random(0,8)<<random(0,4)|0x80);

cave[33]=(random(0,8)<<random(1,5)|0x01);

}

}



if(timec==0)

{

cave[i
2]=cave[i2+2];

cave[i
2+1]=cave[i2+3];

numberc++;

}



}



for(int j=0;j<=15;j++)

{

for(int k=0;k<=5;k++)

{

if(rowb[k]==j)

{

//用于判断子弹打下哪个B是子弹,C是目标 B^C 异或

if((dots[post[k]
2]&cave[j2])||(dots[post[k]2+1]&cave[j2+1]))

{

cave[j
2]=dots[post[k]2]^cave[j2];

cave[j2+1]=dots[post[k]2+1]^cave[j2+1];

rowb[k]=2;

}

}

}

//判断飞机是否接触洞穴

if(j==1)

if((plane2[count
4-4]&cave[j2])||(plane2[count4-3]&cave[j2+1]))

fail=1;

if(j==2)

if((plane2[count
4-2]&cave[j2])||(plane2[count4-1]&cave[j*2+1]))

fail=1;

}

}

}


via - 极客工坊

标签: Arduino教程