TCJSGame Component Class: Complete Reference Guide
Introduction to the Component Class
The Component Class is the fundamental building block of TCJSGame, representing all game objects, characters, items, and UI elements. Every visible entity in your game is a Component instance.
🏗️ Component Creation and Initialization
Basic Component Creation
// Syntax: new Component(width, height, color, x, y, type)
// Rectangle component
const player = new Component(50, 50, "red", 100, 100, "rect");
// Image component
const enemy = new Component(64, 64, "images/enemy.png", 200, 150, "image");
// Text component
const scoreText = new Component("20px", "impact", "white", 10, 30, "text");
scoreText.text = "Score: 0";
// Circle (using rect type with equal dimensions)
const ball = new Component(40, 40, "blue", 300, 200, "rect");
Constructor Parameters
class Component {
constructor(
width = 0, // Width of the component
height = 0, // Height of the component
color = null, // Color or image path
x = 0, // X position
y = 0, // Y position
type // "rect", "image", or "text"
) {
// Initialization code...
}
}
⚙️ Core Properties
Position and Size Properties
const box = new Component(100, 50, "green", 200, 150, "rect");
// Position properties
box.x = 250; // Set X coordinate
box.y = 300; // Set Y coordinate
console.log(box.x); // Get X coordinate
// Size properties
box.width = 120; // Set width
box.height = 60; // Set height
console.log(box.width); // Get width
// Center point calculation
const centerX = box.x + box.width / 2;
const centerY = box.y + box.height / 2;
Physics and Movement Properties
const player = new Component(30, 30, "blue", 100, 100, "rect");
// Enable physics
player.physics = true;
// Gravity settings
player.gravity = 0.5; // Gravity strength
player.gravitySpeed = 0; // Current gravity velocity
// Movement speeds
player.speedX = 2; // Horizontal speed
player.speedY = -3; // Vertical speed
// Bounce factor (0-1)
player.bounce = 0.6; // Bounce elasticity
Visual Properties
const obj = new Component(40, 40, "red", 100, 100, "rect");
// Color and appearance
obj.color = "yellow"; // Change color
obj.color = "#FF0000"; // Hex color
obj.color = "rgba(255,0,0,0.5)"; // With transparency
// Rotation
obj.angle = 45 * Math.PI / 180; // Rotate 45 degrees (radians)
obj.changeAngle = true; // Enable rotation rendering
// For image components
if (obj.type === "image") {
console.log(obj.image.src); // Access image source
}
🎯 Core Methods
Movement Methods
const player = new Component(30, 30, "blue", 100, 100, "rect");
// Basic movement (automatically called each frame)
player.move();
// Angular movement (for rotated movement)
player.moveAngle();
// Stop all movement
player.stopMove();
// Boundary collision
player.hitBottom(); // Handle hitting bottom of canvas
Rendering Methods
const obj = new Component(50, 50, "red", 100, 100, "rect");
// Standard update (called automatically)
obj.update();
// Backup update method (for show/hide functionality)
obj.bUpdate();
// Visibility control
obj.hide(); // Make invisible
obj.show(); // Make visible again
Interaction Methods
const button = new Component(200, 50, "green", 300, 400, "rect");
// Check if component was clicked/tapped
if (button.clicked()) {
console.log("Button was clicked!");
}
// Collision detection with another component
const player = new Component(30, 30, "blue", 100, 100, "rect");
const enemy = new Component(40, 40, "red", 120, 120, "rect");
if (player.crashWith(enemy)) {
console.log("Player collided with enemy!");
}
🎮 Practical Usage Examples
Player Character with Physics
// Create player with physics
const player = new Component(30, 30, "blue", 100, 100, "rect");
player.physics = true;
player.gravity = 0.5;
player.bounce = 0.3;
// Add to display
display.add(player);
// In update function
function update() {
// Keyboard controls
if (display.keys[37]) player.speedX = -5; // Left
if (display.keys[39]) player.speedX = 5; // Right
if (display.keys[38] && player.gravitySpeed === 0) {
player.speedY = -12; // Jump
}
// Boundary checking
if (player.y > display.canvas.height - player.height) {
player.hitBottom();
}
}
Interactive UI Button
// Create a button
const startButton = new Component(200, 60, "green", 300, 250, "rect");
startButton.text = "START GAME";
display.add(startButton);
// Click handling
function update() {
if (startButton.clicked()) {
console.log("Game started!");
startButton.color = "darkgreen"; // Visual feedback
}
}
Projectile System
const bullets = [];
function shootBullet(x, y, angle) {
const bullet = new Component(10, 10, "yellow", x, y, "rect");
bullet.physics = true;
bullet.speedX = Math.cos(angle) * 10;
bullet.speedY = Math.sin(angle) * 10;
display.add(bullet);
bullets.push(bullet);
}
// Clean up off-screen bullets
function update() {
bullets.forEach((bullet, index) => {
if (bullet.x < 0 || bullet.x > display.canvas.width ||
bullet.y < 0 || bullet.y > display.canvas.height) {
bullet.hide();
bullets.splice(index, 1);
}
});
}
🔄 Advanced Movement Patterns
Following Mouse/Touch
const follower = new Component(30, 30, "purple", 200, 200, "rect");
function update() {
// Smooth follow mouse
follower.x += (mouse.x - follower.x) * 0.1;
follower.y += (mouse.y - follower.y) * 0.1;
}
Orbital Movement
const planet = new Component(20, 20, "orange", 400, 300, "rect");
const centerX = 400, centerY = 300;
let angle = 0;
function update() {
angle += 0.02;
planet.x = centerX + Math.cos(angle) * 100;
planet.y = centerY + Math.sin(angle) * 100;
}
Sine Wave Movement
const waveObj = new Component(20, 20, "cyan", 100, 300, "rect");
let time = 0;
function update() {
time += 0.1;
waveObj.x += 2;
waveObj.y = 300 + Math.sin(time) * 50;
// Reset when off screen
if (waveObj.x > display.canvas.width) {
waveObj.x = -20;
}
}
🎨 Visual Effects and Animation
Pulsating Effect
const pulsator = new Component(50, 50, "red", 200, 200, "rect");
let scale = 1;
let growing = true;
function update() {
if (growing) {
scale += 0.02;
if (scale > 1.5) growing = false;
} else {
scale -= 0.02;
if (scale < 0.5) growing = true;
}
pulsator.width = 50 * scale;
pulsator.height = 50 * scale;
}
Color Cycling
const colorChanger = new Component(50, 50, "red", 300, 200, "rect");
let hue = 0;
function update() {
hue = (hue + 1) % 360;
colorChanger.color = `hsl(${hue}, 100%, 50%)`;
}
Rotation Animation
const spinner = new Component(40, 40, "green", 400, 200, "rect");
spinner.changeAngle = true;
function update() {
spinner.angle += 0.05; // Rotate continuously
}
⚡ Performance Optimization
Object Pooling for Frequent Creation/Destruction
class ObjectPool {
constructor(createFunc) {
this.pool = [];
this.create = createFunc;
}
get() {
if (this.pool.length > 0) {
return this.pool.pop();
}
return this.create();
}
release(obj) {
obj.hide();
this.pool.push(obj);
}
}
// Usage for bullets
const bulletPool = new ObjectPool(() => {
return new Component(10, 10, "yellow", 0, 0, "rect");
});
function shootBullet(x, y) {
const bullet = bulletPool.get();
bullet.show();
bullet.x = x;
bullet.y = y;
bullet.speedX = 5;
// ... other setup
}
Efficient Collision Detection
// Spatial partitioning for better performance
const grid = {};
function updateObjectGrid(obj) {
const gridX = Math.floor(obj.x / 100);
const gridY = Math.floor(obj.y / 100);
const key = `${gridX},${gridY}`;
if (!grid[key]) grid[key] = [];
grid[key].push(obj);
}
function checkLocalCollisions(obj) {
const gridX = Math.floor(obj.x / 100);
const gridY = Math.floor(obj.y / 100);
// Only check collisions with objects in nearby cells
for (let x = gridX - 1; x <= gridX + 1; x++) {
for (let y = gridY - 1; y <= gridY + 1; y++) {
const key = `${x},${y}`;
if (grid[key]) {
grid[key].forEach(other => {
if (obj !== other && obj.crashWith(other)) {
// Handle collision
}
});
}
}
}
}
🔧 Common Patterns and Recipes
Health Bar System
class HealthBar {
constructor(x, y, width, height, maxHealth) {
this.background = new Component(width, height, "red", x, y, "rect");
this.foreground = new Component(width, height, "green", x, y, "rect");
this.maxHealth = maxHealth;
this.currentHealth = maxHealth;
}
setHealth(health) {
this.currentHealth = Math.max(0, Math.min(health, this.maxHealth));
const ratio = this.currentHealth / this.maxHealth;
this.foreground.width = this.background.width * ratio;
}
addToDisplay() {
display.add(this.background);
display.add(this.foreground);
}
}
// Usage
const healthBar = new HealthBar(50, 20, 200, 20, 100);
healthBar.addToDisplay();
healthBar.setHealth(75); // Set to 75% health
Timer Component
class GameTimer {
constructor(x, y) {
this.time = 0;
this.displayText = new Component(20, 20, "white", x, y, "text");
this.running = true;
}
update() {
if (this.running) {
this.time += 1/50; // Assuming 50 FPS
this.displayText.text = `Time: ${this.time.toFixed(1)}s`;
}
}
stop() {
this.running = false;
}
reset() {
this.time = 0;
this.running = true;
}
}
🐛 Troubleshooting Common Issues
Component Not Visible
// Check if component was added to display
const obj = new Component(50, 50, "red", 100, 100, "rect");
display.add(obj); // Don't forget this!
// Check if component is hidden
obj.show(); // Ensure it's visible
// Check if in correct scene
display.scene = 0; // Make sure scene matches
Physics Not Working
const obj = new Component(50, 50, "blue", 100, 100, "rect");
// Enable physics
obj.physics = true; // Required for gravity/movement
// Set gravity
obj.gravity = 0.5; // Add downward force
// Ensure move() is called (handled automatically by Display)
Collision Detection Issues
// Ensure both objects have proper dimensions
obj1.width = 50; obj1.height = 50;
obj2.width = 50; obj2.height = 50;
// Check positions are overlapping
console.log("Obj1:", obj1.x, obj1.y);
console.log("Obj2:", obj2.x, obj2.y);
// Use crashWith method correctly
if (obj1.crashWith(obj2)) {
// Handle collision
}
📚 Conclusion
The Component Class is the workhorse of TCJSGame, providing:
- Visual representation through rectangles, images, and text
- Physics and movement capabilities
- Collision detection between game objects
- Interaction handling for mouse/touch input
- Flexible rendering with rotation and styling options
Mastering Components is essential for creating engaging TCJSGame experiences. They serve as the foundation for everything from simple UI elements to complex game characters and interactive objects.
Remember to always add your Components to the Display using display.add(component)
and leverage the built-in physics and collision systems for realistic game behavior.
Top comments (0)