2017/11/24(金) [n年前の日記]
#1 [lua][love2d] love2dで敵をたくさん出してみる
Luaでクラスを作る方法が分かってきたので love2d で実験。雑魚的相当のオブジェクトをたくさん出せそうかテスト。
こんな感じに。
以下の環境で動かしてみたけれど、どちらも同じように動作した。
こんな感じに。
以下の環境で動かしてみたけれど、どちらも同じように動作した。
- Windows10 x64 + love2d 0.10.2
- Raspberry Pi Zero W + raspbian jessie + SDL2(OpenGL ES enable) + love2d
◎ 画像とソース。 :
使用画像は以下。License : CC0 / Public Domain ってことで。
_bg_640x480_02.png
_enemy02.png
ソースは以下。
_conf.lua
_main.lua
画像とソースをテキトーな名前のフォルダに入れて、love フォルダ名、で実行。
_bg_640x480_02.png
_enemy02.png
ソースは以下。
_conf.lua
function love.conf(t) t.window.title = "Enemys Test01" t.window.width = 1280 t.window.height = 720 t.window.vsync = true -- t.window.fullscreen = true -- t.window.fullscreentype = "exclusive" end
_main.lua
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, wdw_h = love.graphics.getDimensions()
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_02.png")
enemy_img = love.graphics.newImage("enemy02.png")
-- define enemy class
Enemy = {}
Enemy.new = function(x, y, dx, dy, xw, ang, angspd, img)
local obj = {}
obj.activate = true
obj.x = x
obj.y = y
obj.dx = dx
obj.dy = dy
obj.bx = x
obj.by = y
obj.xw = xw
obj.angle = ang
obj.angspd = angspd
obj.img = img
obj.img_w = img:getWidth()
obj.img_h = img:getHeight()
setmetatable(obj, {__index = Enemy})
return obj
end
Enemy.update = function(self, dt)
if not self.activate then return end
self.bx = self.bx + self.dx * dt
self.y = self.y + self.dy * dt
self.x = self.bx + self.xw * math.sin(math.rad(self.angle))
self.angle = (self.angle + self.angspd * dt) % 360.0
if self.y - self.img_h > scr_h then self.activate = false end
end
Enemy.draw = function(self)
if not self.activate then return end
local x = self.x - self.img_w / 2
local y = self.y - self.img_h / 2
local ang = math.rad(self.angle)
local scale = 1.0
local ox = self.img_w / 2
local oy = self.img_h / 2
love.graphics.draw(self.img, x, y, ang, scale, scale, ox, oy)
end
-- work
enemys = {}
born_timer = 0.0
math.randomseed(0)
-- framerate steady
min_dt = 1 / 60
next_time = love.timer.getTime()
end
function love.update(dt)
-- update
next_time = next_time + min_dt
if dt > 1.0 then return end
born_timer = born_timer + dt
if born_timer >= 0.3 then
-- enemy born
born_timer = born_timer - 0.3
x = math.random(scr_w)
y = -32
dx = 0
dy = 40 + math.random(80)
xw = 50
ang = math.random(360)
angspd = 240
obj = Enemy.new(x, y, dx, dy, xw, ang, angspd, enemy_img)
table.insert(enemys, obj)
end
-- move enemys
for i, spr in ipairs(enemys) do
spr:update(dt)
end
-- remove enemy
local elen = #enemys
for i=elen,1,-1 do
if not enemys[i].activate then
table.remove(enemys, i)
end
end
end
function love.draw()
-- set canvas
love.graphics.setCanvas(canvas)
-- draw BG
love.graphics.setColor(255, 255, 255)
love.graphics.draw(bgimg, 0, 0)
-- draw objects
love.graphics.setColor(255, 255, 255)
for i, spr in ipairs(enemys) do
spr:draw()
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)
love.graphics.print("enemys: "..tostring(#enemys), 10, 60)
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
画像とソースをテキトーな名前のフォルダに入れて、love フォルダ名、で実行。
◎ 少し解説。 :
上記のソースでは、Enemy というクラスを作って処理をしてる。以下の3つのメソッドを用意した。
Luaでクラスを作る際の書き方については、以下の解説ページが参考になった。
_Luaでオブジェクト指向(1)―基本はコロン記法とメタテーブル - Minecraftとタートルと僕
_blog/luaoo.md at master - kengonakajima/blog
色んな書き方があるっぽいけど…。
- クラス生成用メソッド Enemy.new
- 座標更新処理用メソッド Enemy.update
- 描画処理用メソッド Enemy.draw
Luaでクラスを作る際の書き方については、以下の解説ページが参考になった。
_Luaでオブジェクト指向(1)―基本はコロン記法とメタテーブル - Minecraftとタートルと僕
_blog/luaoo.md at master - kengonakajima/blog
色んな書き方があるっぽいけど…。
- hoge.new の中で他のメソッドも書くやり方だと、インスタンスを作るたびにメソッドが別領域に作られてメモリの無駄遣いになる。
- かといって setmetatable を使うと、メソッドは同じ領域を使うからメモリの面では助かるけど、メソッド名の検索が一々入るから処理速度は遅くなる。
[ ツッコむ ]
以上、1 日分です。
