Version 1.10
This commit is contained in:
parent
ef47c37d0f
commit
701ba42bd3
154
changelog.txt
154
changelog.txt
|
|
@ -1,12 +1,164 @@
|
|||
[Future Plans]
|
||||
+ Save Gallery
|
||||
+ Human Update
|
||||
+ Suggest new additions at https://link.R74n.com/sandboxels-feedback
|
||||
|
||||
See sneak peaks for upcoming updates on the Discord: https://discord.gg/ejUc6YPQuS
|
||||
|
||||
A fancier version of this changelog can be found here: https://sandboxels.R74n.com/changelog
|
||||
|
||||
[Version 1.10 - August 2, 2024 - Return of the Sand]
|
||||
+ Rice
|
||||
+ Galvanized Steel (Hidden)
|
||||
+ Midas Touch
|
||||
+ Limitless Mode setting to remove pixel and cursor size limits
|
||||
+ Wide canvas size setting
|
||||
+ Czech language
|
||||
+ Liquid Ozone (Hidden)
|
||||
[Rendering]
|
||||
~ Improved cursor smoothness, at up to 60 FPS
|
||||
+ Shift+C to screenshot without background
|
||||
+ Aurora Borealis and other Flash effects fade out over time
|
||||
+ Fire has a gradient effect
|
||||
+ Metals, Charcoal, and more glow when hot
|
||||
+ Wood chars as it gets hot
|
||||
+ Embers get more intense over time
|
||||
+ Fireflies, Blasters, and Fireballs glow
|
||||
+ Fancy Textures setting is now "Fancy Pixels"
|
||||
+ Fancy Pixels setting toggles per-element rendering effects
|
||||
[Sponge Rework]
|
||||
+ Sponges and Cloth keep track of moisture
|
||||
+ Moisture can be released by smashing or boiling
|
||||
+ Sponge becomes darker as it absorbs Water
|
||||
+ Dust prevents Sponge from absorbing liquids
|
||||
[Ray Changes]
|
||||
+ Rays spawn particles when hitting border
|
||||
+ Rays delete from top to bottom
|
||||
~ Freeze Ray has a lighter color
|
||||
[Fuse Changes]
|
||||
+ Fuse won't emit any smoke when burning
|
||||
+ Fuse can carry electricity
|
||||
+ Fuse won't conduct into E-cloners or Sensors
|
||||
+ These new mechanics can create simple toggle switches or logic gates
|
||||
+ Sensors ignore Flash
|
||||
+ Sensors are immune to Acid
|
||||
~ Moved Fuse to Machines
|
||||
~ E-cloners no longer conduct back into Wires
|
||||
[Ocean Changes]
|
||||
+ Foam generates on sandy Salt Water shores
|
||||
+ Foam generates when Salt Water wets Sand
|
||||
+ Algae and Dead Bugs can Foam up Water
|
||||
+ Nitrogen can encourage Algae growth
|
||||
+ Fish and Humans can make air Bubbles in Water
|
||||
[Other Changes]
|
||||
+ Extinguishing elements can be drawn over burning pixels
|
||||
+ Steel texture
|
||||
~ Void deletes pixels instantly regardless of hardness
|
||||
~ Pipes are indestructible
|
||||
+ Superconductivity in Aluminum, Gallium, Lead, Mercury, Tin, Tungsten, Uranium, Zinc
|
||||
+ Charcoal neutralizes Poison
|
||||
+ Silver control rod reaction produces Radiation
|
||||
+ Antimatter reacts with Proton, Neutron, and Electric
|
||||
~ Diamonds only evaporate if Oxygen or Fire is present
|
||||
~ Recolored Hydrogen flame
|
||||
+ Molten Salt can explode on contact with Water
|
||||
+ Hot Wax can explode on contact with Water
|
||||
~ Unhid Borax
|
||||
+ Ruins can be damaged by Fire, Smoke, Dirty Water, and Humans
|
||||
~ Ruins can't be dragged
|
||||
~ Dust from Ruins is more grainy
|
||||
+ Paper breaks into Confetti
|
||||
+ Paper can turn Oxygen into Fragrance
|
||||
+ Lamp Oil freezes into Wax
|
||||
+ Gunpowder recipe
|
||||
~ Dynamite is slightly stronger than TNT
|
||||
+ Bleach stains Porcelain
|
||||
+ Rad Steam, Glass, and Shards dirty Water
|
||||
~ Humans spawn with their full bodies immediately
|
||||
+ Fish die slowly in Pool Water or Vinegar
|
||||
+ Worms decompose Feathers
|
||||
+ Birds rarely drop Feathers
|
||||
+ Birds eat Stink Bugs
|
||||
+ Stink Bugs eat Beans
|
||||
~ Frogs cook into accurate color
|
||||
+ Hives will break into some Wax
|
||||
+ Bees give Humans rashes
|
||||
+ Ant Farm world gen type
|
||||
+ Grass is killed by Baking Soda
|
||||
+ Lichen are killed by Stench and Smog
|
||||
+ Poison can be filtered by Charcoal and Gravel
|
||||
+ Vinegar can cure Meat
|
||||
+ Tea can mix with Nut Milk
|
||||
+ Coffee and Tea can mix with Milk variants
|
||||
+ Nut Milk can be radiated
|
||||
+ Mayo can be made from Grease or Nut Oil
|
||||
+ Sodium, Potassium, and Calcium react with Nut Milk
|
||||
+ Iron can be rusted by Coffee, Tea, Broth, and Juice
|
||||
+ Coffee kills Snails and Slugs
|
||||
+ Soda made from Juice has unique color
|
||||
+ Udder produces more Milk when smashed
|
||||
+ Hair can get dandruff if too oily
|
||||
+ Skin will grow Hair when cold
|
||||
+ Lead can infect Blood
|
||||
+ Epsom Salt can cure Infection and kill Mushroom Spores
|
||||
+ Fallout makes Meat Rocket
|
||||
~ Seeds element changes immediately
|
||||
+ Bless can heal Glass and Clay Shards
|
||||
+ Bless and Glue can heal Ruins
|
||||
+ Bless turns Gunpowder to Charcoal
|
||||
+ Bless removes Warp
|
||||
+ Rainbow can take over Static
|
||||
+ Ink and Art can be drawn over Paper
|
||||
+ Strange Matter explodes when entering Void
|
||||
+ Malware can be made from Electric + Virus
|
||||
+ Snake kills Rats, Birds, and Eggs
|
||||
~ Earthquakes and Tsunamis have a maximum magnitude
|
||||
~ Recolored Fallout
|
||||
~ Updated Hydrogen and Helium shock colors
|
||||
~ E-wall displays with a hyphen
|
||||
~ Decreased Spray Paint density
|
||||
+ Borax alias 'Sodium Borate'
|
||||
~ Buttons are spaced more evenly, and more GUI changes
|
||||
~ Cooldowns don't apply when paused
|
||||
+ Save slot overwriting popup
|
||||
~ Save slot overwriting warning is red
|
||||
[Bug Fixes]
|
||||
~ Fixed: Shift button doesn't appear on some iPads
|
||||
~ Fixed: Gaps when using tools, like Erase or Paint
|
||||
~ Fixed: Erase tool cannot make lines with Shift
|
||||
~ Fixed: Cursor is slow when on low TPS
|
||||
~ Fixed: Jittering gas colors
|
||||
~ Fixed: Smoke from Cold Fire is hot
|
||||
~ Fixed: Replace Mode can override pixel limit
|
||||
~ Fixed: Yolk and Cream fail to make Eggnog
|
||||
~ Fixed: Some fireflies spawn with yellow color already
|
||||
~ Fixed: Using Antibomb on a Tsunami creates Unknown
|
||||
~ Fixed: Color Sand, Stained Glass, Rainbow, Static, and Border don't color when paused
|
||||
~ Fixed: Rainbow doesn't conduct heat
|
||||
~ Fixed: Some placed elements are not affected by custom air temperature
|
||||
~ Fixed: Some placed elements color wrong if changing state with custom air temperature
|
||||
~ Fixed: Custom-color elements take color from previously placed random-color element
|
||||
~ Fixed: Mobile Shift button can become desynchronized
|
||||
~ Fixed: Shocker and Tesla Coil shock themselves
|
||||
~ Fixed: Shocking Nitro causes ghost pixels
|
||||
[Technical]
|
||||
~ Rendering was overhauled, which could cause some mods to break
|
||||
+ See 1.10example.js for all new rendering/modding features
|
||||
+ Moddable views
|
||||
+ Moddable and overridable keybinds
|
||||
+ Canvas layer rendering system
|
||||
+ Functions runEveryTick, runPerPixel, renderEachPixel, renderPrePixel, renderPostPixel
|
||||
+ 'renderer' element property
|
||||
+ 'onPlace', 'onDelete', 'onChange', 'onBreak' element property
|
||||
+ 'alpha' element and pixel property, for opacity (0-1)
|
||||
+ 'glow' pixel property (true/false)
|
||||
+ 'superconductAt' element property (Celsius)
|
||||
~ Background color is no longer drawn to canvas
|
||||
~ Optimized MOLTEN behavior
|
||||
+ Unknown pixels show invalid element when hovered over
|
||||
+ Invisible ghost pixels should be automatically removed
|
||||
~ Pixels created after passing pixel limit will be removed next frame
|
||||
- Removed Wide beta keybind
|
||||
|
||||
[Version 1.9.5 - May 15, 2024 - Update of the Summer]
|
||||
+ Mixer
|
||||
+ Grinder
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@
|
|||
<body>
|
||||
<h1><a href="https://sandboxels.R74n.com" class="backbutton"><</a> Sandboxels Controls</h1>
|
||||
|
||||
</ul>
|
||||
<p>Below is a list of all controls in <a href="https://sandboxels.R74n.com/">Sandboxels</a>. <em>Community <a href="mod-list">mods</a> may change controls.</em></p>
|
||||
|
||||
<div id="controls">
|
||||
|
||||
<h2>Keyboard/Mouse Controls</h2>
|
||||
|
|
@ -81,7 +82,7 @@
|
|||
<tr><td>Draw pixels</td> <td><kbd>Left Click</kbd></td></tr>
|
||||
<tr><td>Erase pixels</td> <td><kbd>Right Click</kbd></td></tr>
|
||||
<tr><td>Pick element</td> <td><kbd>Middle Click</kbd></td></tr>
|
||||
<tr><td>Pause simulation</td> <td><kbd>Space</kbd> or <kbd>P</kbd></td></tr>
|
||||
<tr><td>Pause simulation</td> <td><kbd>Space</kbd> or <kbd>P</kbd> or <kbd>K</kbd> or <kbd>`</kbd></td></tr>
|
||||
<tr><td>Intensify effect</td> <td><kbd>Shift</kbd> + <kbd style="background-color:red;">Heat</kbd>/<kbd style="background-color:blue;">Cool</kbd>/<kbd style="background-color:#c1cfb6;color:black">Drag</kbd>/<kbd style="background-color:#fff4b5;color:black">Mix</kbd>/<kbd style="background-color:yellow;color:black">Shock</kbd>/<kbd style="background-color:888888;color:white">Smash</kbd></td></tr>
|
||||
<tr><td>Draw line</td> <td><kbd>Shift</kbd> + <kbd>Click</kbd></td></tr>
|
||||
<tr><td>Change cursor size</td> <td><kbd>Scroll</kbd> or <kbd>+</kbd><kbd>-</kbd> or <kbd>[</kbd><kbd>]</kbd></td></tr>
|
||||
|
|
@ -96,7 +97,7 @@
|
|||
<tr><td>Reset canvas</td> <td><kbd>R</kbd></td></tr>
|
||||
<tr><td>Single step</td> <td><kbd>></kbd></td></tr>
|
||||
<tr><td>Fullscreen</td> <td><kbd>F</kbd> or <kbd>F11</kbd></td></tr>
|
||||
<tr><td>Normal view</td> <td><kbd>1</kbd></td></tr>
|
||||
<tr><td>Normal view</td> <td><kbd>1</kbd> or <kbd>1</kbd></td></tr>
|
||||
<tr><td>Thermal view</td> <td><kbd>2</kbd></td></tr>
|
||||
<tr><td>Basic view (No effects)</td> <td><kbd>3</kbd></td></tr>
|
||||
<tr><td>Hide canvas</td> <td><kbd>H</kbd></td></tr>
|
||||
|
|
@ -141,7 +142,7 @@
|
|||
<tr><td>C1, C0.75, ...</td> <td>Electric charge of the pixel</tr>
|
||||
</table>
|
||||
|
||||
<p>The original <a href="https://r74n.com/controls.txt">plain text version</a> may not be maintained.</p>
|
||||
<p>The original <a href="https://sandboxels.r74n.com/controls.txt">plain text version</a> may not be maintained.</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@
|
|||
<p>Make sure you do not have Low Power Mode enabled on your device.</p>
|
||||
<p>This can limit JavaScript speeds, especially on mobile devices.</p>
|
||||
<p>On Microsoft Edge, this is also called 'Efficiency Mode'. On Chrome, it's called 'Energy Saver'.</p>
|
||||
<p>If this doesn't work, try turning off "Fancy Pixels" in the Sandboxels settings menu, or switching to a smaller canvas size.</p>
|
||||
|
||||
<h2>Screen flickers or stays black unless paused</h2>
|
||||
<p>The canvas may flicker or disappear if an error occurs when trying to simulate certain pixels.</p>
|
||||
|
|
|
|||
2584
index.html
2584
index.html
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,118 @@
|
|||
|
||||
|
||||
|
||||
/* == Custom View Modes == */
|
||||
|
||||
viewInfo[4] = { // Small Pixels
|
||||
name: "grid",
|
||||
pre: function(ctx) {
|
||||
// run any code before pixels are rendered
|
||||
drawSquare(ctx,"#00ff00",20,20,5);
|
||||
},
|
||||
pixel: function(pixel,ctx) {
|
||||
// run any code when each individual pixel is rendered
|
||||
drawSquare(ctx,pixel.color,pixel.x,pixel.y,0.66)
|
||||
},
|
||||
post: function(ctx) {
|
||||
// run any code after pixels are rendered
|
||||
drawPlus(ctx,"#ff0000",10,10) // Like a gas
|
||||
}
|
||||
};
|
||||
|
||||
// Number keys will automatically switch views.
|
||||
|
||||
|
||||
|
||||
/* == Custom Element Renderers == */
|
||||
|
||||
elements.ball.renderer = function(pixel,ctx) {
|
||||
// Draw three horizontal squares
|
||||
drawSquare(ctx,"#00ff00",pixel.x-1,pixel.y);
|
||||
drawSquare(ctx,"#00ff00",pixel.x,pixel.y);
|
||||
drawSquare(ctx,"#00ff00",pixel.x+1,pixel.y);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* == Custom Global Renderers == */
|
||||
|
||||
renderEachPixel(function(pixel,ctx) {
|
||||
// run any code when each individual pixel is rendered
|
||||
if (pixel.element === "rock") {
|
||||
drawSquare(ctx,"#00ff00",pixel.x,pixel.y-1);
|
||||
}
|
||||
})
|
||||
renderPrePixel(function(ctx) {
|
||||
// run any code before pixels are rendered
|
||||
drawSquare(ctx,"#ff00ff",10,40);
|
||||
})
|
||||
renderPostPixel(function(ctx) {
|
||||
// run any code after pixels are rendered
|
||||
drawSquare(ctx,"#ffff00",30,40);
|
||||
})
|
||||
|
||||
runPerPixel(function(pixel) {
|
||||
// run any code on each pixel every tick
|
||||
tryMove(pixel,pixel.x+1,pixel.y);
|
||||
})
|
||||
|
||||
runEveryTick(function() {
|
||||
// run any code after pixels are simulated per tick
|
||||
if (pixelTicks % 90 === 0) {
|
||||
logMessage("tick"+pixelTicks);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// If you NEED to overwrite drawPixels(), which is NOT RECOMMENDED, you must return true.
|
||||
/*
|
||||
oldDrawPixels = drawPixels;
|
||||
drawPixels = function(forceTick=false) {
|
||||
oldDrawPixels(forceTick);
|
||||
// ...
|
||||
return true;
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* == Custom canvas layers == */
|
||||
|
||||
// WARNING: Performance may decrease. Use canvasLayers.pixels unless necessary.
|
||||
addCanvasLayer("effects");
|
||||
// One of the following is required to have the layer render automatically.
|
||||
canvasLayersPost.push(canvasLayers["effects"]); // Render after pixels
|
||||
// canvasLayersPre.push(canvasLayers["effects"]); // Render before pixels
|
||||
|
||||
effectsCtx = canvasLayers["effects"].getContext("2d");
|
||||
|
||||
|
||||
|
||||
/* == Custom Keybinds == */
|
||||
|
||||
keybinds["Digit7"] = function(e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
// Override existing keybind
|
||||
keybinds["KeyH"] = function() {
|
||||
logMessage("H was pressed!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* == New Element Events == */
|
||||
|
||||
elements.slime.onPlace = function(pixel) {
|
||||
logMessage(pixel.element+" placed")
|
||||
}
|
||||
elements.slime.onDelete = function(pixel) {
|
||||
logMessage(pixel.element+" deleted at "+pixelTicks)
|
||||
}
|
||||
elements.slime.onChange = function(pixel,element) {
|
||||
logMessage(pixel.element+" changed into "+element)
|
||||
}
|
||||
elements.slime.onBreak = function(pixel) {
|
||||
// breakInto property not necessary to fire
|
||||
logMessage(pixel.element+" broken")
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
settings.textures = 0;
|
||||
if (elements.dirt) {elements.dirt.color = [
|
||||
"#9e6b4b",
|
||||
"#9e6b4b",
|
||||
|
|
@ -159,3 +160,10 @@ if (elements.yeast && elements.yeast.reactions) {
|
|||
if (elements.yeast.reactions.grape) {elements.yeast.reactions.grape.color2 = "#916851";}
|
||||
if (elements.yeast.reactions.juice) {elements.yeast.reactions.juice.color2 = "#916851";}
|
||||
}
|
||||
if (elements.freeze_ray) {elements.freeze_ray.color = ["#0000ff","#5500ff"];}
|
||||
if (elements.hydrogen) {delete elements.hydrogen.fireColor;}
|
||||
if (elements.steel) {delete elements.steel.colorPattern;}
|
||||
if (elements.galvanized_steel) {delete elements.galvanized_steel.colorPattern;}
|
||||
if (elements.bird) {delete elements.bird.stateHighColor;}
|
||||
if (elements.frog) {delete elements.frog.stateHighColor;}
|
||||
if (elements.fallout) {elements.fallout.color = ["#63b85a","#448044","#598044","#7bb85a"];}
|
||||
11
mods/find.js
11
mods/find.js
|
|
@ -110,11 +110,6 @@ function findFilterPrompt() {
|
|||
return findElement;
|
||||
};
|
||||
|
||||
runAfterLoad(function() {
|
||||
oldDrawPixels = drawPixels;
|
||||
drawPixels = function(forceTick=false) {
|
||||
oldDrawPixels(forceTick);
|
||||
//console.log(find);
|
||||
if(find) { findHighlighting() };
|
||||
};
|
||||
});
|
||||
renderPostPixel(findHighlighting);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,56 +1,21 @@
|
|||
clearInterval(tickInterval);
|
||||
|
||||
tick = function() {
|
||||
// If mouseIsDown, do mouseAction
|
||||
if (mouseIsDown && !shaping) {
|
||||
mouseAction(null,mousePos.x,mousePos.y);
|
||||
}
|
||||
// Get the canvas
|
||||
var canvas = document.getElementById("game");
|
||||
var ctx = canvas.getContext("2d");
|
||||
// Clear the canvas
|
||||
if (!settings["bg"]) {ctx.clearRect(0, 0, canvas.width, canvas.height)}
|
||||
else {
|
||||
if(settings["bg"] instanceof Array) {
|
||||
settings.bgAngle ??= 0;
|
||||
var angle = (settings.bgAngle) * Math.PI / 180;
|
||||
ctx.fillStyle = ctx.createLinearGradient(
|
||||
0,
|
||||
0,
|
||||
canvas.width * Math.cos(angle) + 0,
|
||||
canvas.height * Math.sin(angle)
|
||||
);
|
||||
var colors = settings["bg"];
|
||||
for(i = 0; i < colors.length; i++) {
|
||||
var color = colors[i];
|
||||
var position = i / (colors.length - 1);
|
||||
ctx.fillStyle.addColorStop(position,color);
|
||||
};
|
||||
} else {
|
||||
ctx.fillStyle = settings["bg"];
|
||||
renderPrePixel(function(ctx) {
|
||||
if(settings["bg"] instanceof Array) {
|
||||
settings.bgAngle ??= 0;
|
||||
var angle = (settings.bgAngle) * Math.PI / 180;
|
||||
ctx.fillStyle = ctx.createLinearGradient(
|
||||
0,
|
||||
0,
|
||||
canvas.width * Math.cos(angle) + 0,
|
||||
canvas.height * Math.sin(angle)
|
||||
);
|
||||
var colors = settings["bg"];
|
||||
for(i = 0; i < colors.length; i++) {
|
||||
var color = colors[i];
|
||||
var position = i / (colors.length - 1);
|
||||
ctx.fillStyle.addColorStop(position,color);
|
||||
};
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
|
||||
if (!paused && settings.events) {
|
||||
doRandomEvents();
|
||||
}
|
||||
|
||||
drawPixels();
|
||||
|
||||
if (shaping) {
|
||||
if (shaping === 1) { // Draw a white line from shapeStart.x to shapeStart.y
|
||||
ctx.beginPath();
|
||||
ctx.strokeStyle = "white";
|
||||
ctx.lineWidth = 2;
|
||||
ctx.moveTo(shapeStart.x*pixelSize+pixelSizeHalf, shapeStart.y*pixelSize+pixelSizeHalf);
|
||||
ctx.lineTo(mousePos.x*pixelSize+pixelSizeHalf, mousePos.y*pixelSize+pixelSizeHalf);
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//ticks ++;
|
||||
}
|
||||
|
||||
tickInterval = setInterval(tick, 1000/tps);
|
||||
} else {
|
||||
ctx.fillStyle = settings["bg"];
|
||||
};
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
})
|
||||
208
mods/heatglow.js
208
mods/heatglow.js
|
|
@ -1,138 +1,76 @@
|
|||
function weightedAverage(num1, num2, weight){
|
||||
return ((weight * num1)+((1-weight)*num2))
|
||||
}
|
||||
const heatfunc = function(pixel){
|
||||
if (pixel.element != "metal_scrap" || eLists.metals.includes(pixel.scrapType) || !pixel.scrapType){{
|
||||
if (pixel.ogR == null || pixel.ogG == null || pixel.ogB == null || (pixel.element != pixel.ogElement && pixel.element == "metal_scrap") || (pixel.element != "metal_scrap" && pixel.ogElement == "metal_scrap") || (pixel.element == "oxidized_copper" && pixel.ogElement == "copper")){
|
||||
pixel.ogR = parseInt(pixel.color.slice(4, pixel.color.indexOf(',')), 10)
|
||||
pixel.ogG = parseInt(pixel.color.slice(pixel.color.indexOf(',') + 1, pixel.color.lastIndexOf(',')), 10)
|
||||
pixel.ogB = parseInt(pixel.color.slice(pixel.color.lastIndexOf(',') + 1, -1), 10)
|
||||
pixel.ogElement = pixel.element
|
||||
}
|
||||
var gethigh = 1000
|
||||
var ctemp = 0
|
||||
var ogR = 0
|
||||
var ogG = 0
|
||||
var ogB = 0
|
||||
if (elements[pixel.element].tempHigh){
|
||||
gethigh = elements[pixel.element].tempHigh
|
||||
} else if (pixel.scrapType) {
|
||||
gethigh = elements[pixel.scrapType].tempHigh
|
||||
}
|
||||
var halftemp = ((20+gethigh)/2)
|
||||
if (pixel.temp <= (gethigh) - halftemp){
|
||||
ctemp = 0;
|
||||
} else if (pixel.temp > (gethigh)-halftemp && pixel.temp <= gethigh){
|
||||
ctemp = ((1/halftemp)*pixel.temp)-(((gethigh)-halftemp)/halftemp)
|
||||
}
|
||||
if (ctemp <= 0.5){
|
||||
newR = (((510-(2*pixel.ogR))*ctemp)+pixel.ogR);
|
||||
newG = ((0-((2*pixel.ogG)*ctemp))+pixel.ogG);
|
||||
newB = ((0-((2*pixel.ogB)*ctemp))+pixel.ogB);
|
||||
}else if (ctemp > 0.5){
|
||||
newR = 255;
|
||||
newG = ((510*ctemp)-255);
|
||||
newB= ((280*ctemp)-140);
|
||||
}
|
||||
let weight = (1-(ctemp/1.3))
|
||||
pixel.color = "rgb(" + weightedAverage(pixel.ogR, newR, weight) + "," + weightedAverage(pixel.ogG, newG, weight) + "," + weightedAverage(pixel.ogB, newB, weight) + ")";
|
||||
// lightmap.js integration below
|
||||
if (enabledMods.includes("mods/lightmap.js")){
|
||||
if (pixel.temp <= (gethigh) - halftemp){
|
||||
ctemp = 0;
|
||||
} else if (pixel.temp > (gethigh)-halftemp && pixel.temp <= gethigh){
|
||||
ctemp = ((1/halftemp)*pixel.temp)-(((gethigh)-halftemp)/halftemp)
|
||||
}
|
||||
if (ctemp <= 0.5){
|
||||
LnewR = (((510-(2*0))*ctemp)+0);
|
||||
LnewG = ((0-((2*0)*ctemp))+0);
|
||||
LnewB = ((0-((2*0)*ctemp))+0);
|
||||
}else if (ctemp > 0.5){
|
||||
LnewR = 255;
|
||||
LnewG = ((510*ctemp)-255);
|
||||
LnewB= ((280*ctemp)-140);
|
||||
}
|
||||
let x = Math.floor(pixel.x / lightmapScale);
|
||||
let y = Math.floor(pixel.y / lightmapScale);
|
||||
lightmap[y][x] = { color: [LnewR/3, LnewG/3, LnewB/3]};
|
||||
}
|
||||
}}};
|
||||
if (!eLists.metals) { eLists.metals = [] }
|
||||
if (!settings.heatglowMode){settings.heatglowMode = 1; saveSettings();}
|
||||
if (!eLists.metals) { eLists.metals = [] }
|
||||
eLists.metals = eLists.metals.concat(["iron", "glass", "copper", "gold", "brass","steel","nickel","zinc","silver","aluminum","bronze","metal_scrap","oxidized_copper","tin","lead", "rose_gold", "tungsten"])
|
||||
eLists.metals.forEach(metal => {
|
||||
const prefunc = elements[metal].tick;
|
||||
if (!prefunc){
|
||||
elements[metal].tick = heatfunc;
|
||||
}else{
|
||||
const modfunc = function(pixel){
|
||||
heatfunc(pixel);
|
||||
prefunc(pixel);
|
||||
};
|
||||
elements[metal].tick = modfunc;
|
||||
}
|
||||
if (elements[metal].behavior == behaviors.WALL){
|
||||
elements[metal].movable = false;
|
||||
}
|
||||
});
|
||||
elements.color_baker = {
|
||||
color: "#F61212",
|
||||
tool: function(pixel) {
|
||||
pixel.ogR = parseInt(pixel.color.slice(4, pixel.color.indexOf(',')), 10)
|
||||
pixel.ogG = parseInt(pixel.color.slice(pixel.color.indexOf(',') + 1, pixel.color.lastIndexOf(',')), 10)
|
||||
pixel.ogB = parseInt(pixel.color.slice(pixel.color.lastIndexOf(',') + 1, -1), 10)
|
||||
},
|
||||
category: "tools",
|
||||
excludeRandom: true,
|
||||
desc: "Use to bake a metals paint color into its 'true' color, for heating purposes.",
|
||||
}
|
||||
/*
|
||||
const plantfunc = function(pixel){
|
||||
if (pixel.ogR == null || pixel.ogG == null || pixel.ogB == null){
|
||||
pixel.ogR = parseInt(pixel.color.slice(4, pixel.color.indexOf(',')), 10)
|
||||
pixel.ogG = parseInt(pixel.color.slice(pixel.color.indexOf(',') + 1, pixel.color.lastIndexOf(',')), 10)
|
||||
pixel.ogB = parseInt(pixel.color.slice(pixel.color.lastIndexOf(',') + 1, -1), 10)
|
||||
var deadR = 130;
|
||||
var deadG = 103;
|
||||
var deadB = 40;
|
||||
var burnR = 30;
|
||||
var burnG = 30;
|
||||
var burnB = 30;
|
||||
var newR = pixel.ogR;
|
||||
var newG = pixel.ogG;
|
||||
var newB = pixel.ogB;
|
||||
}else{
|
||||
var gethigh = (elements[pixel.element].tempHigh)
|
||||
var halftemp = ((20+gethigh)/2)
|
||||
if (pixel.temp > halftemp){
|
||||
var ctemp = ((1/halftemp)*pixel.temp)-(((gethigh)-halftemp)/halftemp);
|
||||
} else (ctemp = 0)
|
||||
if (ctemp <= 0.5 && ctemp > 0){
|
||||
newR = weightedAverage(deadR, pixel.ogR, 2*ctemp);
|
||||
newG = weightedAverage(deadG, pixel.ogG, 2*ctemp);
|
||||
newB = weightedAverage(deadB, pixel.ogB, 2*ctemp);
|
||||
}else if (ctemp > 0.5){
|
||||
var modctemp = 2*(ctemp%0.5)
|
||||
newR = weightedAverage(burnR, deadR, 2*modctemp);
|
||||
newG = weightedAverage(burnG, deadG, 2*modctemp);
|
||||
newB = weightedAverage(burnB, deadB, 2*modctemp);
|
||||
}
|
||||
if (!ctemp == 0){
|
||||
pixel.color = "rgb(" + newR + "," + newG + "," + newB + ")";
|
||||
} else {pixel.color = "rgb(" + pixel.ogR + "," + pixel.ogG + "," + pixel.ogB + ")"}
|
||||
if (!eLists.heatBlacklist) {eLists.heatBlacklist = []}
|
||||
eLists.heatBlacklist = eLists.heatBlacklist.concat(["void", "sun", "light", "plasma", "fire", "border", "heater", "superheater"])
|
||||
function tempToRGB(temp){
|
||||
if (temp <= 6500){
|
||||
return{
|
||||
r: 255,
|
||||
g: Math.max(-325.757*Math.pow(0.999581, temp)+272.879, 0),
|
||||
b: Math.max(-571.403*Math.pow(0.999675, temp)+321.955, 0)
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
r: Math.max(604.879*Math.pow(0.999697, temp)+169.618, 0),
|
||||
g: Math.max(719.488*Math.pow(0.999599, temp)+201.788, 0),
|
||||
b: 255
|
||||
}
|
||||
};
|
||||
if (!eLists.burnplants) { eLists.burnplants = [] }
|
||||
eLists.burnplants = eLists.burnplants.concat(["plant","dead_plant","grass","algae","sapling","evergreen","cactus","seeds","grass_seed","wheat_seed","flower_seed","pistil","petal","tree_branch","bamboo_plant","mushroom_spore","mushroom_stalk","mushroom_gill","mushroom_cap","hyphae","pumpkin_seed","pumpkin","corn","corn_seed","potato","potato_seed","root"])
|
||||
eLists.burnplants.forEach(plant => {
|
||||
const prefunc = elements[plant].tick;
|
||||
if (!prefunc){
|
||||
elements[plant].tick = plantfunc;
|
||||
}else{
|
||||
const modfunc = function(pixel){
|
||||
prefunc(pixel);
|
||||
plantfunc(pixel);
|
||||
};
|
||||
elements[plant].tick = modfunc;
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
function oldtempToRgb(temp, pixel){
|
||||
let halftemp = ((20+elements[pixel.element].tempHigh)/2)
|
||||
let fulltemp = elements[pixel.element].tempHigh
|
||||
let ctemp = 0;
|
||||
if (pixel.temp <= fulltemp - halftemp){
|
||||
ctemp = 0;
|
||||
} else {
|
||||
ctemp = temp/(fulltemp-halftemp)-halftemp/(fulltemp-halftemp);
|
||||
}
|
||||
if (ctemp <= 0.5){
|
||||
return{
|
||||
r: (510*ctemp),
|
||||
g: 0,
|
||||
b: 0,
|
||||
opacity: (ctemp/1.3)
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
r: 255,
|
||||
g: ((510*ctemp)-255),
|
||||
b: ((280*ctemp)-140),
|
||||
opacity: (ctemp/1.3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderPresets.HEATGLOW = function(pixel,ctx) {
|
||||
drawDefault(ctx,pixel)
|
||||
}
|
||||
|
||||
renderEachPixel(function(pixel,ctx) {
|
||||
// run any code when each individual pixel is rendered
|
||||
if (!eLists.heatBlacklist.includes(pixel.element)){
|
||||
let color, opacity;
|
||||
if (settings.heatglowMode == 1){
|
||||
color = tempToRGB(pixel.temp)
|
||||
opacity = Math.max(0, Math.min(1, -3.5486801*Math.pow(0.9960659, pixel.temp)+0.73333))
|
||||
} else {
|
||||
color = oldtempToRgb(pixel.temp, pixel)
|
||||
opacity = color.opacity
|
||||
if (!eLists.metals.includes(pixel.element)){
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (elements[pixel.element].glow || elements[pixel.element].isGas){
|
||||
drawPlus(ctx,"rgba(" + color.r + ", " + color.g + ", " + color.b + ", " + opacity +")",pixel.x,pixel.y)
|
||||
} else {
|
||||
drawSquare(ctx,"rgba(" + color.r + ", " + color.g + ", " + color.b + ", " + opacity +")",pixel.x,pixel.y)
|
||||
}}
|
||||
})
|
||||
keybinds["KeyH"] = function(){
|
||||
if (settings.heatglowMode == 1){settings.heatglowMode = 2}
|
||||
else {settings.heatglowMode = 1}
|
||||
saveSettings();
|
||||
logMessage("Heat glow mode switched.")
|
||||
}
|
||||
|
|
@ -223,15 +223,6 @@ runAfterLoadList.push(() => drawPixels = (function() {
|
|||
for (var i = 0; i < newCurrentPixels.length; i++) {
|
||||
pixel = newCurrentPixels[i];
|
||||
if (pixel.del) {continue}
|
||||
if (!paused || forceTick) {
|
||||
if (elements[pixel.element].tick) {
|
||||
elements[pixel.element].tick(pixel);
|
||||
}
|
||||
if (pixel.del) {continue}
|
||||
if (elements[pixel.element].behavior) {
|
||||
pixelTick(pixel);
|
||||
}
|
||||
};
|
||||
if (pixel.con) { pixel = pixel.con }
|
||||
if (elements[pixel.element].isGas || elements[pixel.element].glow) {
|
||||
pixelsLast.push(pixel);
|
||||
|
|
@ -266,11 +257,6 @@ runAfterLoadList.push(() => drawPixels = (function() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!settings["bg"]) {ctx.clearRect(0, 0, canvas.width, canvas.height)}
|
||||
else {
|
||||
ctx.fillStyle = settings["bg"];
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
var pixelDrawList = pixelsFirst.concat(pixelsLast);
|
||||
for (var i = 0; i < pixelDrawList.length; i++) {
|
||||
pixel = pixelDrawList[i];
|
||||
|
|
@ -480,25 +466,8 @@ runAfterLoadList.push(() => drawPixels = (function() {
|
|||
if (ctx.globalAlpha < 1) {
|
||||
ctx.globalAlpha = 1;
|
||||
}
|
||||
|
||||
if (elements[currentElement].maxSize < mouseSize) {
|
||||
var mouseOffset = Math.trunc(elements[currentElement].maxSize/2);
|
||||
}
|
||||
else {
|
||||
var mouseOffset = Math.trunc(mouseSize/2);
|
||||
}
|
||||
var topLeft = [mousePos.x-mouseOffset,mousePos.y-mouseOffset];
|
||||
var bottomRight = [mousePos.x+mouseOffset,mousePos.y+mouseOffset];
|
||||
// Draw a square around the mouse
|
||||
ctx.strokeStyle = "white";
|
||||
ctx.strokeRect(topLeft[0]*pixelSize,topLeft[1]*pixelSize,(bottomRight[0]-topLeft[0]+1)*pixelSize,(bottomRight[1]-topLeft[1]+1)*pixelSize);
|
||||
// draw one transparent pixel in the center
|
||||
if (settings.precision) {
|
||||
ctx.fillStyle = "rgba(255,255,255,0.5)";
|
||||
ctx.fillRect(mousePos.x*pixelSize,mousePos.y*pixelSize,pixelSize,pixelSize);
|
||||
}
|
||||
if ((!paused) || forceTick) {pixelTicks++};
|
||||
} else oldDrawPixels.apply(this, arguments);
|
||||
return true;
|
||||
}
|
||||
}()));
|
||||
}
|
||||
|
|
@ -307,11 +307,6 @@ elements.technetium = {
|
|||
},
|
||||
elements.destroyable_pipe = {
|
||||
color: "#414c4f",
|
||||
onSelect: function() {
|
||||
if(!enabledMods.contains("mods/nousersthings.js")){
|
||||
logMessage("credit to nousersthings.js for this element")
|
||||
}
|
||||
},
|
||||
tick: function(pixel) {
|
||||
if (!pixel.stage && pixelTicks-pixel.start > 60) {
|
||||
for (var i = 0; i < squareCoords.length; i++) {
|
||||
|
|
@ -2672,9 +2667,9 @@ elements.healing_serum = {
|
|||
pixel.waitReduce = true
|
||||
}
|
||||
if (pixel.wait == 0){
|
||||
if (!pixel.elementsSeen[pixelMap[x][y].element] && pixelMap[x][y].element != "healing_serum"){
|
||||
if (!pixel.elementsSeen[pixelMap[x][y].element] && !(["healing_serum", "bless", "experience"].includes(pixelMap[x][y].element))){
|
||||
pixel.elementsSeen[pixelMap[x][y].element] = 1
|
||||
} else if (pixelMap[x][y].element != "healing_serum") {
|
||||
} else if (!(["healing_serum", "bless", "experience"].includes(pixelMap[x][y].element))) {
|
||||
pixel.elementsSeen[pixelMap[x][y].element] += 1
|
||||
}
|
||||
}
|
||||
|
|
@ -2941,6 +2936,7 @@ elements.run_some_code = {
|
|||
color: "#68b2cf",
|
||||
category: "tools",
|
||||
canPlace: false,
|
||||
tool: function(){},
|
||||
onSelect: function(){
|
||||
let code = prompt("Enter code to run")
|
||||
if (code){
|
||||
|
|
@ -3358,9 +3354,8 @@ elements.super_heat_conductor = {
|
|||
}
|
||||
}
|
||||
}
|
||||
let ogdrawPixels = drawPixels
|
||||
drawPixels = function(forceTick=false){
|
||||
if (!paused || forceTick){
|
||||
runEveryTick(function() {
|
||||
// run any code after pixels are simulated per tick
|
||||
var heatpixels = currentPixels.filter(function(pixelToCheck) {
|
||||
if (pixelToCheck.element == "global_heat_conductor"){
|
||||
return true;
|
||||
|
|
@ -3372,9 +3367,8 @@ drawPixels = function(forceTick=false){
|
|||
var avg = (randomPixel.temp + newPixel.temp)/2;
|
||||
randomPixel.temp = avg;
|
||||
newPixel.temp = avg;
|
||||
}}
|
||||
ogdrawPixels(forceTick)
|
||||
}
|
||||
}
|
||||
})
|
||||
elements.global_heat_conductor = {
|
||||
color: "#55251e",
|
||||
behavior: behaviors.WALL,
|
||||
|
|
@ -3455,3 +3449,86 @@ elements.outer_outliner = {
|
|||
deletePixel(pixel.x, pixel.y)
|
||||
}
|
||||
}
|
||||
function highestValueObjectKey(object){
|
||||
let max = -Infinity
|
||||
for (var key in object){
|
||||
if (object[key] > (object[max]||-Infinity)){
|
||||
max = key
|
||||
}
|
||||
}
|
||||
return max
|
||||
}
|
||||
function sumOfObjectValues(object){
|
||||
let sum = 0
|
||||
for (var key in object){
|
||||
sum += object[key]
|
||||
}
|
||||
return sum
|
||||
}
|
||||
neighborRandomChance = {
|
||||
1: 0.015,
|
||||
2: 0.03,
|
||||
3: 0.06,
|
||||
4: 0.12,
|
||||
5: 0.2,
|
||||
6: 0.5,
|
||||
7: 0.8,
|
||||
8: 1
|
||||
}
|
||||
elements.colored_filler = {
|
||||
color: elements.rainbow.color,
|
||||
behavior: behaviors.WALL,
|
||||
category: "special",
|
||||
customColor: true,
|
||||
properties: {
|
||||
"initalized": false,
|
||||
},
|
||||
onSelect: function(pixel){
|
||||
logMessage("It is reccomended to place this while paused.")
|
||||
},
|
||||
tick: function(pixel){
|
||||
let fillerNeighbors = {}
|
||||
for (var i = 0; i < adjacentCoords.length; i++) {
|
||||
var x = pixel.x+adjacentCoords[i][0];
|
||||
var y = pixel.y+adjacentCoords[i][1];
|
||||
if (isEmpty(x,y)) {
|
||||
createPixel("colored_filler", x, y)
|
||||
pixelMap[x][y].color = pixel.color;
|
||||
pixelMap[x][y].initalized = true
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < squareCoords.length; i++) {
|
||||
var x = pixel.x+squareCoords[i][0];
|
||||
var y = pixel.y+squareCoords[i][1];
|
||||
if (!isEmpty(x, y, true)){
|
||||
var otherPixel = pixelMap[x][y];
|
||||
if (otherPixel.element == "colored_filler" && otherPixel.color != pixel.color){
|
||||
fillerNeighbors[otherPixel.color] = (fillerNeighbors[otherPixel.color]||0)+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(Object.keys(fillerNeighbors).length > 0){
|
||||
let mostSeenColor = highestValueObjectKey(fillerNeighbors)
|
||||
let opposingCount = sumOfObjectValues(fillerNeighbors)
|
||||
if (Math.random() < neighborRandomChance[opposingCount]){
|
||||
pixel.color = mostSeenColor;
|
||||
}
|
||||
}
|
||||
},
|
||||
renderer: function(pixel, ctx){
|
||||
if (!pixel.initalized){
|
||||
var rgb = hexToRGB(currentColor);
|
||||
pixel.color = "rgb("+rgb.r+","+rgb.g+","+rgb.b+")";
|
||||
pixel.initalized = true;
|
||||
}
|
||||
if (pixel.color != "monochrome" && pixel.color != "rainbow"){
|
||||
drawSquare(ctx, pixel.color, pixel.x, pixel.y);
|
||||
} else {
|
||||
if (pixel.color == "monochrome"){
|
||||
drawSquare(ctx, "hsl(0, 0%, " + 100*Math.abs(Math.asin(Math.sin(pixelTicks/30)))/(0.5*Math.PI) + "%)", pixel.x, pixel.y);
|
||||
} else if (pixel.color == "rainbow"){
|
||||
drawSquare(ctx, "hsl(" + ((pixelTicks%60)/60)*360 + ", 100%, 50%)", pixel.x, pixel.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
133
mods/pressure.js
133
mods/pressure.js
|
|
@ -114,44 +114,14 @@ doVelocity = function(pixel) {
|
|||
}
|
||||
}
|
||||
|
||||
drawPixels = function(forceTick=false) {
|
||||
// newCurrentPixels = shuffled currentPixels
|
||||
var newCurrentPixels = currentPixels.slice();
|
||||
var pixelsFirst = [];
|
||||
var pixelsLast = [];
|
||||
if (!paused || forceTick) {
|
||||
shuffleArray(newCurrentPixels);
|
||||
}
|
||||
/*{newCurrentPixels.sort(function(p) { // shuffle the pixels but keep elements[p.element].isGas last
|
||||
return 0.5 - Math.random();
|
||||
})} // shuffle the pixels if not paused*/
|
||||
for (var i = 0; i < newCurrentPixels.length; i++) {
|
||||
pixel = newCurrentPixels[i];
|
||||
//if (pixelMap[pixel.x][pixel.y] == undefined || currentPixels.indexOf(pixel) == -1) {continue}
|
||||
if (pixel.del) {continue}
|
||||
if (!paused || forceTick) {
|
||||
doVelocity(pixel);
|
||||
pixel.prevX = pixel.x;
|
||||
pixel.prevY = pixel.y;
|
||||
if (pixel.del) {continue}
|
||||
if (elements[pixel.element].tick) { // Run tick function if it exists
|
||||
elements[pixel.element].tick(pixel);
|
||||
}
|
||||
if (pixel.del) {continue}
|
||||
if (elements[pixel.element].behavior) { // Parse behavior if it exists
|
||||
pixelTick(pixel);
|
||||
}
|
||||
};
|
||||
if (pixel.con) { pixel = pixel.con }
|
||||
if (elements[pixel.element].isGas || elements[pixel.element].glow) {
|
||||
pixelsLast.push(pixel);
|
||||
}
|
||||
else {
|
||||
pixelsFirst.push(pixel);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < newCurrentPixels.length; i++) {
|
||||
pixel = newCurrentPixels[i];
|
||||
runPerPixel(function(pixel) {
|
||||
doVelocity(pixel);
|
||||
pixel.prevX = pixel.x;
|
||||
pixel.prevY = pixel.y;
|
||||
})
|
||||
runEveryTick(function() {
|
||||
for (var i = 0; i < currentPixels.length; i++) {
|
||||
pixel = currentPixels[i];
|
||||
let density = elements[pixel.element].density ? elements[pixel.element].density : 1;
|
||||
let accelx = (pixel.x - pixel.prevX)/2 * (1+(pixel.pressure ? pixel.pressure : 0)/density);
|
||||
let accely = (pixel.y - pixel.prevY)/2 * (1+(pixel.pressure ? pixel.pressure : 0)/density);
|
||||
|
|
@ -164,92 +134,7 @@ drawPixels = function(forceTick=false) {
|
|||
else
|
||||
pixel.vy += accely;
|
||||
}
|
||||
// Draw the current pixels
|
||||
var canvas = document.getElementById("game");
|
||||
var ctx = canvas.getContext("2d");
|
||||
// Clear the canvas
|
||||
if (!settings["bg"]) {ctx.clearRect(0, 0, canvas.width, canvas.height)}
|
||||
else {
|
||||
ctx.fillStyle = settings["bg"];
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
var pixelDrawList = pixelsFirst.concat(pixelsLast);
|
||||
for (var i = 0; i < pixelDrawList.length; i++) {
|
||||
pixel = pixelDrawList[i];
|
||||
if (pixelMap[pixel.x][pixel.y] == undefined) {continue}
|
||||
if (pixel.con) { pixel = pixel.con }
|
||||
if (view===null || view===3) {
|
||||
ctx.fillStyle = pixel.color;
|
||||
}
|
||||
else if (view === 2) { // thermal view
|
||||
var temp = pixel.temp;
|
||||
if (temp < -50) {temp = -50}
|
||||
if (temp > 6000) {temp = 6000}
|
||||
// logarithmic scale, with coldest being 225 (-50 degrees) and hottest being 0 (6000 degrees)
|
||||
var hue = Math.round(225 - (Math.log(temp+50)/Math.log(6000+50))*225);
|
||||
if (hue < 0) {hue = 0}
|
||||
if (hue > 225) {hue = 225}
|
||||
ctx.fillStyle = "hsl("+hue+",100%,50%)";
|
||||
}
|
||||
else if (view === 4) { // smooth view, average of surrounding pixels
|
||||
var colorlist = [];
|
||||
// check adjacent coords on the pixelMap, add the color to the list if the pixel is not empty and the color indexOf "rgb" is not -1
|
||||
for (var j = 0; j < biCoords.length; j++) {
|
||||
var x = pixel.x + biCoords[j][0];
|
||||
var y = pixel.y + biCoords[j][1];
|
||||
if (isEmpty(x,y,true) || elements[pixelMap[x][y].element].state !== elements[pixel.element].state) {continue}
|
||||
var color = pixelMap[x][y].color;
|
||||
if (color.indexOf("rgb") !== -1) {
|
||||
colorlist.push(color.match(/\d+/g));
|
||||
}
|
||||
}
|
||||
if (colorlist.length === 0) {
|
||||
ctx.fillStyle = pixel.color;
|
||||
}
|
||||
else {
|
||||
ctx.fillStyle = averageRGB(colorlist);
|
||||
}
|
||||
}
|
||||
if (ctx.globalAlpha < 1 && !(elements[pixel.element].isGas || elements[pixel.element].glow)) {
|
||||
ctx.globalAlpha = 1;
|
||||
}
|
||||
if ((view === null || view === 4) && (elements[pixel.element].isGas || elements[pixel.element].glow)) {
|
||||
if (ctx.globalAlpha!==0.5) { ctx.globalAlpha = 0.5; }
|
||||
ctx.fillRect((pixel.x-1)*pixelSize, (pixel.y)*pixelSize, pixelSize*3, pixelSize);
|
||||
ctx.fillRect((pixel.x)*pixelSize, (pixel.y-1)*pixelSize, pixelSize, pixelSize*3);
|
||||
}
|
||||
else { // draw the pixel (default)
|
||||
ctx.fillRect(pixel.x*pixelSize, pixel.y*pixelSize, pixelSize, pixelSize);
|
||||
}
|
||||
if (pixel.charge && view !== 2) { // Yellow glow on charge
|
||||
if (!elements[pixel.element].colorOn) {
|
||||
ctx.fillStyle = "rgba(255,255,0,0.5)";
|
||||
ctx.fillRect(pixel.x*pixelSize, pixel.y*pixelSize, pixelSize, pixelSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ctx.globalAlpha < 1) {
|
||||
ctx.globalAlpha = 1;
|
||||
}
|
||||
|
||||
if (elements[currentElement].maxSize < mouseSize) {
|
||||
var mouseOffset = Math.trunc(elements[currentElement].maxSize/2);
|
||||
}
|
||||
else {
|
||||
var mouseOffset = Math.trunc(mouseSize/2);
|
||||
}
|
||||
var topLeft = [mousePos.x-mouseOffset,mousePos.y-mouseOffset];
|
||||
var bottomRight = [mousePos.x+mouseOffset,mousePos.y+mouseOffset];
|
||||
// Draw a square around the mouse
|
||||
ctx.strokeStyle = "white";
|
||||
ctx.strokeRect(topLeft[0]*pixelSize,topLeft[1]*pixelSize,(bottomRight[0]-topLeft[0]+1)*pixelSize,(bottomRight[1]-topLeft[1]+1)*pixelSize);
|
||||
// draw one transparent pixel in the center
|
||||
if (settings.precision) {
|
||||
ctx.fillStyle = "rgba(255,255,255,0.5)";
|
||||
ctx.fillRect(mousePos.x*pixelSize,mousePos.y*pixelSize,pixelSize,pixelSize);
|
||||
}
|
||||
if ((!paused) || forceTick) {pixelTicks++};
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
|
|
|
|||
126
mods/velocity.js
126
mods/velocity.js
|
|
@ -46,125 +46,7 @@ doVelocity = function(pixel) {
|
|||
}
|
||||
}
|
||||
|
||||
drawPixels = function(forceTick=false) {
|
||||
// newCurrentPixels = shuffled currentPixels
|
||||
var newCurrentPixels = currentPixels.slice();
|
||||
var pixelsFirst = [];
|
||||
var pixelsLast = [];
|
||||
if (!paused || forceTick) {
|
||||
shuffleArray(newCurrentPixels);
|
||||
}
|
||||
/*{newCurrentPixels.sort(function(p) { // shuffle the pixels but keep elements[p.element].isGas last
|
||||
return 0.5 - Math.random();
|
||||
})} // shuffle the pixels if not paused*/
|
||||
for (var i = 0; i < newCurrentPixels.length; i++) {
|
||||
pixel = newCurrentPixels[i];
|
||||
//if (pixelMap[pixel.x][pixel.y] == undefined || currentPixels.indexOf(pixel) == -1) {continue}
|
||||
if (pixel.del) {continue}
|
||||
if (!paused || forceTick) {
|
||||
doVelocity(pixel);
|
||||
if (elements[pixel.element].tick) { // Run tick function if it exists
|
||||
elements[pixel.element].tick(pixel);
|
||||
}
|
||||
if (pixel.del) {continue}
|
||||
if (elements[pixel.element].behavior) { // Parse behavior if it exists
|
||||
pixelTick(pixel);
|
||||
}
|
||||
};
|
||||
if (pixel.con) { pixel = pixel.con }
|
||||
if (elements[pixel.element].isGas || elements[pixel.element].glow) {
|
||||
pixelsLast.push(pixel);
|
||||
}
|
||||
else {
|
||||
pixelsFirst.push(pixel);
|
||||
}
|
||||
}
|
||||
// Draw the current pixels
|
||||
var canvas = document.getElementById("game");
|
||||
var ctx = canvas.getContext("2d");
|
||||
// Clear the canvas
|
||||
if (!settings["bg"]) {ctx.clearRect(0, 0, canvas.width, canvas.height)}
|
||||
else {
|
||||
ctx.fillStyle = settings["bg"];
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
var pixelDrawList = pixelsFirst.concat(pixelsLast);
|
||||
for (var i = 0; i < pixelDrawList.length; i++) {
|
||||
pixel = pixelDrawList[i];
|
||||
if (pixelMap[pixel.x][pixel.y] == undefined) {continue}
|
||||
if (pixel.con) { pixel = pixel.con }
|
||||
if (view===null || view===3) {
|
||||
ctx.fillStyle = pixel.color;
|
||||
}
|
||||
else if (view === 2) { // thermal view
|
||||
var temp = pixel.temp;
|
||||
if (temp < -50) {temp = -50}
|
||||
if (temp > 6000) {temp = 6000}
|
||||
// logarithmic scale, with coldest being 225 (-50 degrees) and hottest being 0 (6000 degrees)
|
||||
var hue = Math.round(225 - (Math.log(temp+50)/Math.log(6000+50))*225);
|
||||
if (hue < 0) {hue = 0}
|
||||
if (hue > 225) {hue = 225}
|
||||
ctx.fillStyle = "hsl("+hue+",100%,50%)";
|
||||
}
|
||||
else if (view === 4) { // smooth view, average of surrounding pixels
|
||||
var colorlist = [];
|
||||
// check adjacent coords on the pixelMap, add the color to the list if the pixel is not empty and the color indexOf "rgb" is not -1
|
||||
for (var j = 0; j < biCoords.length; j++) {
|
||||
var x = pixel.x + biCoords[j][0];
|
||||
var y = pixel.y + biCoords[j][1];
|
||||
if (isEmpty(x,y,true) || elements[pixelMap[x][y].element].state !== elements[pixel.element].state) {continue}
|
||||
var color = pixelMap[x][y].color;
|
||||
if (color.indexOf("rgb") !== -1) {
|
||||
colorlist.push(color.match(/\d+/g));
|
||||
}
|
||||
}
|
||||
if (colorlist.length === 0) {
|
||||
ctx.fillStyle = pixel.color;
|
||||
}
|
||||
else {
|
||||
ctx.fillStyle = averageRGB(colorlist);
|
||||
}
|
||||
}
|
||||
if (ctx.globalAlpha < 1 && !(elements[pixel.element].isGas || elements[pixel.element].glow)) {
|
||||
ctx.globalAlpha = 1;
|
||||
}
|
||||
if ((view === null || view === 4) && (elements[pixel.element].isGas || elements[pixel.element].glow)) {
|
||||
if (ctx.globalAlpha!==0.5) { ctx.globalAlpha = 0.5; }
|
||||
ctx.fillRect((pixel.x-1)*pixelSize, (pixel.y)*pixelSize, pixelSize*3, pixelSize);
|
||||
ctx.fillRect((pixel.x)*pixelSize, (pixel.y-1)*pixelSize, pixelSize, pixelSize*3);
|
||||
}
|
||||
else { // draw the pixel (default)
|
||||
ctx.fillRect(pixel.x*pixelSize, pixel.y*pixelSize, pixelSize, pixelSize);
|
||||
}
|
||||
if (pixel.charge && view !== 2) { // Yellow glow on charge
|
||||
if (!elements[pixel.element].colorOn) {
|
||||
ctx.fillStyle = "rgba(255,255,0,0.5)";
|
||||
ctx.fillRect(pixel.x*pixelSize, pixel.y*pixelSize, pixelSize, pixelSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ctx.globalAlpha < 1) {
|
||||
ctx.globalAlpha = 1;
|
||||
}
|
||||
|
||||
if (elements[currentElement].maxSize < mouseSize) {
|
||||
var mouseOffset = Math.trunc(elements[currentElement].maxSize/2);
|
||||
}
|
||||
else {
|
||||
var mouseOffset = Math.trunc(mouseSize/2);
|
||||
}
|
||||
var topLeft = [mousePos.x-mouseOffset,mousePos.y-mouseOffset];
|
||||
var bottomRight = [mousePos.x+mouseOffset,mousePos.y+mouseOffset];
|
||||
// Draw a square around the mouse
|
||||
ctx.strokeStyle = "white";
|
||||
ctx.strokeRect(topLeft[0]*pixelSize,topLeft[1]*pixelSize,(bottomRight[0]-topLeft[0]+1)*pixelSize,(bottomRight[1]-topLeft[1]+1)*pixelSize);
|
||||
// draw one transparent pixel in the center
|
||||
if (settings.precision) {
|
||||
ctx.fillStyle = "rgba(255,255,255,0.5)";
|
||||
ctx.fillRect(mousePos.x*pixelSize,mousePos.y*pixelSize,pixelSize,pixelSize);
|
||||
}
|
||||
if ((!paused) || forceTick) {pixelTicks++};
|
||||
}
|
||||
runPerPixel(doVelocity);
|
||||
|
||||
|
||||
})
|
||||
|
|
@ -206,7 +88,8 @@ explodeAt = function(x,y,radius,fire="fire") {
|
|||
var info = elements[pixel.element];
|
||||
if (info.hardness) { // lower damage depending on hardness(0-1)
|
||||
if (info.hardness < 1) {
|
||||
damage = damage * ((1 - info.hardness)*10);
|
||||
// more hardness = less damage, logarithmic
|
||||
damage *= Math.pow((1-info.hardness),info.hardness);
|
||||
}
|
||||
else { damage = 0; }
|
||||
}
|
||||
|
|
@ -232,6 +115,9 @@ explodeAt = function(x,y,radius,fire="fire") {
|
|||
else {
|
||||
var newfire = fire;
|
||||
}
|
||||
if (elements[pixel.element].onBreak !== undefined) {
|
||||
elements[pixel.element].onBreak(pixel);
|
||||
}
|
||||
changePixel(pixel,newfire);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
157
style.css
157
style.css
|
|
@ -288,7 +288,7 @@ button, input[type="submit"], input[type="reset"] {
|
|||
#controls button[current="true"], #controls button[on="true"] {
|
||||
border: 1px solid #ffffff;
|
||||
filter: brightness(110%);
|
||||
box-shadow: 0 5px 15px rgba(255, 255, 255, .4);
|
||||
/* box-shadow: 0 5px 15px rgba(255, 255, 255, .4); */
|
||||
color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
#controls .elementButton[current="true"] {
|
||||
|
|
@ -303,7 +303,11 @@ button, input[type="submit"], input[type="reset"] {
|
|||
color:lime;
|
||||
}
|
||||
#controls div {
|
||||
display:block;
|
||||
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
|
||||
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
|
||||
display: -ms-flexbox; /* TWEENER - IE 10 */
|
||||
display: -webkit-flex; /* NEW - Chrome */
|
||||
display:flex;
|
||||
}
|
||||
.stat {
|
||||
margin-right: 25px;
|
||||
|
|
@ -319,58 +323,6 @@ button, input[type="submit"], input[type="reset"] {
|
|||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
/* screen size < 800px */
|
||||
@media screen and (max-width: 800px) { /* Mobile Styles */
|
||||
.pagetitle {
|
||||
font-size: 1em;
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
#bottomLeftBox, #bottomRightBox {
|
||||
width: 100%;
|
||||
margin: 1px;
|
||||
text-align: left;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
#gameDiv { /*game canvas*/
|
||||
margin-top: 0;
|
||||
}
|
||||
.stat {
|
||||
margin-right: 15px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
#stats {
|
||||
width: 97%;
|
||||
margin-left: 5px;
|
||||
font-size: 0.75em;
|
||||
height: 2.5em
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 600px) {
|
||||
#gameDiv { /*game canvas*/
|
||||
margin-top: 0;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-top: none;
|
||||
}
|
||||
.pagetitle {
|
||||
display: none
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 800px) { /* Desktop-Only Styles */
|
||||
#gameDiv {
|
||||
width:800px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -0%);
|
||||
}
|
||||
}
|
||||
/* screen size > 1325px, h1::after {content:" Sandboxels"} */
|
||||
@media screen and (min-width: 1325px) {
|
||||
.pagetitle::after {content:" Sandboxels"}
|
||||
}
|
||||
#stat-pos, #stat-pixels, #stat-shift, #stat-tps, #stat-ticks, #stat-view {
|
||||
float:left;
|
||||
}
|
||||
|
|
@ -394,6 +346,11 @@ button, input[type="submit"], input[type="reset"] {
|
|||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
#toolControls button, #category-tools button {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
/* Scrollbars */
|
||||
|
|
@ -438,23 +395,32 @@ button, input[type="submit"], input[type="reset"] {
|
|||
background-color: rgba(255, 255, 255, 0.125);
|
||||
white-space: nowrap;
|
||||
overflow-x: auto;
|
||||
flex-wrap: wrap;
|
||||
overflow-y: hidden;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding-bottom:1px;
|
||||
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
|
||||
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
|
||||
display: -ms-flexbox; /* TWEENER - IE 10 */
|
||||
display: -webkit-flex; /* NEW - Chrome */
|
||||
display:flex;
|
||||
}
|
||||
#categoryControls button {
|
||||
/* Borderless buttons */
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
padding-right: 8px;
|
||||
padding-left: 3px;
|
||||
padding-right: 3px;
|
||||
margin: 0;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
z-index:0;
|
||||
flex-grow: 1;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
||||
background-color: #202020;
|
||||
}
|
||||
#categoryControls button:not(:last-child) {
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.4);
|
||||
|
|
@ -464,12 +430,85 @@ button, input[type="submit"], input[type="reset"] {
|
|||
background-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
.category {
|
||||
margin-top:0.75em;
|
||||
margin-top:0.25em;
|
||||
margin-bottom:0.25em;
|
||||
position:relative;
|
||||
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
|
||||
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
|
||||
display: -ms-flexbox; /* TWEENER - IE 10 */
|
||||
display: -webkit-flex; /* NEW - Chrome */
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
flex-wrap:wrap;
|
||||
flex-direction: row;
|
||||
text-align:center;
|
||||
justify-content:space-evenly;
|
||||
flex-wrap:wrap;
|
||||
}
|
||||
.category button {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.category:after {
|
||||
content: "";
|
||||
flex-grow: 20
|
||||
}
|
||||
|
||||
/* screen size < 800px */
|
||||
@media screen and (max-width: 800px) { /* Mobile Styles */
|
||||
.pagetitle {
|
||||
font-size: 1em;
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
#bottomLeftBox, #bottomRightBox {
|
||||
width: 100%;
|
||||
margin: 1px;
|
||||
text-align: left;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
#gameDiv { /*game canvas*/
|
||||
margin-top: 0;
|
||||
}
|
||||
.stat {
|
||||
margin-right: 15px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
#stats {
|
||||
width: 97%;
|
||||
margin-left: 5px;
|
||||
font-size: 0.75em;
|
||||
height: 2.5em
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 600px) {
|
||||
#gameDiv { /*game canvas*/
|
||||
margin-top: 0;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-top: none;
|
||||
}
|
||||
.pagetitle {
|
||||
display: none
|
||||
}
|
||||
#categoryControls {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
#categoryControls button {
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 800px) { /* Desktop-Only Styles */
|
||||
#gameDiv {
|
||||
width:800px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -0%);
|
||||
}
|
||||
}
|
||||
/* screen size > 1325px, h1::after {content:" Sandboxels"} */
|
||||
@media screen and (min-width: 1325px) {
|
||||
.pagetitle::after {content:" Sandboxels"}
|
||||
}
|
||||
button, input { /*Disable double tap zoom on mobile devices*/
|
||||
touch-action: manipulation;
|
||||
|
|
|
|||
Loading…
Reference in New Issue