File: falldown.lua - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

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: