SHOW:
|
|
- or go back to the newest paste.
1 | local scr_x, scr_y = term.getSize() | |
2 | palateFile = fs.combine(shell.dir(),"palate") | |
3 | - | levelFile = nil |
3 | + | levelFile = "level" |
4 | ||
5 | guy = { | |
6 | x = 2, --Your X position on the MAP, not the screen. | |
7 | y = 5, --Same, but with Y. | |
8 | speedY = 0, --I want to represent gravity fairly accurately. | |
9 | char = "O", --The character that represents you. | |
10 | mode = "", --Determines whether you are walking, jumping, whatever. | |
11 | grounded = false, --Whether or not you are on solid ground, and can jump. | |
12 | bgcol = colors.red, --Background color. | |
13 | txtcol = colors.yellow, --Text color. | |
14 | name = "Mario", --Thine name! I just added this in case I want to use it. | |
15 | } | |
16 | ||
17 | local tArg = {...} | |
18 | if tArg[1] then | |
19 | levelFile = fs.combine(shell.dir(),tArg[1]) | |
20 | end | |
21 | if tArg[2] then | |
22 | palateFile = fs.combine(shell.dir(),tArg[2]) | |
23 | end | |
24 | ||
25 | scrollX = 0 | |
26 | scrollY = 0 | |
27 | ||
28 | function CTB(_color) --Color To Blit | |
29 | local blitcolors = { | |
30 | [colors.white] = "0", | |
31 | [colors.orange] = "1", | |
32 | [colors.magenta] = "2", | |
33 | [colors.lightBlue] = "3", | |
34 | [colors.yellow] = "4", | |
35 | [colors.lime] = "5", | |
36 | [colors.pink] = "6", | |
37 | [colors.gray] = "7", | |
38 | [colors.lightGray] = "8", | |
39 | [colors.cyan] = "9", | |
40 | [colors.purple] = "a", | |
41 | [colors.blue] = "b", | |
42 | [colors.brown] = "c", | |
43 | [colors.green] = "d", | |
44 | [colors.red] = "e", | |
45 | [colors.black] = "f", | |
46 | } | |
47 | return blitcolors[_color] | |
48 | end | |
49 | ||
50 | if fs.exists(palateFile) then | |
51 | dofile(palateFile) | |
52 | end | |
53 | ||
54 | if not palate then | |
55 | palate = { --I say palate because it can (as should be expected to) be changed per game. | |
56 | [1] = { --Blocks will be stored as IDs, not by name. | |
57 | desc = "air", --Brief description of what it is supposed to represent. | |
58 | char = " ", --Character used to represent it. | |
59 | txtcol = colors.black, --TEXT color. Uses colors API, not blit. | |
60 | bgcol = colors.black, --BACKGROUND color. Again, colors API. | |
61 | solid = false, --Whether or not you can go through it. | |
62 | isLiquid = false, --Whether it is a liquid or not. | |
63 | touchDamage = 0, --Damage done by TOUCHING IT. Meaning, being inside it OR a space next to it. | |
64 | insideDamage = 0, --Damage done by BEING IN THE SAME SPACE AS IT. Not being next to it. | |
65 | gravity = 1, --Gravity (let's just say in G's) when INSIDE the block. | |
66 | }, --Oh BTW, [1] will always be air. That's constant. Also, it's not really a block, but an empty space. | |
67 | [2] = { | |
68 | desc = "sto ne", | |
69 | char = "L", | |
70 | txtcol = colors.lightGray, | |
71 | bgcol = colors.gray, | |
72 | solid = true, | |
73 | isLiquid = false, | |
74 | touchDamage = 0, | |
75 | insideDamage = 0, | |
76 | gravity = 1, | |
77 | }, | |
78 | [3] = { | |
79 | desc = "woodplank", | |
80 | char = "=", | |
81 | txtcol = colors.orange, | |
82 | bgcol = colors.brown, | |
83 | solid = true, | |
84 | isLiquid = false, | |
85 | touchDamage = 0, | |
86 | insideDamage = 0, | |
87 | gravity = 1, | |
88 | }, | |
89 | [4] = { | |
90 | desc = "water", | |
91 | char = "/", | |
92 | txtcol = colors.lightBlue, | |
93 | bgcol = colors.cyan, | |
94 | solid = false, | |
95 | isLiquid = true, | |
96 | touchDamage = 0, | |
97 | insideDamage = 0, | |
98 | gravity = 0.4, | |
99 | }, | |
100 | [5] = { | |
101 | desc = "lava", | |
102 | char = "#", | |
103 | txtcol = colors.red, | |
104 | bgcol = colors.orange, | |
105 | solid = false, | |
106 | isLiquid = true, | |
107 | touchDamage = 0, | |
108 | insideDamage = 2, | |
109 | gravity = 1.2, | |
110 | }, | |
111 | [6] = { | |
112 | desc = "cactus", | |
113 | char = "#", | |
114 | txtcol = colors.gray, | |
115 | bgcol = colors.green, | |
116 | solid = true, | |
117 | isLiquid = false, | |
118 | touchDamage = 1, | |
119 | insideDamage = 0, | |
120 | gravity = 1, | |
121 | }, | |
122 | } | |
123 | local file = fs.open(palateFile,"w") | |
124 | file.write("palate = "..textutils.serialise(palate)) | |
125 | file.close() | |
126 | end | |
127 | selectedItem = 1 | |
128 | local level | |
129 | if levelFile then | |
130 | local file = fs.open(levelFile,"r") | |
131 | level = textutils.unserialize(file.readAll()) | |
132 | file.close() | |
133 | else | |
134 | level = {{}} | |
135 | end | |
136 | ||
137 | function inflateLevel(_level) | |
138 | local output = _level | |
139 | local maxLong = 0 | |
140 | local maxHigh = #level | |
141 | for a = 1, #_level do | |
142 | for b = 1, #_level[a] do | |
143 | if #_level[a][b] > maxLong then | |
144 | maxLong = #_level[a] | |
145 | end | |
146 | end | |
147 | end | |
148 | for a = 1, maxHigh do | |
149 | if not _level[a] then | |
150 | - | lobster = palate[level[x+scrollX][(scr_y-y)+scrollY+1]] --Well it wasn't a rock |
150 | + | output[a] = {} |
151 | - | if lobster and y ~= scr_y then |
151 | + | |
152 | for b = 1, maxLong do | |
153 | if not _level[a][b] then | |
154 | output[a][b] = 1 | |
155 | end | |
156 | end | |
157 | end | |
158 | return output | |
159 | end | |
160 | ||
161 | level = inflateLevel(level) | |
162 | ||
163 | local function clearDot(x,y,col) | |
164 | local pX,pY = term.getCursorPos() | |
165 | term.setCursorPos(x,y) | |
166 | if col then | |
167 | term.blit(" ",CTB(col),CTB(col)) | |
168 | else | |
169 | - | function drawDock(_palate,selected) |
169 | + | |
170 | end | |
171 | - | term.setBackgroundColor(colors.white) |
171 | + | |
172 | end | |
173 | ||
174 | - | local dockpos = {} |
174 | + | |
175 | - | for a = 1, #_palate do |
175 | + | |
176 | - | term.setCursorPos(a,scr_y) |
176 | + | |
177 | - | table.insert(dockpos,{x=a,desc=_palate[a].desc}) |
177 | + | |
178 | - | term.blit(_palate[a].char,CTB(_palate[a].txtcol),CTB(_palate[a].bgcol)) |
178 | + | |
179 | - | term.setCursorPos(scr_x-#_palate[selected].desc,scr_y) |
179 | + | |
180 | - | term.setTextColor(colors.black) |
180 | + | |
181 | - | term.setBackgroundColor(colors.white) |
181 | + | |
182 | - | term.write(_palate[selected].desc) |
182 | + | |
183 | end | |
184 | - | return dockpos |
184 | + | |
185 | function renderLevel(_level,_scrollX,_scrollY) | |
186 | if guy.x > math.floor(scr_x/2) then | |
187 | - | function handleKey(e) |
187 | + | scrollX = guy.x - math.floor(scr_x/2) |
188 | - | local _,key = table.unpack(e) |
188 | + | term.clear() |
189 | - | oldScrollX, oldScrollY = scrollX, scrollY |
189 | + | |
190 | - | if key == keys.left and scrollX > 0 then |
190 | + | clearDot(guy.x,guy.y,palate[level[guy.y][guy.x]].bgcol) |
191 | - | scrollX = scrollX - 1 |
191 | + | |
192 | - | elseif key == keys.right then |
192 | + | |
193 | - | scrollX = scrollX + 1 |
193 | + | |
194 | - | elseif key == keys.down and scrollY > 0 then |
194 | + | |
195 | - | scrollY = scrollY - 1 |
195 | + | lobster = palate[level[(scr_y-y)+scrollY+1][x+scrollX]] --Well it wasn't a rock |
196 | - | elseif key == keys.up then |
196 | + | if lobster then |
197 | - | scrollY = scrollY + 1 |
197 | + | |
198 | - | elseif key == keys.q then |
198 | + | |
199 | - | handleQuit() |
199 | + | |
200 | end | |
201 | - | if oldScrollX ~= scrollX or oldScrollY ~= scrollY then |
201 | + | |
202 | - | palateclear() |
202 | + | |
203 | - | drawDock(palate,selectedItem) |
203 | + | term.setCursorPos(guy.x-scrollX,(scr_y-guy.y)+scrollY) |
204 | term.blit(guy.char,CTB(guy.txtcol),CTB(guy.bgcol)) | |
205 | end | |
206 | ||
207 | function handleQuit() | |
208 | - | function handleMouseClick(e) |
208 | + | |
209 | - | local _,button,x,y = table.unpack(e) |
209 | + | |
210 | - | local dockpos = drawDock(palate,selectedItem) |
210 | + | |
211 | - | if y == scr_y then --handle dock clicking |
211 | + | |
212 | - | for a = 1, #dockpos do |
212 | + | |
213 | - | if dockpos[a].x == x then |
213 | + | |
214 | - | selectedItem = a |
214 | + | |
215 | - | dockpos = drawDock(palate,selectedItem) |
215 | + | |
216 | - | break |
216 | + | function handleGuyPhysics(mode) |
217 | local gravity | |
218 | if level[guy.y] then | |
219 | - | else --handle drawing things |
219 | + | if level[guy.y][guy.x] then |
220 | - | if not level[x+scrollX] then level[x+scrollX] = {} end |
220 | + | gravity = palate[level[guy.y][guy.x]].gravity |
221 | - | if selectedItem == 1 then --air |
221 | + | |
222 | - | level[x+scrollX][(scr_y-y)+scrollY+1] = nil |
222 | + | gravity = palate[1].gravity |
223 | - | clearDot(x,y,palate[1].bgcol) |
223 | + | |
224 | else | |
225 | - | level[x+scrollX][(scr_y-y)+scrollY+1] = selectedItem |
225 | + | gravity = palate[1].gravity |
226 | end | |
227 | guy.speedY = guy.speedY - gravity | |
228 | if level[guy.x] then | |
229 | if level[guy.x][guy.y-gravity] then | |
230 | if palate[level[guy.y-gravity][guy.x]].solid then | |
231 | guy.grounded = true | |
232 | guy.speedY = 0 | |
233 | - | drawDock(palate,selectedItem) |
233 | + | else |
234 | guy.grounded = false | |
235 | guy.y = guy.y + guy.speedY | |
236 | - | evt = {os.pullEvent()} |
236 | + | |
237 | - | if evt[1] == "mouse_click" or evt[1] == "mouse_drag" then |
237 | + | |
238 | - | handleMouseClick(evt) |
238 | + | guy.grounded = false |
239 | - | elseif evt[1] == "key" then |
239 | + | guy.y = guy.y + guy.speedY |
240 | - | handleKey(evt) |
240 | + | |
241 | end | |
242 | if mode == "jump" then | |
243 | if guy.grounded then | |
244 | guy.speedY = 5*gravity | |
245 | - | doit() |
245 | + | |
246 | end | |
247 | if mode == "walkRight" then | |
248 | if level[guy.x+1] then | |
249 | if level[guy.y][guy.x+1] then | |
250 | if not level[guy.y][guy.x+1].solid then | |
251 | guy.x = guy.x + 1 | |
252 | end | |
253 | else | |
254 | guy.x = guy.x + 1 | |
255 | end | |
256 | else | |
257 | guy.x = guy.x + 1 | |
258 | end | |
259 | end | |
260 | if mode == "walkLeft" then | |
261 | if level[guy.y] then | |
262 | if level[guy.y][guy.x-1] then | |
263 | if not level[guy.y][guy.x-1].solid then | |
264 | guy.x = guy.x - 1 | |
265 | end | |
266 | else | |
267 | guy.x = guy.x - 1 | |
268 | end | |
269 | else | |
270 | guy.x = guy.x - 1 | |
271 | end | |
272 | end | |
273 | end | |
274 | ||
275 | function handleKeyMovement() | |
276 | keysPressed = { | |
277 | ["right"] = false, | |
278 | ["left"] = false, | |
279 | ["space"] = false, | |
280 | } | |
281 | while true do | |
282 | local evt = {os.pullEvent()} | |
283 | if evt[1] == "key" then | |
284 | if evt[2] == keys.right then | |
285 | keysPressed["right"] = true | |
286 | elseif evt[2] == keys.left then | |
287 | keysPressed["left"] = true | |
288 | elseif evt[2] == keys.space then | |
289 | keysPressed["space"] = true | |
290 | end | |
291 | elseif evt[1] == "key_up" then | |
292 | if evt[2] == keys.right then | |
293 | keysPressed["right"] = false | |
294 | elseif evt[2] == keys.left then | |
295 | keysPressed["left"] = false | |
296 | elseif evt[2] == keys.space then | |
297 | keysPressed["space"] = false | |
298 | end | |
299 | end | |
300 | end | |
301 | end | |
302 | ||
303 | function doit() | |
304 | palateclear() | |
305 | renderLevel(level,scrollX,scrollY) | |
306 | while true do | |
307 | sleep(0.05) | |
308 | if keysPressed["space"] and guy.grounded then | |
309 | handleGuyPhysics("jump") | |
310 | end | |
311 | if keysPressed["right"] then | |
312 | handleGuyPhysics("walkRight") | |
313 | elseif keysPressed["left"] then | |
314 | handleGuyPhysics("walkLeft") | |
315 | else | |
316 | handleGuyPhysics() | |
317 | end | |
318 | renderLevel(level,scrollX,scrollY) | |
319 | end | |
320 | end | |
321 | ||
322 | parallel.waitForAny(doit,handleKeyMovement) |