mieki256's diary



2017/11/02(木) [n年前の日記]

#1 [lua][love2d][raspberrypi] love2dでインチキ多関節

love2dを勉強中。どのくらいスプライト相当が描画できそうか動作確認。

とりあえず、 _昔DXRubyを使って書いたインチキ多関節 を移植してみたり。こんな感じになった。

inchiki_takansetsu_love2d_ss.gif

スプライト相当を64枚描画してるのに、この速度。素晴らしい。

ただ、Pi Zero W上では、動きがちょっとガクガクしてる感じもする。

ひょっとすると、getFPS() が取得してるのは love.update() が呼ばれてる頻度で、描画はまた別なのかな。まあ、内部的には60FPS相当で処理できてるということなら、それはそれでいいか…。

何にせよ、Pi Zero上でリアルタイム系の2Dゲームを作ってみたい、てな場合、Lua + love2d は良い選択肢になりそうな予感。…OpenGL ESを有効にしたSDL2をビルドしないといかんあたりがハードルになりそうではあるけど。その版も apt でインストールできればいいのに。

使用画像とソース。 :

使用画像は以下。License : CC0 / Public Domain ってことで。

_bg_640x480.png
_ufo.png

ソースは以下。

_conf.lua
function love.conf(t)
  t.window.title = "Inchiki Takansetsu"
  t.window.width = 1280
  t.window.height = 720
  t.window.vsync = true
  -- t.window.fullscreen = true
  -- t.window.fullscreentype = "exclusive"
end

_main.lua
-- Inchiki Takansetsu

function love.load()
  -- init

  -- set filter
  love.graphics.setDefaultFilter("nearest", "nearest")

  scr_w = 640
  scr_h = 480
  canvas = love.graphics.newCanvas(scr_w, scr_h)

  -- get window width and height
  wdw_w = love.graphics.getWidth()
  wdw_h = love.graphics.getHeight()

  scr_scale = math.min((wdw_w / scr_w), (wdw_h / scr_h))
  scr_ofsx = (wdw_w - (scr_w * scr_scale)) / 2
  scr_ofsy = (wdw_h - (scr_h * scr_scale)) / 2

  -- load image
  bgimg = love.graphics.newImage("bg_640x480.png")
  img = love.graphics.newImage("ufo.png")
  img_w = img:getWidth()
  img_h = img:getHeight()

  -- work
  nmax = 64
  bx = scr_w / 2
  by = 0
  startdeg = 0
  poslist = {}
  for i=1,nmax do
    poslist[i] = {x=0, y=0}
  end

  -- framerate steady
  min_dt = 1 / 60
  next_time = love.timer.getTime()
end

function love.update(dt)
  -- update

  next_time = next_time + min_dt

  -- get mouse position
  local mx, my = love.mouse.getPosition()
  mx = (mx - scr_ofsx) / scr_scale
  my = (my - scr_ofsy) / scr_scale

  local dw = mx - bx
  local dh = my - by
  local deg = startdeg
  local h = 100
  for i=1,nmax do
    local ii = i - 1
    local x = bx + (dw * ii / nmax) - (img_w / 2)
    local y = by + (dh * ii / nmax) - (img_h / 2)
    -- local hh = h * ii / nmax
    local hh = h
    x = x + hh * math.sin(math.rad(deg))
    poslist[i].x = x
    poslist[i].y = y
    deg = deg + 8
  end

  startdeg = startdeg + 360 * dt
end

function love.draw()

  -- set canvas
  love.graphics.setCanvas(canvas)

  -- draw BG
  love.graphics.setColor(255, 255, 255)
  love.graphics.draw(bgimg, 0, 0)
  love.graphics.setColor(255, 255, 255)

  -- draw objs
  for i=1,nmax do
    local x = poslist[i].x
    local y = poslist[i].y
    love.graphics.draw(img, x, y)
  end

  -- unset canvas
  love.graphics.setCanvas()

  -- draw canvas to window
  love.graphics.setColor(255, 255, 255)
  love.graphics.draw(canvas, scr_ofsx, scr_ofsy, 0, scr_scale, scr_scale)

  love.graphics.print("FPS: "..tostring(love.timer.getFPS()), 10, 10)
  love.graphics.print("env: "..tostring(love.system.getOS()), 10, 40)

  if love.system.getOS() == "Windows" then
    -- wait
    local cur_time = love.timer.getTime()
    if next_time <= cur_time then
      next_time = cur_time
    else
      love.timer.sleep(next_time - cur_time)
    end
  end
