| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- import { _decorator, Component, Node, Sprite, SpriteFrame, resources, Prefab, instantiate, UITransform, Vec2, Vec3, RigidBody2D, macro } from 'cc';
- const { ccclass, property } = _decorator;
- @ccclass('WeaponRandomSpawner')
- export class WeaponRandomSpawner extends Component {
- /**
- * Pellet prefab used as bullet. Drag the Pellet.prefab into this slot in the editor.
- */
- @property({ type: Prefab })
- public pelletPrefab: Prefab | null = null;
- /**
- * Time interval (seconds) between two shots.
- */
- @property
- public fireInterval: number = 1.0;
- /** Cached weapon sprite component (WeaponBlock/B1/Weapon) */
- private _weaponSprite: Sprite | null = null;
- /** The sprite frame chosen randomly at scene start */
- private _selectedFrame: SpriteFrame | null = null;
- onLoad() {
- // Locate the Weapon sprite component inside the prefab hierarchy
- const b1Node: Node | null = this.node.getChildByName('B1');
- if (!b1Node) {
- console.error('[WeaponRandomSpawner] Cannot find child node "B1"');
- return;
- }
- const weaponNode: Node | null = b1Node.getChildByName('Weapon');
- if (!weaponNode) {
- console.error('[WeaponRandomSpawner] Cannot find grand-child node "Weapon" under B1');
- return;
- }
- this._weaponSprite = weaponNode.getComponent(Sprite);
- if (!this._weaponSprite) {
- console.error('[WeaponRandomSpawner] Sprite component missing on Weapon node');
- return;
- }
- // Load all sprite frames under resources/images/PlantsSprite at runtime
- resources.loadDir('images/PlantsSprite', SpriteFrame, (err, assets) => {
- if (err) {
- console.error('[WeaponRandomSpawner] Failed to load PlantsSprite resources:', err);
- return;
- }
- if (!assets || assets.length === 0) {
- console.warn('[WeaponRandomSpawner] No sprite frames found in images/PlantsSprite');
- return;
- }
- // Pick one sprite frame randomly and apply to weapon
- this._selectedFrame = assets[Math.floor(Math.random() * assets.length)];
- if (this._weaponSprite) {
- this._weaponSprite.spriteFrame = this._selectedFrame;
- }
- });
- }
- start() {
- // Start auto-fire schedule
- this.schedule(this._fire.bind(this), this.fireInterval);
- }
- /**
- * Instantiate a bullet prefab, copy the weapon sprite frame to it (scaled to half size)
- * and give it an upward velocity.
- */
- private _fire() {
- if (!this.pelletPrefab || !this._selectedFrame) {
- return; // Not ready yet
- }
- const bullet: Node = instantiate(this.pelletPrefab);
- // Add to the same scene, at world position of the weapon muzzle (current node)
- this.node.scene?.addChild(bullet);
- bullet.setWorldPosition(this.node.worldPosition);
- // Set bullet sprite frame
- const bulletSprite = bullet.getComponent(Sprite);
- if (bulletSprite) {
- bulletSprite.spriteFrame = this._selectedFrame;
- }
- // Match bullet size to half of weapon sprite size
- const weaponUi = this._weaponSprite?.node.getComponent(UITransform);
- const bulletUi = bullet.getComponent(UITransform);
- if (weaponUi && bulletUi) {
- const size = weaponUi.contentSize;
- bulletUi.setContentSize(size.width * 0.5, size.height * 0.5);
- } else {
- // Fallback: scale the whole node
- bullet.setScale(this.node.scale.x * 0.5, this.node.scale.y * 0.5, 1);
- }
- // Give the bullet an upward velocity if it has a RigidBody2D component
- const rb = bullet.getComponent(RigidBody2D);
- if (rb) {
- rb.linearVelocity = new Vec2(0, 600);
- }
- }
- }
|