-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclassic.lua
More file actions
185 lines (157 loc) · 5.09 KB
/
Copy pathclassic.lua
File metadata and controls
185 lines (157 loc) · 5.09 KB
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
--
-- classic
--
-- Copyright (c) 2014, rxi
--
-- This module is free software; you can redistribute it and/or modify it under
-- the terms of the MIT license. See LICENSE for details.
--
--[[
This module provides a simple classical inheritance system.
- 'Object' is the root base class. It provides the fundamental mechanisms for
class creation (:extend), instantiation (Class()), type checking (:is),
and interface implementation (:implement). It is a general-purpose class
and does not inherently know about game loops, updating, or drawing.
Think of it as the blueprint for making blueprints.
- 'GameObject' extends 'Object'. It is specifically designed for entities
that need to be updated each frame (move, animate),
and drawn on screen. It introduces methods like :update, :draw, :remove
and their collective counterparts (:updateAll, :drawAll).
--]]
---@class Object
---@description The fundamental base class for creating other classes.
---@field public objects table<number, Object> List of instances created directly from this class.
---@field public subclasses table<number, Object> List of direct subclasses created using `:extend()`.
---@field public super table | nil The parent class this class was extended from.
local Object = {}
Object.__index = Object
Object.objects = {}
Object.subclasses = {}
--- Constructor (called via ClassName(...))
---@param ... any Arguments passed to the instance constructor
function Object:new(...)
end
--- Creates a new class that inherits from this class (`self`).
---@generic Class:Object
---@param self Class
---@return table Class An new class table that inherits from `self`. Use `---@class NewClassName : Object` in your code when using this.
function Object:extend()
local cls = {}
for k, v in pairs(self) do
if k:find("__") == 1 then
cls[k] = v
end
end
cls.__index = cls
cls.super = self
cls.objects = {} -- Add a table to store objects of this class
cls.subclasses = {}
setmetatable(cls, self)
table.insert(self.subclasses,cls)
return cls
end
function Object:implement(...)
for _, cls in pairs({...}) do
for k, v in pairs(cls) do
if self[k] == nil and type(v) == "function" then
self[k] = v
end
end
end
end
--- Checks if an object instance (`self`) is derived from a given class (`T`).
---@param T table The class table to check against.
---@return boolean True if `self` is an instance of `T` or one of its subclasses.
function Object:is(T)
local mt = getmetatable(self)
while mt do
if mt == T then
return true
end
mt = getmetatable(mt)
end
return false
end
function Object:__tostring()
return "Object"
end
--- Metamethod called when a class table is called like a function `ClassName(...)`.
--- Creates, initializes, and stores a new instance.
--- Constructor (called via ClassName(...))
---@generic Class:Object
---@param self Class
---@param ... any Arguments to be passed to the instance's `:new()` method.
---@return Class
function Object:__call(...)
local obj = setmetatable({}, self)
obj:new(...)
table.insert(self.objects, obj)
return obj
end
---@class GameObject : Object things need to be updated and drawn like Shape, Bullet, Player, Enemy. Static things like Sprite, AudioSystem are not GameObject.
---@field objects GameObject[]
---@field subclasses GameObject[]
---@field removed boolean|nil Internal flag set when `remove()` is called on an instance.
---@field notRespondToDrawAll boolean|nil If true on an instance, it will be skipped by `drawAll`.
local GameObject=Object:extend()
--- Marks an instance for removal during the next update cycle.
function GameObject:remove()
self.removed=true
end
--- Removes all instances of this specific GameObject class and recursively
--- calls removeAll on its subclasses. Usually used to clear all objects
--- when entering/leaving a level.
function GameObject:removeAll()
for i =#self.objects,1,-1 do
table.remove(self.objects, i)
end
for key, cls in pairs(self.subclasses) do
cls:removeAll()
end
end
function GameObject:update(dt)
end
function GameObject:updateAll(dt)
-- why Object:updateAll can't update all things
-- it's because I overrode Shape:updateAll so cls call didn't get to Circle, Player, etc. fixed
for key, obj in pairs(self.objects) do
if not obj.removed then
obj:update(dt)
end
end
for key, cls in pairs(self.subclasses) do
cls:updateAll(dt)
end
local nextObjects={}
for i, obj in ipairs(self.objects) do
if not obj.removed then
table.insert(nextObjects,obj)
end
end
self.objects=nextObjects
end
function GameObject:draw()
end
function GameObject:drawAll()
for key, obj in pairs(self.objects) do
if not obj.removed and not obj.notRespondToDrawAll then
obj:draw()
end
end
for key, cls in pairs(self.subclasses) do
cls:drawAll()
end
end
function GameObject:drawText()
end
function GameObject:drawTextAll()
for key, obj in pairs(self.objects) do
if not obj.removed then
obj:drawText()
end
end
for key, cls in pairs(self.subclasses) do
cls:drawTextAll()
end
end
return {Object,GameObject}