Протокосмічні окупанти (чи можете ви його затулити?)


18

Протокорейські загарбники

Це виклик графічного виводу, де завданням є дати найкоротший код на кожній мові.

Завдання

Ваш код повинен дозволяти користувачеві переміщувати наступного прибульця по екрану / вікну.

введіть тут опис зображення

Ваш код може просто завантажити його з локального файлу. Не соромтеся конвертувати його в інший стандартний формат зображення або навіть виправити невеликі помилки пікселів у зображенні, які були вказані в коментарях.

Фон повинен бути білим, а вікно / екран має бути не менше 400 пікселів на 400 пікселів. Якщо ваша мова не підтримує великі вікна / екрани, то використовуйте найбільший розмір, вона підтримує, поки це не менше 200 на 200.

Для переміщення прибульця по екрану код повинен підтримувати вгору / вниз / вліво / вправо за допомогою клавіш зі стрілками на стандартній клавіатурі.

Ваш код повинен бути повноцінною програмою .

Обмеження / обмеження

Чужинець повинен зупинитися на кордонах. Він також повинен плавно рухатись рівномірною швидкістю, без видимого мерехтіння або заїкання, і показуватись принаймні 24 кадрів в секунду. Перехід від однієї сторони екрана / вікна до іншої повинен зайняти від 2 до 5 секунд.

Мови та бібліотеки

Ви можете використовувати будь-яку мову чи бібліотеку, яка вам подобається (це не було розроблено для цього завдання). Однак я хотів би мати можливість протестувати ваш код, якщо це можливо, якщо ви можете надати чіткі інструкції, як запустити його в Ubuntu, що було б дуже вдячно.

Каталог

Фрагмент стека внизу цієї публікації генерує каталог з відповідей а) як список найкоротших варіантів для кожної мови та б) як загальний таблиця лідерів.

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

## Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Якщо ви хочете включити у свій заголовок декілька чисел (наприклад, тому що ваш результат становить суму двох файлів або ви хочете окремо вказати штрафні санкції для перекладача), переконайтесь, що фактичний результат - це останнє число у заголовку:

## Perl, 43 + 2 (-p flag) = 45 bytes

Ви також можете зробити ім'я мови посиланням, яке з’явиться у фрагменті:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


2
Чи можемо ми побудувати чужорідного самостійно? Якщо так, то чи повинні ми включати піксельні помилки (гадаю?) Із зображення?
mınxomaτ

@ mınxomaτ Це не обмежується Linux! Примітка "якщо можливо".

@nimi Спасибі Додано, що ви можете завантажити його з локального файлу.

@ mınxomaτ Ви можете його сконструювати самостійно або просто завантажити з локального файлу. Я не помічав помилок пікселів, але припускаю, що завантаження буде в будь-якому випадку меншим кодом.

Чи можете ви визначити "зупинка на кордонах"? Чи весь інопланетянин повинен бути видно весь час, чи він може частково зупинитися за межами кордону?
Тимофім

Відповіді:


12

Скретч , 221 217 байт

Клацніть зображення, щоб переглянути його в дії. Рух визначається натисканням клавіш , тому він буде плавнішим, чим швидше буде встановлено повторення клавіші.

Зображення включене в проект, але байти Scratch, як правило, підраховуються з текстового подання на гольфі , за цією мета-публікацією . Якщо є незгода щодо того, чи прийнятно це (чи рух досить плавний), повідомте мене, і я спробую обійти його.


Ця відповідь дуже весела!

Як ви виміряли розмір цієї програми?

@Lembik див. Другий абзац.
тимофім

1
генерується в 217 байтах: scratchblocks.github.io/…
ev3commander

1
@Mauris Так, саме про це піклується команда "if on edge, bounce". Ви можете відтворити демонстрацію, натиснувши на зображення!
тимофім

7

Обробка 2, 219 199 241 220 219 байт

