概要
arduinoでspaceinvaderやってみた。
写真
サンプルコード
#include <Adafruit_GFX.h>
#include "Adafruit_TFTLCD.h"
#include "TouchScreen.h"
#include "Space_Invaders.h"
#define XP 8
#define YP A3
#define XM A2
#define YM 9
#define TS_MINX 150
#define TS_MAXX 920
#define TS_MINY 120
#define TS_MAXY 940
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
#define nr_enemy 12
#define chance_shoot 4
int joyX = 0;
char bounce;
char play = 0;
byte level = 1;
unsigned int score = 0;
Enemy * enemy[nr_enemy];
Bullet * ShipBullet = new Bullet();
Bullet * EnemyBullet = new Bullet();
Ship * ship;
void moveShip()
{
int dir = joyX;
if (dir != 0)
{
dir = dir < 0 ? -1 : 1;
tft.fillRect(ship->getY() - 6, ship->getX() - 7, 7, 15, WHITE);
ship->move(dir);
drawShip(ship->getX(), ship->getY());
}
}
void moveBullet()
{
if (ShipBullet->getExist() == 1)
{
tft.drawFastVLine(ShipBullet->getY(), ShipBullet->getX(), 3, WHITE);
ShipBullet->move();
tft.drawFastVLine(ShipBullet->getY(), ShipBullet->getX(), 3, RED);
for (byte i = 0; i < nr_enemy; i++)
{
if (ShipBullet->collisionEnemy(enemy[i]) == 1)
{
enemy[i]->setDead();
score += 100;
}
}
}
if (EnemyBullet->getExist() == 1)
{
tft.drawFastVLine(EnemyBullet->getY(), EnemyBullet->getX(), 3, WHITE);
EnemyBullet->move();
tft.drawFastVLine(EnemyBullet->getY(), EnemyBullet->getX(), 3, RED);
if (EnemyBullet->collisionShip(ship) == 1)
{
ship->setLives(ship->getLives() - 1);
ship->setX(83);
ship->setY(24);
}
}
}
byte remaining_enemys()
{
byte k = 0;
for (byte i = 0; i < nr_enemy; i++)
{
if (enemy[i]->Alive())
{
k++;
}
}
return k;
}
void moveEnemy()
{
bounce = 0;
for (byte i = 0; i < nr_enemy; i++)
{
if (bounce == 0 && enemy[i]->Alive() == true && enemy[i]->move() == 1)
{
for (byte j = 0; j < nr_enemy; j++)
{
if (j < i)
{
enemy[j]->update(1);
}
else if (j > i)
{
enemy[j]->update(0);
}
}
bounce = 1;
}
}
tft.fillRect(0, 0, 200, 100, WHITE);
drawShip(ship->getX(), ship->getY());
drawLives(ship->getLives());
for (byte i = 0; i < nr_enemy; i++)
{
if (enemy[i]->Alive())
{
drawEnemy(enemy[i]->getX(), enemy[i]->getY());
if (enemy[i]->Defeat())
{
play = 2;
}
if ((int) random(chance_shoot) == 0)
{
addBullet(enemy[i]->getX(), enemy[i]->getY(), 3, 0);
}
}
}
}
void addBullet(byte x, byte y, byte newSpeed, char side)
{
if (side == 1 && ShipBullet->getExist() == 0)
{
ShipBullet = new Bullet(x, y, newSpeed);
}
else if (side == 0 && EnemyBullet->getExist() == 0)
{
EnemyBullet = new Bullet(x, y, newSpeed);
}
}
void drawLives(unsigned short int lives)
{
for (byte i = 0; i < lives; i++)
{
drawL(1, 42 - i * 7);
}
}
void drawL(int x0, int y0)
{
int x = y0;
int y = x0;
tft.fillRect(x + 1, y, 3, 5, BLACK);
tft.drawPixel(x, y + 1, BLACK);
tft.drawPixel(x, y + 3, BLACK);
tft.drawFastVLine(x + 4, y + 1, 3, BLACK);
tft.drawPixel(x + 5, y + 2, BLACK);
}
void drawEnemy(byte x0, byte y0)
{
byte x = y0;
byte y = x0;
tft.fillRect(x - 3, y - 2, 7, 3, BLACK);
tft.drawPixel(x - 3, y - 3, BLACK);
tft.drawPixel(x + 3, y - 3, BLACK);
tft.drawPixel(x, y - 4, BLACK);
tft.drawFastHLine(x - 1, y - 3, 3, BLACK);
tft.drawPixel(x - 1, y - 1, WHITE);
tft.drawPixel(x + 1, y - 1, WHITE);
}
void drawShip(byte x0, byte y0)
{
byte x = y0;
byte y = x0;
tft.fillRect(x - 3, y - 2, 2, 3, BLACK);
tft.fillRect(x + 2, y - 2, 2, 3, BLACK);
tft.fillRect(x - 1, y - 1, 3, 2, BLACK);
tft.drawFastVLine(x, y - 4, 3, BLACK);
}
void initGame(byte lvl)
{
if (lvl == 1)
{
ship = new Ship(83, 24);
score = 0;
}
else
{
ship->setX(83);
ship->setY(24);
}
for (byte i = 1; i <= 4; i++)
{
for (byte j = 1; j <= 3; j++)
{
enemy[(i - 1) * 3 + j - 1] = new Enemy(10 * i + 6, 42 - 9 * (j - 1), lvl);
}
}
tft.fillRect(0, 0, 200, 100, WHITE);
drawShip(ship->getX(), ship->getY());
drawLives(ship->getLives());
for (byte i = 0; i < nr_enemy; i++)
{
drawEnemy(enemy[i]->getX(), enemy[i]->getY());
}
}
void setup(void)
{
Serial.begin(115200);
tft.reset();
uint16_t identifier = 0x9341;
tft.begin(identifier);
tft.fillScreen(WHITE);
Serial.println("start");
initGame(level);
tft.drawRect(10, 100, 20, 10, BLUE);
tft.drawRect(60, 100, 20, 10, RED);
tft.drawRect(110, 100, 20, 10, BLUE);
}
void loop()
{
Point p = ts.getPoint();
int st = 0;
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
{
if (p.x < 850 && p.x > 800) st = 1;
if (p.x < 700 && p.x > 650) st = 2;
if (p.x < 550 && p.x > 500) st = 3;
Serial.println(st);
}
if (play == 0)
{
moveEnemy();
if (st == 2) addBullet(ship->getX() - 8, ship->getY(), -3, 1);
if (st == 1) joyX -= 1;
if (st == 3) joyX += 1;
if (joyX < -5) joyX = -5;
if (joyX > 5) joyX = 5;
moveShip();
if (ship->getLives() == 0)
{
play = 2;
}
moveBullet();
if (remaining_enemys() == 0)
{
level += 1;
initGame(level);
}
}
else
{
tft.setCursor(10, 10);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Game Over!");
tft.println(score);
}
delay(10);
}
以上。