Najeźdźcy z kosmosu (czy potrafisz to zrzucić?)

18

Najeźdźcy z kosmosu

Jest to graficzne wyzwanie wyjściowe, w którym zadaniem jest podanie najkrótszego kodu dla każdego języka.

Zadanie

Twój kod powinien umożliwiać użytkownikowi poruszanie się po kosmicie po ekranie / oknie.

wprowadź opis zdjęcia tutaj

Twój kod może po prostu załadować go z pliku lokalnego. Możesz go przekonwertować na inny standardowy format obrazu, a nawet naprawić błędy małych pikseli w obrazie, które zostały wskazane w komentarzach.

Tło powinno być białe, a okno / ekran musi mieć co najmniej 400 pikseli na 400 pikseli. Jeśli twój język nie obsługuje tak dużych okien / ekranów, użyj największego rozmiaru, który obsługuje, o ile nie jest to mniej niż 200 na 200.

Aby przesunąć kosmitę po ekranie, kod powinien obsługiwać górę / dół / lewo / prawo za pomocą klawiszy strzałek na standardowej klawiaturze.

Twój kod powinien być pełnym programem .

Ograniczenia / ograniczenia

Cudzoziemiec powinien zatrzymać się na granicach. Powinien także poruszać się z równomierną prędkością płynnie, bez widocznego migotania lub jąkania i pokazywany co najmniej 24 kl./s. Przejście z jednej strony ekranu / okna na drugą powinno zająć od 2 do 5 sekund.

Języki i biblioteki

Możesz użyć dowolnego języka lub biblioteki, która Ci się podoba (która nie została zaprojektowana do tego wyzwania). Chciałbym jednak móc przetestować twój kod, jeśli to możliwe, więc jeśli możesz podać jasne instrukcje dotyczące uruchamiania go w Ubuntu, byłoby to bardzo mile widziane.

Katalog

Fragment kodu na dole tego postu generuje katalog na podstawie odpowiedzi a) jako listy najkrótszych rozwiązań według języka oraz b) jako ogólnej tabeli wyników.

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

## Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:

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

Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie:

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


źródło
2
Czy sami możemy zbudować kosmitę? Jeśli tak, to czy musimy dołączyć błędy pikseli (tak myślę?) Z obrazu?
mınxomaτ
@ mınxomaτ To nie ogranicza się do Linuksa! Uwaga „jeśli to możliwe”.
@nimi Dzięki. Dodano, że można go załadować z pliku lokalnego.
@ mınxomaτ Możesz go zbudować samodzielnie lub po prostu załadować z pliku lokalnego. Nie zauważyłem błędów pikseli, ale zakładam, że załadowanie go i tak będzie mniej kodu.
Czy potrafisz zdefiniować „przystanek na granicach”? Czy cały kosmita musi być cały czas widoczny, czy może zatrzymać się częściowo poza granicą?
timothymh

Odpowiedzi:

12

Scratch , 221 217 bajtów

Kliknij obraz, aby zobaczyć go w akcji. Ruch jest określany przez naciśnięcia klawiszy , więc będzie on płynniejszy, im szybciej zostanie ustawione powtarzanie klawiszy.

Obraz jest zawarty w projekcie, ale bajty Scratch są zwykle liczone od golfowej reprezentacji tekstowej według tego meta postu . Jeśli istnieje spór co do tego, czy jest to dopuszczalne (lub czy ruch jest wystarczająco płynny), daj mi znać, a ja postaram się go obejść.

tymotka
źródło
Ta odpowiedź to świetna zabawa!
Jak zmierzyłeś rozmiar tego programu?
@Lembik patrz drugi akapit.
timothymh
1
generuje w 217 bajtach: scratchblocks.github.io/…
ev3commander
1
@ Mauris Tak, właśnie o to dba polecenie „if on edge, bounce”. Możesz zagrać w demo, klikając na obrazek!
tymoteusz
7

Przetwarzanie 2, 219 199 241 220 219 bajtów

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);}

Wymaga obrazu zapisanego jak .pngw tym samym katalogu co .pde

Doktor
źródło
6

Python 2, 262 253 246 240 bajtów

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))))

Łał. Co za hackery.

Używa modułu „pygame” znalezionego na stronie http://pygame.org .

Wyjaśnienie

key.set_repeat(1) - Wysyłaj powtarzające się kluczowe zdarzenia przez system zdarzeń co milisekundę