int a,x=0,y=0;void setup(){size(500,500);}void draw(){background(-1);image(loadImage(".png"),x,y);if(keyPressed){a=keyCode;if(a==38)y--;if(a==37)x--;if(a==40)y++;if(a==39)x++;}x=constrain(x,0,436);y=constrain(y,0,454);}

Потрібно зображення, збережене як .pngу тому самому каталозі, що й .pde


6

Python 2, 262 253 246 240 байт

from pygame import*
init()
key.set_repeat(1)
p=[0,0]
d=display
c=d.set_mode((400,)*2)
while c.fill((255,)*3):
 e=event.get(2);c.blit(image.load("I"),p);d.flip()
 if e:x=e[0].key+1;q=x&2;b=q/2;p[b]=max(0,min(336+b*16,p[b]+(1-q)*(1-(2*x&2))))

Ого. Що за хакерство.

Використовується модуль 'pygame', знайдений на http://pygame.org .

Пояснення

key.set_repeat(1) - Надсилайте повторювані ключові події через систему подій кожні мілісекунди

c=d.set_mode((400,)*2) - Створіть дисплейну поверхню 400x400

while c.fill((255,)*3):- Ефективно, while 1:але також очищає екран

e=event.get(2);c.blit(image.load("I"),p);d.flip()- Збирайте лише події на клавіатурі, завантажуйте зображення, збережене у png-файлі під назвою, Iта малюйте його. Оновіть екран

if e:x=e[0].key+1;q=x&2;b=q/2;p[b]=max(0,min(336+b*16,p[b]+(1-q)*(1-(2*x&2)))) - Якщо відбулася подія, визначте, яку клавішу зі стрілками натискали (чи дивно це робити, якщо натиснути інші клавіші), а потім змініть положення поверхні залежно від того, яку клавішу ви натиснули.


Мені дуже подобається ваше рішення.

@Lembik Отже, ім'я одного байтового файлу дозволено? (Тобто без розширення?). Якщо так, я пропоную повністю виключити імена файлів із кількості байтів.
mınxomaτ

@ mınxomaτ Я однобайтовий файл дозволений, але я не хочу вигадувати нову схему балів.

@Lembik Обробка не може обробити однобайтові імена файлів ... тому це несправедливо.
TheDoctor

2
@TheDoctor Це просто в: Різні мови різні! Я пропоную також заборонити виклики, які беруть участь у stdin, ви знаєте, тому що це несправедливо, що для Python потрібно так багато персонажів ...
Aleksi Torhamo

5

Haskell, 410 байт

