原始太空侵略者(你能把它弄伤吗?)


18

原始太空侵略者

这是一个图形输出挑战,任务是提供每种语言最短的代码。

任务

您的代码应允许用户在屏幕/窗口周围移动以下外星人。

在此处输入图片说明

您的代码可以简单地从本地文件加载。可以随意将其转换为另一种标准图像格式,甚至可以修复注释中指出的图像中的小像素错误。

背景应为白色,并且窗口/屏幕必须至少为400像素乘400像素。如果您的语言不支持如此大的窗口/屏幕,则使用不超过200 x 200的最大尺寸。

要在屏幕上移动外星人,代码应使用标准键盘上的箭头键支持上/下/左/右。

您的代码应为完整程序

限制/约束

外星人应该在边界停留。它还应以均匀的速度平稳移动,没有可见的闪烁或卡顿现象,并且至少应显示24fps。从屏幕/窗口的一侧到另一侧大约需要2到5秒。

语言和图书馆

您可以使用自己喜欢的任何语言或库(不是针对此挑战而设计的)。但是,如果可能的话,我希望能够测试您的代码,因此,如果您可以提供有关如何在Ubuntu中运行代码的明确说明,将不胜感激。

目录

这篇文章底部的Stack Snippet会根据答案a)生成目录,a)作为每种语言最短解决方案的列表,b)作为整体排行榜。

为确保您的答案显示出来,请使用以下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τ您可以自己构建它,也可以仅从本地文件加载它。我没有注意到像素错误,但是我认为在任何情况下加载它都会减少代码量。

您可以定义“停在边界”吗?整个外星人是否需要始终可见,还是可以部分停在边界外?
timothymh 2015年

Answers:


12

划痕221个 217字节

单击该图像以查看实际效果。移动是由击键决定的,因此您设置的重复键越快,滑动就越平滑。

图像包含在项目中,但根据此meta post,通常从打高尔夫球的文本表示中算出暂存字节。如果对于是否可以接受(或运动是否足够平稳)存在分歧,请告诉我,我将尝试解决它。


这个答案很有趣!

您如何衡量此计划的规模?

@Lembik参见第二段。
蒂莫西

1
生成217个字节:scratchblocks.github.io/...
ev3commander

1
@Mauris是的,这就是“如果在边缘,弹跳”命令所要处理的。您可以通过单击图像来播放演示!
timothymh 2015年

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

哇。多么骇人听闻的东西。

使用位于http://pygame.org的模块'pygame' 。

说明

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 Processing无法处理单字节文件名...因此这是不公平的。
TheDoctor 2015年

2
@TheDoctor这就是:不同的语言是不同的!我建议我们也禁止接受来自stdin的挑战,因为在Python中这样做需要花费很多字符,这是不公平的……
Aleksi Torhamo 2015年

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任何键将状态中的功能重置为身份功能。

% 将功能从状态应用于当前坐标并检查边界。


我总是很惊讶您甚至可以在Haskell中做这种事情。谢谢!

4

Elm,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

AutoIt269267字节

#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像素的方形窗口,挑战的规格非常酷。默认的大小参数(表示为-1Default)为400x400。在扩展窗口样式设置为34078728。这将强制窗口被双重缓冲并从下到上绘制。根据挑战要求,这对于消除闪烁是必要的。在Windows 10中,这种不寻常的(并且有些未记录的)样式组合破坏了窗口标题栏(禁用了所有悬停效果)。

$1$2被声明,并且将保持x和由控制加载的图像的y偏移$0$3成为该函数的指针_IsPressed以大大缩短代码。

由于不需要退出程序,因此该脚本在无限循环(Until 0)中运行。

$1+=$3("27")-$3("25")通过将强制返回的布尔值动态转换为_IsPressed可以从x偏移量添加或减去的整数来滥用AutoIt中的变量数据类型。与y相同。$1=($1>336)?336:($1<0)?0:$1使用类C语言中已知的三元运算符执行边界检查,以将外星人停在边界处。

GuiCtrlSetPos 将图片控件移动到新坐标。

这是透明外星人的屏幕截图(您甚至可以对角移动):

screenshot


您的背景不白!
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 x 400窗口。我没有进行调整love.keyboard.setKeyRepeat()以加快按键读取速度,因此没有成功,因此我采用了建议的方式,即轮询每个按键的状态。

由于我与Lua的关系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行及之后的外观。

enter image description here

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 x500。如果您调整窗口的大小以使入侵者被排除在外,则在按下下一个移动键时会再次出现。

满足要求的技巧是,入侵者的位置以4的增量更改,但实际移动是以每秒99帧的增量1进行的。


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:如果将代码粘贴到交互式外壳中,则可以更好地解决问题,因为默认情况下它支持缩写命令。
sergiol

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图形框架,这意味着它具有许多有关图像处理的有用功能。要运行,只需将以上内容复制到此处左侧的部分中,然后要移动外星人,请在右侧部分中单击一次以使其聚焦。如果您的浏览器可以处理,则应以60fps的速度运行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.