Steam玩累了?那用 Node.js 写个小游戏:手把手玩懂 JS 运行环境

前言

你可能听说过 "Node.jsJS 的运行环境" ,但这玩意儿到底咋用?提到 JavaScript,你可能先想到它在浏览器里折腾网页特效的样子;但 Node.js 的出现,直接把 JS 从浏览器 "解放" 了出来,让它能像 PythonJava 一样,在操作系统上呼风唤雨 ------ 读写文件、操作终端、搭建后端服务都不在话下。而模块化 ,正是 Node.js 让代码变得整洁、可复用的核心秘诀

今天咱从模块化 入手,再手把手写个小游戏,让你把Node.js玩明白!

一、先认识 Node.js 的 "自带工具":process、__dirname 这些都啥啊?

Node.js 刚启动时,就给我们准备了一堆 "开箱即用" 的工具。

JavaScript 复制代码
// 最基础的控制台输出,和浏览器里的console.log用法一致
console.log('hello');

// Date对象:处理时间和日期,比如new Date()能获取当前时间
console.log(Date);

// 定时器方法:Node.js 里也能设置延时/重复执行的代码
console.log(setTimeout); // 延时执行(毫秒级)
console.log(setInterval); // 重复执行(毫秒级)
// console.log(requestAnimationFrame); // 适配浏览器/Node.js的帧动画(Node.js 16+支持)

// 路径相关:定位文件位置的"神器"
console.log(__dirname); // 打印当前文件所在文件夹的绝对路径
console.log(__filename); // 打印当前文件的完整绝对路径(包含文件名)

// 进程参数:获取终端执行命令时传的参数
console.log(process.argv);

二、Node.js 模块化:代码也能 "打包快递"

写代码像搭积木 ------ 把重复的功能拆成独立文件,要用的时候 "拼" 起来,这就是模块化Node.js 支持两种主流规范:

1. CommonJS:Node.js 自带的 "老牌规范"

就像你寄快递时填 "收件人信息" ,CommonJS 用 module.exports 打包功能,require() 取快递:

JavaScript 复制代码
// lib.js(打包功能)
function add(x, y) {
    return x + y;
}
function minus(x, y) {
    return x - y;
}
// 把 add 和 munus 打包成 "快递"
module.exports = {
    add,
    minus
}
JavaScript 复制代码
// index.js(取快递用功能)
// 用 require 拿到 lib.js 里的 add
const lib = require('./lib.js');
console.log(lib.add(1, 2));    // 输出 3
console.log(lib.minus(1, 2));  // 输出 -1

当然每次console.log都要写一遍lib.,会感到很烦,所以这里用解构的方法会更舒服点:

JavaScript 复制代码
const {add, minus} = require('./lib.js');
console.log(add(1, 2));
console.log(minus(1, 2));

2. ESModule:前端圈的 "新潮流规范"

如果你的项目想和浏览器端代码 "互通" ,可以用 ESModule,但是但是但是重要的事情说三遍:得在 package.json 里加 "type": "module"(一般情况下是有的,直接修改type里的值即可)。

上图更清晰:

还是 common 文件夹的例子:

JavaScript 复制代码
// lib.js(用 export default 打包)
function add(x, y){
    return x + y;
}
function minus(x, y){
    return x - y;
}
export default {
    add,
    minus
}
JavaScript 复制代码
// index.js(用 import 导入)
import lib from './lib.js'
console.log(lib.add(1, 2));    // 输出 3
console.log(lib.minus(1, 2));  // 输出 -1

三、实战:用 Node.js 写 "石头剪刀布" 游戏

没错,"石头剪刀布" 怎么就不算小游戏了,这可不算欺骗哦😮。好了我知道你肯定会觉得很简单然后马上打开Steam的,但来都来了,那就👀看我如何用Node.js写出来的。

逻辑很简单:你在终端输入 "rock/scissor/paper",电脑随机出拳,然后比胜负~