import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Game
main=do b<-loadBMP"b";play(InWindow""(400,400)(0,0))white 200((0,0),id)(b#)e(%)
e(EventKey(SpecialKey k)Down _ _)(c,_)|k==KeyUp=(c,fmap(+1))|k==KeyDown=(c,fmap(+(-1)))|k==KeyLeft=(c,((+(-1))?))|k==KeyRight=(c,((+1)?))
e(EventKey _ Up _ _)(c,_)=(c,id)
e _ w=w
_%(c,f)=(s?(s<$>f c),f)
s=min 200.max(-200)
b#((x,y),_)=Translate x y b
f?(a,b)=(f a,b)

Зображення прибульця очікується у файлі, названому bу .bmpформаті.

Я новачок у бібліотеці Gloss, тому, можливо, це не оптимально. Хтось знає, чи можу я перевірити, чи натискається клавіша замість відстеження KeyUp/ KeyDownподій?

Як це працює: останні чотири параметри play- це стан світу (ініціалізований з ((0,0),id), функція малювання зображення із стану ( #), обробник подій ( e) та функція, яка змінює стан з часом ( %).

Стан - це пара координат xy і функція, як їх змінювати щоразу, коли %викликається.

#переміщує растрову карту ( b) до поточних координат і малює її.

eшукає або KeyDownподії клавіш курсору і встановлює відповідні функції в стані, або для KeyUpбудь-якої клавіші, щоб скинути функцію в стані на функцію ідентичності.

% застосовує функцію від стану до поточних координат і перевіряє межі.


Мене завжди дивує, що ти навіть можеш робити подібні речі в Хаскеллі. Дякую!

4

В'яз, 240 байт

import Graphics.Element as G
import Keyboard as K
import Time
import Signal exposing(..)
c=min 800>>max 64
i(x,y)=G.container x y G.middle(G.image 64 48"http://i.stack.imgur.com/CUweU.png")
main=i<~foldp(\{x,y}(v,w)->(c v+x,c w-y))(99,99)(sampleOn(Time.fps 200)K.arrows)

Спробуйте тут . Кількість байтів відбувається після заміни URL-адреси на .png.


Можливо, мені доведеться зараз вивчити Елма. Дякую.

3

AutoIt , 269 267 байт

#include<Misc.au3>
GUICreate(0,-1,-1,-1,-1,-1,34078728)
$0=GUICtrlCreatePic("b.bmp",0,0,64,48)
GUISetState()
Dim $1,$2
$3=_IsPressed
Do
$1+=$3("27")-$3("25")
$2+=$3("28")-$3("26")
$1=($1>336)?336:($1<0)?0:$1
$2=($2>352)?352:($2<0)?0:$2
GUICtrlSetPos($0,$1,$2)
Until 0

Потрібно зберегти зображення як b.bmp у каталозі сценаріїв. Якщо ви хочете використовувати зображення з реальною прозорістю, вам доведеться перетворити його з PNG в 32-бітну растрову карту (OT: дійсно не оцінений формат).

Пояснення

Нам потрібно імпортувати, Misc.au3щоб отримати доступ до _IsPressed. Функція, яка приймає код ключа і повертається Trueабо Falseпри натисканні клавіші.

Специфікація виклику є досить крутою в тому, що нам потрібно створити квадратне вікно 400 пікселів. Параметри розміру за замовчуванням (позначаються як -1або Default) - 400x400. Розширений стиль вікна встановлюється в 34078728. Це змушує подвійне буферизацію вікна та малювати знизу вгору. Це необхідно для усунення мерехтіння відповідно до вимоги виклику. У Windows 10 ця незвична (і дещо недокументована) комбінація стилів розбиває рядок заголовка вікна (усі вивідні ефекти вимкнено).

$1і $2оголошуються і будуть утримувати зсув x і y зображення, завантаженого елементом управління $0. $3стає вказівником на функцію, _IsPressedщоб значно скоротити код.

Оскільки не потрібно виходити з програми, цей скрипт працює у нескінченному циклі ( Until 0).

$1+=$3("27")-$3("25")зловживає типом даних варіанту в AutoIt, динамічно _IsPressedвиводячи булеве значення, повернене з цілого числа, яке може бути додане або підрядне від зміщення x. Те саме для у. $1=($1>336)?336:($1<0)?0:$1використовує потрійний оператор, відомий з мов, подібних С, щоб здійснити перевірку меж, щоб зупинити прибульця на кордонах.

GuiCtrlSetPos переміщує керування зображенням на нові координати.

Ось скріншот із прозорим прибульцем (ви можете навіть рухатись по діагоналі):

скріншот


Ваш фон не білий!
sergiol

2

Lua + LÖVE, 291 символ

x=0
y=0
l=love
g=l.graphics
l.window.setMode(400,400)
i=g.newImage("i")
function l.update()d=l.keyboard.isDown
if d("left")and x>0 then x=x-1 end
if d("right")and x<336 then x=x+1 end
if d("up")and y>0 then y=y-1 end
if d("down")and y<352 then y=y+1 end
end
function l.draw()g.draw(i,x,y)end

Для цього використовується непереборне вікно розміром 400 х 400. Я не мав успіху з коригуваннямlove.keyboard.setKeyRepeat() на пришвидшення читання клавіш, тому я зробив рекомендований спосіб, опитуючи статус кожного ключа.

Оскільки моє відношення до Луї forне найкраще, ні цього разу не вдалося зробити циклічні роботи коротшими, ніж жорстке кодування дампа за умовами кожного ключа.


2

SpecBAS - 285 255 байт

1 GRAPHIC NEW v LOAD "inv8.bmp" TRANSPARENT 15
2 PALETTE COPY v,0,1 TO 5: GRAPHIC REMAP v
3 LET x,y=100
4 CLS : WINDOW PUT GRAPHIC v,0,x,y
5 LET x=x+KEYST(39)-KEYST(37),y=y+KEYST(40)-KEYST(38)
6 LET x=CLAMP(x,1 TO 400),y=CLAMP(y,1 TO 400)
7 WAIT SCREEN 
8 GO TO 4

Завантажує зображення - колір 15 яскраво-білий, так що стає прозорим.

Використовуючи оригінальне зображення та стандартну палітру SpecBAS, це вийшло трохи дивним, тому лінія 2 перемикає їх на відповідність вхідному зображенню. Знизу зображено, як це виглядає без рядка 2 і після.

введіть тут опис зображення

Команда CLAMP обмежує графіку між 1 і 400 в обох напрямках, економить на кількох операторах IF ... THEN.

Рядок 9 просто чекає, коли речі наздогнать і запобіжить мерехтіння.

Він переміщується по одному пікселю за часом, на основі булевої перевірки, яка клавіша натиснута, тому потрібно тривати трохи більше 5 секунд, щоб перейти з боку в бік.


2

Ruby with Shoes, 252 243 символи

Shoes.app{background white
i=image'i'
m=[0,0]
a=[:width,:height]
animate(99){i.left+=m[0]<=>i.left
i.top+=m[1]<=>i.top}
keypress{|k|d,v={?u=>[1,-1],?d=>[1,1],?l=>[0,-1],?r=>[0,1]}[k[0]];m[d]=[[m[d]+v*4,self.send(p=a[d])-i.send(p)].min,0].max}}

Для цього використовується вікно зміни розміру, яке починається з замовчування 600 x 500. Якщо змінити розмір вікна, щоб окупант не залишився, він повернеться після натискання наступної клавіші руху.

Трюк у задоволенні вимог полягає в тому, що позиція окупанта змінюється з кроком 4, але фактичний рух здійснюється з кроком 1 на 99 кадрів в секунду.


2

Tcl / Tk , 242 байти

grid [canvas .c -w 400 -he 403 -bg #FFF -highlightt 0]
.c cr i 30 24 -i [image c photo -fi .png] -t p
lmap {k b x y} "Up 1]>25 0 -5 Right 0]<368 5 0 Down 1]<376 0 5 Left 0]>30 -5 0" {bind . <$k> "if \[lindex \[.c coo p] $b {.c move p $x $y}"}

Щоб запустити його в будь-якому Linux: у вас повинні бути встановлені Tcl і Tk; потім скопіюйте код у файл, скажімо invaders.tcl; Вам також потрібно зберегти зображення, як .pngу тій же папці. Для запуску сценарію wish invaders.tcl в оболонці. PS: Це може бути більше гольфу, якщо код замість цього вставити в інтерактивну оболонку, оскільки він підтримує команди за замовчуванням скорочених команд.
серхіол

1

JavaScript (використовуючи paper.js), 215 байт

v=new Raster("http://i.stack.imgur.com/CUweU.png",99,99);p=new Size(4,0)
onFrame=e=>{if(!v.isInside(view.bounds)){p=-p};v.position+=p}
onKeyDown=e=>{p=new Size([[0,-4],[0,4],[-4,0],[4,0]]["udlr".indexOf(e.key[0])])}

paper.js - це графічна структура JS, що означає, що вона має багато корисних функцій щодо маніпулювання зображеннями. Для запуску, просто скопіювати вище в розділі зліва тут , а потім, щоб перемістити іноземця навколо, натисніть один раз в правій частині , щоб дати йому фокус. Якщо ваш браузер може працювати з ним, він повинен працювати зі швидкістю 60 кадрів в секунду.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.