Add button interaction

This commit is contained in:
asraelite 2018-03-02 22:30:26 +00:00
parent 6223b35536
commit 4a253b0184
12 changed files with 247 additions and 23 deletions

116
dist/img/logo2.svg vendored Normal file
View file

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64.151123mm"
height="10.796241mm"
viewBox="0 0 64.151123 10.796241"
version="1.1"
id="svg8"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="logo2.svg">
<defs
id="defs2">
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Drop Shadow"
id="filter1303">
<feFlood
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood1293" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite1295" />
<feGaussianBlur
in="composite1"
stdDeviation="0.5"
result="blur"
id="feGaussianBlur1297" />
<feOffset
dx="-2.77556e-17"
dy="2.80331e-15"
result="offset"
id="feOffset1299" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite1301" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="107.1283"
inkscape:cy="-50.628416"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:measure-start="0,0"
inkscape:measure-end="0,0"
inkscape:window-width="1366"
inkscape:window-height="714"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-3.5809397,-43.192417)">
<flowRoot
xml:space="preserve"
id="flowRoot10"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:53.33333206px;line-height:1.25;font-family:'Estrangelo Antioch';-inkscape-font-specification:'Estrangelo Antioch';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
transform="scale(0.26458333)"><flowRegion
id="flowRegion12"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:53.33333206px;font-family:'Estrangelo Antioch';-inkscape-font-specification:'Estrangelo Antioch'"><rect
id="rect14"
width="688.57141"
height="180"
x="-17.142857"
y="193.94826"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:53.33333206px;font-family:'Estrangelo Antioch';-inkscape-font-specification:'Estrangelo Antioch'" /></flowRegion><flowPara
id="flowPara16"></flowPara></flowRoot> <text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:'Estrangelo Antioch';-inkscape-font-specification:'Estrangelo Antioch';letter-spacing:0px;word-spacing:0px;opacity:1;fill:#eea769;fill-opacity:1;stroke:#c56311;stroke-width:0.26458332;stroke-opacity:1;filter:url(#filter1303)"
x="8.15172"
y="50.577496"
id="text20"><tspan
sodipodi:role="line"
id="tspan18"
x="8.15172"
y="50.577496"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Estrangelo Antioch';-inkscape-font-specification:'Estrangelo Antioch';fill:#eea769;fill-opacity:1;stroke:#c56311;stroke-width:0.26458332;stroke-opacity:1">Improcket</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View file

@ -1,6 +1,7 @@
export const images = {
title: {
logo: 'logo.png'
logo: 'logo.png',
logoSvg: 'logo2.svg'
}
};

5
js/game/events.mjs Normal file
View file

@ -0,0 +1,5 @@
import * as game from './index.mjs';
export function startGame() {
console.log('started');
}

View file

@ -1,6 +1,7 @@
import * as graphics from './graphics/index.mjs';
import * as gui from './gui/index.mjs';
import * as assets from './assets.mjs';
import * as graphics from '../graphics/index.mjs';
import * as gui from '../gui/index.mjs';
import * as assets from '../assets.mjs';
import * as input from '../input.mjs';
export let game;
@ -15,14 +16,17 @@ export async function init() {
graphics.init();
await assets.init();
gui.init();
input.init();
// Recursive `requestAnimationFrame` can cause problems with Parcel.
while(true) {
await tick();
await new Promise(res => requestAnimationFrame(()=>{}));
await new Promise(res => requestAnimationFrame(res));
}
}
async function tick() {
gui.tick();
graphics.render();
input.tick();
}

View file

@ -26,7 +26,12 @@ function renderImage(element) {
}
function renderButton(element) {
context.fillStyle = '#983';
if (element.mouseHeld) {
context.fillStyle = '#706244';
} else {
context.fillStyle = element.mouseOver ? '#ad9869' : '#917f58';
}
context.fillRect(...element.shape);
context.strokeStyle = '#541';
context.strokeWidth = 4;

View file

@ -1,4 +1,4 @@
import {game} from '../game.mjs';
import {game} from '../game/index.mjs';
import {getContainedSectors} from '../world/index.mjs';
import * as background from './background.mjs';
import * as gui from './gui.mjs';

View file

@ -1,13 +1,12 @@
import {Rect} from './misc.mjs';
const defaultOptions = {
draw: true // Whether the element itself will be rendered.
}
export default class GuiElement {
export default class GuiElement extends Rect {
constructor(x, y, w, h, options = {}) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
super(x, y, w, h);
this.children = new Set();
this.parent = null;
@ -16,6 +15,11 @@ export default class GuiElement {
this.options = Object.assign({}, defaultOptions, options);
}
tick() {
this.tickMouse();
this.children.forEach(c => c.tick());
}
append(element) {
this.children.add(element);
element.parent = this;
@ -24,14 +28,8 @@ export default class GuiElement {
clear() {
this.children.clear();
}
get shape() {
return [this.x, this.y, this.w, this.h];
}
get center() {
return [this.x + this.w / 2, this.y + this.h / 2];
}
// Code should be self-describing, comments are for fucking about.
// - Albert Einstein
posRelative({x = null, xc = 0, y = null, yc = 0, w = null, h = null}) {
if (x !== null) {

View file

@ -10,6 +10,10 @@ export function init() {
changeView('title');
}
export function tick() {
root.tick();
}
export function changeView(view) {
root.clear();

View file

@ -0,0 +1,44 @@
import * as input from '../input.mjs';
export class Rect {
constructor(x = 0, y = 0, w = 0, h = 0) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.onclick = null;
this.mouseHeld = false;
}
tickMouse() {
if (this.mouseHeld == true && !input.mouse.held[0] && this.mouseOver)
if (this.onclick !== null)
this.onclick();
if (!this.mouseHeld && input.mouse.pressed[0] && this.mouseOver)
this.mouseHeld = true;
if (!input.mouse.held[0])
this.mouseHeld = false;
}
get shape() {
return [this.x, this.y, this.w, this.h];
}
get center() {
return [this.x + this.w / 2, this.y + this.h / 2];
}
get mouseOver() {
return this.containsPoint(input.mouse.x, input.mouse.y);
}
get mouseClicked() {
return this.mouseOver() && input.mouse.pressed[0];
}
containsPoint(x, y) {
return x > this.x && x < this.x + this.w
&& y > this.y && y < this.y + this.h;
}
}

View file

@ -4,6 +4,7 @@ import {canvas} from '../graphics/index.mjs';
import GuiFrame from './frame.mjs';
import GuiImage from './image.mjs';
import GuiButton from './button.mjs';
import * as events from '../game/events.mjs';
export function root() {
return new GuiFrame(0, 0, canvas.width, canvas.height, {
@ -19,8 +20,8 @@ export function title() {
logo.posRelative({ x: 0.5, xc: 0.5, y: 0.2 });
// TODO: Implement call to change view to game.
let startFunction = () => {};
let start = new GuiButton('Start game', startFunction, 0, 0, 200);
let startFunction = events.startGame;
let start = new GuiButton('Start game', events.startGame, 0, 0, 200);
shadow.append(start);
start.posRelative({ x: 0.5, xc: 0.5, y: 0.7 });

View file

@ -1,3 +1,3 @@
import { init } from './game.mjs';
import { init } from './game/index.mjs';
window.addEventListener('load', init);

46
js/input.mjs Normal file
View file

@ -0,0 +1,46 @@
import {canvas} from './graphics/index.mjs';
export const mouse = { pressed: {}, held: {}, x: 0, y: 0 };
export const keyCode = { pressed: {}, held: {} };
export const key = { pressed: {}, held: {} };
export const action = {};
const mapping = {};
export function tick() {
mouse.pressed = {};
keyCode.pressed = {};
key.pressed = {};
}
export function init() {
window.addEventListener('keydown', event => {
keyCode.pressed[event.code] = !keyCode.held[event.code];
keyCode.held[event.code] = true;
key.pressed[event.key] = !keyCode.held[event.key];
key.held[event.key] = true;
});
window.addEventListener('keyup', event => {
keyCode.pressed[event.code] = false;
keyCode.held[event.code] = false;
key.pressed[event.key] = false;
key.held[event.key] = false;
});
// Ṕ͕͖ẖ̨̖̺͓̪̹n̼͇͔̯̝̖g̙̩̭͕ͅͅl̻̰͘u͎̥͍̗ͅi̼̞̪̩͚̜͖ ̫̝̻͚͟m͎̳̙̭̩̩̕g̟̤̬̮l̫̕w̶͚͈͚̟͔͖n͏̝͖̞̺ͅa͏̹͓̬̺f̗̬̬̬̖̫͜h͙̘̝̱̬̗͜ ̼͎͖C̱͔̱͖ṭ̬̱͖h̵̰̼̘̩ùlh̙́u̪̫ ̪̺̹̙̯R̞͓̹̞͍͎͉͎̦͙ͅl͇̠̮y̙̪̰̪͙̖e̢̩͉͙̼h̗͔̹̳ ̶w̨̼͍̝̭̣̣ͅg̶̳̦̳a̴͉̹͙̭̟ͅh͈͎̞̜͉̼̜̠́͞n̲a̯g̮͚͓̝l̠ ̹̹̱͙̝f̧̝͖̱h̪̟̻͖̖t͎͘aͅg̤̘͜n̶͈̻̻̝̳
window.addEventListener('mousedown', event => {
mouse.pressed[event.button] = !mouse.held[event.button];
mouse.held[event.button] = true;
});
window.addEventListener('mouseup', event => {
mouse.pressed[event.button] = false;
mouse.held[event.button] = false;
});
window.addEventListener('mousemove', event => {
let rect = canvas.getBoundingClientRect();
mouse.x = event.clientX - rect.left;
mouse.y = event.clientY - rect.top;
});
}