【开源】ESP8266局域网复古乒乓球对战

该文是一个使用ESP8266微控制器和OLED屏幕创建的局域网双人乒乓球游戏项目。设备通过WiFi连接,利用UDP进行通信,更新玩家的球拍位置并同步游戏状态。用户通过按键控制球拍,游戏开始和运行的数据通过UDP包进行交换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本系列,是记录自己入门嵌入式领域的学习笔记。

看看能坚持多久。

今天是2023年5月4日

源代码的来源:https://github.com/taichi-maker/ESP8266_Multiplayer_Pong

项目需求:

ESP8266_OLED屏幕实现局域网复古乒乓球对战

硬件连接:

  D1(8266)<------------>SCL(oled)

  D2(8266)<------------>SDA(oled)

  D5(8266)<------------>按键UP引脚

  D6(8266)<------------>按键DOWN引脚

  3V3(8266)<----------->VCC(oled)

  GND(8266)<----------->GND(oled)

  备注:使用的两个按键另一端均为接地(GND)

程序源码:

引入的库文件的头文件
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Ticker.h>
//

作为STA_slave需要的参数
#define ssid      "XXXXXXX"       //这里改成你的设备当前环境下WIFI名字
#define password  "XXXXXXX"     //这里改成你的设备当前环境下WIFI密码
IPAddress master_IP(192, 168, 1, 14); //master机子接入点的ip地址

//

///UDP传输相关参数
WiFiUDP Udp;//实例化WiFiUDP对象
unsigned int localUdpPort = 4321;  // 自定义本地监听端口
unsigned int remoteUdpPort = 1234;  // 自定义远程监听端口
int slavepad = 16;  //slave机的球拍位置
int masterpad = 16; //master机的球拍位置
Ticker changedata;//实例化一个定时器对象
//


//游戏运行的各项参数///
uint8_t ball_x = 64, ball_y = 32;
uint8_t ball_x0 = 64, ball_y0 = 32;
uint8_t ball_dir_x = 1, ball_dir_y = 1;
unsigned long ball_update;
unsigned long paddle_update;
const uint8_t CPU_X = 12;
uint8_t cpu_y = 16;
const uint8_t PLAYER_X = 115;
uint8_t player_y = 16;
const unsigned long PADDLE_RATE = 33;
const unsigned long BALL_RATE = 16;
const uint8_t PADDLE_HEIGHT = 24;
int scoreCPU = 0;
int scoreUSER = 0;
int startflag = 0;
int keyflag = 0;
//int end_x = 0;
uint8_t new_x = 1;
uint8_t new_y = 1;
//

/按键引脚定义/
#define UP_BUTTON 14//GOIO14=D5
#define DOWN_BUTTON 12//GOIO12=D6
//

/oled显示定义/
#define SCREEN_WIDTH 128 // OLED宽度像素
#define SCREEN_HEIGHT 64 // OLED高度像素
// 0.96寸SSD1306,I2C协议 (SDA, SCL 标号)
#define OLED_RESET     3 // Reset pin ,虽然用不上但是还是要设置
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//

///初始化使用的函数
void drawCourt();;//画出球场
void splash();//初始界面
void printScreen();//打印双方分数
void Multiplayer();//游戏主函数。多人联机是由单人游戏扩展而来。单人游戏文件可在github测试用文件中找到
void UDPsetup();//初始化UDP链接
void UDPgetstart();//初始化UDP链接
void UDPgetdata();//接受和发送游戏进行时传输的数据
void UDPsend();//UDP发送信息函数
void gamestart();//确定游戏开始的函数
void tochar();//进行数值和字符串转换并发送的函数
void change();//交换数据的函数。此函数包含tochar()和UDPgetdata()
void wifiSTAconnect();//作为slave机的AP热点开启初始化
//void gamerestart();
//

void setup() {
  串口初始化
  Serial.begin(115200);//打开串口
  Serial.println();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);//使用I2C地址0x3C初始化(对于128x64)
  display.clearDisplay();
  unsigned long start = millis();
  pinMode(UP_BUTTON, INPUT_PULLUP);//按键初始化为上拉输入
  pinMode(DOWN_BUTTON, INPUT_PULLUP);
  digitalWrite(UP_BUTTON, 1);
  digitalWrite(DOWN_BUTTON, 1);
  UDPsetup();//UDP链接初始化
  changedata.attach(0.02, change);//开启定时器,每0.02秒就同步一次数据
  splash();//开机初始化界面
  wifiSTAconnect();//作为slave的无线终端初始化
  gamestart();//确认开始游戏界面
  drawCourt();//画球场的框线
  printScores();//屏幕显示分数

  while (millis() - start < 2000);
  ball_update = millis();
  paddle_update = ball_update;
}

void loop() {

  Multiplayer();

}

//
void drawCourt() {
  display.drawRect(0, 0, 128, 64, WHITE);
  for (int i = 0; i < SCREEN_HEIGHT; i += 4) {
    display.drawFastVLine(SCREEN_WIDTH / 2, i, 2, WHITE);
  }
}

void splash()
{
  display.clearDisplay();
  display.setTextColor(WHITE);
  centerPrint("PONG", 0, 3);
  centerPrint("By BlackBox114", 24, 1);
  centerPrint("Code by", 33, 1);
  centerPrint("TaichiMacker", 42, 1);
  display.fillRect(0, SCREEN_HEIGHT - 10, SCREEN_WIDTH, 10, WHITE);
  display.setTextColor(BLACK);
  centerPrint("Press key to start!", SCREEN_HEIGHT - 9, 1);

  display.display();


  while (true) {
    ESP.wdtFeed();//长时间循环会触发看门狗复位,因此需要喂狗
    if (digitalRead(DOWN_BUTTON) + digitalRead(UP_BUTTON) < 2) {
      break;
    }
    display.clearDisplay();
  }

  // soundStart();

}

void centerPrint(char *text, int y, int size)
{
  display.setTextSize(size);
  display.setCursor(SCREEN_WIDTH / 2 - ((strlen(text)) * 6 * size) / 2, y);
  display.print(text);
}

void printScores() {

  //print scores
  int SIZE = 2;
  int SCORE_PADDING = 10;
  //以分数位置为基准,修改整体宽度
  int scoreCP
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值