Dotship: Juego en Arduino (LCD + Pot + Pushbutton)

Ok, esto es algo que se me ocurrió hacer al programar un poco en un framework de Lua llamado Löve (luego les contaré sobre eso). Se trata de un juego simple que podemos programar en nuestro arduino haciendo uso de un LCD y una pequeña función llamada lcd.createChar().

dotship lcd game

En este juego tú eres un simple pixel que se desplaza únicamente lateralmente y que puede disparar. El objetivo es evitar que ‘el enemigo’ llegue hasta donde estás tú. Cada vez que matas al enemigo éste reaparece más enojado y con mayor velocidad, así que en realidad no puedes ganar, sólo se trata de sobrevivir por el mayor tiempo posible.

Lo que se necesita

  • Arduino
  • LCD 16×2 Hitachi HD44780 compatible (es decir, la más común)
  • 2 Potenciómetros (cualquier tamaño está bien)
  • 1 Pushbutton
  • 1 Resistencia de 10 Kohms
  • 1 Resistencia de 100 ohms
El potenciómetro va a ser nuestro ‘analog stick’ de bajos recursos: con él controlaremos a nuestra nave-pixel. El pushbutton es el gatillo de nuestra superduper arma destructora.

El diagrama

dotship diagrama

 

dotship lcd game 2

En la foto hay dos pushbuttons por otro programa que estaba haciendo antes, sólo es necesario uno. El segundo potenciómetro (el de abajo) es el que ajusta el contraste del LCD.

El código

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*
  __DOTSHIP__
  "The adventure of a dot-shaped ship versus the thing-shaped 
  immortal enemy"
 
  A simple Arduino game that uses a common 16x2 LCD (Hitachi 
  HD44780 compatible) and a potentiometer and a pushbutton as 
  a controller.
 
  You can find the LCD wiring here: 
  http://arduino.cc/en/Tutorial/LiquidCrystal
    - RS to 12
    - Enable to 11
    - Data pins to 5, 4, 3, 2
    - R/W to GND
 
  also you will need a:
  * Potentiometer: 
    - end pins to +5v and GND
    - middle pin to A0 pin
  * Pushbutton:
    - attached to pin 8 from +5V
    - 10K resistor attached to pin 8 from ground
 
  More details: http://thebatzuk.org/2011/09/dotship-juego-en-
  arduino-lcd-pot-pushbutton.html
 
  11 Sep 2011
  by Raúl Rivas (thebatzuk)   <--------\
                                        \  
  You can use, copy and modify           \
  this code but do not remove this  line -\
*/
 
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 
unsigned long time = 0;
boolean game = true;
unsigned int score = 0;
 
// potentiometer and button pins
int pot_pin = 0;
int bttn_pin = 8;
int bttn_val = 0;
int bttn_last = 0;
 
// ship variables 
int ship_px = 0;
int ship_y = 0;
 
// shoots variables
boolean shot = false;
int shoot_time = 0;
byte shot_pos[5] = {B00001, B00010, B00100, B01000, B10000};
int shoot_x = 14;
int shoot_y = 0;
int shoot_px = 0;
int mi = 0;
 
// enemies variables
byte enemies[8] = {B00000, B00110, B00001, B01111, B01111, 
                   B00001, B00110, B00000};
int enemy_y = 0;
int enemy_x = 0;
int enemy_vel = 100;
int vel_increment = 20;
 
void setup() 
{
  lcd.begin(16, 2);
  lcd.createChar(2, enemies);
  randomSeed(analogRead(1));
}
 
void loop() 
{
  if(game)
  {
    time++;
    // ship stuff
    byte ship[8] = {B00000, B00000, B00000, B00000, B00000, 
                    B00000, B00000, B00000};
    ship_px = map(analogRead(pot_pin), 0, 1023, 0, 16);
    if(ship_px >= 0 && ship_px <= 7)
      ship_y = 0;
    else if(ship_px >= 8 && ship_px <= 15)
      ship_y = 1; 
    ship[ship_px - ship_y * 8] = B10000;
    lcd.createChar(0, ship);
    lcd.setCursor(15, ship_y);
    lcd.write(0);
 
    // shoots stuff
    byte shoot[8] = {B00000, B00000, B00000, B00000, B00000, 
                     B00000, B00000, B00000};
    bttn_val = digitalRead(bttn_pin);
    if(bttn_val != bttn_last && bttn_val == HIGH && !shot)
    {
      shot = true;
      shoot_time = 0;
      mi = 0;
      shoot_px = ship_px - ship_y * 8;
      shoot_y = ship_y;
    }
    if(shot)
    {
      for(int i = 0; i < 15; i++)
      {
        if(shoot_time >= mi && shoot_time <= mi+4)
        {
          shoot_x = 14 - (mi / 5);
          mi += 5;
          if(shoot_x == 0)
            shot = false;
          break;
        }
      }
      shoot[shoot_px] = shot_pos[shoot_time - (14 - shoot_x) * 5];
      lcd.createChar(1, shoot);
      lcd.setCursor(shoot_x, shoot_y);
      lcd.write(1);
      shoot_time++;
    }
 
    // enemies stuff
    if(time % enemy_vel == 0)
    {
      enemy_x++;
      enemy_y = random(0, 2);
    }
    lcd.setCursor(enemy_x, enemy_y);
    lcd.write(2);
    // enemy got shot:
    if(shoot_y == enemy_y && shoot_x == enemy_x && 
       shoot_px > 0 && shoot_px < 7)
    {
      score += 10 * enemy_x;
      enemy_x = 0;
      enemy_vel -= vel_increment;
      vel_increment -= 5;
      if(enemy_vel <= 0)
        enemy_vel = 2;
      if(vel_increment <= 0)
        vel_increment = 5;
      shot = false;
      shoot_x = 14;
      delay(25);
    }
    else if(enemy_x > 14)
      game = false;
 
    // other stuff
    delay(15);
    lcd.clear();
    bttn_last = bttn_val;
  }
  else
  { 
    lcd.setCursor(0, 0); 
    lcd.print("Game Over.");
    lcd.setCursor(0, 1); 
    lcd.print("Score: ");
    lcd.print(score);
    // reset Arduino to play again
  }
}

También puedes encontrar el código aquí: Dotship, an Arduino Game (LCD, Pot and Pushbutton)

La función de las LCD es mostrar caracteres (a-z, 0-9), sin embargo cada segmento tiene pixeles individuales que puede ser ‘explotados’ para hacer este tipo de juegos. La función lcd.createChar() te permite crear caracteres extras a los que admite la pantalla LCD, por medio de una matriz puedes decidir cual pixel se enciende y cual no. Además éstos caracteres especiales pueden ser creados dinámicamente, por lo que las posibilidades son bastante amplias.

Eso es todo, espero y alguien lo pruebe en su arduino y nos cuente que tal está.

  1. *.* dice:

    yo quiero jugar!!! jeje

  2. Arianxo dice:

    Buen trabajo, enhorabuena.

Hola, escribe aquí tu comentario: