Игра «Охота на уток» на Ардуино + пистолет - Своими руками
Своими руками

Игра «Охота на уток» на Ардуино + пистолет

>

Игра «Охота на уток» на Ардуино + пистолетПодростки 90-х прекрасно помнят такие игровые приставки, как Dendy и Sega. Как правило, в комплекте с приставками были два игровых джойстика, и этого было достаточно для большинства игр. Но были игры, для которых требовалось особенное оборудование, в частности – пистолет. Из этого пистолета нужно было стрелять по, например, уткам на экране телевизора. При попадании в утку засчитывалось очко.
Именно подобный пистолет + игру и решил сделать мастер.
Инструменты и материалы: -Arduino UNO;-Фотоэлемент;-Микропереключатель;-Два резистора по 10 кОм;-Провода;
-Картон;
-Соломка для коктейля;-Черная изолента;
-Небольшой кусочек пластилина;
-Клей;
Шаг первый: принцип работы
Тогда мало кто понимал, как работает это устройство. Некоторые говорили, что пистолет стреляет лазером, другие – светом, были и такие, кто утверждал, что от пистолета “поломается экран”.

На самом деле, все было гораздо проще. На пистолете был установлен фотоэлемент и он не испускал свет, а наоборот, принимал.
В момент нажатия на курок экран на долю секунды становился черным (глазу такой переход незаметен). Следующий кадр показывал на экране белый квадрат именно в том месте, где была утка в момент выстрела. Если пистолет был наведен точно в цель, то фотоэлемент фиксировал переход от черного к белому и засчитывал попадания.

Именно по такому принципу и будет реализована данная самоделка. Правда мастер будет использовать Ардуино, и устройство адаптировано для ЖК-монитора компьютера.

Шаг второй: ствол
Сначала мастер изготавливает ствол пистолета. Для ствола он использует соломинку для коктейля. Свет не должен проникать сквозь стенки соломинки, и он оборачивает ее черной изолентой. Соломинка для питья должна быть длинной и узкой, но достаточной для размещения внутри фотоэлемента.

К ножкам фотоэлемента нужно припаять провода, а сам фотоэлемент закрепить внутри соломинки с помощью пластилина.
Подключается он к аналоговом входе A2 Arduino. Чем длиннее провод – тем лучше, легче будет протестировать настройку.
Кнопка подключается к цифровом входе 2 Arduino. Это будет спусковая скоба пистолета.
Игра «Охота на уток» на Ардуино + пистолетИгра «Охота на уток» на Ардуино + пистолетИгра «Охота на уток» на Ардуино + пистолетШаг третий: код
Дальше нужно загрузить код в Arduino:
Игра «Охота на уток» на Ардуино + пистолет Показать / Скрыть текстbool pressed = false;

const int ROUND_DELAY = 25;
const int BAM_DELAY = 75;

void setup() {
// put your setup code here, to run once:
pinMode(2, INPUT);
pinMode(A2, INPUT);
Serial.begin(115200);
}

void loop() {
// put your main code here, to run repeatedly:
if(digitalRead(2) == HIGH) {
pressed = true;
}
if((digitalRead(2) == LOW) && pressed) {
Serial.println("bam!");
delay(BAM_DELAY);
int power = analogRead(A2);
Serial.println(power);
pressed = false;
}
delay(ROUND_DELAY);
}
В этом коде есть две константы:
Фрагмент ROUND_DELAY, не так уж и важен. Он отвечает за задержку между нажатием кнопки и реакцией игры. Также, если значения достаточно большие, – может полностью пропустить нажатие.

Фрагмент BAM_DELAY – важен. Она дает игре время для переключения между пользовательским видом игры с деревьями, кустами и утками и режимом обнаружения выстрела с полностью черным фоном и одним белым прямоугольником.

Настройка
Для настройки открываем Serial Monitor (Ctrl + Shift + M) и устанавливаем скорость передачи данных 115200. При нажатии на кнопку на мониторе должно отобразиться
bam!
2
Дальше наводим пистолет на белый участок экрана и снова нажимаем кнопку. Теперь должно отобразиться что-то вроде:
bam!
56
В последнем тесте наводим пистолет на черный участок экрана и нажимаем курок. Должно отобразиться:
bam!
0
Эти тесты позволяют убедиться, что кнопка работает нормально, а фотоэлемент может различать белые и черные участки на экране. Если у белого недостаточно высокое значение – можно попробовать увеличить яркость монитора.

Шаг четвертый: игра
Игру можно использовать ту, которую создал мастер или написать свою.
При создании игры нужно учитывать следующие факторы:
-фоновое изображение, которое должно быть нарисовано за передним планом и утками
-изображение переднего плана должно быть нарисовано над утками. У него должен быть альфа-канал (пустое пространство, прозрачность), чтобы можно было видеть уток за деревьями.
-должна быть живая утка, в которую игроку придется стрелять
-должна быть мертвая утка, если игрок добился успеха
-должна быть собака без утки
-должна быть собака с уткой
Игра «Охота на уток» на Ардуино + пистолетИгра «Охота на уток» на Ардуино + пистолетИгра «Охота на уток» на Ардуино + пистолетДальше нужно установить библиотеки pyserial и pygame
PS > pip install pyserial
PS > pip install pygame
Сохраните код ниже в файле game.py:
Игра «Охота на уток» на Ардуино + пистолет Показать / Скрыть текстfrom serial import Serial
from random import choice
import pygame
import time

DELIM = "n".encode()
TRAGECTORIES = [(10, -10), (5, -15), (7, -12)]
START_POS = [((100, 500), 1), ((1100, 500), -1)]

ser = Serial("COM3", 115200, timeout=0.01)

waiting = True
pygame.display.set_caption("Hunt")
window_surface = pygame.display.set_mode((1280, 760))

back = pygame.image.load("back.png")
front = pygame.image.load("front.png")
duck = (pygame.image.load("duck.png"), pygame.image.load("dead_duck.png"))
back_duck = (pygame.transform.flip(duck[0], True, False),
pygame.transform.flip(duck[1], True, False))
dogs = (pygame.image.load("dog-0.png"), pygame.image.load("dog-1.png"))

black_background = pygame.Surface((1280, 760))
black_background.fill(pygame.Color('#000000'))
bird = pygame.Surface((200, 200))
bird.fill(pygame.Color('#ffffff'))

dog_pos = None
dog_id = 0
dog_direction = (0, -5)
bird_pos = None
tragectory = None
direction = None
is_alive = None
score = 0

while waiting:
for event in pygame.event.get():
if event.type == pygame.QUIT:
waiting = False

if dog_pos is None:
if bird_pos is None:
tragectory = choice(TRAGECTORIES)
start = choice(START_POS)
bird_pos = start[0]
direction = start[1]
tragectory = (tragectory[0] * start[1], tragectory[1])
is_alive = True
else:
if is_alive:
bird_pos = (bird_pos[0] + tragectory[0],
bird_pos[1] + tragectory[1])
else:
bird_pos = (bird_pos[0] + tragectory[0],
bird_pos[1] – tragectory[1])

resp = ser.read_until(DELIM).decode()[:-1]

if resp != "":
window_surface.blit(black_background, (0, 0))
window_surface.blit(bird, bird_pos)
else:
window_surface.blit(back, (0, 0))
window_surface.blit(
(duck if direction == 1 else back_duck)
[0 if is_alive else 1], bird_pos)
window_surface.blit(front, (0, 0))

pygame.display.update()

if resp != "":
ser.timeout = 0.15
power_str = ser.read_until(DELIM).decode()[:-1]
ser.timeout = 0.01
power = int(power_str)
if is_alive and power > 20:
score = score + 1
is_alive = False

if bird_pos[1] < -200 or bird_pos[1] > 500:
dog_direction = (0, -5)
dog_pos = (440, 420)
if bird_pos[1] < -200:
dog_id = 0
else:
dog_id = 1
bird_pos = None
else:
window_surface.blit(back, (0, 0))
window_surface.blit(dogs[dog_id], dog_pos)
window_surface.blit(front, (0, 0))
pygame.display.update()

dog_pos = (dog_pos[0] + dog_direction[0],
dog_pos[1] + dog_direction[1])
if dog_pos[1] < 220:
dog_direction = (0, 5)
elif dog_pos[1] > 420:
dog_pos = None
При необходимости нужно заменить строку «COM3» на имя последовательного интерфейса, используемого Arduino на платформе пользователя.
Дальше можно запустить игру, используя:
python game.py
Это простая игра, которая будет показывать по одной утке за раз, и реагировать на ввод из последовательного порта. Когда он получит какой-то сигнал от пистолета – он отобразит черный фон с белым прямоугольником в том месте, где находилась утка.
Из предыдущего сеанса настройки нужно убедиться, что константа 20 подходит для фотоэлемента.
На этом шаге можно убедиться, что все работает хорошо и в игру можно играть.
Игра «Охота на уток» на Ардуино + пистолетИгра «Охота на уток» на Ардуино + пистолетИгра «Охота на уток» на Ардуино + пистолетШаг пятый: пистолет
Для реалистичности и удобства нужен пистолет. Его можно сделать самостоятельно, как мастер, или приспособить игрушечный для этих целей.
Игра «Охота на уток» на Ардуино + пистолетИгра «Охота на уток» на Ардуино + пистолетИгра «Охота на уток» на Ардуино + пистолетШаг шестой: окончательный результат
По словам мастера, игра вполне рабочая, хотя есть и отличия от оригинала. В оригинальной игре был режим одновременной стрельбы по двум птицам. Этого можно добиться несколькими способами – можно попробовать запустить несколько раундов с отображением белых прямоугольников, по одному для каждой птицы. Или это могут быть два фотоэлемента, покрытые цветными фильтрами, или более сложный датчик освещенности. В этом случае можно отобразить красный прямоугольник для одной птицы и синий прямоугольник для другой.
Один пистолет можно использовать для разных игр по схожему принципу. Конечно, формы самих пистолетов могут усилить ощущения от игры. Оружие также можно оснастить тактильным откликом, чтобы сделать опыт стрельбу более правдоподобной.

Также можно установить датчик наклона, который можно было использовать для «перезарядки» пушки. Например, можно ограничить количество выстрелов до 8. Чтобы перезарядить пистолет, игрок должен направить его вниз (датчик наклона зафиксирует это событие), а затем выстрелить снова.

На видео можно посмотреть небольшой фрагмент игры.

SitesReady

Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного. - Альберт Эйнштейн

Follow us

Don't be shy, get in touch. We love meeting interesting people and making new friends.