posodobitev
This commit is contained in:
58
tools/create_spritesheet.js
Normal file
58
tools/create_spritesheet.js
Normal file
@@ -0,0 +1,58 @@
|
||||
// Spritesheet Creator - combines 6 individual frames into horizontal spritesheet
|
||||
const { createCanvas, loadImage } = require('canvas');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
async function createSpritesheet(frames, outputPath) {
|
||||
const frameWidth = 64;
|
||||
const frameHeight = 64;
|
||||
const totalWidth = frameWidth * frames.length;
|
||||
|
||||
const canvas = createCanvas(totalWidth, frameHeight);
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
console.log(`Creating spritesheet: ${totalWidth}x${frameHeight}`);
|
||||
|
||||
for (let i = 0; i < frames.length; i++) {
|
||||
try {
|
||||
const img = await loadImage(frames[i]);
|
||||
ctx.drawImage(img, i * frameWidth, 0, frameWidth, frameHeight);
|
||||
console.log(` Frame ${i + 1}: ${path.basename(frames[i])}`);
|
||||
} catch (err) {
|
||||
console.error(`Error loading frame ${i + 1}:`, err.message);
|
||||
}
|
||||
}
|
||||
|
||||
const buffer = canvas.toBuffer('image/png');
|
||||
fs.writeFileSync(outputPath, buffer);
|
||||
console.log(`✅ Spritesheet saved: ${outputPath}`);
|
||||
}
|
||||
|
||||
// Define frame paths
|
||||
const playerFrames = [
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/player_frame_1_idle_1765466652332.png',
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/player_frame_2_left_1765466686157.png',
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/player_frame_3_mid_left_1765466722379.png',
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/player_frame_4_right_1765466767612.png',
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/player_frame_5_mid_right_1765466812029.png',
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/player_frame_6_idle_return_1765466859078.png'
|
||||
];
|
||||
|
||||
const zombieFrames = [
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/zombie_frame_1_idle_1765466924235.png',
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/zombie_frame_2_left_1765466975297.png',
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/zombie_frame_3_mid_left_1765467026661.png',
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/zombie_frame_4_right_1765467064996.png',
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/zombie_frame_5_mid_right_1765467114381.png',
|
||||
'C:/Users/hipod/.gemini/antigravity/brain/c3cb08b5-19b4-4254-a001-eeab1394eb46/zombie_frame_6_idle_return_1765467152088.png'
|
||||
];
|
||||
|
||||
// Run
|
||||
(async () => {
|
||||
console.log('🎬 Creating spritesheets...\n');
|
||||
|
||||
await createSpritesheet(playerFrames, 'c:/novafarma/assets/player_dreadlocks.png');
|
||||
await createSpritesheet(zombieFrames, 'c:/novafarma/assets/zombie_worker.png');
|
||||
|
||||
console.log('\n✅ ALL DONE!');
|
||||
})();
|
||||
69
tools/farming_controls_template.js
Normal file
69
tools/farming_controls_template.js
Normal file
@@ -0,0 +1,69 @@
|
||||
// FARMING CONTROLS - Add to Player.js
|
||||
|
||||
// In handleAction() method, add this code:
|
||||
|
||||
handleFarmingAction() {
|
||||
if (!this.scene.farmingSystem) return;
|
||||
|
||||
const selectedSlot = this.scene.scene.get('UIScene').selectedSlot;
|
||||
const inventory = this.scene.inventorySystem;
|
||||
const item = inventory ? inventory.slots[selectedSlot] : null;
|
||||
const itemType = item ? item.type : null;
|
||||
|
||||
// Get grid position player is facing
|
||||
const facingX = this.gridX;
|
||||
const facingY = this.gridY;
|
||||
|
||||
// Adjust based on direction (optional - or use mouse click position)
|
||||
// For now, use tile player is standing on
|
||||
|
||||
// HOE - Till soil
|
||||
if (itemType === 'hoe') {
|
||||
const success = this.scene.farmingSystem.tillSoil(facingX, facingY);
|
||||
if (success) {
|
||||
// Play sound/animation
|
||||
if (this.scene.soundManager) this.scene.soundManager.playDig();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// SEEDS - Plant
|
||||
if (itemType === 'carrot' || itemType === 'wheat') {
|
||||
const success = this.scene.farmingSystem.plantSeed(facingX, facingY, itemType);
|
||||
if (success) {
|
||||
// Consume seed
|
||||
inventory.removeItem(itemType, 1);
|
||||
if (this.scene.soundManager) this.scene.soundManager.playPlant();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// EMPTY HAND - Harvest
|
||||
if (!itemType) {
|
||||
const success = this.scene.farmingSystem.harvestCrop(facingX, facingY);
|
||||
if (success) {
|
||||
if (this.scene.soundManager) this.scene.soundManager.playHarvest();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// In Player update(), listen for SPACE or MOUSE CLICK:
|
||||
// Add to existing input handling:
|
||||
|
||||
/*
|
||||
if (this.scene.input.keyboard.checkDown(this.scene.input.keyboard.addKey('SPACE'), 300)) {
|
||||
this.handleFarmingAction();
|
||||
}
|
||||
*/
|
||||
|
||||
// OR use mouse click on tile:
|
||||
/*
|
||||
this.scene.input.on('pointerdown', (pointer) => {
|
||||
const worldPoint = this.scene.cameras.main.getWorldPoint(pointer.x, pointer.y);
|
||||
const gridPos = this.scene.iso.toGrid(worldPoint.x, worldPoint.y);
|
||||
|
||||
// Farming action at clicked tile
|
||||
this.farmAtTile(gridPos.x, gridPos.y);
|
||||
});
|
||||
*/
|
||||
109
tools/time_control_panel.js
Normal file
109
tools/time_control_panel.js
Normal file
@@ -0,0 +1,109 @@
|
||||
// Time Speed Control Panel
|
||||
// Add to UIScene.js
|
||||
|
||||
createTimeControlPanel() {
|
||||
const x = this.scale.width - 170;
|
||||
const y = 250; // Below resources
|
||||
|
||||
// Container
|
||||
this.timeControlContainer = this.add.container(x, y);
|
||||
this.timeControlContainer.setDepth(1000);
|
||||
|
||||
// Background
|
||||
const bg = this.add.graphics();
|
||||
bg.fillStyle(0x1a1a2a, 0.8);
|
||||
bg.fillRect(0, 0, 150, 100);
|
||||
bg.lineStyle(2, 0x4a90e2, 0.8);
|
||||
bg.strokeRect(0, 0, 150, 100);
|
||||
this.timeControlContainer.add(bg);
|
||||
|
||||
// Title
|
||||
const title = this.add.text(75, 15, 'TIME SPEED', {
|
||||
fontSize: '12px',
|
||||
fontFamily: 'Courier New',
|
||||
fill: '#ffffff',
|
||||
fontStyle: 'bold'
|
||||
}).setOrigin(0.5, 0.5);
|
||||
this.timeControlContainer.add(title);
|
||||
|
||||
// Speed buttons
|
||||
const speeds = [
|
||||
{ label: '1x', value: 1.0, y: 40 },
|
||||
{ label: '2x', value: 2.0, y: 60 },
|
||||
{ label: '5x', value: 5.0, y: 80 }
|
||||
];
|
||||
|
||||
this.timeSpeedButtons = [];
|
||||
|
||||
speeds.forEach((speed, i) => {
|
||||
const btn = this.add.text(75, speed.y, speed.label, {
|
||||
fontSize: '14px',
|
||||
fontFamily: 'Courier New',
|
||||
fill: '#4a90e2',
|
||||
fontStyle: 'bold',
|
||||
backgroundColor: '#1a1a2a',
|
||||
padding: { x: 20, y: 5 }
|
||||
}).setOrigin(0.5, 0.5);
|
||||
|
||||
btn.setInteractive({ useHandCursor: true });
|
||||
btn.on('pointerdown', () => {
|
||||
this.setTimeSpeed(speed.value);
|
||||
this.highlightSpeedButton(i);
|
||||
});
|
||||
|
||||
this.timeControlContainer.add(btn);
|
||||
this.timeSpeedButtons.push(btn);
|
||||
});
|
||||
|
||||
// Highlight default (1x)
|
||||
this.highlightSpeedButton(0);
|
||||
|
||||
// Pause button
|
||||
const pauseBtn = this.add.text(10, 15, '⏸️', {
|
||||
fontSize: '18px'
|
||||
}).setOrigin(0, 0.5);
|
||||
|
||||
pauseBtn.setInteractive({ useHandCursor: true });
|
||||
pauseBtn.on('pointerdown', () => {
|
||||
this.toggleTimePause();
|
||||
});
|
||||
|
||||
this.timeControlContainer.add(pauseBtn);
|
||||
this.pauseBtn = pauseBtn;
|
||||
}
|
||||
|
||||
setTimeSpeed(speed) {
|
||||
if (this.gameScene && this.gameScene.timeSystem) {
|
||||
this.gameScene.timeSystem.timeScale = speed;
|
||||
console.log(`⏱️ Time speed: ${speed}x`);
|
||||
}
|
||||
}
|
||||
|
||||
highlightSpeedButton(index) {
|
||||
this.timeSpeedButtons.forEach((btn, i) => {
|
||||
if (i === index) {
|
||||
btn.setStyle({ fill: '#ffff00', backgroundColor: '#2a4a6a' });
|
||||
} else {
|
||||
btn.setStyle({ fill: '#4a90e2', backgroundColor: '#1a1a2a' });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
toggleTimePause() {
|
||||
if (!this.gameScene || !this.gameScene.timeSystem) return;
|
||||
|
||||
const ts = this.gameScene.timeSystem;
|
||||
|
||||
if (ts.timeScale === 0) {
|
||||
// Unpause
|
||||
ts.timeScale = this.lastTimeScale || 1.0;
|
||||
this.pauseBtn.setText('⏸️');
|
||||
console.log('▶️ Time resumed');
|
||||
} else {
|
||||
// Pause
|
||||
this.lastTimeScale = ts.timeScale;
|
||||
ts.timeScale = 0;
|
||||
this.pauseBtn.setText('▶️');
|
||||
console.log('⏸️ Time paused');
|
||||
}
|
||||
}
|
||||
160
tools/ui_panels_code.js
Normal file
160
tools/ui_panels_code.js
Normal file
@@ -0,0 +1,160 @@
|
||||
// ZOMBIE & FARM STATS PANELS - Add to UIScene.js
|
||||
|
||||
// Call this in create() method:
|
||||
createZombieStatsPanel() {
|
||||
const panelWidth = 220;
|
||||
const panelHeight = 140;
|
||||
const x = 20;
|
||||
const y = 120; // Below player stats
|
||||
|
||||
// Container
|
||||
this.zombieStatsContainer = this.add.container(x, y);
|
||||
this.zombieStatsContainer.setDepth(1000);
|
||||
|
||||
// Background
|
||||
const bg = this.add.graphics();
|
||||
bg.fillStyle(0x1a1a2e, 0.9);
|
||||
bg.fillRect(0, 0, panelWidth, panelHeight);
|
||||
bg.lineStyle(2, 0x8a2be2, 0.8); // Purple border (zombie theme)
|
||||
bg.strokeRect(0, 0, panelWidth, panelHeight);
|
||||
this.zombieStatsContainer.add(bg);
|
||||
|
||||
// Title
|
||||
const title = this.add.text(panelWidth / 2, 15, '🧟 ZOMBIE WORKER', {
|
||||
fontSize: '14px',
|
||||
fontFamily: 'Courier New',
|
||||
fill: '#8a2be2',
|
||||
fontStyle: 'bold'
|
||||
}).setOrigin(0.5);
|
||||
this.zombieStatsContainer.add(title);
|
||||
|
||||
// Stats Text
|
||||
this.zombieNameText = this.add.text(10, 35, 'Name: Worker #1', {
|
||||
fontSize: '12px',
|
||||
fill: '#ffffff'
|
||||
});
|
||||
this.zombieStatsContainer.add(this.zombieNameText);
|
||||
|
||||
this.zombieTaskText = this.add.text(10, 55, 'Task: IDLE', {
|
||||
fontSize: '12px',
|
||||
fill: '#ffff00'
|
||||
});
|
||||
this.zombieStatsContainer.add(this.zombieTaskText);
|
||||
|
||||
this.zombieLevelText = this.add.text(10, 75, 'Level: 1 (0/100 XP)', {
|
||||
fontSize: '12px',
|
||||
fill: '#00ff00'
|
||||
});
|
||||
this.zombieStatsContainer.add(this.zombieLevelText);
|
||||
|
||||
// Energy Bar
|
||||
this.add.text(10, 95, 'ENERGY:', { fontSize: '11px', fill: '#aaaaaa' });
|
||||
this.zombieEnergyBar = this.drawMiniBar(10, 110, panelWidth - 20, 15, 0x00aaff, 100);
|
||||
this.zombieStatsContainer.add(this.zombieEnergyBar.bg);
|
||||
this.zombieStatsContainer.add(this.zombieEnergyBar.fill);
|
||||
|
||||
// Initially hidden - shows when zombie is selected/nearby
|
||||
this.zombieStatsContainer.setVisible(false);
|
||||
}
|
||||
|
||||
createFarmStatsPanel() {
|
||||
const panelWidth = 220;
|
||||
const panelHeight = 120;
|
||||
const x = 20;
|
||||
const y = 280; // Below zombie stats
|
||||
|
||||
// Container
|
||||
this.farmStatsContainer = this.add.container(x, y);
|
||||
this.farmStatsContainer.setDepth(1000);
|
||||
|
||||
// Background
|
||||
const bg = this.add.graphics();
|
||||
bg.fillStyle(0x1a2e1a, 0.9);
|
||||
bg.fillRect(0, 0, panelWidth, panelHeight);
|
||||
bg.lineStyle(2, 0x00ff00, 0.8); // Green border (farm theme)
|
||||
bg.strokeRect(0, 0, panelWidth, panelHeight);
|
||||
this.farmStatsContainer.add(bg);
|
||||
|
||||
// Title
|
||||
const title = this.add.text(panelWidth / 2, 15, '🌾 FARM STATS', {
|
||||
fontSize: '14px',
|
||||
fontFamily: 'Courier New',
|
||||
fill: '#00ff00',
|
||||
fontStyle: 'bold'
|
||||
}).setOrigin(0.5);
|
||||
this.farmStatsContainer.add(title);
|
||||
|
||||
// Stats
|
||||
this.farmCropsPlantedText = this.add.text(10, 40, 'Crops Planted: 0', {
|
||||
fontSize: '12px',
|
||||
fill: '#ffffff'
|
||||
});
|
||||
this.farmStatsContainer.add(this.farmCropsPlantedText);
|
||||
|
||||
this.farmCropsHarvestedText = this.add.text(10, 60, 'Total Harvested: 0', {
|
||||
fontSize: '12px',
|
||||
fill: '#ffff00'
|
||||
});
|
||||
this.farmStatsContainer.add(this.farmCropsHarvestedText);
|
||||
|
||||
this.farmGoldEarnedText = this.add.text(10, 80, 'Gold Earned: 0g', {
|
||||
fontSize: '12px',
|
||||
fill: '#ffd700'
|
||||
});
|
||||
this.farmStatsContainer.add(this.farmGoldEarnedText);
|
||||
|
||||
this.farmDaysText = this.add.text(10, 100, 'Days Farmed: 0', {
|
||||
fontSize: '12px',
|
||||
fill: '#aaaaaa'
|
||||
});
|
||||
this.farmStatsContainer.add(this.farmDaysText);
|
||||
}
|
||||
|
||||
drawMiniBar(x, y, width, height, color, initialPercent = 100) {
|
||||
// Background
|
||||
const bg = this.add.graphics();
|
||||
bg.fillStyle(0x000000, 0.5);
|
||||
bg.fillRect(x, y, width, height);
|
||||
bg.lineStyle(1, 0xffffff, 0.3);
|
||||
bg.strokeRect(x, y, width, height);
|
||||
|
||||
// Fill
|
||||
const fill = this.add.graphics();
|
||||
fill.fillStyle(color, 1);
|
||||
const maxWidth = width - 4;
|
||||
const currentWidth = (maxWidth * initialPercent) / 100;
|
||||
fill.fillRect(x + 2, y + 2, currentWidth, height - 4);
|
||||
|
||||
return { bg, fill, x, y, width, height, color };
|
||||
}
|
||||
|
||||
setMiniBarValue(bar, percent) {
|
||||
percent = Phaser.Math.Clamp(percent, 0, 100);
|
||||
bar.fill.clear();
|
||||
bar.fill.fillStyle(bar.color, 1);
|
||||
const maxWidth = bar.width - 4;
|
||||
const currentWidth = (maxWidth * percent) / 100;
|
||||
bar.fill.fillRect(bar.x + 2, bar.y + 2, currentWidth, bar.height - 4);
|
||||
}
|
||||
|
||||
// Update methods (call from update())
|
||||
updateZombieStats(zombie) {
|
||||
if (!zombie || !this.zombieStatsContainer) return;
|
||||
|
||||
this.zombieStatsContainer.setVisible(true);
|
||||
this.zombieNameText.setText(`Name: ${zombie.name || 'Worker #1'}`);
|
||||
this.zombieTaskText.setText(`Task: ${zombie.task || 'IDLE'}`);
|
||||
this.zombieLevelText.setText(`Level: ${zombie.level || 1} (${zombie.xp || 0}/100 XP)`);
|
||||
|
||||
const energy = zombie.energy !== undefined ? zombie.energy : 100;
|
||||
this.setMiniBarValue(this.zombieEnergyBar, energy);
|
||||
}
|
||||
|
||||
updateFarmStats(stats) {
|
||||
if (!stats || !this.farmStatsContainer) return;
|
||||
|
||||
this.farmCropsPlantedText.setText(`Crops Planted: ${stats.cropsPlanted || 0}`);
|
||||
this.farmCropsHarvestedText.setText(`Total Harvested: ${stats.totalHarvested || 0}`);
|
||||
this.farmGoldEarnedText.setText(`Gold Earned: ${stats.goldEarned || 0}g`);
|
||||
this.farmDaysText.setText(`Days Farmed: ${stats.daysFarmed || 0}`);
|
||||
}
|
||||
Reference in New Issue
Block a user