| |
|
|
| window.erasing_radius = 15; |
| window.asset_size = 8; |
|
|
| |
| window.ground = []; |
| window.ceiling = []; |
|
|
| |
| window.terrain = { |
| ground: [], |
| ceiling: [] |
| }; |
|
|
| |
| window.align_terrain = { |
| align: true, |
| ceiling_offset: null, |
| ground_offset: null, |
| smoothing: null |
| }; |
|
|
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| function init_game(cppn_input_vector, water_level, creepers_width, creepers_height, creepers_spacing, |
| smoothing, creepers_type, ground, ceiling, align, zoom=null, scroll=null) { |
|
|
| let agents = { |
| morphologies: [], |
| policies: [], |
| positions: [] |
| } |
|
|
| |
| if(window.game != null){ |
| window.game.pause(); |
| agents.morphologies = [...window.game.env.agents.map(a => a.morphology)]; |
| agents.policies = [...window.game.env.agents.map(a => a.policy)]; |
| agents.positions = [...window.game.env.agents.map(agent => agent.agent_body.reference_head_object.GetPosition())]; |
| } |
| window.game = new Game(agents, cppn_input_vector, water_level, creepers_width, creepers_height, |
| creepers_spacing, smoothing, creepers_type, ground, ceiling, align); |
| window.set_agent_selected(-1); |
| window.asset_selected = null; |
|
|
| if(zoom == null){ |
| window.game.env.set_zoom(INIT_ZOOM); |
| } |
| else { |
| window.game.env.set_zoom(zoom); |
| } |
|
|
| if(scroll == null){ |
| window.game.env.set_scroll(window.agent_selected, INIT_SCROLL_X, 0); |
| } |
| else{ |
| window.game.env.set_scroll(window.agent_selected, scroll[0], scroll[1]); |
| } |
| window.game.env.render(); |
| } |
|
|
| |
| |
| |
| |
| function getCreepersType() { |
| return document.getElementById("creepersType").value == 'Swingable'; |
| } |
|
|
| |
| |
| |
| |
| |
| async function onLoadInit() { |
| window.cppn_model = await tf.loadGraphModel('./js/CPPN/weights/same_ground_ceiling_cppn/tfjs_model/model.json'); |
| window.init_default(); |
| window.loadDefaultEnv(); |
| |
| window.introTourSetUp(); |
| } |
|
|
| |
| window.addEventListener("load", onLoadInit, false); |
|
|
| |
|
|
| |
| |
| |
| |
| |
| |
| function convertPosCanvasToEnv(x_pos, y_pos){ |
| let x = Math.max(-window.canvas.width * 0.01, Math.min(x_pos, window.canvas.width * 1.01)); |
| let y = Math.max(0, Math.min(y_pos, window.canvas.height)); |
|
|
| x += window.game.env.scroll[0]; |
| y = -(y - window.game.env.scroll[1]); |
|
|
| x = x / (window.game.env.scale * window.game.env.zoom); |
| y = y / (window.game.env.scale * window.game.env.zoom); |
|
|
| y += (1 - window.game.env.scale * window.game.env.zoom) * RENDERING_VIEWER_H/(window.game.env.scale * window.game.env.zoom) |
| + (window.game.env.zoom - 1) * (window.game.env.ceiling_offset)/window.game.env.zoom * 1/3 + RENDERING_VIEWER_H; |
|
|
| return {x: x, y: y}; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| function convertPosEnvToCanvas(x_pos, y_pos){ |
| let x = x_pos * window.game.env.scale * window.game.env.zoom - window.game.env.scroll[0]; |
| let y = window.game.env.scroll[1] - (y_pos - RENDERING_VIEWER_H) * window.game.env.scale * window.game.env.zoom |
| + (1 - window.game.env.scale * window.game.env.zoom) * RENDERING_VIEWER_H |
| + (window.game.env.zoom - 1) * window.game.env.ceiling_offset * window.game.env.scale * 1/3; |
|
|
| return {x: x, y: y}; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| function isPosInsideBody(pos, body){ |
| let shape = body.GetFixtureList().GetShape(); |
|
|
| if(shape.m_type == b2.Shape.e_circle){ |
| let center = body.GetWorldCenter(); |
| return Math.pow(center.x - pos.x, 2) + Math.pow(center.y - pos.y, 2) <= Math.pow(shape.m_radius, 2); |
| } |
| } |
|
|
| |
| |
| |
| function mousePressed(){ |
|
|
| |
| document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach((el, index) => { |
| let tooltip = bootstrap.Tooltip.getInstance(el); |
| tooltip.hide(); |
| }); |
|
|
| |
| if(mouseX >= 0 && mouseX <= window.canvas.width |
| && mouseY >= 0 && mouseY <= window.canvas.height){ |
|
|
| |
| window.prevMouseX = mouseX; |
| window.prevMouseY = mouseY; |
|
|
| |
| if(window.is_drawing_circle()){ |
| let mousePos = convertPosCanvasToEnv(mouseX, mouseY); |
| window.game.env.create_circle_asset(mousePos, window.asset_size * 2 / window.game.env.scale); |
|
|
| if(window.agent_selected != null){ |
| window.agent_selected.is_selected = false; |
| window.set_agent_selected(-1); |
| } |
| window.game.env.render(); |
| } |
|
|
| |
| else if(!window.is_drawing()){ |
| let mousePos = convertPosCanvasToEnv(mouseX, mouseY); |
|
|
| |
| let one_agent_touched = false; |
| for(let i = 0; i < window.game.env.agents.length; i++){ |
| let agent = window.game.env.agents[i]; |
|
|
| |
| let is_agent_touched = agent.agent_body.isPosInside(mousePos); |
|
|
| |
| if(is_agent_touched){ |
| one_agent_touched = true; |
|
|
| if(!agent.is_selected) { |
| agent.is_selected = true; |
| window.set_agent_selected(i); |
| for (let other_agent of window.game.env.agents) { |
| if (other_agent != agent) { |
| other_agent.is_selected = false; |
| } |
| } |
| } |
| break; |
| } |
| |
| else { |
| agent.is_selected = false; |
| } |
| } |
|
|
| |
| if(!one_agent_touched && window.agent_selected != null){ |
| window.set_agent_selected(-1); |
| } |
|
|
| |
| if(!one_agent_touched){ |
| let one_asset_touched = false; |
| for(let asset of window.game.env.assets_bodies){ |
|
|
| |
| let is_asset_touched = isPosInsideBody(mousePos, asset.body); |
|
|
| |
| if(is_asset_touched){ |
| one_asset_touched = true; |
|
|
| if(!asset.is_selected){ |
| asset.is_selected = true; |
| window.asset_selected = asset; |
| for(let other_asset of window.game.env.assets_bodies){ |
| if(other_asset != asset){ |
| other_asset.is_selected = false; |
| } |
| } |
| break; |
| } |
| } |
| |
| else if(!is_asset_touched){ |
| asset.is_selected = false; |
| } |
| } |
|
|
| |
| if(!one_asset_touched && window.asset_selected != null){ |
| window.asset_selected = null; |
| } |
| } |
|
|
| window.game.env.render(); |
| } |
| } |
| } |
|
|
| |
| document.addEventListener('mousedown', (event) => { |
| if(window.is_drawing() || window.is_drawing_circle()){ |
| let canvas_id = "#" + window.canvas.canvas.id; |
|
|
| |
| let authorized_elements = [ |
| document.querySelector(canvas_id), |
| document.querySelector('#drawGroundButton'), |
| document.querySelector('#drawCeilingButton'), |
| document.querySelector('#eraseButton') |
| ]; |
|
|
| |
| if(authorized_elements.indexOf(event.target) == -1) { |
| window.deselectDrawingButtons(); |
| } |
| } |
| }); |
|
|
| |
| |
| |
| |
| function mouseDragged(){ |
|
|
| |
| if(mouseX >= 0 && mouseX <= window.canvas.width |
| && mouseY >= 0 && mouseY <= window.canvas.height) { |
|
|
| |
| if(window.is_drawing()) { |
|
|
| |
| let mousePos = convertPosCanvasToEnv(mouseX, mouseY); |
|
|
| |
| let y_offset = SCROLL_Y_MAX - window.game.env.scroll[1]; |
|
|
| |
| if(window.is_drawing_ground() && mousePos.x > (INITIAL_TERRAIN_STARTPAD - 1) * TERRAIN_STEP){ |
| drawing_canvas.push(); |
| drawing_canvas.stroke("#66994D"); |
| drawing_canvas.strokeWeight(4); |
| |
| drawing_canvas.line(mouseX, mouseY + y_offset, window.prevMouseX, window.prevMouseY + y_offset); |
| drawing_canvas.pop(); |
| window.terrain.ground.push(mousePos); |
| } |
|
|
| |
| else if(window.is_drawing_ceiling() && mousePos.x > (INITIAL_TERRAIN_STARTPAD - 1) * TERRAIN_STEP){ |
| drawing_canvas.push(); |
| drawing_canvas.stroke("#808080"); |
| drawing_canvas.strokeWeight(4); |
| |
| drawing_canvas.line(mouseX, mouseY + y_offset, window.prevMouseX, window.prevMouseY + y_offset); |
| drawing_canvas.pop(); |
| window.terrain.ceiling.push(mousePos); |
| } |
|
|
| |
| else if(window.is_erasing() && mousePos.x > INITIAL_TERRAIN_STARTPAD * TERRAIN_STEP){ |
|
|
| |
| trace_canvas.clear(); |
| trace_canvas.noStroke(); |
| trace_canvas.fill(255); |
| trace_canvas.circle(mouseX, mouseY + y_offset, window.erasing_radius * 2); |
|
|
| |
| window.terrain.ground = window.terrain.ground.filter(function(point, index, array){ |
| return Math.pow(point.x - mousePos.x, 2) + Math.pow(point.y - mousePos.y, 2) > Math.pow(window.erasing_radius / (window.game.env.scale * window.game.env.zoom), 2); |
| }); |
| window.terrain.ceiling = window.terrain.ceiling.filter(function(point, index, array){ |
| return Math.pow(point.x - mousePos.x, 2) + Math.pow(point.y - mousePos.y, 2) > Math.pow(window.erasing_radius / (window.game.env.scale * window.game.env.zoom), 2); |
| }); |
|
|
| |
| drawing_canvas.erase(); |
| drawing_canvas.circle(mouseX, mouseY + y_offset, window.erasing_radius * 2); |
| drawing_canvas.noErase(); |
| } |
|
|
| |
| else{ |
| cursor(MOVE); |
| window.game.env.set_scroll(null, window.game.env.scroll[0] + window.prevMouseX - mouseX, window.game.env.scroll[1] + mouseY - prevMouseY); |
|
|
| |
| window.refresh_drawing(); |
| y_offset = SCROLL_Y_MAX - window.game.env.scroll[1]; |
| } |
|
|
| |
| window.game.env.render(); |
| image(drawing_canvas, 0, -y_offset); |
| image(trace_canvas, 0, -y_offset); |
| image(forbidden_canvas, 0, -y_offset); |
| } |
|
|
| |
| else{ |
| cursor(MOVE); |
|
|
| |
| for (let agent of window.game.env.agents) { |
|
|
| |
| if (agent.is_selected) { |
|
|
| |
| let terrain_length; |
| if (agent.agent_body.body_type == BodyTypesEnum.CLIMBER) { |
| terrain_length = window.game.env.terrain_ceiling[window.game.env.terrain_ceiling.length - 1].x; |
| } |
| else if (agent.agent_body.body_type == BodyTypesEnum.WALKER) { |
| terrain_length = window.game.env.terrain_ground[window.game.env.terrain_ground.length - 1].x; |
| } |
| else if(agent.agent_body.body_type == BodyTypesEnum.SWIMMER){ |
| terrain_length = Math.max(window.game.env.terrain_ground[window.game.env.terrain_ground.length - 1].x, |
| window.game.env.terrain_ceiling[window.game.env.terrain_ceiling.length - 1].x); |
| } |
|
|
| |
| let mousePos = convertPosCanvasToEnv(mouseX, mouseY); |
| let x = Math.max(0.02, Math.min(0.98, mousePos.x / terrain_length)) * terrain_length; |
|
|
| |
| window.game.env.set_agent_position(agent, x, mousePos.y); |
| window.game.env.render(); |
| window.is_dragging_agent = true; |
| break; |
| } |
| } |
|
|
| |
| for(let asset of window.game.env.assets_bodies){ |
|
|
| |
| if (asset.is_selected && !window.is_dragging_agent) { |
| let terrain_length = Math.max(window.game.env.terrain_ground[window.game.env.terrain_ground.length - 1].x, |
| window.game.env.terrain_ceiling[window.game.env.terrain_ceiling.length - 1].x); |
|
|
| |
| let mousePos = convertPosCanvasToEnv(mouseX, mouseY); |
| mousePos.x = Math.max(0.02, Math.min(0.98, mousePos.x / terrain_length)) * terrain_length; |
|
|
| |
| window.game.env.set_asset_position(asset, mousePos); |
| window.game.env.render(); |
| window.is_dragging_asset = true; |
| } |
| } |
|
|
| |
| if(!window.is_dragging_agent && !window.is_dragging_asset){ |
|
|
| |
| if(window.agent_followed != null){ |
| window.set_agent_followed(-1); |
| } |
| window.game.env.set_scroll(null, window.game.env.scroll[0] + window.prevMouseX - mouseX, window.game.env.scroll[1] + mouseY - prevMouseY); |
| window.game.env.render(); |
| } |
| } |
| } |
|
|
| |
| else if(window.is_dragging_agent |
| && mouseY >= 0 && mouseY < window.canvas.height){ |
|
|
| if(mouseX < 0){ |
| window.dragging_side = "left"; |
| } |
| else if(mouseX > window.canvas.width){ |
| window.dragging_side = "right"; |
| } |
|
|
| cursor(MOVE); |
|
|
| |
| for (let agent of window.game.env.agents) { |
|
|
| |
| if (agent.is_selected) { |
|
|
| |
| window.game.env.set_scroll(null); |
|
|
| |
| let terrain_length; |
| if (agent.agent_body.body_type == BodyTypesEnum.CLIMBER) { |
| terrain_length = window.game.env.terrain_ceiling[window.game.env.terrain_ceiling.length - 1].x; |
| } |
| else if (agent.agent_body.body_type == BodyTypesEnum.WALKER) { |
| terrain_length = window.game.env.terrain_ground[window.game.env.terrain_ground.length - 1].x; |
| } |
| else if(agent.agent_body.body_type == BodyTypesEnum.SWIMMER){ |
| terrain_length = Math.max(window.game.env.terrain_ground[window.game.env.terrain_ground.length - 1].x, |
| window.game.env.terrain_ceiling[window.game.env.terrain_ceiling.length - 1].x); |
| } |
|
|
| |
| let mousePos = convertPosCanvasToEnv(mouseX, mouseY); |
| let x = Math.max(0.02, Math.min(0.98, mousePos.x / terrain_length)) * terrain_length; |
|
|
| |
| window.game.env.set_agent_position(agent, x, mousePos.y); |
| window.game.env.render(); |
| break; |
| } |
| } |
|
|
| |
| return false; |
| } |
|
|
| window.prevMouseX = mouseX; |
| window.prevMouseY = mouseY; |
| } |
|
|
| |
| |
| |
| function mouseReleased(){ |
| cursor(); |
| window.is_dragging_agent = false; |
| window.is_dragging_asset = false; |
| window.dragging_side = null; |
| } |
|
|
| |
| |
| |
| function mouseMoved(){ |
|
|
| |
| if(window.is_drawing_circle()){ |
| trace_canvas.clear(); |
| if(mouseX >= 0 && mouseX <= window.canvas.width |
| && mouseY >= 0 && mouseY <= window.canvas.height) { |
| trace_canvas.noStroke(); |
| trace_canvas.fill(136, 92, 0, 180); |
| trace_canvas.circle(mouseX, mouseY + SCROLL_Y_MAX - window.game.env.scroll[1], window.asset_size * 4 * window.game.env.zoom); |
| } |
| window.game.env.render(); |
| image(trace_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| } |
|
|
| |
| else if (window.is_erasing()) { |
| trace_canvas.clear(); |
| if (mouseX >= 0 && mouseX <= window.canvas.width |
| && mouseY >= 0 && mouseY <= window.canvas.height) { |
| trace_canvas.noStroke(); |
| trace_canvas.fill(255, 180); |
| trace_canvas.circle(mouseX, mouseY + SCROLL_Y_MAX - window.game.env.scroll[1], window.erasing_radius * 2); |
| } |
| window.game.env.render(); |
| image(drawing_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| image(trace_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| image(forbidden_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| function mouseWheel(event){ |
| if(mouseX >= 0 && mouseX <= window.canvas.width |
| && mouseY >= 0 && mouseY <= window.canvas.height) { |
|
|
| trace_canvas.clear(); |
|
|
| |
| if(window.is_drawing_circle()){ |
| window.asset_size = Math.max(3, Math.min(window.asset_size - event.delta / 100, 30)); |
| trace_canvas.noStroke(); |
| trace_canvas.fill(136, 92, 0, 180); |
| trace_canvas.circle(mouseX, mouseY + SCROLL_Y_MAX - window.game.env.scroll[1], window.asset_size * 4 * window.game.env.zoom); |
| window.game.env.render(); |
| image(trace_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| } |
|
|
| |
| else if(window.is_erasing()){ |
| window.erasing_radius = Math.max(5, Math.min(window.erasing_radius - event.delta / 100, 30)); |
| trace_canvas.noStroke(); |
| trace_canvas.fill(255, 180); |
| trace_canvas.circle(mouseX, mouseY + SCROLL_Y_MAX - window.game.env.scroll[1], window.erasing_radius * 2); |
| window.game.env.render(); |
| image(drawing_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| image(trace_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| image(forbidden_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| } |
|
|
| |
| else { |
| window.game.env.set_zoom(window.game.env.zoom - event.delta / 2000); |
| |
| window.game.env.set_scroll(null, window.game.env.scroll[0], window.game.env.scroll[1]); |
|
|
| |
| if(window.is_drawing()){ |
| window.refresh_drawing(); |
| window.game.env.render(); |
| image(drawing_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| image(forbidden_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| } |
| else{ |
| window.game.env.render(); |
| } |
|
|
| } |
|
|
| |
| return false; |
| } |
| } |
|
|
| |
| |
| |
| |
| function keyPressed(){ |
| |
| if(keyCode == DELETE){ |
| if(window.agent_selected != null){ |
| window.delete_agent(agent_selected); |
| window.agent_selected(null); |
| return false; |
| } |
| else if(window.asset_selected != null){ |
| window.game.env.delete_asset(window.asset_selected); |
| window.asset_selected = null; |
| window.game.env.render(); |
| return false; |
| } |
| } |
| } |
|
|
| |
| |
| |
| function windowResized(){ |
|
|
| let canvas_container = document.querySelector('#canvas_container'); |
|
|
| |
| RENDERING_VIEWER_W = canvas_container.offsetWidth; |
| INIT_ZOOM = RENDERING_VIEWER_W / ((TERRAIN_LENGTH + INITIAL_TERRAIN_STARTPAD) * 1.05 * TERRAIN_STEP * SCALE); |
| THUMBNAIL_ZOOM = RENDERING_VIEWER_W / ((TERRAIN_LENGTH + INITIAL_TERRAIN_STARTPAD) * 0.99 * TERRAIN_STEP * SCALE); |
|
|
| |
| resizeCanvas(RENDERING_VIEWER_W, RENDERING_VIEWER_H); |
| drawing_canvas.resizeCanvas(RENDERING_VIEWER_W + SCROLL_X_MAX, RENDERING_VIEWER_H + 2 * SCROLL_Y_MAX); |
| trace_canvas.resizeCanvas(RENDERING_VIEWER_W + SCROLL_X_MAX, RENDERING_VIEWER_H + 2 * SCROLL_Y_MAX); |
| forbidden_canvas.resizeCanvas(RENDERING_VIEWER_W + SCROLL_X_MAX, RENDERING_VIEWER_H + 2 * SCROLL_Y_MAX); |
|
|
| |
| if(is_drawing()){ |
| window.refresh_drawing(); |
| window.game.env.render(); |
| image(drawing_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| image(forbidden_canvas, 0, -SCROLL_Y_MAX + window.game.env.scroll[1]); |
| } |
| |
| else{ |
| window.init_default(); |
| } |
| } |
|
|
| window.downloadObjectAsJson = (exportObj, exportName) => { |
| let dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj)); |
| let downloadAnchorNode = document.createElement('a'); |
| downloadAnchorNode.setAttribute("href", dataStr); |
| downloadAnchorNode.setAttribute("download", exportName + ".json"); |
| document.body.appendChild(downloadAnchorNode); |
| downloadAnchorNode.click(); |
| downloadAnchorNode.remove(); |
| } |
|
|
| window.strUcFirst = (a) => { |
| return (a+'').charAt(0).toUpperCase()+a.substr(1); |
| } |
|
|
| window.draw_forbidden_area = () => { |
| forbidden_canvas.clear(); |
| forbidden_canvas.stroke("#FF0000"); |
| forbidden_canvas.strokeWeight(3); |
| forbidden_canvas.fill(255, 50, 0, 75); |
| let w = convertPosEnvToCanvas((INITIAL_TERRAIN_STARTPAD - 1) * TERRAIN_STEP, 0).x; |
| forbidden_canvas.rect(0, 0, w, RENDERING_VIEWER_H + 2 * SCROLL_Y_MAX); |
| } |
|
|