如何从其他类访问JavaScript中spaceship_build函数内的飞船对象属性?
Hey there! Let's break down how to fix that issue where you can't access your spaceship_object properties from other classes. You tried using a closure with fly_left nested in spaceship_build()—that's a solid start, but let's explore a few more robust solutions tailored to your PixiJS setup.
Instead of using a standalone function to build your ship, wrap everything in a class. This keeps your ship's properties and behaviors tightly coupled, and makes it easy to pass the ship instance to other classes that need access to it.
import * as PIXI from 'pixi.js'; class Spaceship { constructor() { // Initialize PixiJS sprite this.sprite = new PIXI.Sprite(PIXI.Texture.from('spaceship.png')); // Ship properties this.energy = 100; this.shipclass = 'Interceptor'; // Optional: Set initial position/scale this.sprite.x = 100; this.sprite.y = 200; } // Your fly_left method, now part of the class fly_left() { this.sprite.x -= 5; // Adjust energy as needed this.energy -= 1; // Prevent energy from going negative this.energy = Math.max(0, this.energy); } } // Create your ship instance once const playerShip = new Spaceship(); // Now use it in another class class EnemyAI { constructor(playerShip) { // Inject the ship instance into the enemy class this.playerShip = playerShip; } trackPlayer() { // Access ship properties directly console.log(`Player ship energy: ${this.playerShip.energy}`); console.log(`Player ship type: ${this.playerShip.shipclass}`); } } // Pass the ship instance to the enemy AI const enemy = new EnemyAI(playerShip); enemy.trackPlayer(); // Logs ship's energy and class playerShip.fly_left(); // Move the ship and reduce energy enemy.trackPlayer(); // Shows updated energy
This approach is clean, scalable, and follows modern JavaScript best practices. It also makes it easy to create multiple ship instances if you ever need to.
If you prefer to stick with a function-based setup, you can export your spaceship_object from a module so other files can import it. This works great for simpler projects where you only need one player ship.
// spaceship.js import * as PIXI from 'pixi.js'; // Define your ship object globally within the module export const spaceship_object = { energy: 100, shipclass: 'Interceptor', sprite: null }; export function spaceship_build() { // Initialize the sprite and attach it to the object spaceship_object.sprite = new PIXI.Sprite(PIXI.Texture.from('spaceship.png')); spaceship_object.sprite.x = 100; spaceship_object.sprite.y = 200; } // Your fly_left function, now modifying the exported object export function fly_left() { spaceship_object.sprite.x -= 5; spaceship_object.energy -= 1; } // In another file (e.g., enemy.js) import { spaceship_object } from './spaceship.js'; class Enemy { attackPlayer() { // Access the ship's properties directly spaceship_object.energy -= 20; console.log(`Player energy after attack: ${spaceship_object.energy}`); } }
Just make sure to call spaceship_build() once before accessing the sprite or properties to avoid null errors.
Your initial closure idea is valid—you just need to make sure spaceship_build() returns an object that exposes the properties and methods you need to access externally. This is great if you want some properties to be private (not directly modifiable from outside).
import * as PIXI from 'pixi.js'; function spaceship_build() { // Private variables (can't be modified directly outside the closure) let _energy = 100; const _shipclass = 'Interceptor'; // Read-only private property const sprite = new PIXI.Sprite(PIXI.Texture.from('spaceship.png')); sprite.x = 100; sprite.y = 200; // Return a public interface with getters/setters and methods return { // Getter for energy (with optional validation) get energy() { return _energy; }, // Setter for energy (prevents negative values) set energy(newValue) { _energy = Math.max(0, newValue); }, // Getter for ship class (read-only) get shipclass() { return _shipclass; }, // Expose the sprite directly if needed get sprite() { return sprite; }, // Your fly_left method fly_left() { sprite.x -= 5; _energy -= 1; } }; } // Create your ship instance const playerShip = spaceship_build(); // Use it in another class class HUD { update() { console.log(`Current Energy: ${playerShip.energy}`); console.log(`Ship Class: ${playerShip.shipclass}`); } } const hud = new HUD(); hud.update(); // Logs 100 and "Interceptor" playerShip.fly_left(); hud.update(); // Logs 99 and "Interceptor" // playerShip.shipclass = 'Battleship'; // This won't work—_shipclass is private
This keeps sensitive state (like energy) protected from accidental modification while still letting other classes read and interact with it safely.
Whichever approach you pick, the key is to make your spaceship_object (or ship instance) accessible to other classes either by passing it around (dependency injection), exporting it, or exposing it via a closure interface. This avoids the "hidden object" problem you're facing right now.
内容的提问来源于stack exchange,提问作者user5090322

