Keys to Move
Time to bring your hero to LIFE! 🎮 This is the moment where your game transforms from a static picture into an interactive experience. Player control is what separates games from movies - and you’re about to master it! By the end of this chapter, your hero will respond to your every command, moving smoothly through your tile-based world.
Try it! Use your arrow keys to move the red square around! ⬅️➡️⬆️⬇️
Notice how the hero changes color when moving and stays within the boundaries!
MODERN CHARACTER SETUP 🎨
Forget complex movie clips and keyframes! Modern game development uses much simpler, more powerful approaches. Let’s build a character system that’s both easier to understand and more flexible than the old Flash methods.
Enhanced Hero Object:
const hero = {
// Position in tile coordinates
tileX: 3,
tileY: 2,
// Pixel coordinates (calculated from tile position)
x: 0,
y: 0,
// Movement properties
speed: 2, // How fast we move (pixels per frame)
isMoving: false, // Are we currently moving?
direction: 'down', // Which way are we facing?
// Visual representation
sprite: null, // Our PixiJS sprite
// Animation (we'll enhance this!)
animationFrame: 0,
animationSpeed: 0.2
};
Why this is better than Flash:
- ✅ Simpler: No complex keyframe management
- ✅ Flexible: Easy to add new properties and behaviors
- ✅ Modern: Uses current web standards
- ✅ Performant: No movie clip overhead
- ✅ Debuggable: Easy to inspect and modify
KEYBOARD INPUT: THE MODERN WAY 🎯
Step 1: Set Up Input Tracking
Modern games use event listeners to track keyboard input. This is much more reliable and flexible than Flash’s old Key.isDown method:
// Create an object to track which keys are currently pressed
const keys = {
ArrowUp: false,
ArrowDown: false,
ArrowLeft: false,
ArrowRight: false,
// You can easily add more keys later!
Space: false,
KeyZ: false
};
// Listen for key presses
window.addEventListener('keydown', (event) => {
if (keys.hasOwnProperty(event.code)) {
keys[event.code] = true;
event.preventDefault(); // Prevent browser scroll
}
});
// Listen for key releases
window.addEventListener('keyup', (event) => {
if (keys.hasOwnProperty(event.code)) {
keys[event.code] = false;
event.preventDefault();
}
});
Why this rocks:
- 🎮 Multiple keys: Handle multiple simultaneous key presses
- 🚀 Responsive: Immediate reaction to input
- 🔧 Flexible: Easy to add new controls
- 🌐 Standard: Works across all modern browsers
MOVEMENT LOGIC: CLEAN & POWERFUL 🚀
Step 2: Create the Movement System
Let’s create a clean movement system that’s easy to understand and modify:
function updateMovement() {
let moved = false;
let newDirection = hero.direction;
// Check each direction
if (keys.ArrowUp) {
hero.tileY--;
newDirection = 'up';
moved = true;
} else if (keys.ArrowDown) {
hero.tileY++;
newDirection = 'down';
moved = true;
} else if (keys.ArrowLeft) {
hero.tileX--;
newDirection = 'left';
moved = true;
} else if (keys.ArrowRight) {
hero.tileX++;
newDirection = 'right';
moved = true;
}
// Update hero state
if (moved) {
hero.direction = newDirection;
hero.isMoving = true;
updateHeroPosition(); // Convert tile pos to pixels
} else {
hero.isMoving = false;
}
// Update visual direction (we'll enhance this!)
updateHeroAppearance();
}
// Convert tile coordinates to pixel coordinates
function updateHeroPosition() {
hero.x = (hero.tileX * TILE_SIZE) + (TILE_SIZE / 2);
hero.y = (hero.tileY * TILE_SIZE) + (TILE_SIZE / 2);
// Update sprite position
hero.sprite.x = hero.x;
hero.sprite.y = hero.y;
}
// Update hero appearance based on direction
function updateHeroAppearance() {
// Simple visual feedback (you can make this more sophisticated!)
if (hero.isMoving) {
hero.sprite.tint = 0xffff00; // Yellow when moving
} else {
hero.sprite.tint = 0xffffff; // White when still
}
}
Connect to the Game Loop:
// In PixiJS, add this to your ticker for 60fps updates
app.ticker.add(updateMovement);
What makes this awesome:
- 🎯 Clear logic: Easy to understand what each part does
- 🔄 Reusable: Same pattern works for any moving object
- 📈 Scalable: Easy to add features like acceleration, animation
- 🛡️ Reliable: Consistent 60fps updates with PixiJS ticker
ADDING VISUAL DIRECTION 🎨
Make Your Hero Face the Right Way:
function updateHeroAppearance() {
const sprite = hero.sprite;
// Reset transformations
sprite.scale.x = 1;
sprite.rotation = 0;
// Update visual based on direction
switch (hero.direction) {
case 'left':
sprite.scale.x = -1; // Flip horizontally
break;
case 'right':
// Default orientation (no change needed)
break;
case 'up':
sprite.rotation = -Math.PI / 2; // Rotate 90° counter-clockwise
break;
case 'down':
sprite.rotation = Math.PI / 2; // Rotate 90° clockwise
break;
}
// Movement feedback
sprite.tint = hero.isMoving ? 0xffff00 : 0xffffff;
// Optional: Add subtle scale animation when moving
if (hero.isMoving) {
const pulse = Math.sin(Date.now() * 0.01) * 0.05 + 1;
sprite.scale.y = pulse;
}
}
ADVANCED: SMOOTH MOVEMENT 🚀
Want buttery-smooth movement instead of tile-by-tile jumping?
function updateSmoothMovement() {
let targetX = (hero.tileX * TILE_SIZE) + (TILE_SIZE / 2);
let targetY = (hero.tileY * TILE_SIZE) + (TILE_SIZE / 2);
// Smooth interpolation
const lerpSpeed = 0.2;
hero.x += (targetX - hero.x) * lerpSpeed;
hero.y += (targetY - hero.y) * lerpSpeed;
hero.sprite.x = hero.x;
hero.sprite.y = hero.y;
}
🏆 MOVEMENT MASTERY ACHIEVED!
You’ve just built a complete movement system that rivals professional games! Your hero responds instantly to input, faces the right direction, and moves smoothly through your world.
What you’ve conquered:
- ✅ Modern keyboard input handling
- ✅ Clean movement logic
- ✅ Visual direction feedback
- ✅ Smooth animation techniques
- ✅ The foundation for ALL game interactions!
Ready for the next challenge? Let’s add collision detection so your hero can’t walk through walls! Next: Hit the Wall