顯示具有 LÖVE 標籤的文章。 顯示所有文章
顯示具有 LÖVE 標籤的文章。 顯示所有文章

2011年5月11日 星期三

在 LÖVE 實作追蹤系統

前言

之前用 actionscript3.0 做守塔遊戲的時候,有做了一個簡單的追蹤系統,現在把它移植到 LÖVE 上。

追蹤系統可以用在導彈,或是其它需要尾隨的應用。

 

範例程式下載

Tracker.love

 

情境說明

建立四個半徑不同大小的圓,追蹤的速度與半徑大小成反比;最小的圓追滑鼠,剩下的分別追比自己小一階的圓。

 

Screenshot

SNAGHTMLf1fcca

SNAGHTMLf2b4b0

 

程式碼(都在範例檔案內)

main.lua

 
require("lua/Circle")
require("lua/Tracker")
 
function love.load()
    mouse = {}
    
    circle1 = Circle.create(5)
    circle2 = Circle.create(10)
    circle3 = Circle.create(15)
    circle4 = Circle.create(20)
end
 
function love.update(dt)
    -- we need tracker/target provide x,y index for Tracker system
    
    -- let mouse provide x,y index
    mouse.x, mouse.y = love.mouse.getPosition()
    
    -- args = speed, tracker, target
    Tracker.trace(8, circle1, mouse)
    Tracker.trace(6, circle2, circle1)
    Tracker.trace(4, circle3, circle2)
    Tracker.trace(2, circle4, circle3)
end
 
function love.draw()
    circle1:draw()
    circle2:draw()
    circle3:draw()
    circle4:draw()
end

conf.lua

function love.conf(t)
    t.title = "Tracker"         -- The title of the window the game is in (string)
    t.author = "bmzz"           -- The author of the game (string)
    t.identity = nil            -- The name of the save directory (string)
    t.version = 072             -- The LOVE version this game was made for (number)
    t.console = false           -- Attach a console (boolean, Windows only)
    t.screen.width = 800        -- The window width (number)
    t.screen.height = 600       -- The window height (number)
    t.screen.fullscreen = false -- Enable fullscreen (boolean)
    t.screen.vsync = true       -- Enable vertical sync (boolean)
    t.screen.fsaa = 0           -- The number of FSAA-buffers (number)
    t.modules.joystick = false  -- Enable the joystick module (boolean)
    t.modules.audio = false     -- Enable the audio module (boolean)
    t.modules.keyboard = false  -- Enable the keyboard module (boolean)
    t.modules.event = true      -- Enable the event module (boolean)
    t.modules.image = false     -- Enable the image module (boolean)
    t.modules.graphics = true   -- Enable the graphics module (boolean)
    t.modules.timer = true      -- Enable the timer module (boolean)
    t.modules.mouse = true      -- Enable the mouse module (boolean)
    t.modules.sound = false     -- Enable the sound module (boolean)
    t.modules.physics = false   -- Enable the physics module (boolean)
end

lua/Circle.lua

 
Circle = {}
Circle.__index = Circle
 
function Circle.create(radius, attributes)
    attrs = attributes or {}
    
    local self = {}
    setmetatable(self, Circle)
    
    self.radius = radius
    self.segments = radius / 2
    if self.segments < 50 then self.segments = 50 end
    
    self.mode = attrs.mode or "line"
    
    self.x = attrs.x or 0
    self.y = attrs.y or 0
    
    self.color = attrs.color or {255, 255, 255}
    
    return self
end
 
function Circle:draw()
    love.graphics.setColor(self.color)
    love.graphics.circle(self.mode, self.x, self.y, self.radius, self.segments)
end

lua/Tracker.lua

 
Tracker = {}
 
function Tracker.trace(speed, tracker, target)
    local diffx = target.x - tracker.x
    local diffy = target.y - tracker.y
    
    local dist = math.sqrt(diffx ^ 2 + diffy ^ 2)
    local perc = speed / dist
    
    if dist > speed then
        tracker.x = tracker.x + diffx * perc
        tracker.y = tracker.y + diffy * perc
    else
        tracker.x = target.x
        tracker.y = target.y
    end
