mirror of
https://github.com/GoogleChrome/chrome-extensions-samples.git
synced 2026-03-26 13:19:49 +07:00
26
functional-samples/tutorial.mole-game/README.md
Normal file
26
functional-samples/tutorial.mole-game/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Mole Game
|
||||
|
||||
This mole game is based on a YouTube tutorial in our Chrome Extensions series. Watch it [here](https://goo.gle/Chrome-Ext).
|
||||
|
||||
<img src="mole-game.png" width=500>
|
||||
|
||||
## Overview
|
||||
|
||||
In the sample, moles periodically appear from pipes in the browser toolbar. You score points by clicking the icon before the mole disappears.
|
||||
|
||||
If enabled, a browser tab is closed if you miss one of the moles.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Each icon in the browser toolbar is a seperate extension. The extensions communicate using the `chrome.runtime.sendMessage` API and the `chrome.runtime.onMessageExternal` event.
|
||||
|
||||
To discover mole extensions, the controller extension uses the `chrome.management` API.
|
||||
|
||||
By default, the tab closing behavior is disabled. You can enable this by commenting out the line in `mole/service-worker.js`.
|
||||
|
||||
## Running this extension
|
||||
|
||||
1. Clone this repository.
|
||||
1. Make several copies of the `mole` directory.
|
||||
1. Load the `controller` directory and all mole directories in Chrome as [unpacked extensions](https://developer.chrome.com/docs/extensions/mv3/getstarted/development-basics/#load-unpacked).
|
||||
1. Wait for a mole to appear!
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "mole controller",
|
||||
"version": "1.0",
|
||||
"manifest_version": 3,
|
||||
"background": {
|
||||
"service_worker": "service-worker.js"
|
||||
},
|
||||
"permissions": ["management", "alarms"],
|
||||
"action": {}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
chrome.runtime.onInstalled.addListener(() => {
|
||||
chrome.alarms.create({ periodInMinutes: (1 / 60) * 3 });
|
||||
});
|
||||
|
||||
chrome.alarms.onAlarm.addListener(async () => {
|
||||
const extensions = await chrome.management.getAll();
|
||||
const moles = extensions.filter((e) => e.name === 'mole');
|
||||
|
||||
const randomIndex = Math.floor(Math.random() * moles.length);
|
||||
|
||||
chrome.runtime.sendMessage(moles[randomIndex].id, { id: chrome.runtime.id });
|
||||
});
|
||||
|
||||
let counter = 0;
|
||||
|
||||
chrome.runtime.onMessageExternal.addListener(() => {
|
||||
counter++;
|
||||
chrome.action.setBadgeText({ text: `${counter}` });
|
||||
});
|
||||
BIN
functional-samples/tutorial.mole-game/mole-game.png
Normal file
BIN
functional-samples/tutorial.mole-game/mole-game.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 386 KiB |
BIN
functional-samples/tutorial.mole-game/mole/icon-empty.png
Normal file
BIN
functional-samples/tutorial.mole-game/mole/icon-empty.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
BIN
functional-samples/tutorial.mole-game/mole/icon-mole.png
Normal file
BIN
functional-samples/tutorial.mole-game/mole/icon-mole.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
12
functional-samples/tutorial.mole-game/mole/manifest.json
Normal file
12
functional-samples/tutorial.mole-game/mole/manifest.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "mole",
|
||||
"version": "1.0",
|
||||
"manifest_version": 3,
|
||||
"background": {
|
||||
"service_worker": "service-worker.js"
|
||||
},
|
||||
"action": {
|
||||
"default_icon": "icon-empty.png"
|
||||
},
|
||||
"permissions": ["management", "tabs"]
|
||||
}
|
||||
38
functional-samples/tutorial.mole-game/mole/service-worker.js
Normal file
38
functional-samples/tutorial.mole-game/mole/service-worker.js
Normal file
@@ -0,0 +1,38 @@
|
||||
let failTimeout;
|
||||
let moleShowing = false;
|
||||
let controllerId;
|
||||
|
||||
chrome.action.onClicked.addListener(() => {
|
||||
if (!moleShowing) return;
|
||||
|
||||
chrome.runtime.sendMessage(controllerId, 'success');
|
||||
hideMole();
|
||||
|
||||
failTimeout && clearTimeout(failTimeout);
|
||||
failTimeout = undefined;
|
||||
});
|
||||
|
||||
function showMole() {
|
||||
chrome.action.setIcon({ path: 'icon-mole.png' });
|
||||
moleShowing = true;
|
||||
}
|
||||
|
||||
function hideMole() {
|
||||
chrome.action.setIcon({ path: 'icon-empty.png' });
|
||||
moleShowing = false;
|
||||
}
|
||||
|
||||
chrome.runtime.onMessageExternal.addListener((msg) => {
|
||||
controllerId = msg.id;
|
||||
showMole();
|
||||
failTimeout = setTimeout(async () => {
|
||||
hideMole();
|
||||
const tabs = await chrome.tabs.query({});
|
||||
const eligibleTabs = tabs.filter((t) => t.title.includes('Example'));
|
||||
|
||||
if (eligibleTabs.length > 0) {
|
||||
// const tabToClose = Math.floor(Math.random() * eligibleTabs.length);
|
||||
// chrome.tabs.remove(eligibleTabs[tabToClose].id);
|
||||
}
|
||||
}, 2000);
|
||||
});
|
||||
Reference in New Issue
Block a user