mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-21 11:18:08 +00:00
Enhance player mechanics by implementing character sprite sheet, scaling, and animations. Updated player creation to use sprite instead of rectangle, added movement direction tracking, and refined collision detection for improved gameplay experience.
This commit is contained in:
190
index.html
190
index.html
@@ -1716,6 +1716,7 @@
|
||||
this.load.image('room_ceo_l', 'assets/rooms/room_ceo_l.png');
|
||||
this.load.image('room_spooky_basement_l', 'assets/rooms/room_spooky_basement_l.png');
|
||||
this.load.image('door', 'assets/tiles/door.png');
|
||||
|
||||
// Load object sprites
|
||||
this.load.image('pc', 'assets/objects/pc.png');
|
||||
this.load.image('key', 'assets/objects/key.png');
|
||||
@@ -1734,6 +1735,12 @@
|
||||
this.load.image('lockpick', 'assets/objects/lockpick.png');
|
||||
this.load.image('spoofing_kit', 'assets/objects/spoofing_kit.png');
|
||||
|
||||
// Load character sprite sheet instead of single image
|
||||
this.load.spritesheet('hacker', 'assets/characters/hacker.png', {
|
||||
frameWidth: 64,
|
||||
frameHeight: 64
|
||||
});
|
||||
|
||||
// Get scenario from URL parameter or use default
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const scenarioFile = urlParams.get('scenario') || 'assets/scenarios/ceo_exfil.json';
|
||||
@@ -1790,17 +1797,104 @@
|
||||
worldBounds.height
|
||||
);
|
||||
|
||||
// Create player first
|
||||
player = this.add.rectangle(400, 300, 32, 32, 0xff0000);
|
||||
// Create player as sprite
|
||||
player = this.add.sprite(400, 300, 'hacker', 0);
|
||||
this.physics.add.existing(player);
|
||||
player.body.setSize(16, 16);
|
||||
player.body.setOffset(8, 8);
|
||||
|
||||
// Scale the character up by 25%
|
||||
player.setScale(1.25);
|
||||
|
||||
// Set smaller collision box at the feet
|
||||
player.body.setSize(15, 10);
|
||||
player.body.setOffset(25, 50); // Adjusted offset to account for scaling
|
||||
|
||||
player.body.setCollideWorldBounds(true);
|
||||
player.body.setBounce(0);
|
||||
player.body.setDrag(0);
|
||||
player.body.setFriction(0);
|
||||
|
||||
// Enable physics debug to see the collision box
|
||||
this.physics.world.debugGraphic.clear();
|
||||
this.physics.world.drawDebug = true;
|
||||
|
||||
// Force debug display to be visible and on top
|
||||
this.physics.world.debugGraphic.setVisible(true);
|
||||
this.physics.world.debugGraphic.setDepth(9999);
|
||||
|
||||
// Set player depth to ensure it renders above most objects
|
||||
player.setDepth(2000);
|
||||
|
||||
// Track player direction and movement state
|
||||
player.direction = 'down'; // Initial direction
|
||||
player.isMoving = false;
|
||||
player.lastDirection = 'down';
|
||||
|
||||
player.setDepth(1000);
|
||||
// Create animations for each direction
|
||||
this.anims.create({
|
||||
key: 'walk-right',
|
||||
frames: this.anims.generateFrameNumbers('hacker', { start: 1, end: 4 }),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
|
||||
this.anims.create({
|
||||
key: 'walk-down',
|
||||
frames: this.anims.generateFrameNumbers('hacker', { start: 6, end: 9 }),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
|
||||
this.anims.create({
|
||||
key: 'walk-up',
|
||||
frames: this.anims.generateFrameNumbers('hacker', { start: 11, end: 14 }),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
|
||||
this.anims.create({
|
||||
key: 'walk-up-right',
|
||||
frames: this.anims.generateFrameNumbers('hacker', { start: 16, end: 19 }),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
|
||||
this.anims.create({
|
||||
key: 'walk-down-right',
|
||||
frames: this.anims.generateFrameNumbers('hacker', { start: 21, end: 24 }),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
|
||||
// Create idle frames (first frame of each row)
|
||||
this.anims.create({
|
||||
key: 'idle-right',
|
||||
frames: [{ key: 'hacker', frame: 0 }],
|
||||
frameRate: 1
|
||||
});
|
||||
|
||||
this.anims.create({
|
||||
key: 'idle-down',
|
||||
frames: [{ key: 'hacker', frame: 5 }],
|
||||
frameRate: 1
|
||||
});
|
||||
|
||||
this.anims.create({
|
||||
key: 'idle-up',
|
||||
frames: [{ key: 'hacker', frame: 10 }],
|
||||
frameRate: 1
|
||||
});
|
||||
|
||||
this.anims.create({
|
||||
key: 'idle-up-right',
|
||||
frames: [{ key: 'hacker', frame: 15 }],
|
||||
frameRate: 1
|
||||
});
|
||||
|
||||
this.anims.create({
|
||||
key: 'idle-down-right',
|
||||
frames: [{ key: 'hacker', frame: 20 }],
|
||||
frameRate: 1
|
||||
});
|
||||
|
||||
// Initialize room layout after player creation
|
||||
initializeRooms.call(this);
|
||||
@@ -1913,6 +2007,9 @@
|
||||
}
|
||||
|
||||
function update() {
|
||||
// Make sure debug is always enabled
|
||||
this.physics.world.drawDebug = true;
|
||||
|
||||
// updates the player's movement
|
||||
updatePlayerMovement.call(this);
|
||||
|
||||
@@ -2342,6 +2439,10 @@
|
||||
if (!isMoving || !targetPoint) {
|
||||
if (player.body.velocity.x !== 0 || player.body.velocity.y !== 0) {
|
||||
player.body.setVelocity(0, 0);
|
||||
player.isMoving = false;
|
||||
|
||||
// Play idle animation based on last direction
|
||||
player.anims.play(`idle-${player.direction}`, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -2359,6 +2460,10 @@
|
||||
if (distanceSq < ARRIVAL_THRESHOLD * ARRIVAL_THRESHOLD) {
|
||||
isMoving = false;
|
||||
player.body.setVelocity(0, 0);
|
||||
player.isMoving = false;
|
||||
|
||||
// Play idle animation based on last direction
|
||||
player.anims.play(`idle-${player.direction}`, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2377,20 +2482,45 @@
|
||||
const velocityX = (dx / distance) * MOVEMENT_SPEED;
|
||||
const velocityY = (dy / distance) * MOVEMENT_SPEED;
|
||||
|
||||
// Only update velocity if it changed significantly
|
||||
const currentVX = player.body.velocity.x;
|
||||
const currentVY = player.body.velocity.y;
|
||||
const velocityDiffX = Math.abs(currentVX - velocityX);
|
||||
const velocityDiffY = Math.abs(currentVY - velocityY);
|
||||
|
||||
if (velocityDiffX > 1 || velocityDiffY > 1) {
|
||||
player.body.setVelocity(velocityX, velocityY);
|
||||
// Set velocity directly without checking for changes
|
||||
player.body.setVelocity(velocityX, velocityY);
|
||||
|
||||
// Determine direction based on velocity
|
||||
const absVX = Math.abs(velocityX);
|
||||
const absVY = Math.abs(velocityY);
|
||||
|
||||
// Set player direction and animation
|
||||
if (absVX > absVY * 2) {
|
||||
// Mostly horizontal movement
|
||||
player.direction = velocityX > 0 ? 'right' : 'right'; // Use right animation but flip
|
||||
player.setFlipX(velocityX < 0); // Flip sprite horizontally if moving left
|
||||
} else if (absVY > absVX * 2) {
|
||||
// Mostly vertical movement
|
||||
player.direction = velocityY > 0 ? 'down' : 'up';
|
||||
player.setFlipX(false);
|
||||
} else {
|
||||
// Diagonal movement
|
||||
if (velocityY > 0) {
|
||||
player.direction = 'down-right';
|
||||
} else {
|
||||
player.direction = 'up-right';
|
||||
}
|
||||
player.setFlipX(velocityX < 0); // Flip sprite horizontally if moving left
|
||||
}
|
||||
|
||||
// Play appropriate animation if not already playing
|
||||
if (!player.isMoving || player.lastDirection !== player.direction) {
|
||||
player.anims.play(`walk-${player.direction}`, true);
|
||||
player.isMoving = true;
|
||||
player.lastDirection = player.direction;
|
||||
}
|
||||
|
||||
// Stop if collision detected
|
||||
if (player.body.blocked.none === false) {
|
||||
isMoving = false;
|
||||
player.body.setVelocity(0, 0);
|
||||
player.isMoving = false;
|
||||
player.anims.play(`idle-${player.direction}`, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2784,13 +2914,33 @@
|
||||
|
||||
// checks if the player is in bounds
|
||||
function isPlayerInBounds(bounds) {
|
||||
const buffer = 0; // Changed from TILE_SIZE (48) to 0
|
||||
return (
|
||||
player.x >= bounds.x - buffer &&
|
||||
player.x <= bounds.x + bounds.width + buffer &&
|
||||
player.y >= bounds.y - buffer &&
|
||||
player.y <= bounds.y + bounds.height + buffer
|
||||
);
|
||||
// Use the player's physics body bounds for more precise detection
|
||||
const playerBody = player.body;
|
||||
const playerBounds = {
|
||||
left: playerBody.x,
|
||||
right: playerBody.x + playerBody.width,
|
||||
top: playerBody.y,
|
||||
bottom: playerBody.y + playerBody.height
|
||||
};
|
||||
|
||||
// Calculate the overlap area between player and room
|
||||
const overlapWidth = Math.min(playerBounds.right, bounds.x + bounds.width) -
|
||||
Math.max(playerBounds.left, bounds.x);
|
||||
const overlapHeight = Math.min(playerBounds.bottom, bounds.y + bounds.height) -
|
||||
Math.max(playerBounds.top, bounds.y);
|
||||
|
||||
// Require a minimum overlap percentage (e.g., 50% of player width/height)
|
||||
const minOverlapPercent = 0.5;
|
||||
const playerWidth = playerBounds.right - playerBounds.left;
|
||||
const playerHeight = playerBounds.bottom - playerBounds.top;
|
||||
|
||||
const widthOverlapPercent = overlapWidth / playerWidth;
|
||||
const heightOverlapPercent = overlapHeight / playerHeight;
|
||||
|
||||
return overlapWidth > 0 &&
|
||||
overlapHeight > 0 &&
|
||||
widthOverlapPercent >= minOverlapPercent &&
|
||||
heightOverlapPercent >= minOverlapPercent;
|
||||
}
|
||||
|
||||
// handles room changes
|
||||
|
||||
Reference in New Issue
Block a user