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 日分です。