draw_level = (level) -> for block, position in level switch block when 0 then color = colors.floor when 3 then color = colors.wall when 1 then color = colors.key when 2 then color = colors.door when 7 then color = colors.exit when 5 then color = colors.breakable pixel(position, config.pixelsize, config.pixelsize, color) reset_layers = () -> shadow_layer = [0..(config.map.width*config.map.height)].map -> 0 enemy_layer = [0..(config.map.width*config.map.height)].map -> 0 init_level = () -> level = [0..(config.map.width*config.map.height)].map -> 0 inventar.key = false load_level = (number) -> if number is levels.length config.gamewin = true else init_level() level = levels[number] parse_levelentities(level) # function: update player position update_player_position = () -> new_position = player.position if keymap[37] and toxy(player.position).x > 0 # left new_position = new_position-1 if keymap[39] and toxy(player.position).x < config.map.width-1 # right new_position = new_position+1 if keymap[38] and toxy(player.position).y > 0 # up new_position = new_position - config.map.width if keymap[40] and toxy(player.position).y < config.map.height-1 # down new_position = new_position + config.map.width switch level[new_position] # EXIT when 7 current_level++ load_level(current_level) return # DOOR when 2 if inventar.key inventar.key = false level[new_position] = 0 # KEY when 1 inventar.key = true level[new_position] = 0 #console.log enemy_layer if enemy_layer[new_position] > 0 and !config.debug config.gameover = true if level[new_position] in blocks.walkable then player.position = new_position # function: draw player draw_player = (position) -> pixel(position, config.pixelsize, config.pixelsize, colors.player) map_range = (from, to, s) -> to[0] + (s-from[0]) * (to[1] - to[0]) / (from[1] - from[0]) calculate_lightray = (x1, y1, x2, y2, type) -> switch type when 'enemy' then selected_layer = enemy_layer else selected_layer = shadow_layer pixel_x1 = x1*config.pixelsize + (config.pixelsize/2) pixel_y1 = y1*config.pixelsize + (config.pixelsize/2) pixel_x2 = x2*config.pixelsize + (config.pixelsize/2) pixel_y2 = y2*config.pixelsize + (config.pixelsize/2) dx = Math.abs(pixel_x1 - pixel_x2) dy = Math.abs(pixel_y1 - pixel_y2) s = 0.99 / (if dx>dy then dx else dy) t = 0.0 # show me the rays if config.debug context.beginPath() context.strokeStyle = 'blue' context.moveTo(pixel_x1+config.map.origin.x,pixel_y1+config.map.origin.y) context.lineTo(pixel_x2+config.map.origin.x,pixel_y2+config.map.origin.y) context.stroke() hit_wall = false while t < 1.0 dx = Math.round((1.0-t)*pixel_x1 + t*pixel_x2) dy = Math.round((1.0-t)*pixel_y1 + t*pixel_y2) dx = Math.floor(dx/config.pixelsize) dy = Math.floor(dy/config.pixelsize) # FLOOR? if level[dy*config.map.width + dx] is 0 break if hit_wall and !config.debug if selected_layer[dy*config.map.width + dx] == 0 if t > 0.5 selected_layer[dy*config.map.width + dx] += map_range([0.5, 1], [1, 0], t) else selected_layer[dy*config.map.width + dx] += 1 # WALL? else if level[dy*config.map.width + dx] is 3 break if type is 'enemy' if t > 0.5 selected_layer[dy*config.map.width + dx] += map_range([0.5, 1], [1, 0], t) else selected_layer[dy*config.map.width + dx] += 1 hit_wall = true # ENTITIY? else if level[dy*config.map.width + dx] in blocks.entities if t > 0.5 selected_layer[dy*config.map.width + dx] += map_range([0.5, 1], [1, 0], t) else selected_layer[dy*config.map.width + dx] += 1 break if !config.debug and level[dy*config.map.width + dx] isnt 1 and level[dy*config.map.width + dx] isnt 8 else selected_layer[dy*config.map.width + dx] = .5 break if !config.debug t += s illuminate = (x1, y1, range, type = 'shadow') -> r = 0 while r < Math.PI*2 x2 = range*Math.cos(r) + x1 y2 = range*Math.sin(r) + y1 # bug: edge blurry stuff #x2 = config.map.width-1 if x2 > config.map.width-1 #y2 = config.map.height-1 if y2 > config.map.height-1 # #x2 = 0 if x2 < 0 #y2 = 0 if y2 < 0 calculate_lightray(x1, y1, x2, y2, type) r += 0.03 calculate_lights = () -> #illuminate(8, 8, 5) illuminate(toxy(player.position).x, toxy(player.position).y, player.lightrange) for block, position in level switch block # 6 = LIGHT # CAMERA when 8 illuminate(toxy(position).x, toxy(position).y, 4, 'enemy') draw_lights = (type) -> switch type when 'enemy' color = '255, 0, 0' selected_layer = enemy_layer else color = '0, 0, 0' selected_layer = shadow_layer for brightness, position in selected_layer switch type when 'enemy' alpha = brightness*.5 else alpha = 1-brightness if level[position] in blocks.entities if alpha < 0.4 then alpha = 0 pixel(position, config.pixelsize, config.pixelsize, 'rgba('+color+', '+alpha+')') break_walls = (position) -> level[position-1] = 0 if level[position-1] is 5 or config.debug level[position+1] = 0 if level[position+1] is 5 or config.debug level[position-config.map.width] = 0 if level[position-config.map.width] is 5 or config.debug level[position+config.map.width] = 0 if level[position+config.map.width] is 5 or config.debug # get input keymap = [] addEventListener 'keydown', (event) -> keymap[event.keyCode] = true #console.log event.keyCode #if event.keyCode == 187 then player.lightrange++ if event.keyCode == 187 config.pixelsize += 2 update_canvas() #current_level++ #load_level(current_level) #if event.keyCode == 189 then player.lightrange-- if event.keyCode == 189 config.pixelsize -= 2 update_canvas() if event.keyCode == 68 then config.debug = !config.debug if event.keyCode == 32 then break_walls(player.position) if event.keyCode == 76 then config.lights = !config.lights addEventListener 'keyup', (event) -> keymap[event.keyCode] = false parse_levelentities = -> for block, position in level switch block when 4 player.position = position level[position] = 0 # startup config load_level(current_level) # the awesome main loop main_loop = -> if config.gamewin rect(0, 0, config.map.width*config.pixelsize, config.map.height*config.pixelsize+config.map.origin.y, '#ffffff') write(250, 100, 'You won, awesome!', 20, '#000000') else if config.gameover rect(0, 0, config.map.width*config.pixelsize, config.map.height*config.pixelsize+config.map.origin.y, '#ff0000') write(150, 100, 'Oh noes!', 20, '#ffffff') else reset_layers() calculate_lights() draw_level(level) update_player_position() if config.lights draw_lights('shadow') draw_lights('enemy') draw_player(player.position) draw_hud() setTimeout main_loop, 50 main_loop()