第一步:先写 "游戏核心逻辑"(模块化拆分)

把 "出拳、比胜负" 的功能拆到 game/lib.js

JavaScript 复制代码
// game/lib.js(游戏核心逻辑)
module.exports = function (playerAction) {
    // 电脑随机出拳(rock/scissor/paper 三选一)
    const arr = ['rock', 'scissor', 'paper'];
    const index = Math.floor(Math.random() * 3); // 向下取整(0,1,2)
    const computerAction = arr[index];
    console.log(`我出了${computerAction}`);

    // 比胜负,返回结果(0=平,-1=你赢,1=你输)
    if (computerAction === playerAction) {
        console.log('平局');
        return 0;
    } else if ((playerAction === 'rock' && computerAction === 'scissor') ||
        (playerAction === 'scissor' && computerAction === 'paper') ||
        (playerAction === 'paper' && computerAction === 'rock')) {
        console.log('你赢了');
        return -1;
    } else {
        console.log('你输了');
        return 1;
    }
}

第二步:写 "终端交互逻辑"(调用核心功能)

game/index.js 里,用 Node.js 的 process 模块获取你在终端的输入,再调用游戏逻辑:

JavaScript 复制代码
// game/index.js(终端交互)
const game = require('./lib.js');
let count = 0; // 统计你赢的次数

// 监听终端输入(你输入的内容会传到 e 里)
process.stdin.on('data', e => {
    // 把输入的内容转成字符串,去掉空格
    const playerAction = e.toString().trim();
    // 调用游戏逻辑,拿到结果
    const result = game(playerAction);
    
    if (result === -1) {
        count++;
    }
    
    // 赢 3 次就结束游戏
    if (count === 3) {
        console.log('你太厉害了,我不玩了');
        process.exit(); // 结束 Node.js 进程
    }
});

第三步:跑起来!在终端玩游戏

打开终端,进入 game 文件夹,执行:

bash 复制代码
node index.js

然后输入 rock/scissor/paper,就能和电脑 PK 啦~

占用你玩2分钟玩Steam的时间看完了我的石头剪刀布~ 😊 ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄

四、总结:Node.js 到底是啥?

一句话: 它不仅是 "JS 运行环境",更是让你用 JS 写 "能和操作系统互动" 代码的工具------ 比如读文件、监听终端输入、写后端服务... 而模块化是它的 "基本功",帮你把代码写得更整洁、更好维护~

结语

从模块化规范的拆解,到石头剪刀布游戏的落地,不难发现 Node.js 的魅力:它让 JavaScript 跳出了前端的局限,拥有了跨场景开发的能力。小小的 requireexport 背后,是代码组织的大智慧;简单的终端交互游戏里,藏着后端开发的雏形。

希望这篇内容能让你对 Node.js 不再陌生,下次遇到复杂项目时,也能想起用模块化思维拆解问题,用 Node.js 敲出属于自己的有趣代码。

另外要查看Node.js详细资料的话,官网在这:

Node.js 官网

相关推荐
快乐星球喂4 小时前
子组件和父组件之间优雅通信---松耦合
前端·vue.js
不想秃头的程序员4 小时前
JS原型链详解
前端·面试
fighting不想说话4 小时前
NodeJs:前端工程化推手
node.js
simon91244 小时前
ElementUI:表格如何展示超出单元格的内容且不影响单元格?
前端·vue.js·element
天外天-亮4 小时前
Vue 中常用的指令
前端·javascript·vue.js
清风细雨_林木木4 小时前
vite与vue的cli的区别
前端·javascript·vue.js
亚洲小炫风4 小时前
react 资源清单
前端·javascript·react.js
IT古董4 小时前
【前端】Headless UI 深度实战:构建可访问、可定制的现代前端组件
前端·ui
南囝coding4 小时前
Knip - 一键清理项目无用代码
前端·后端