Skip to content

Commit bc0349b

Browse files
KuanlanKuanlan
authored andcommitted
new example
1 parent 252f7e4 commit bc0349b

File tree

2 files changed

+244
-92
lines changed

2 files changed

+244
-92
lines changed

data/example/src/main.lua

Lines changed: 191 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,212 @@
1-
local timer = 0
2-
local window = { width = 1280, height = 720, }
1+
--------------------------------------------------------------------------------
2+
--- LuaSTG basic example
3+
--- by Kuanlan@outlook.com
4+
--------------------------------------------------------------------------------
5+
36
local Keyboard = lstg.Input.Keyboard
47
local task = require("task")
58
local global_tasks = task.Manager()
6-
local global_color = lstg.Color(255, 0, 0, 0)
7-
local function set_camera()
9+
10+
--------------------------------------------------------------------------------
11+
--- camera
12+
13+
local window = { width = 1280, height = 720, }
14+
local function applyCamera()
815
lstg.SetViewport(0, window.width, 0, window.height)
916
lstg.SetScissorRect(0, window.width, 0, window.height)
1017
lstg.SetOrtho(0, window.width, 0, window.height)
1118
lstg.SetImageScale(1)
1219
lstg.SetFog()
1320
end
21+
22+
--------------------------------------------------------------------------------
23+
--- game object
24+
25+
local LAYER_PLAYER = 0
26+
local LAYER_ENEMY_BULLET = 100
27+
local GROUP_PLAYER = 1
28+
local GROUP_ENEMY_BULLET = 2
29+
local function clamp(v, a, b)
30+
return math.max(a, math.min(v, b))
31+
end
32+
local player_class = {
33+
function(self)
34+
self.group = GROUP_PLAYER
35+
self.layer = LAYER_PLAYER
36+
self.img = "player-rect"
37+
self.rect = true
38+
self.a = 8 -- 16x16
39+
self.b = 8
40+
self.bound = false
41+
self.x = window.width / 2
42+
self.y = window.height / 4
43+
end,
44+
function(self) end,
45+
function(self)
46+
local dx = 0
47+
local dy = 0
48+
if Keyboard.GetKeyState(Keyboard.Left) and Keyboard.GetKeyState(Keyboard.Right) then
49+
dx = 0
50+
elseif Keyboard.GetKeyState(Keyboard.Left) then
51+
dx = -1
52+
elseif Keyboard.GetKeyState(Keyboard.Right) then
53+
dx = 1
54+
end
55+
if Keyboard.GetKeyState(Keyboard.Down) and Keyboard.GetKeyState(Keyboard.Up) then
56+
dy = 0
57+
elseif Keyboard.GetKeyState(Keyboard.Down) then
58+
dy = -1
59+
elseif Keyboard.GetKeyState(Keyboard.Up) then
60+
dy = 1
61+
end
62+
if dx ~= 0 and dy ~= 0 then
63+
local k = math.sqrt(2.0) * 0.5
64+
dx = dx * k
65+
dy = dy * k
66+
end
67+
local speed = 4
68+
if Keyboard.GetKeyState(Keyboard.LeftShift) then
69+
speed = 2
70+
end
71+
self.x = clamp(self.x + speed * dx, 8, window.width - 8)
72+
self.y = clamp(self.y + speed * dy, 8, window.height - 8)
73+
end,
74+
lstg.DefaultRenderFunc,
75+
function(self, other)
76+
if other.group == GROUP_ENEMY_BULLET then
77+
lstg.Del(other)
78+
end
79+
end,
80+
function(self) end;
81+
is_class = true,
82+
}
83+
local bullet_class = {
84+
function(self)
85+
self.group = GROUP_ENEMY_BULLET
86+
self.layer = LAYER_ENEMY_BULLET
87+
self.img = "bullet-rect"
88+
self.rect = true
89+
self.a = 4 -- 16x16 / 2
90+
self.b = 4
91+
self.hscale = 0.5
92+
self.vscale = 0.5
93+
end,
94+
function(self) end,
95+
function(self) end,
96+
lstg.DefaultRenderFunc,
97+
function(self, other) end,
98+
function(self) end;
99+
is_class = true,
100+
}
101+
local function createBullet(x, y, a, v)
102+
local obj = lstg.New(bullet_class)
103+
obj.x = x
104+
obj.y = y
105+
lstg.SetV(obj, v, a, true)
106+
return obj
107+
end
108+
local function buildGameObjectScene()
109+
lstg.ResetPool()
110+
lstg.New(player_class)
111+
global_tasks:add(function()
112+
while true do
113+
local x, y = window.width / 2, window.height / 2
114+
for i = 0, 239 do
115+
createBullet(x, y, (i / 240) * 360, 3)
116+
end
117+
task.wait(4)
118+
end
119+
end)
120+
end
121+
local function updateGameObject()
122+
lstg.ObjFrame()
123+
lstg.SetBound(0, window.width, 0, window.height)
124+
lstg.BoundCheck()
125+
lstg.CollisionCheck(GROUP_PLAYER, GROUP_ENEMY_BULLET)
126+
lstg.UpdateXY()
127+
lstg.AfterFrame()
128+
end
129+
local function renderGameObject()
130+
lstg.ObjRender()
131+
end
132+
133+
--------------------------------------------------------------------------------
134+
--- background
135+
136+
local timer = 0
137+
local function updateBackground()
138+
timer = timer + 1
139+
end
140+
local function renderText(font, text, x, y, scale, color, oscale, ocolor, align)
141+
local d = oscale
142+
local k = oscale * math.sqrt(2.0) * 0.5
143+
local s = 2 * scale
144+
lstg.RenderTTF(font, text, x - d, x - d, y, y, align, ocolor, s)
145+
lstg.RenderTTF(font, text, x + d, x + d, y, y, align, ocolor, s)
146+
lstg.RenderTTF(font, text, x, x, y - d, y - d, align, ocolor, s)
147+
lstg.RenderTTF(font, text, x, x, y + d, y + d, align, ocolor, s)
148+
lstg.RenderTTF(font, text, x - k, x - k, y + k, y + k, align, ocolor, s)
149+
lstg.RenderTTF(font, text, x + k, x + k, y + k, y + k, align, ocolor, s)
150+
lstg.RenderTTF(font, text, x + k, x + k, y - k, y - k, align, ocolor, s)
151+
lstg.RenderTTF(font, text, x - k, x - k, y - k, y - k, align, ocolor, s)
152+
lstg.RenderTTF(font, text, x, x, y, y, align, color, s)
153+
end
154+
local function renderBackground()
155+
local cx, cy = window.width / 2, window.height / 2
156+
renderText("Sans", "海内存知己\n天涯若比邻\n欢迎来到 LuaSTG Sub",
157+
cx, cy,
158+
1, lstg.Color(255, 2255, 255, 255),
159+
4, lstg.Color(255, 0, 0, 0),
160+
1 + 4)
161+
local circle_r = 300
162+
for i = 0, (360 - 1), (360 / 60) do
163+
local angle = i + timer * 0.17
164+
local cosv, sinv = math.cos(math.rad(angle)), math.sin(math.rad(angle))
165+
local hscale = 16 + 15 * math.sin(math.rad(i * 11 + timer * 0.11))
166+
local cr = circle_r + hscale * 8
167+
lstg.Render("black-rect", cx + cr * cosv, cy + cr * sinv, angle, hscale, 1)
168+
end
169+
end
170+
local function drawDebugInfo()
171+
renderText("Sans", "移动/Move: ←↑↓→ 低速移动/Slower Move: LeftShift",
172+
4, 4,
173+
0.5, lstg.Color(255, 2255, 255, 255),
174+
2, lstg.Color(255, 0, 0, 0),
175+
0 + 8)
176+
local text = string.format("OBJ %d FPS %.2f", lstg.GetnObj(), lstg.GetFPS())
177+
renderText("Sans", text,
178+
window.width - 4, 4,
179+
0.5, lstg.Color(255, 2255, 255, 255),
180+
2, lstg.Color(255, 0, 0, 0),
181+
2 + 8)
182+
end
183+
184+
--------------------------------------------------------------------------------
185+
--- framework
186+
14187
function GameInit()
15188
lstg.ChangeVideoMode(window.width, window.height, true, false)
16-
set_camera()
189+
applyCamera()
17190
lstg.LoadTexture("white", "res/white.png", false)
18191
lstg.LoadImage("white", "white", 0, 0, 16, 16)
192+
lstg.LoadImage("black-rect", "white", 0, 0, 16, 16)
193+
lstg.SetImageState("black-rect", "", lstg.Color(255, 0, 0, 0))
194+
lstg.LoadImage("player-rect", "white", 0, 0, 16, 16)
195+
lstg.SetImageState("player-rect", "", lstg.Color(255, 64, 64, 255))
196+
lstg.LoadImage("bullet-rect", "white", 0, 0, 16, 16)
197+
lstg.SetImageState("bullet-rect", "", lstg.Color(96, 0, 0, 0))
19198
if not lstg.LoadTTF("Sans", "C:/Windows/Fonts/msyh.ttc", 48, 48) then
20199
lstg.LoadTTF("Sans", "C:/Windows/Fonts/msyh.ttf", 48, 48) -- Windows 7
21200
end
22-
global_tasks:add(function()
23-
while true do
24-
for i = 1, 60 do
25-
global_color.r = (i / 60) * 128
26-
global_color.b = (i / 60) * 128
27-
task.wait(1)
28-
end
29-
for i = 59, 0, -1 do
30-
global_color.r = (i / 60) * 128
31-
global_color.b = (i / 60) * 128
32-
task.wait(1)
33-
end
34-
global_tasks:add(function()
35-
for i = 1, 15 do
36-
global_color.g = (i / 15) * 192
37-
task.wait(1)
38-
end
39-
for i = 14, 0, -1 do
40-
global_color.g = (i / 15) * 192
41-
task.wait(1)
42-
end
43-
end)
44-
end
45-
end)
201+
buildGameObjectScene()
46202
end
47203
function GameExit()
48204
end
49205
function FrameFunc()
50206
global_tasks:remove_dead()
51207
global_tasks:resume_all()
52-
lstg.ObjFrame()
53-
lstg.BoundCheck()
54-
lstg.CollisionCheck(1, 2) -- group 1 and group 2
55-
lstg.UpdateXY()
56-
lstg.AfterFrame()
57-
timer = timer + 1
208+
updateBackground()
209+
updateGameObject()
58210
if Keyboard.GetKeyState(Keyboard.Escape) then
59211
return true -- exit
60212
end
@@ -63,18 +215,9 @@ end
63215
function RenderFunc()
64216
lstg.BeginScene()
65217
lstg.RenderClear(lstg.Color(255, 255, 255, 255))
66-
set_camera()
67-
lstg.ObjRender()
68-
local cx, cy = window.width / 2, window.height / 2
69-
lstg.RenderTTF("Sans", "海内存知己\n天涯若比邻\n欢迎来到 LuaSTG Sub", cx, cx, cy, cy, 1 + 4, lstg.Color(255, 0, 0, 0), 2)
70-
lstg.SetImageState("white", "", global_color)
71-
local circle_r = 300
72-
for i = 0, (360 - 1), (360 / 60) do
73-
local angle = i + timer * 0.17
74-
local cosv, sinv = math.cos(math.rad(angle)), math.sin(math.rad(angle))
75-
local hscale = 16 + 15 * math.sin(math.rad(i * 11 + timer * 0.11))
76-
local cr = circle_r + hscale * 8
77-
lstg.Render("white", cx + cr * cosv, cy + cr * sinv, angle, hscale, 1)
78-
end
218+
applyCamera()
219+
renderGameObject()
220+
renderBackground()
221+
drawDebugInfo()
79222
lstg.EndScene()
80223
end