c=d.set_mode((400,)*2) - Utwórz powierzchnię wyświetlania 400 x 400

while c.fill((255,)*3): - Efektywnie while 1: ale także czyści ekran

e=event.get(2);c.blit(image.load("I"),p);d.flip() - Zbieraj tylko zdarzenia klawiatury, załaduj obraz zapisany w pliku png o nazwie I i narysuj go. Zaktualizuj ekran

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)))) - Jeśli wystąpiło zdarzenie, sprawdź, który klawisz strzałki został naciśnięty (robi dziwne rzeczy, jeśli naciśniesz inne klawisze), a następnie zmień położenie powierzchni w zależności od tego, który klawisz został naciśnięty.

niebieski
źródło
Naprawdę podoba mi się twoje rozwiązanie.
@Lembik Tak więc dozwolona jest nazwa pliku jednobajtowego? (Tj. Bez rozszerzenia?). Jeśli tak, sugeruję całkowite wykluczenie nazw plików z liczby bajtów.
mınxomaτ
@ mınxomaτ Nazwa pliku jednobajtowego jest dozwolona, ​​ale nie chcę wymyślać nowego schematu oceniania.
@Lembik Processing nie może obsłużyć jednobajtowych nazw plików ... więc jest to niesprawiedliwe.
TheDoctor
2
@TheDoctor To tylko w: Różne języki są różne! Proponuję, abyśmy również nie zezwalali na wyzwania, które wymagają wkładu ze standardowego wejścia, ponieważ to niesprawiedliwe, że potrzeba tak wielu znaków, aby zrobić to w Pythonie ...
Aleksi Torhamo,
5

Haskell, 410 bajtów

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)

Zdjęcie kosmity jest oczekiwane w pliku o nazwie bw.bmp formacie.

Jestem nowy w bibliotece Gloss, więc może to nie jest optymalne. Czy ktoś wie, czy mogę sprawdzić, czy naciśnięto klawisz zamiast śledzenia KeyUp/ KeyDownzdarzeń?

Jak to działa: ostatnie cztery parametry playto stan świata (zainicjowany ((0,0),id), funkcja rysująca obraz ze stanu ( #), moduł obsługi zdarzeń ( e) i funkcja zmieniająca stan w czasie ( %).

Stan to para współrzędnych xy i funkcja zmiany ich przy każdym %wywołaniu.

#przesuwa bitmapę ( b) na bieżące współrzędne i rysuje ją.

ewyszukuje KeyDownzdarzenia klawiszy kursora i ustawia odpowiednie funkcje w stanie lub KeyUpdowolnego klawisza, aby zresetować funkcję w stanie do funkcji tożsamości.

% stosuje funkcję od stanu do bieżących współrzędnych i sprawdza granice.

nimi
źródło
Zawsze jestem zdumiony, że możesz zrobić coś takiego w Haskell. Dziękuję Ci!
4

Wiąz 240 bajtów

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)

Wypróbuj tutaj . Liczba bajtów następuje po zamianie adresu URL na .png.

Lynn
źródło
Być może będę musiał się teraz nauczyć Wiązu. Dziękuję Ci.
3

AutoIt , 269 267 bajtów

#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

Wymaga zapisania obrazu jako b.bmp w katalogu skryptów. Jeśli chcesz użyć obrazu z faktyczną przezroczystością, musisz przekonwertować go z PNG na 32-bitową mapę bitową (OT: naprawdę niedoceniony format).

Wyjaśnienie

Musimy zaimportować, Misc.au3aby uzyskać dostęp do _IsPressed. Funkcja, która akceptuje kod klucza i zwraca go Truelub Falsepo naciśnięciu klawisza.

Specyfikacja wyzwania jest całkiem fajna, ponieważ musimy stworzyć kwadratowe okno o wielkości 400 pikseli. Domyślne parametry rozmiaru (oznaczone jako -1lub Default) to 400 x 400. Styl rozszerzonego systemu Windows jest ustawiony na34078728 . Wymusza to podwójne buforowanie okna i rysowanie od dołu do góry. Jest to konieczne, aby wyeliminować migotanie zgodnie z wymaganiami wyzwania. W systemie Windows 10 ta niezwykła (i nieco nieudokumentowana) kombinacja stylów łamie pasek tytułu okna (wszystkie efekty aktywowania są wyłączone).

$1i $2są zadeklarowane i będą zawierać przesunięcie xiy obrazu załadowanego przez układ sterowania $0. $3staje się wskaźnikiem funkcji, _IsPressedktóry znacznie skraca kod.

Ponieważ nie jest wymagane, aby móc wyjść z programu, skrypt ten działa w nieskończonej pętli ( Until 0).

$1+=$3("27")-$3("25")nadużywa wariantu typu danych w AutoIt, dynamicznie rzutując wartość logiczną zwróconą z _IsPressedna liczbę całkowitą, którą można dodać lub podnosić z przesunięcia x. To samo dla y. $1=($1>336)?336:($1<0)?0:$1używa operatora trójskładnikowego znanego z języków podobnych do C do wykonania kontroli granic, aby zatrzymać kosmitę na granicach.

GuiCtrlSetPos przesuwa kontrolkę obrazu do nowych współrzędnych.

Oto zrzut ekranu z przezroczystym kosmitą (możesz nawet poruszać się po przekątnej):

zrzut ekranu

mınxomaτ
źródło
Twoje tło nie jest białe!
sergiol,
2

Lua + LÖVE, 291 znaków

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

Wykorzystuje to okno o nieograniczonych rozmiarach 400 x 400. Nie udało mi się dostosować love.keyboard.setKeyRepeat()do przyspieszenia odczytu klucza, więc zrobiłem to w zalecany sposób, sprawdzając status każdego klucza.

Ponieważ moja relacja z Luą fornie jest najlepsza, ani tym razem nie udało się sprawić, by pętla była krótsza niż zrzutowanie na stałe stanu każdego klucza.

człowiek w pracy
źródło
2

SpecBAS - 285 255 bajtów

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

Ładuje obraz - kolor 15 jest jasny biały, dzięki czemu staje się przezroczysty.

Użycie oryginalnego obrazu i domyślnej palety SpecBAS sprawiło, że wyszło ono nieco dziwnie, więc linia 2 przełącza je, aby dopasować do obrazu wejściowego. Poniższe zdjęcie pokazuje, jak to wygląda bez linii 2 i po niej.

wprowadź opis zdjęcia tutaj

Komenda CLAMP ogranicza grafikę między 1 a 400 w obu kierunkach, zapisuje kilka instrukcji IF ... THEN.

Linia 9 po prostu czeka, aż rzeczy nadrobią zaległości i zapobiegnie migotaniu.

Porusza się o jeden piksel na raz w oparciu o logiczne sprawdzenie, który klawisz jest wciśnięty, więc przejście z boku na bok zajmuje nieco więcej niż 5 sekund.

Brian
źródło
2

Rubin z butami, 252 243 znaków

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}}

Wykorzystuje to okno o zmiennym rozmiarze, zaczynające się domyślnie 600 x 500. Jeśli zmienisz rozmiar okna, aby najeźdźca został pominięty, wróci po naciśnięciu klawisza następnego ruchu.

Sztuczka, by spełnić te wymagania, polega na tym, że pozycja najeźdźcy zmienia się w krokach co 4, ale rzeczywisty ruch wykonuje się w krokach co 1 przy 99 klatkach na sekundę.

człowiek w pracy
źródło
2

Tcl / Tk , 242 bajty

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}"}
sergiol
źródło
Aby uruchomić go w dowolnym systemie Linux: musisz mieć zainstalowane Tcl i Tk; następnie skopiuj kod do pliku, powiedzmy invaders.tcl; musisz także zapisać obraz jak .pngw tym samym folderze. Aby uruchomić skrypt, wpisz wish invaders.tcl w powłoce. PS: Może być bardziej golfowy, jeśli zamiast tego wkleja się kod w interaktywną powłokę, ponieważ obsługuje domyślnie skrócone polecenia.
sergiol,
1

JavaScript (przy użyciu paper.js), 215 bajtów

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 to framework graficzny JS, co oznacza, że ​​zawiera wiele przydatnych funkcji związanych z manipulowaniem obrazami. Aby uruchomić, po prostu skopiuj powyższe do sekcji po lewej stronie , a następnie, aby przesunąć kosmitę, kliknij raz w prawej sekcji, aby go ustawić. Jeśli twoja przeglądarka sobie z tym poradzi, powinna działać przy 60 klatkach na sekundę.

ivzem
źródło