end

2011年5月4日 星期三

在 LÖVE 實作 Button

前言

絕大部分的應用,都會需要 Button,但在 LÖVE 沒有內建的 Button,因此需要自己實作。

 

範例程式下載

button.love

 

情境說明

左上角建立了三個 Button,都會偵測 hover 事件;上面兩個 Button 按下去時,會在畫面中央印出 Button 上面的文字,而 Clear Button 按下去的時候,將會清除畫面中央的文字。

 

Screenshot

SNAGHTML4aafd2b

 

程式碼(都在範例檔案內)

main.lua

 
require("lua/button.lua")
 
function love.load()
    text = ""
    
    -- 可在建立 Button 時宣告屬性
    buttons = {
        button1 = Button.create("Hello"),
        button2 = Button.create("World", {
            y = 20,
            fontcolor = {255, 0, 0}
        }),
        button3 = Button.create("Clear", {
            y = 40,
            font = love.graphics.newFont(15),
            fontcolor = {0, 255, 0}
        })
    }
    
    buttons.button2.text = "HELLO WORLD" -- 也可隨時調整文字
end
 
function love.update(dt)
    -- 主要畫面更新資訊時,也一併更新所有 button 的資訊
    for dummy, button in pairs(buttons) do
        button:update(dt)
    end
end
 
function love.mousepressed(x, y, button)
    -- 按下滑鼠按鍵時,將資訊傳給 Button:mousepressed 做判斷,可得知是否觸發 press
    if buttons.button1:mousepressed(x, y, button) then
        text = text .. buttons.button1.text .. "\n"
    end
    
    if buttons.button2:mousepressed(x, y, button) then
        text = text .. buttons.button2.text .. "\n"
    end
    
    if buttons.button3:mousepressed(x, y, button) then
        text = ""
    end
end
 
function love.draw()
    -- 繪製主要畫面時,也一併繪製所有的 Button
    for dummy, button in pairs(buttons) do
        button:draw()
    end
    
    love.graphics.setColor(255, 255, 255)
    
    -- 如果 Button hover 狀態為 true,顯示文字在 (600, 0) 的地方
    for dummy, button in pairs(buttons) do
        if button.hover then love.graphics.print(button.text .. " hover", 600, 0) end
    end
    
    love.graphics.print(text, 400, 0)
end

lua/button.lua

 
Button = {}
Button.__index = Button
 
function Button.create(text, attributes)
    attrs = attributes or {}
    
    local button = {}
    setmetatable(button, Button)
    
    -- hover 狀態紀錄,會隨時更新,不可設定
    button.hover = false
    
    -- 可設定的屬性,除 text 外皆有 default 值
    button.text = text
    button.x = attrs.x or 0
    button.y = attrs.y or 0
    
    button.font = attrs.font or love.graphics.newFont(12)
    button.fontcolor = attrs.fontcolor or {255, 255, 255}
    
    return button
end
 
function Button:update(dt)
    -- 動態更新 Button 的寬與高
    self.width = self.font:getWidth(self.text)
    self.height = self.font:getHeight()
    
    -- 抓取滑鼠座標
    local x, y = love.mouse.getPosition()
    
    -- 滑鼠座標落在 Button 內,將 hover 狀態更新為 true 反之為 false
    if x > self.x and x < self.x + self.width and
       y > self.y and y < self.y + self.height then
        self.hover = true
    else
        self.hover = false
    end
end
 
function Button:mousepressed(x, y, button)
    -- hover 狀態為 true,此時偵測到滑鼠按鍵按下,才會回傳 true 反之為 false
    if self.hover then
        return true
    else
        return false
    end
end
 
function Button:draw()
    love.graphics.setFont(self.font)
    love.graphics.setColor(self.fontcolor)
    love.graphics.print(self.text, self.x, self.y)
end