data/example/src/task.lua

Lines changed: 53 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,72 @@
1+
--------------------------------------------------------------------------------
2+
--- lua coroutine wrapper - task manager
3+
--- by Kuanlan@outlook.com
4+
--------------------------------------------------------------------------------
15

26
---@class task
37
local M = {}
4-
task = M
58

6-
---@return task.Manager
7-
function M.Manager()
8-
---@class task.Manager
9-
local I = {}
9+
---@class task.Manager
10+
local I = {}
1011

11-
I.size = 0
12+
I.size = 0
1213

13-
--- Note: "thread" in lua are actually coroutines
14-
---@param f function
15-
---@return thread
16-
function I:add(f)
17-
local co = coroutine.create(f)
18-
self.size = self.size + 1
19-
self[self.size] = co
20-
return co
21-
end
14+
--- Note: "thread" in lua are actually coroutines
15+
---@param f function
16+
---@return thread
17+
function I:add(f)
18+
local co = coroutine.create(f)
19+
self.size = self.size + 1
20+
self[self.size] = co
21+
return co
22+
end
2223

23-
--- resume all not "dead" coroutines
24-
function I:resume_all()
25-
local n = self.size
26-
for i = 1, n do
27-
if coroutine.status(self[i]) ~= "dead" then
28-
assert(coroutine.resume(self[i]))
29-
end
24+
--- resume all not "dead" coroutines
25+
function I:resume_all()
26+
local n = self.size
27+
for i = 1, n do
28+
if coroutine.status(self[i]) ~= "dead" then
29+
assert(coroutine.resume(self[i]))
3030
end
3131
end
32+
end
3233

