| | |
| |
|
| | 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); |
| | } |
| |
|