Game Making Between the PEKs and the PIMPs

View this thread on: d.buzz | hive.blog | peakd.com | ecency.com
·@paulmoon410·
0.000 HBD
Game Making Between the PEKs and the PIMPs
<center>![](https://images.ecency.com/DQmPnV3cFGuwzR5pDKUBsANco9XJuNmCm2vG3aP5dFZfjcs/image.png)</center>

If anyone is interested in helping me with coding some of the game, please reach out. It's something I've been working on in between @enginewitty and the PIMP backend work, and my own PeakeCoin Projects. This is the code as far as I have come. It can be a lot of work, but it does come with its perks.

I'll work on getting this uploaded so it's playable as I work on it.

```javascript

//game.js



// Babylon.js 2D top-down setup
const canvas = document.getElementById("gameCanvas");
const engine = new BABYLON.Engine(canvas, true);
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3(0.95, 0.95, 0.95);

// Camera for side-view 2.5D (like Mario)
const camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 50, 150), scene);
camera.setTarget(new BABYLON.Vector3(0, 50, 0));
camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;
camera.orthoLeft = -canvas.width / 2;
camera.orthoRight = canvas.width / 2;
camera.orthoTop = canvas.height / 2;
camera.orthoBottom = -canvas.height / 2;

// Add lighting (essential for Babylon.js materials)
const light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 1.0;

// Simple tile map (10x10 for demo)
const TILE_SIZE = 48;
const MAP_W = 10;
const MAP_H = 10;
const map = [
  [0,0,0,0,0,0,0,0,0,0],
  [0,1,1,0,0,0,1,1,1,0],
  [0,0,0,0,1,0,0,0,1,0],
  [0,1,0,0,1,0,1,0,0,0],
  [0,1,0,0,0,0,1,0,1,0],
  [0,0,0,1,1,0,0,0,1,0],
  [0,1,0,0,0,0,1,0,0,0],
  [0,1,1,1,0,1,1,0,1,0],
  [0,0,0,0,0,0,0,0,1,0],
  [0,0,1,1,1,0,0,0,0,0],
];

// Create side-view ground platforms (like Mario levels)
for (let x = 0; x < MAP_W * 2; x++) {
  // Ground platform
  const ground = BABYLON.MeshBuilder.CreateBox(`ground_${x}`, {width: TILE_SIZE, height: TILE_SIZE/2, depth: TILE_SIZE}, scene);
  ground.position.x = (x - MAP_W) * TILE_SIZE;
  ground.position.y = 0; // Ground level
  ground.position.z = 0;
  const groundMat = new BABYLON.StandardMaterial(`groundMat_${x}`, scene);
  groundMat.diffuseColor = new BABYLON.Color3(0.4, 0.3, 0.2); // Brown ground
  ground.material = groundMat;
  
  // Occasional platforms at different heights
  if (x % 4 === 0 && x > 2) {
    const platform = BABYLON.MeshBuilder.CreateBox(`platform_${x}`, {width: TILE_SIZE * 2, height: TILE_SIZE/3, depth: TILE_SIZE}, scene);
    platform.position.x = (x - MAP_W) * TILE_SIZE;
    platform.position.y = 60 + Math.sin(x * 0.5) * 30; // Varying platform heights
    platform.position.z = 0;
    const platMat = new BABYLON.StandardMaterial(`platMat_${x}`, scene);
    platMat.diffuseColor = new BABYLON.Color3(0.2, 0.6, 0.2); // Green platforms
    platform.material = platMat;
  }
}

// Player as a colored circle

// Player as a simple human figure (top-down)


const playerGroup = new BABYLON.TransformNode("playerGroup", scene);

// Create super smooth character with joint hierarchy
const charSize = 20;

// Create materials with bright outline effect
const createOutlineMaterial = (color, outlineColor = new BABYLON.Color3(0, 1, 1)) => {
  const mat = new BABYLON.StandardMaterial("material", scene);
  mat.diffuseColor = color;
  mat.emissiveColor = color.scale(0.1); // Slight glow
  
  // Create outline effect using edge rendering
  mat.backFaceCulling = false;
  return mat;
};

// Head with smooth sphere
const head = BABYLON.MeshBuilder.CreateSphere("head", {diameter: charSize, segments: 32}, scene);
const headMat = createOutlineMaterial(new BABYLON.Color3(1, 0.85, 0.7));
head.material = headMat;
head.position.y = 55;
head.position.z = 0;
head.parent = playerGroup;

// Neck connector (smooth joint)
const neck = BABYLON.MeshBuilder.CreateCylinder("neck", {height: 8, diameter: 6, tessellation: 16}, scene);
neck.material = headMat;
neck.position.y = 46;
neck.parent = playerGroup;

// Torso (smooth rounded rectangle)
const torso = BABYLON.MeshBuilder.CreateCylinder("torso", {height: charSize * 1.4, diameter: charSize * 0.9, tessellation: 8}, scene);
const torsoMat = createOutlineMaterial(new BABYLON.Color3(0.9, 0.3, 0.3));
torso.material = torsoMat;
torso.position.y = 35;
torso.parent = playerGroup;

// Shoulder joints (smooth connection points)
const leftShoulder = BABYLON.MeshBuilder.CreateSphere("leftShoulder", {diameter: 6, segments: 16}, scene);
leftShoulder.material = headMat;
leftShoulder.position.x = -charSize * 0.4;
leftShoulder.position.y = 42;
leftShoulder.parent = playerGroup;

const rightShoulder = BABYLON.MeshBuilder.CreateSphere("rightShoulder", {diameter: 6, segments: 16}, scene);
rightShoulder.material = headMat;
rightShoulder.position.x = charSize * 0.4;
rightShoulder.position.y = 42;
rightShoulder.parent = playerGroup;

// Upper arms (smooth cylinders)
const leftUpperArm = BABYLON.MeshBuilder.CreateCylinder("leftUpperArm", {height: charSize * 0.7, diameter: 5, tessellation: 12}, scene);
const armMat = createOutlineMaterial(new BABYLON.Color3(1, 0.8, 0.6));
leftUpperArm.material = armMat;
leftUpperArm.position.x = -charSize * 0.4;
leftUpperArm.position.y = 35;
leftUpperArm.parent = playerGroup;

const rightUpperArm = BABYLON.MeshBuilder.CreateCylinder("rightUpperArm", {height: charSize * 0.7, diameter: 5, tessellation: 12}, scene);
rightUpperArm.material = armMat;
rightUpperArm.position.x = charSize * 0.4;
rightUpperArm.position.y = 35;
rightUpperArm.parent = playerGroup;

// Elbow joints
const leftElbow = BABYLON.MeshBuilder.CreateSphere("leftElbow", {diameter: 4, segments: 12}, scene);
leftElbow.material = armMat;
leftElbow.position.x = -charSize * 0.4;
leftElbow.position.y = 28;
leftElbow.parent = playerGroup;

const rightElbow = BABYLON.MeshBuilder.CreateSphere("rightElbow", {diameter: 4, segments: 12}, scene);
rightElbow.material = armMat;
rightElbow.position.x = charSize * 0.4;
rightElbow.position.y = 28;
rightElbow.parent = playerGroup;

// Forearms
const leftForearm = BABYLON.MeshBuilder.CreateCylinder("leftForearm", {height: charSize * 0.6, diameter: 4, tessellation: 12}, scene);
leftForearm.material = armMat;
leftForearm.position.x = -charSize * 0.4;
leftForearm.position.y = 22;
leftForearm.parent = playerGroup;

const rightForearm = BABYLON.MeshBuilder.CreateCylinder("rightForearm", {height: charSize * 0.6, diameter: 4, tessellation: 12}, scene);
rightForearm.material = armMat;
rightForearm.position.x = charSize * 0.4;
rightForearm.position.y = 22;
rightForearm.parent = playerGroup;

// Hip joints
const leftHip = BABYLON.MeshBuilder.CreateSphere("leftHip", {diameter: 6, segments: 16}, scene);
const legMat = createOutlineMaterial(new BABYLON.Color3(0.2, 0.2, 0.9));
leftHip.material = legMat;
leftHip.position.x = -charSize * 0.2;
leftHip.position.y = 25;
leftHip.parent = playerGroup;

const rightHip = BABYLON.MeshBuilder.CreateSphere("rightHip", {diameter: 6, segments: 16}, scene);
rightHip.material = legMat;
rightHip.position.x = charSize * 0.2;
rightHip.position.y = 25;
rightHip.parent = playerGroup;

// Thighs
const leftThigh = BABYLON.MeshBuilder.CreateCylinder("leftThigh", {height: charSize * 0.8, diameter: 6, tessellation: 12}, scene);
leftThigh.material = legMat;
leftThigh.position.x = -charSize * 0.2;
leftThigh.position.y = 18;
leftThigh.parent = playerGroup;

const rightThigh = BABYLON.MeshBuilder.CreateCylinder("rightThigh", {height: charSize * 0.8, diameter: 6, tessellation: 12}, scene);
rightThigh.material = legMat;
rightThigh.position.x = charSize * 0.2;
rightThigh.position.y = 18;
rightThigh.parent = playerGroup;

// Knee joints
const leftKnee = BABYLON.MeshBuilder.CreateSphere("leftKnee", {diameter: 5, segments: 12}, scene);
leftKnee.material = legMat;
leftKnee.position.x = -charSize * 0.2;
leftKnee.position.y = 12;
leftKnee.parent = playerGroup;

const rightKnee = BABYLON.MeshBuilder.CreateSphere("rightKnee", {diameter: 5, segments: 12}, scene);
rightKnee.material = legMat;
rightKnee.position.x = charSize * 0.2;
rightKnee.position.y = 12;
rightKnee.parent = playerGroup;

// Calves
const leftCalf = BABYLON.MeshBuilder.CreateCylinder("leftCalf", {height: charSize * 0.7, diameter: 5, tessellation: 12}, scene);
leftCalf.material = legMat;
leftCalf.position.x = -charSize * 0.2;
leftCalf.position.y = 7;
leftCalf.parent = playerGroup;

const rightCalf = BABYLON.MeshBuilder.CreateCylinder("rightCalf", {height: charSize * 0.7, diameter: 5, tessellation: 12}, scene);
rightCalf.material = legMat;
rightCalf.position.x = charSize * 0.2;
rightCalf.position.y = 7;
rightCalf.parent = playerGroup;

// Feet for complete walking cycle
const leftFoot = BABYLON.MeshBuilder.CreateBox("leftFoot", {width: 8, height: 3, depth: 12}, scene);
const footMat = createOutlineMaterial(new BABYLON.Color3(0.3, 0.2, 0.1));
leftFoot.material = footMat;
leftFoot.position.x = -charSize * 0.2;
leftFoot.position.y = 2;
leftFoot.parent = playerGroup;

const rightFoot = BABYLON.MeshBuilder.CreateBox("rightFoot", {width: 8, height: 3, depth: 12}, scene);
rightFoot.material = footMat;
rightFoot.position.x = charSize * 0.2;
rightFoot.position.y = 2;
rightFoot.parent = playerGroup;

// Add bright outline effect to entire character
playerGroup.getChildMeshes().forEach(mesh => {
  if (mesh.material) {
    mesh.renderOutline = true;
    mesh.outlineWidth = 0.5;
    mesh.outlineColor = new BABYLON.Color3(0, 1, 1); // Bright cyan outline
  }
});

// Store body parts for smooth animation
const bodyParts = {
  head, neck, torso,
  leftShoulder, rightShoulder,
  leftUpperArm, rightUpperArm,
  leftElbow, rightElbow,
  leftForearm, rightForearm,
  leftHip, rightHip,
  leftThigh, rightThigh,
  leftKnee, rightKnee,
  leftCalf, rightCalf,
  leftFoot, rightFoot
};

// Initial position (standing on ground)
playerGroup.position.x = 0;
playerGroup.position.y = 25; // Standing on ground level
playerGroup.position.z = 0;

// Add a simple test box to verify rendering
const testBox = BABYLON.MeshBuilder.CreateBox("testBox", {size: 20}, scene);
const testMat = new BABYLON.StandardMaterial("testMat", scene);
testMat.diffuseColor = new BABYLON.Color3(1, 0, 0); // bright red
testBox.material = testMat;
testBox.position.x = 100;
testBox.position.y = 100;
testBox.position.z = 2;

console.log("Player created at position:", playerGroup.position);
console.log("Camera position:", camera.position);
console.log("Camera ortho bounds:", camera.orthoLeft, camera.orthoRight, camera.orthoTop, camera.orthoBottom);
console.log("Test box created at:", testBox.position);

// Player movement with Mario-style physics
let playerX = 0;
let playerVelocityY = 0; // For jumping/gravity
let isMoving = false;
let walkCycle = 0;
const speed = 3;
const keys = {};

// Super smooth joint animation with fluid movement
function animateWalk() {
  if (!isMoving) {
    // Smoothly return to neutral pose with interpolation
    bodyParts.leftUpperArm.rotation.z = BABYLON.Scalar.Lerp(bodyParts.leftUpperArm.rotation.z, 0, 0.15);
    bodyParts.rightUpperArm.rotation.z = BABYLON.Scalar.Lerp(bodyParts.rightUpperArm.rotation.z, 0, 0.15);
    bodyParts.leftForearm.rotation.z = BABYLON.Scalar.Lerp(bodyParts.leftForearm.rotation.z, 0, 0.15);
    bodyParts.rightForearm.rotation.z = BABYLON.Scalar.Lerp(bodyParts.rightForearm.rotation.z, 0, 0.15);
    bodyParts.leftThigh.rotation.z = BABYLON.Scalar.Lerp(bodyParts.leftThigh.rotation.z, 0, 0.15);
    bodyParts.rightThigh.rotation.z = BABYLON.Scalar.Lerp(bodyParts.rightThigh.rotation.z, 0, 0.15);
    bodyParts.leftCalf.rotation.z = BABYLON.Scalar.Lerp(bodyParts.leftCalf.rotation.z, 0, 0.15);
    bodyParts.rightCalf.rotation.z = BABYLON.Scalar.Lerp(bodyParts.rightCalf.rotation.z, 0, 0.15);
    bodyParts.torso.position.y = BABYLON.Scalar.Lerp(bodyParts.torso.position.y, 35, 0.15);
    bodyParts.head.position.y = BABYLON.Scalar.Lerp(bodyParts.head.position.y, 55, 0.15);
    return;
  }
  
  walkCycle += 0.2; // Smooth cycle speed
  
  // Calculate fluid movement phases
  const armPhase = Math.sin(walkCycle) * 0.5;
  const legPhase = Math.sin(walkCycle) * 0.7;
  const kneePhase = Math.sin(walkCycle + Math.PI/3) * 0.4;
  const elbowPhase = Math.sin(walkCycle + Math.PI/4) * 0.3;
  const bounce = Math.abs(Math.sin(walkCycle * 2)) * 2;
  const sway = Math.sin(walkCycle * 0.5) * 0.05;
  
  // Super smooth arm movement with natural joint articulation
  bodyParts.leftUpperArm.rotation.z = armPhase;
  bodyParts.rightUpperArm.rotation.z = -armPhase;
  
  // Forearms follow with natural elbow bend
  bodyParts.leftForearm.rotation.z = armPhase * 0.6 + elbowPhase;
  bodyParts.rightForearm.rotation.z = -armPhase * 0.6 - elbowPhase;
  
  // Biomechanically correct leg movement
  bodyParts.leftThigh.rotation.z = legPhase;
  bodyParts.rightThigh.rotation.z = -legPhase;
  
  // Correct knee bending: knees bend when leg swings forward (lifting), straighten when pushing back
  const leftKneeBend = legPhase > 0 ? Math.abs(legPhase) * 0.8 : 0; // Bend when swinging forward
  const rightKneeBend = -legPhase > 0 ? Math.abs(-legPhase) * 0.8 : 0; // Bend when swinging forward
  
  bodyParts.leftCalf.rotation.z = -leftKneeBend; // Negative rotation bends knee forward
  bodyParts.rightCalf.rotation.z = -rightKneeBend;
  
  // Smooth body movement
  bodyParts.torso.position.y = 35 + bounce;
  bodyParts.head.position.y = 55 + bounce;
  bodyParts.neck.position.y = 46 + bounce;
  
  // Natural body sway and rotation
  bodyParts.torso.rotation.z = sway;
  bodyParts.head.rotation.z = sway * 0.5;
  
  // Shoulder movement follows arm swing
  bodyParts.leftShoulder.position.y = 42 + bounce + Math.sin(walkCycle + armPhase) * 0.5;
  bodyParts.rightShoulder.position.y = 42 + bounce + Math.sin(walkCycle - armPhase) * 0.5;
  
  // Hip movement follows leg swing
  bodyParts.leftHip.rotation.z = legPhase * 0.3;
  bodyParts.rightHip.rotation.z = -legPhase * 0.3;
  
  // Joint connections move smoothly
  bodyParts.leftElbow.position.y = 28 + bounce + Math.sin(walkCycle + elbowPhase) * 0.3;
  bodyParts.rightElbow.position.y = 28 + bounce + Math.sin(walkCycle - elbowPhase) * 0.3;
  
  // Knee position follows thigh movement but also lifts during bending
  const leftKneeHeight = 12 + bounce * 0.5 + (leftKneeBend * 2); // Knee lifts when bending
  const rightKneeHeight = 12 + bounce * 0.5 + (rightKneeBend * 2);
  
  bodyParts.leftKnee.position.y = leftKneeHeight;
  bodyParts.rightKnee.position.y = rightKneeHeight;
  
  // Calf position should follow knee movement
  bodyParts.leftCalf.position.y = 7 + bounce * 0.3 + (leftKneeBend * 1.5);
  bodyParts.rightCalf.position.y = 7 + bounce * 0.3 + (rightKneeBend * 1.5);
  
  // Feet follow the walking cycle - lift when leg swings forward, plant when stepping
  const leftFootLift = leftKneeBend * 3; // Foot lifts more dramatically
  const rightFootLift = rightKneeBend * 3;
  
  bodyParts.leftFoot.position.y = 2 + leftFootLift;
  bodyParts.rightFoot.position.y = 2 + rightFootLift;
  
  // Foot angle changes during walk cycle
  bodyParts.leftFoot.rotation.z = leftKneeBend * 0.3; // Foot tilts up when lifting
  bodyParts.rightFoot.rotation.z = rightKneeBend * 0.3;
}

// Handle keyboard input
window.addEventListener("keydown", (e) => {
  keys[e.key.toLowerCase()] = true;
});

window.addEventListener("keyup", (e) => {
  keys[e.key.toLowerCase()] = false;
});

// Side-scrolling movement (Mario-style)
function updateMovement() {
  let moving = false;
  let deltaX = 0;
  
  // Horizontal movement only (side-scrolling)
  if (keys['d'] || keys['arrowright']) {
    deltaX += speed;
    moving = true;
    // Face right
    playerGroup.rotation.y = 0;
  }
  if (keys['a'] || keys['arrowleft']) {
    deltaX -= speed;
    moving = true;
    // Face left
    playerGroup.rotation.y = Math.PI;
  }
  
  // Jump (Mario-style)
  if (keys['w'] || keys['arrowup'] || keys[' ']) {
    if (Math.abs(playerGroup.position.y - 25) < 5) { // Only jump if on ground
      playerVelocityY = 8; // Jump force
    }
  }
  
  // Apply horizontal movement
  playerX += deltaX;
  playerGroup.position.x = playerX;
  
  // Apply gravity and vertical movement
  playerVelocityY -= 0.3; // Gravity
  playerGroup.position.y += playerVelocityY;
  
  // Ground collision
  if (playerGroup.position.y <= 25) {
    playerGroup.position.y = 25;
    playerVelocityY = 0;
  }
  
  // Update animation state
  isMoving = moving;
  animateWalk();
}

engine.runRenderLoop(() => {
  updateMovement();
  scene.render();
});
👍 , , , , , , , , , , , , , , , , , , , ,