001: -- falldown, lua edition \o/
002: -- � 2k12 r043v/dph
003:
004:
005: -- init function, launched at start
006: function setup()
007: -- game option
008: game = { map = { data = {}, sizey = 6000, speed = 450, scroll = 0, bg = {255,0,255}, tile = { size = { x=50, y=50 }, color = { {255,0,0},{0,255,0},{0,0,255},{255,255,0},{0,255,255} } } },
009: hero = { isFall=1, color = {255,0,0}, size = { x=32, y=32 }, pos = { x=0, y=0 } },
010: screen = { size = { x=0, y=0 }, fps = 30 },
011: }
012:
013: -- init hero position
014: game.hero.pos.x = math.floor( (WIDTH/2)+(game.hero.size.x/2) )
015: game.hero.pos.y = -20--(hero.size.y)
016:
017: -- compute tile number by line and colon
018: game.screen.size.x = math.floor( WIDTH / game.map.tile.size.x )
019: game.screen.size.y = math.floor( HEIGHT / game.map.tile.size.y )
020:
021: -- max percent of line filled
022: game.map.limit = math.floor(game.screen.size.x*(90/100))
023:
024: -- compute initial speed
025: game.hero.oldSpeed = 0
026: game.map.oldSpeed = 0
027: game.map.speedRatio = 0
028: game.hero.speedRatio = 0
029: game.screen.frameFlip = 0
030:
031: refreshHeroSpeed()
032:
033: -- generate a random map
034: generateMap()
035:
036: -- get ready for action!
037: end
038:
039: function refreshHeroSpeed()
040: game.hero.speed = math.floor(game.map.speed*1.1);
041: end
042:
043: -- loop function
044: function draw()
045: -- clear screen
046: background(game.map.bg[1],game.map.bg[2],game.map.bg[3]);
047:
048: -- detect speed change and change current map/hero speed
049: if game.map.oldSpeed ~= game.speed or game.hero.oldSpeed ~= hero.speed then
050: game.map.oldSpeed = game.map.speed
051: game.hero.oldhSpeed = game.hero.speed
052: game.map.speedRatio = game.map.speed/game.screen.fps
053: game.hero.speedRatio = (game.map.speed+game.hero.speed)/game.screen.fps
054: end
055:
056: -- compute current move for hero and map in this frame
057: game.screen.frameFlip = game.screen.frameFlip+1
058: if game.screen.frameFlip >= game.screen.fps then game.screen.frameFlip = 0 end
059: game.map.currentSpeed = math.floor((game.screen.frameFlip+1)*game.map.speedRatio) - math.floor(game.screen.frameFlip*game.map.speedRatio)
060: game.hero.currentSpeed = math.floor((game.screen.frameFlip+1)*game.hero.speedRatio) - math.floor(game.screen.frameFlip*game.hero.speedRatio)
061:
062: -- check keys
063: -- if keyboard.pressed['up'] then game.map.speed = game.map.speed+1; refreshHeroSpeed() end
064: -- if keyboard.pressed['down'] then game.map.speed = game.map.speed-1; refreshHeroSpeed() end
065:
066: if keyboard.pressed['left'] then
067: local n
068: for n=0,game.hero.currentSpeed/2,1 do
069: local tiletopleft,tiletopright,bottomIndex,leftIndex,tiletopleft,tilebottomleft
070: bottomIndex = math.floor((game.hero.pos.y+(game.hero.size.y-4))/game.map.tile.size.y)+2
071: topIndex = math.floor((game.hero.pos.y+4)/game.map.tile.size.y)+2
072: leftIndex = math.floor( (game.hero.pos.x-2)/game.map.tile.size.x)+1
073: if leftIndex <= 0 then break end
074: tiletopleft = game.map.data[topIndex][leftIndex]
075: tilebottomleft = game.map.data[bottomIndex][leftIndex]
076: if game.hero.pos.x > 0 and tilebottomleft+tiletopleft==0 then game.hero.pos.x = game.hero.pos.x-1 else break end
077: end
078: end
079:
080: if keyboard.pressed['right'] then
081: local n
082: for n=0,game.hero.currentSpeed/2,1 do
083: local tiletopleft,tiletopright,bottomIndex,rightIndex,tiletopright,tilebottomright
084: bottomIndex = math.floor((game.hero.pos.y+(game.hero.size.y-4))/game.map.tile.size.y)+2
085: topIndex = math.floor( (game.hero.pos.y+4)/game.map.tile.size.y)+2
086: rightIndex = math.floor( ((game.hero.pos.x+2)+game.hero.size.x)/game.map.tile.size.x )+1
087: if rightIndex > game.screen.size.x then break end
088: tiletopright = game.map.data[topIndex][rightIndex]
089: tilebottomright = game.map.data[bottomIndex][rightIndex]
090: if game.hero.pos.x < ( WIDTH-game.hero.size.x ) and tilebottomright+tiletopright==0 then game.hero.pos.x = game.hero.pos.x+1 else break end
091: end
092: end
093:
094: -- blit the map
095: drawMap();
096:
097: -- blit hero�
098: fill(game.hero.color[1],game.hero.color[2],game.hero.color[3],1);
099: rect(game.hero.pos.x,HEIGHT-( (game.hero.pos.y+game.hero.size.y) - game.map.scroll),game.hero.size.x,game.hero.size.y);
100:
101: -- scroll the map
102: game.map.scroll = game.map.scroll + game.map.currentSpeed
103:
104: -- go hero down
105: local n
106: for n=0,game.hero.currentSpeed,1 do
107: -- check down tile
108: local tileleft,tileright,bottomIndex,leftIndex,rightIndex
109: bottomIndex = math.floor((game.hero.pos.y+game.hero.size.y)/game.map.tile.size.y)+2
110: leftIndex = math.floor(game.hero.pos.x/game.map.tile.size.x)+1
111: rightIndex = math.floor((game.hero.pos.x + (game.hero.size.x-1))/game.map.tile.size.x)+1
112: tileleft = game.map.data[bottomIndex][leftIndex]
113: tileright = game.map.data[bottomIndex][rightIndex]
114: if tileleft + tileright > 0 then
115: if game.hero.isFall == 1 then
116: game.map.speed = game.map.speed+1; refreshHeroSpeed();
117: game.hero.isFall=0
118: end
119: break
120: end
121: game.hero.pos.y = game.hero.pos.y + 1
122: game.hero.isFall = 1
123: --text(100,70,string.format("left %d right %d",tileleft,tileright))
124: end
125:
126: if game.hero.pos.y - game.map.scroll < -500 then
127: setup() -- game over !
128: end
129:
130:
131: -- some debug
132: -- fill(0,255,0,1)
133: -- text(100,100,string.format("scroll %d",game.map.scroll))
134: -- text(100,130,string.format("screen %d*%d => %d*%d",WIDTH,HEIGHT,game.screen.size.x,game.screen.size.y))
135: -- text(100,160,string.format("speed %d px/s current %d frame %d ratio %f",game.map.speed,game.map.currentSpeed,game.screen.frameFlip,game.map.speedRatio))
136: -- text(100,190,string.format("hero : %d speed %d",game.hero.pos.y,game.hero.currentSpeed))
137: end
138:
139: function generateMap()
140: local x,y
141: local n=1
142: local skip=0
143: local count=0
144: local current_color=0
145: local nb_stop_cases=0
146:
147: -- init array
148: for y=1,game.map.sizey,1 do
149: game.map.data[y] = {}
150: for x=1,game.screen.size.x,1 do
151: game.map.data[y][x]=0
152: end
153: end
154:
155: -- generate start
156: for y=1,game.screen.size.y,1 do
157: game.map.data[y][1] = n
158: game.map.data[y][game.screen.size.x] = n
159: if n==1 then n=2 else n=1 end
160: end
161:
162: -- generate other
163: for y=game.screen.size.y+1,game.map.sizey,1 do
164: skip = skip+1
165: if skip==4 then
166: current_color = current_color+1
167: if current_color>3 then current_color=2 end
168: count = count+1
169: if count%42 == 1 then current_color=4 end
170: skip=0
171: nb_stop_cases=0
172: x=1
173: while x<=game.screen.size.x do
174: if nb_stop_cases<game.map.limit then
175: if math.random(0,2)>0 then
176: game.map.data[y][x] = current_color
177: nb_stop_cases = nb_stop_cases+1
178: else
179: game.map.data[y][x] = 0 ;
180: end
181: else
182: game.map.data[y][math.random(1,game.screen.size.x)]=0
183: game.map.data[y][x] = 0 ;
184: end
185: x = x+1
186: end
187: end
188: end
189: end
190:
191: function drawMap()
192: -- compute y start tile position, pixels -> tiles
193: local starty = math.floor(game.map.scroll/game.map.tile.size.y)+1
194:
195: -- scroll is not bloc by bloc, compute first/last line height
196: local decy = game.map.scroll % game.map.tile.size.y
197:
198: -- get number of line need to be blited
199: local endy = starty+game.screen.size.y
200: -- if first line is cliped, need to blit another one line at bottom, cliped too
201: if(decy > 0) then endy = endy+1 end
202:
203: local nx,ny,tile,color,px,py
204: py = HEIGHT+decy
205: for ny=starty,endy,1 do
206: px = 0
207: for nx=1,game.screen.size.x,1 do
208: tile = game.map.data[ny][nx]
209: if(tile > 0) then
210: color = game.map.tile.color[tile]
211: fill(color[1],color[2],color[3],1)
212: rect(px,py,game.map.tile.size.x,game.map.tile.size.y)
213: end
214: px = px+game.map.tile.size.x
215: end
216: py = py-game.map.tile.size.y
217: end
218: end
219: