class Selectable { is_selected = false; x = 0; y = 0; select() { this.is_selected = true; } unselect() { this.is_selected = false; } draw_selection() { } setSelectPosition(X ,Y) { this.x = X; this.y = Y; } } class KeyListener { key; execute() { } executeOnKey(event_key) { if(event_key == this.key) { this.execute(); } } } class Screen { elements = []; selectable_objects = []; current_selected_element; user_select_position = {x: 0, y: 0}; max_select_position = {x: 2, y: 2}; user_can_select=false; // user can choose elements user_can_navigate=false; // user can go to another screen ctx; constructor(ctx) { this.ctx = ctx; this.onFrame = this.onFrame.bind(this); } addElement(elem) { this.elements.push(elem); } drawAll() { this.ctx.clearRect(0,0, windowSize.width, windowSize.height); this.elements.forEach(element => { this.ctx.save(); element?.draw(this.ctx); this.ctx.restore(); }); } updateAll() { this.elements.forEach(element => { element?.update(); }); } onFrame() { this.drawAll(); this.updateAll(); requestAnimationFrame(this.onFrame); } keypress(event) { if(this.user_can_select == true) { this.select_key_event(event.key); } } select_key_event(key) { if(key == "d") { this.select_go_right(); } if(key == "a") { this.select_go_left(); } if(key == "s") { this.select_go_down(); } if(key == "w") { this.select_go_up(); } } select_go_right() { if(this.user_select_position.x == this.max_select_position.x - 1) { this.set_select_positionX(0); } else { this.set_select_positionX(this.user_select_position.x + 1); } } select_go_left() { if(this.user_select_position.x == 0) { this.set_select_positionX(this.max_select_position.x - 1); } else { this.set_select_positionX(this.user_select_position.x - 1); } } select_go_down() { if(this.user_select_position.y == this.max_select_position.y - 1) { this.set_select_positionY(0); } else { this.set_select_positionY(this.user_select_position.y + 1); } } select_go_up() { if(this.user_select_position.y == 0) { this.set_select_positionY(this.max_select_position.y - 1); } else { this.set_select_positionY(this.user_select_position.y - 1); } } set_select_positionX(x) { this.user_select_position.x = x; this.select_position_changed(); } set_select_positionY(y) { this.user_select_position.y = y; this.select_position_changed(); } select_position_changed() { if(this.current_selected_element != null) { this.current_selected_element.unselect(); } this.select(this.get_select_object(this.user_select_position)) } get_select_object(pos) { var result = null; this.selectable_objects.forEach(element => { if(element.x == pos.x && element.y == pos.y) { result = element; } }) return result; } select(obj) { obj.select(); this.current_selected_element = obj; } unselect() { this.current_selected_element.unselect(); this.current_selected_element = null; } makeSelectable(obj) { var select_obj = new Selectable(); Object.assign(obj, select_obj); obj.select = select_obj.select; obj.unselect = select_obj.unselect; obj.draw_selection = select_obj.draw_selection; obj.setSelectPosition = select_obj.setSelectPosition; } addToSelectable(obj, pos) { obj.setSelectPosition(pos.x, pos.y); this.selectable_objects.push(obj); } } class MainMenu extends Screen{ constructor(ctx) { super(ctx); } load() { } } /* Sprite, must place after Rectangle class Sprite extends Rectangle{ } */ class Shape { startX; startY; originX; originY; color; rotation = 0; draw(ctx) { } update() { } translate(x, y) { this.startX = x; this.startY = y; } translateX(x) { this.startX = x; } translateY(y) { this.startY = y; } } class Rectangle extends Shape{ width; height; constructor(startX, startY, width, height, color) { super() this.startX = startX; this.startY = startY; this.width = width; this.height = height; this.color = color; this.originX = startX; this.originY = startY; } draw(ctx) { ctx.translate(this.originX, this.originY); ctx.rotate(this.rotation); ctx.translate(-(this.originX), -(this.originY)); ctx.fillStyle = this.color; ctx.fillRect(this.startX,this.startY, this.width,this.height); if("is_selected" in this) { if(this.is_selected) { this.draw_selection(ctx); } } } drawStroke(ctx) { ctx.strokeStyle = "blue"; ctx.lineWidth = 5; ctx.strokeRect(this.startX, this.startY,this.width,this.height); } setCenterOrigin() { this.originX = this.startX + this.width / 2; this.originY = this.startY + this.height / 2; } } class Text extends Shape{ value; font; constructor(value, x,y, font, color) { super(); this.value = value; this.font = font; this.x = x; this.y = y; this.color = color; } draw(ctx) { ctx.font = this.font; ctx.fillStyle = this.color; ctx.fillText(this.value, this.x, this.y); } setValue(newValue) { this.value = newValue; } getValue() { return this.value; } getWidth(ctx) { return ctx.measureText(this.value); } getCenterXFrom(ctx, x, maxWidth) { let width = this.getWidth(ctx).width; let a = x + (maxWidth / 1); return (a + (width / (this.value.length + 1))); } } class Sprite extends Rectangle { img; src; constructor(x,y,w,h,src) { super(x,y,w,h,"green"); this.src = src; this.img = new Image(); this.img.src = this.src; } draw(ctx) { ctx.translate(this.originX, this.originY); ctx.rotate(this.rotation); ctx.translate(-(this.originX), -(this.originY)); ctx.drawImage(this.img,this.startX,this.startY, this.width,this.height); if("is_selected" in this) { if(this.is_selected) { this.draw_selection(ctx); } } } } class Circle extends Shape{ radius; }