33-
--- remove all "dead" coroutines
34-
function I:remove_dead()
35-
local j = 1
36-
local n = self.size
37-
for i = 1, n do
38-
if coroutine.status(self[i]) ~= "dead" then
39-
if i > j then
40-
self[j] = self[i]
41-
end
42-
j = j + 1
34+
--- remove all "dead" coroutines
35+
function I:remove_dead()
36+
local j = 1
37+
local n = self.size
38+
for i = 1, n do
39+
if coroutine.status(self[i]) ~= "dead" then
40+
if i > j then
41+
self[j] = self[i]
4342
end
43+
j = j + 1
4444
end
45-
for k = j, n do
46-
self[k] = nil
47-
end
48-
self.size = j - 1
4945
end
46+
for k = j, n do
47+
self[k] = nil
48+
end
49+
self.size = j - 1
50+
end
5051

51-
--- remove all coroutines
52-
function I:clear()
53-
local n = self.size
54-
for i = 1, n do
55-
self[i] = nil
56-
end
57-
self.size = 0
52+
--- remove all coroutines
53+
function I:clear()
54+
local n = self.size
55+
for i = 1, n do
56+
self[i] = nil
5857
end
58+
self.size = 0
59+
end
5960

60-
return I
61+
---@return task.Manager
62+
function M.Manager()
63+
---@type task.Manager
64+
local C = { size = 0 }
65+
C.add = I.add
66+
C.resume_all = I.resume_all
67+
C.remove_dead = I.remove_dead
68+
C.clear = I.clear
69+
return C
6170
end
6271

6372
---@param times number

0 commit comments

Comments
 (0)