end

function love.keypressed(key, isrepeat)
  -- ESC to exit
  if key == "escape" then
    love.event.quit()
  end
end

何かテキトーな名前のフォルダを作って、画像と *.lua を入れて、「love フォルダ名」で実行できる。

それにしても…。 _DXRuby版 と比べると、長いな…。

少し説明。 :

Raspberry Pi Zero上でフルスクリーン表示をする関係で、一旦 canvas 内に描画してから、その canvas をウインドウに描画する、ということをしてる。先日書いたソースではアスペクト比がおかしい状態で引き延ばしてたけど、今回はアスペクト比をちゃんと維持するようにしてみた。love.load() の中で、canvasの拡大縮小率や描画座標を求めてる。

マウス座標の取得は、love.mouse.getPosition() でできるらしい。
local mx, my = love.mouse.getPosition()
今回、canvas を拡大縮小して描画してるので、ソレを考慮してマウス座標を求めてる。

Windows上ではFPS値がスゴイことになってたけど、どうやら本来は、時間を測って sleep を入れるべき、らしい。 _love.timer.sleep (日本語) - LOVE で、そのあたりのサンプルが提示されてる。ただ、Raspberry Pi上で動かした場合は、特に何もしなくても love.timer.getFPS() が 60FPS を返すので、今回は Windows上で動いてる時のみ、該当処理が行われるようにしてみた。

_love.system.getOS() で、OS種類が取得できる。
  • Windows10 x64上で動かしたら、"Windows" が返ってきた。
  • Raspberry Pi上で動かしたら、"Linux" が返ってきた。
ん? コレって、フツーのLinux上で動かしているのか、Raspberry Pi上で動かしているのかは、判別できないのかな? 今後の課題かも。

#2 [lua][love2d] NTEmacs上にlua-modeを追加

昨日まで、lua + love2d のソースを _Notepad++ で編集していたのだけど。どうも個人的に使い勝手がしっくりこない感じがしてきたので、emacs(NTEmacs 24.5.1) に lua-mode 等をインストールして環境整備を。ちなみに環境は Windows10 x64。

いやまあ、Notepad++ での編集も、それほど悪くないのだけど。ショートカットキー一発で、love2dを実行できるように設定できたりもするので…。フツーは Notepad++ のほうがオススメというか。

lua-modeのインストール。 :

lua-mode は以下。…じゃないかな。たぶん。

_Lua-mode

M-x list-package で一覧を表示して、lua-mode 20170130版をインストール。(C-s で lua-mode を検索して、該当行でiキーを押してxキー)。

~/.emacs に以下を追加。
;; ----------------------------------------
;; lua-mode

;; This snippet enables lua-mode
;; This line is not necessary, if lua-mode.el is already on your load-path
;; (add-to-list 'load-path "/path/to/directory/where/lua-mode-el/resides")

(autoload 'lua-mode "lua-mode" "Lua editing mode." t)
(add-to-list 'auto-mode-alist '("\\.lua$" . lua-mode))
(add-to-list 'interpreter-mode-alist '("lua" . lua-mode))

インデントレベルが3になってる模様。2にする。
(setq lua-indent-level 2)

これで、.lua を開いたら lua-mode になってくれた。

love2d用のマイナーモードをインストール。 :

love2d用のマイナーモード、love-minor-mode.el を公開してくれてる方が居るようで。これもありがたく使わせてもらおう…。

_ejmr/love-minor-mode: An Emacs minor mode for LOVE

love-minor-mode.el をDL。emacs からパスが通ってる場所に置く。

love-minor-mode.el 内で、love.exe の場所を決め打ちしてるところがあるので修正。「love.exe」で検索すれば見つかるはず。もっとも、love.exe にPATHが通ってる環境なら、.el 内を編集する必要はないけれど。

~/.emacs に以下を追加。
;; love2d love-minor-mode
(require 'love-minor-mode)

使い方は…。例えば main.lua 等を開いている状態で、M-x love-minor-mode を実行。「Love-minor-mode enabled」と表示されたら該当マイナーモードが有効になる。再度 M-x love-minor-mode と打てば無効になる。

M-p に love/play が割り当てられているので、main.lua を編集中に M-p を叩けば、love.exe を呼び出して実行してくれる。

以上、1 日分です。

過去ログ表示

Prev - 2017/11 -
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

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project