feat: Implement player block breaking with 10-pixel range and inventory collection
This commit is contained in:
parent
d765defa9d
commit
80c243ebf8
@ -29,7 +29,7 @@ class Player extends Entity {
|
|||||||
this.maxHealth = 100;
|
this.maxHealth = 100;
|
||||||
this.health = 100;
|
this.health = 100;
|
||||||
this.breakingPower = 1;
|
this.breakingPower = 1;
|
||||||
this.breakingRange = 3;
|
this.breakingRange = 10; // Increased from 3 to 10 pixels
|
||||||
this.isBreaking = false;
|
this.isBreaking = false;
|
||||||
this.breakingCooldown = 0;
|
this.breakingCooldown = 0;
|
||||||
this.breakingCooldownMax = 10;
|
this.breakingCooldownMax = 10;
|
||||||
@ -252,30 +252,38 @@ class Player extends Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
breakBlock() {
|
breakBlock() {
|
||||||
// Calculate the position in front of the player
|
// Get mouse position in world coordinates
|
||||||
const halfWidth = this.width / 2;
|
const worldX = Math.floor(currentMouseX / PIXEL_SIZE) + worldOffsetX;
|
||||||
const breakX = Math.floor(this.x + (this.direction * this.breakingRange));
|
const worldY = Math.floor(currentMouseY / PIXEL_SIZE) + worldOffsetY;
|
||||||
const breakY = Math.floor(this.y);
|
|
||||||
|
|
||||||
// Get the block type at that position
|
// Calculate distance from player to target block
|
||||||
const blockType = getPixel(breakX, breakY);
|
const distance = Math.sqrt(
|
||||||
|
Math.pow(worldX - this.x, 2) +
|
||||||
|
Math.pow(worldY - this.y, 2)
|
||||||
|
);
|
||||||
|
|
||||||
// Only break non-empty blocks that aren't special entities
|
// Only break blocks within range
|
||||||
if (blockType !== EMPTY &&
|
if (distance <= this.breakingRange) {
|
||||||
blockType !== WATER &&
|
// Get the block type at that position
|
||||||
blockType !== FIRE &&
|
const blockType = getPixel(worldX, worldY);
|
||||||
blockType !== SQUARE &&
|
|
||||||
blockType !== CIRCLE &&
|
|
||||||
blockType !== TRIANGLE) {
|
|
||||||
|
|
||||||
// Add to inventory based on block type
|
// Only break non-empty blocks that aren't special entities
|
||||||
this.addToInventory(blockType);
|
if (blockType !== EMPTY &&
|
||||||
|
blockType !== WATER &&
|
||||||
|
blockType !== FIRE &&
|
||||||
|
blockType !== SQUARE &&
|
||||||
|
blockType !== CIRCLE &&
|
||||||
|
blockType !== TRIANGLE) {
|
||||||
|
|
||||||
// Replace with empty space
|
// Add to inventory based on block type
|
||||||
setPixel(breakX, breakY, EMPTY);
|
this.addToInventory(blockType);
|
||||||
|
|
||||||
// Create a breaking effect (particles)
|
// Replace with empty space
|
||||||
this.createBreakingEffect(breakX, breakY, blockType);
|
setPixel(worldX, worldY, EMPTY);
|
||||||
|
|
||||||
|
// Create a breaking effect (particles)
|
||||||
|
this.createBreakingEffect(worldX, worldY, blockType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
js/input.js
19
js/input.js
@ -18,7 +18,7 @@ window.addEventListener('keydown', (e) => {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start breaking blocks with E key
|
// Start breaking blocks with E key or left mouse button
|
||||||
if (e.code === 'KeyE' && player) {
|
if (e.code === 'KeyE' && player) {
|
||||||
player.startBreaking();
|
player.startBreaking();
|
||||||
}
|
}
|
||||||
@ -106,9 +106,15 @@ function handleMouseDown(e) {
|
|||||||
worldOffsetXBeforeDrag = worldOffsetX;
|
worldOffsetXBeforeDrag = worldOffsetX;
|
||||||
worldOffsetYBeforeDrag = worldOffsetY;
|
worldOffsetYBeforeDrag = worldOffsetY;
|
||||||
} else {
|
} else {
|
||||||
// Left mouse button for drawing
|
// Left mouse button for drawing or breaking blocks
|
||||||
isDrawing = true;
|
if (player) {
|
||||||
draw(x, y);
|
// If player exists, start breaking blocks
|
||||||
|
player.startBreaking();
|
||||||
|
} else {
|
||||||
|
// Otherwise use normal drawing
|
||||||
|
isDrawing = true;
|
||||||
|
draw(x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,6 +155,11 @@ function handleMouseUp(e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
isDragging = false;
|
isDragging = false;
|
||||||
|
|
||||||
|
// Stop breaking blocks if player exists
|
||||||
|
if (player) {
|
||||||
|
player.stopBreaking();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw(x, y) {
|
function draw(x, y) {
|
||||||
|
44
js/render.js
44
js/render.js
@ -175,16 +175,42 @@ function displayDebugInfo() {
|
|||||||
|
|
||||||
// Render breaking indicator for player
|
// Render breaking indicator for player
|
||||||
function renderBreakingIndicator(ctx, offsetX, offsetY) {
|
function renderBreakingIndicator(ctx, offsetX, offsetY) {
|
||||||
// Calculate position in front of player
|
// Get mouse position in world coordinates
|
||||||
const breakX = Math.floor(player.x + (player.direction * player.breakingRange));
|
const worldX = Math.floor(currentMouseX / PIXEL_SIZE) + worldOffsetX;
|
||||||
const breakY = Math.floor(player.y);
|
const worldY = Math.floor(currentMouseY / PIXEL_SIZE) + worldOffsetY;
|
||||||
|
|
||||||
|
// Calculate distance from player to target block
|
||||||
|
const distance = Math.sqrt(
|
||||||
|
Math.pow(worldX - player.x, 2) +
|
||||||
|
Math.pow(worldY - player.y, 2)
|
||||||
|
);
|
||||||
|
|
||||||
// Convert to screen coordinates
|
// Convert to screen coordinates
|
||||||
const screenX = (breakX - offsetX) * PIXEL_SIZE;
|
const screenX = (worldX - offsetX) * PIXEL_SIZE;
|
||||||
const screenY = (breakY - offsetY) * PIXEL_SIZE;
|
const screenY = (worldY - offsetY) * PIXEL_SIZE;
|
||||||
|
const playerScreenX = (player.x - offsetX) * PIXEL_SIZE;
|
||||||
|
const playerScreenY = (player.y - offsetY) * PIXEL_SIZE;
|
||||||
|
|
||||||
|
// Draw breaking range circle
|
||||||
|
ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(
|
||||||
|
playerScreenX,
|
||||||
|
playerScreenY,
|
||||||
|
player.breakingRange * PIXEL_SIZE,
|
||||||
|
0,
|
||||||
|
Math.PI * 2
|
||||||
|
);
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
// Draw target indicator
|
||||||
|
if (distance <= player.breakingRange) {
|
||||||
|
ctx.strokeStyle = '#ff0000';
|
||||||
|
} else {
|
||||||
|
ctx.strokeStyle = '#888888'; // Gray when out of range
|
||||||
|
}
|
||||||
|
|
||||||
// Draw breaking indicator
|
|
||||||
ctx.strokeStyle = '#ff0000';
|
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.strokeRect(
|
ctx.strokeRect(
|
||||||
screenX - PIXEL_SIZE/2,
|
screenX - PIXEL_SIZE/2,
|
||||||
@ -193,9 +219,9 @@ function renderBreakingIndicator(ctx, offsetX, offsetY) {
|
|||||||
PIXEL_SIZE
|
PIXEL_SIZE
|
||||||
);
|
);
|
||||||
|
|
||||||
// Draw line from player to breaking point
|
// Draw line from player to target point
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo((player.x - offsetX) * PIXEL_SIZE, (player.y - offsetY) * PIXEL_SIZE);
|
ctx.moveTo(playerScreenX, playerScreenY);
|
||||||
ctx.lineTo(screenX, screenY);
|
ctx.lineTo(screenX, screenY);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user