Begin work on pong

This commit is contained in:
shylie 2025-06-04 20:10:07 -04:00
parent 14a0880ae9
commit bc1443a526
2 changed files with 135 additions and 6 deletions

@ -1 +1 @@
Subproject commit eab338e380c9f7f30a3699097bf925214415120b
Subproject commit 1c9fc51d01e3f5579b25f4b291b4fa01fdd83faf

View File

@ -1,3 +1,4 @@
#include <cmath>
#include <cstdlib>
#include <pico/stdio_usb.h>
@ -5,9 +6,59 @@
#include <picoled/SSD1306.h>
namespace
{
struct rect
{
float x, y, w, h;
void draw(picoled::oled& oled) const
{
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
oled(x + i, y + j) = true;
}
}
}
float left() const { return x; }
float right() const { return x + w; }
float top() const { return y; }
float bottom() const { return y + h; }
float middle_h() const { return x + w / 2.0f; }
float middle_v() const { return y + h / 2.0f; }
bool overlaps(const rect& other) const
{
const bool x_overlaps =
(left() >= other.left() && left() <= other.right()) ||
(right() >= other.left() && right() <= other.right());
const bool y_overlaps =
(top() >= other.top() && top() <= other.bottom()) ||
(bottom() >= other.top() && bottom() <= other.bottom());
return x_overlaps && y_overlaps;
}
};
constexpr uint8_t LEFT_BUTTON = 2;
constexpr uint8_t MIDDLE_BUTTON = 3;
constexpr uint8_t RIGHT_BUTTON = 4;
constexpr float PADDLE_SPEED = 20;
constexpr float INITIAL_BALL_SPEED = 32;
}
int main()
{
stdio_usb_init();
srand(time_us_64());
i2c_init(i2c0, 3 * 1000 * 1000);
gpio_set_function(0, GPIO_FUNC_I2C);
@ -15,19 +66,97 @@ int main()
gpio_pull_up(0);
gpio_pull_up(1);
gpio_set_function(LEFT_BUTTON, GPIO_FUNC_SIO);
gpio_set_function(MIDDLE_BUTTON, GPIO_FUNC_SIO);
gpio_set_function(RIGHT_BUTTON, GPIO_FUNC_SIO);
gpio_set_dir(LEFT_BUTTON, GPIO_IN);
gpio_set_dir(MIDDLE_BUTTON, GPIO_IN);
gpio_set_dir(RIGHT_BUTTON, GPIO_IN);
gpio_pull_down(LEFT_BUTTON);
gpio_pull_down(MIDDLE_BUTTON);
gpio_pull_down(RIGHT_BUTTON);
picoled::ssd1306 oled(i2c0, 0x3C);
oled.update();
rect player = { 8.0f, oled.get_height() / 2.0f - 8.0f, 4.0f, 16.0f };
rect ai = { oled.get_width() - 8.0f - 4.0f, oled.get_height() / 2.0f - 8.0f, 4.0f, 16.0f };
rect ball = { 64.0f - 2.0f, 32.0f - 2.0f, 4.0f, 4.0f };
float ball_dir = (((rand() % 1000000) / 1000000.0f) - 0.5f) * 3.1415926f * 2.0f;
float ball_dx = cosf(ball_dir);
float ball_dy = sinf(ball_dir);
float ball_speed = INITIAL_BALL_SPEED;
int64_t us = time_us_32();
while (true)
{
for (int i = 0; i < 16; i++)
{
const int x = rand() % oled.get_width();
const int y = rand() % oled.get_height();
oled.clear();
oled(x, y).invert();
for (int i = 0; i < oled.get_width(); i++)
{
oled(i, 0) = true;
oled(i, oled.get_height() - 1) = true;
}
for (int i = 0; i < oled.get_height(); i++)
{
oled(0, i) = true;
oled(oled.get_width() - 1, i) = true;
}
int64_t current = time_us_32();
float dt = std::abs(current - us) / 1000000.0f;
us = current;
if (gpio_get(LEFT_BUTTON)) { player.y -= PADDLE_SPEED * dt; }
if (gpio_get(MIDDLE_BUTTON)) { player.y += PADDLE_SPEED * dt; }
float diff = ball.middle_v() - ai.middle_v();
ai.y += 1.35f * diff * dt;
ball.x += ball_dx * dt * ball_speed;
ball.y += ball_dy * dt * ball_speed;
if (ball.overlaps(player))
{
ball_dx = -ball_dx;
ball.x = player.right();
ball_speed += 1.0f;
}
if (ball.overlaps(ai))
{
ball_dx = -ball_dx;
ball.x = ai.left() - ball.w;
ball_speed += 1.0f;
}
if (ball.left() < 0)
{
ball_dx = -ball_dx;
ball.x = 0;
}
if (ball.right() >= oled.get_width())
{
ball_dx = -ball_dx;
ball.x = oled.get_width() - ball.w;
}
if (ball.top() < 0)
{
ball_dy = -ball_dy;
ball.y = 0;
}
if (ball.bottom() >= oled.get_height())
{
ball_dy = -ball_dy;
ball.y = oled.get_height() - ball.h;
}
player.draw(oled);
ai.draw(oled);
ball.draw(oled);
oled.update();
}
}