Skip to content

Instantly share code, notes, and snippets.

@Kethku
Last active February 22, 2019 07:37
Show Gist options
  • Save Kethku/744aa8ae60a449549066e4beabd91151 to your computer and use it in GitHub Desktop.
Save Kethku/744aa8ae60a449549066e4beabd91151 to your computer and use it in GitHub Desktop.
SCRIPT-8
// title: Destructible Terrain
const gravity = 0.05;
function initTerrain() {
let terrain = [];
for (let y = 0; y < 17; y++) {
let row = [];
for (let x = 0; x < 17; x++) {
if (y > 10 || x == 0 || x == 16) {
row.push(1);
} else {
row.push(0);
}
}
terrain.push(row);
}
return terrain;
}
function initPhysicsObject(x, y, radius, sprite) {
return {
previous: {
x,
y
},
position: {
x,
y
},
radius,
sprite,
grounded: false
}
}
initialState = {
terrain: initTerrain(),
player: initPhysicsObject(20, 20, 3.75, 16)
};
function updatePhysicsObjects(...objects) {
for (const obj of objects) {
let vx = obj.position.x - obj.previous.x;
let vy = obj.position.y - obj.previous.y;
obj.previous.x = obj.position.x;
obj.previous.y = obj.position.y;
vy += gravity;
obj.position.x += vx;
obj.position.y += vy;
obj.collisions = [];
}
}
function handleTerrainCollisions(...objects) {
for (const obj of objects) {
let totalX = 0;
let totalY = 0;
let count = 0;
for (let r = 0; r < Math.PI * 2; r += Math.PI / 10) {
let dx = Math.cos(r) * obj.radius;
let dy = Math.sin(r) * obj.radius;
if (getPixel(obj.position.x + dx, obj.position.y + dy) != 7) {
if (dy > 3) {
obj.grounded = true;
}
totalX += dx;
totalY += dy;
count++;
}
}
if (count == 0) {
obj.grounded = false;
continue;
}
let dx = totalX / count;
let dy = totalY / count;
let length = Math.sqrt(dx * dx + dy * dy);
let nx = dx / length;
let ny = dy / length;
let displacement = obj.radius - length;
obj.position.x -= nx * displacement;
obj.position.y -= ny * displacement;
}
}
const tileWidth = 8;
const tileHeight = 8;
function drawTile(tx, ty, topLeft, topRight, bottomRight, bottomLeft) {
let s = 0;
if (topLeft) s += 1;
if (topRight) s += 2;
if (bottomRight) s += 4;
if (bottomLeft) s += 8;
sprite(tx * tileWidth, ty * tileHeight, s);
}
function drawTerrain(terrain) {
for (let y = 0; y < terrain.length - 1; y++) {
for (let x = 0; x < terrain[y].length - 1; x++) {
drawTile(x, y, terrain[y][x], terrain[y][x + 1], terrain[y + 1][x + 1], terrain[y + 1][x]);
}
}
}
function drawPlayer({ player }) {
sprite(player.position.x - player.radius, player.position.y - player.radius, 16);
}
function cutTerrain(x, y, radius, terrain) {
let tx = Math.round(x / tileWidth);
let ty = Math.round(y / tileHeight);
let tr = Math.floor(radius / tileWidth);
for (let cx = tx - tr; cx <= tx + tr; cx++) {
for (let cy = ty - tr; cy <= ty + tr; cy++) {
if (cy >= 0 && cy < terrain.length) {
let row = terrain[cy];
if (cx >= 0 && cx < row.length) {
row[cx] = false;
}
}
}
}
}
const runSpeed = 0.05;
const airSpeed = 0.01;
function handleInput(input, player, terrain) {
let speed = player.grounded ? runSpeed : airSpeed;
if (input.left) {
player.position.x -= speed;
}
if (input.right) {
player.position.x += speed;
}
if (input.up && player.grounded) {
player.previous.y += 1;
}
if (input.a) {
cutTerrain(player.position.x, player.position.y, 10, terrain);
}
}
update = (state, input) => {
updatePhysicsObjects(state.player);
handleInput(input, state.player, state.terrain);
}
draw = state => {
clear();
drawTerrain(state.terrain);
for (let i = 0; i < 5; i++) {
handleTerrainCollisions(state.player);
}
drawPlayer(state);
print(10, 0, "left/right to move");
print(10, 8, "up to jump");
print(10, 16, "a to cut terrain");
}
{
"lines": [
40,
50,
23,
0,
0,
16,
20,
17
]
}
{
"1": [
"1111 ",
"1112 ",
"112 ",
"12 ",
"2 ",
" ",
" ",
" "
],
"2": [
" 1111",
" 2111",
" 211",
" 21",
" 2",
" ",
" ",
" "
],
"3": [
"11111111",
"11111111",
"11111111",
"11111111",
"22222222",
" ",
" ",
" "
],
"4": [
" ",
" ",
" ",
" 0",
" 01",
" 011",
" 0111",
" 1111"
],
"5": [
"1111 ",
"11110 ",
"111110 ",
"11111100",
"22111111",
" 211111",
" 21111",
" 1111"
],
"6": [
" 1111",
" 1111",
" 1111",
" 1111",
" 1111",
" 1111",
" 1111",
" 1111"
],
"7": [
"11111111",
"11111111",
"11111111",
"11111111",
"21111111",
" 1111111",
" 2111111",
" 221111"
],
"8": [
" ",
" ",
" ",
"0 ",
"10 ",
"110 ",
"1110 ",
"1111 "
],
"9": [
"1111 ",
"1111 ",
"1111 ",
"1111 ",
"1111 ",
"1111 ",
"1111 ",
"1111 "
],
"10": [
" 1111",
" 01111",
" 011111",
"00111111",
"11111122",
"111112 ",
"11112 ",
"1111 "
],
"11": [
"11111111",
"11111111",
"11111111",
"11111111",
"11111112",
"1111111 ",
"1111112 ",
"111122 "
],
"12": [
" ",
" ",
" ",
"00000000",
"11111111",
"11111111",
"11111111",
"11111111"
],
"13": [
"111100 ",
"1111110 ",
"1111111 ",
"11111110",
"11111111",
"11111111",
"11111111",
"11111111"
],
"14": [
" 001111",
" 0111111",
" 1111111",
"01111111",
"11111111",
"11111111",
"11111111",
"11111111"
],
"15": [
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111",
"11111111"
],
"16": [
" 3333 ",
" 333333 ",
"33333333",
"33333333",
"33333333",
"33333333",
" 333333 ",
" 3333 "
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment