我在javascript中创建一个平台游戏,其中玩家是矩形,他们可以在平台上跳跃。这非常简单,但现在我试图添加一种明胶效果'对于玩家来说,当他们降落在平台上时,他们会移动一点(如明胶)。我现在已经搜索了很长时间,但我似乎无法找到关于如何更改矩形形状的任何好例子。
所有我想出的就是在css中使用@keyframes并且我已经尝试过实现它,如果我在html元素上使用它,它就可以工作。这是因为使用DOM元素我可以使用.style访问CSSStyleDeclaration,但是如果我创建一个新的播放器对象,我就可以了(如下面的代码所示)。
我不确定如何将css @keyframes转换为javascript,或者我正在做的事情是不可能的......或者是否有其他(更好的)方法来实现我的目标
var keystate = [];
var players = [];
var jelly = document.getElementById('jelly');
console.log(jelly.style); // shows the CSSStyleDeclarations
document.body.addEventListener("keydown", function(e) {
keystate[e.keyCode] = true;
});
document.body.addEventListener("keyup", function(e) {
keystate[e.keyCode] = false;
});
function gelatine(e) {
if (e.style.webkitAnimationName !== 'gelatine') {
e.style.webkitAnimationName = 'gelatine';
e.style.webkitAnimationDuration = '0.5s';
e.style.display = 'inline-block';
setTimeout(function() {
e.style.webkitAnimationName = '';
}, 1000);
}
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
canvas.width = 500;
canvas.height = 300;
function Player(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.jumping = false;
this.velocityY = 0;
this.gravity = 0.3;
this.speed = 5;
this.timer = 0;
this.delay = 120;
}
Player.prototype.render = function render() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = 'blue';
context.fillRect(this.x, this.y, this.width, this.height);
context.fillStyle = 'black';
context.font = '20pt sans-serif';
context.fillText("I'm not jelly:(", this.x - 160, this.y + 30);
};
Player.prototype.update = function update() {
// arrow up key to jump with the player
if (keystate[38]) {
if (!this.jumping) {
this.jumping = true;
this.velocityY = -this.speed * 2;
}
}
this.velocityY += this.gravity;
this.y += this.velocityY;
if (this.y >= canvas.height - this.height) {
this.y = canvas.height - this.height;
this.jumping = false;
}
if (this.timer === 0) {
gelatine(jelly);
this.timer = this.delay;
}
if (this.timer > 0 && this.timer <= this.delay) {
this.timer--;
}
};
players.push(new Player((canvas.width / 2) - 25, (canvas.height / 2), 50, 50));
console.log(players[0].style); // no CSSStyleDeclarations :(
function render() {
for (var i = 0; i < players.length; i++) {
players[i].render();
}
}
function update() {
for (var i = 0; i < players.length; i++) {
players[i].update();
}
}
function tick() {
update();
render();
requestAnimationFrame(tick);
}
tick();
&#13;
<html>
<head>
<style>
#jelly {
position: absolute;
margin-left: auto;
margin-right: auto;
top: 80px;
bottom: 0;
left: 0;
right: 0;
display: inline-block;
width: 100px;
height: 100px;
background: blue;
}
p {
font-size: 20px;
color: white;
}
canvas {
border: 1px solid #000;
position: absolute;
margin: auto;
top: 20px;
bottom: 0;
left: 0;
right: 0;
}
@keyframes gelatine {
25% {
-webkit-transform: scale(0.9, 1.1);
transform: scale(0.9, 1.1);
}
50% {
-webkit-transform: scale(1.1, 0.9);
transform: scale(1.1, 0.9);
}
75% {
-webkit-transform: scale(0.95, 1.05);
transform: scale(0.95, 1.05);
}
}
</style>
<title>Jelly rectangle</title>
</head>
<body>
<div id="jelly">
<p>   i'm jelly :)</p>
</div>
<canvas id='canvas'></canvas>
</body>
</html>
&#13;
答案 0 :(得分:3)
<强>果冻。强>
要在游戏中使用果冻效果,我们可以利用开放式的基于步骤的效果(即效果长度取决于环境并且没有固定的时间)
果冻和大多数液体具有不可压缩的特性。这意味着无论施加在它们上的力,体积都不会改变。对于2D游戏,这意味着对于果冻,该区域不会改变。这意味着我们可以挤压高度并知道该区域计算宽度。
因此,当物体掉落并撞击地面时,我们可以在高度方向上向物体施加挤压力。模拟减震弹簧我们可以产生非常逼真的果冻效果。
定义果冻
我有点傻,因为它是季节所以变量wobbla和弹性定义了受阻弹簧wobbla
是弹簧从0到1的刚度,0.1非常柔软到1非常僵硬。弹性是弹簧从0到1的阻尼,0表示100%阻尼,1表示没有阻尼。
我还添加了react
,它是应用于弹簧的力的简单乘数。由于这是一款游戏,因此需要夸大效果。 react
乘以施加在弹簧上的力。低于1的值会降低效果,超过1的值会增加效果。
hr
和hd
(是坏名称)是实际高度(显示)和高度增量(每帧高度的变化)。这两个变量控制弹簧效应。
有一个标志表示果冻在地面上,sticky
标志如果是,则保持果冻粘在地上。
还有三种控制果冻的功能
function createJellyBox(image,x, y, wobbla, bouncy, react){
return {
img:image,
x : x, // position
y : y,
dx : 0, // movement deltas
dy : 0,
w : image.width, // width
h : image.height, // height
area : image.width * image.height, // area
hr : image.height, // squashed height chaser
hd : 0, // squashed height delta
wobbla : wobbla, // higher values make it wobble more
bouncy : bouncy, // higher values make it react to change in speed
react : react, // additional reaction multiplier. < 1 reduces reaction > 1 increases reaction
onGround : false, // true if on the ground
sticky : true, // true to stick to the ground. false to let it bounce
squashed : 1, // the amount of squashing or stretching along the height
force : 0, // the force applied to the jelly when it hits the ground
draw : drawJelly, // draw function
update : updateJelly, // update function
reset : resetJelly, // reset function
}
}
功能
控制果冻,重置,更新和绘图有三个功能。 抱歉答案超过了30000个字符的限制,所以请在下面的演示中找到这些功能。
<强>绘图强>
绘制简单地绘制果冻。它使用压扁的值来计算高度,然后从中计算宽度,然后简单地使用设置的宽度和高度绘制图像。图像在其中心绘制,以使计算更简单。
重置强>
只需将果冻重置在由x
和y
定义的位置,您可以通过设置jelly.hr = jelly.h
和jelly.hd = 0
<强>更新强>
这是艰苦的工作。它通过将重力添加到ΔY来更新对象位置。它检查果冻是否已经撞到地面,如果它已经通过添加到jelly.hr
(高度增量)将力施加到jelly.hd
弹簧)力等于非紧急时间的速度jelly.react
我发现施加的力应该是随着时间的推移,因此随着时间的推移,有一点点污垢(标有注释)来施加挤压力。这可以被删除,但它只会降低果冻摇晃效果的平滑度。
最后一件事是重新计算高度并移动果冻,使其不会进入地面。
我肯定是透明的泥饼。如果有必要澄清,那么任何人都可以免费提问。
<强>样本强>
没有演示会有什么好的答案。这是一个果冻模拟。点击画布放下果冻。左上角的三个滑块控制值Wobbla,Bouncy和React。播放值以更改果冻效果。复选框打开和关闭粘性,但您需要一个长屏幕来获得弹跳所需的影响。删除cludge代码以查看粘性的真实目的。
因为我需要一个UI,所以有很多额外的代码不适用于答案。答案代码清楚标记,以便于查找。主循环位于底部。我还没有在FF上测试它,但它应该工作。如果没有让我知道,我会解决它。
var STOP = false; // stops the app
var jellyApp = function(){
/** Compiled by GROOVER Quick run 9:43pm DEC-22-2015 **/
/** fullScreenCanvas.js begin **/
var canvas = (function(){
var canvas = document.getElementById("canv");
if(canvas !== null){
document.body.removeChild(canvas);
}
// creates a blank image with 2d context
canvas = document.createElement("canvas");
canvas.id = "canv";
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.position = "absolute";
canvas.style.top = "0px";
canvas.style.left = "0px";
canvas.style.zIndex = 1000;
canvas.ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
return canvas;
})();
var ctx = canvas.ctx;
/** fullScreenCanvas.js end **/
/** MouseFull.js begin **/
var canvasMouseCallBack = undefined; // if needed
var mouse = (function(){
var mouse = {
x : 0, y : 0, w : 0, alt : false, shift : false, ctrl : false,
interfaceId : 0, buttonLastRaw : 0, buttonRaw : 0,
over : false, // mouse is over the element
bm : [1, 2, 4, 6, 5, 3], // masks for setting and clearing button raw bits;
getInterfaceId : function () { return this.interfaceId++; }, // For UI functions
startMouse:undefined,
};
function mouseMove(e) {
var t = e.type, m = mouse;
m.x = e.offsetX; m.y = e.offsetY;
if (m.x === undefined) { m.x = e.clientX; m.y = e.clientY; }
m.alt = e.altKey;m.shift = e.shiftKey;m.ctrl = e.ctrlKey;
if (t === "mousedown") { m.buttonRaw |= m.bm[e.which-1];
} else if (t === "mouseup") { m.buttonRaw &= m.bm[e.which + 2];
} else if (t === "mouseout") { m.buttonRaw = 0; m.over = false;
} else if (t === "mouseover") { m.over = true;
} else if (t === "mousewheel") { m.w = e.wheelDelta;
} else if (t === "DOMMouseScroll") { m.w = -e.detail;}
if (canvasMouseCallBack) { canvasMouseCallBack(m.x, m.y); }
e.preventDefault();
}
function startMouse(element){
if(element === undefined){
element = document;
}
"mousemove,mousedown,mouseup,mouseout,mouseover,mousewheel,DOMMouseScroll".split(",").forEach(
function(n){element.addEventListener(n, mouseMove);});
}
mouse.mouseStart = startMouse;
return mouse;
})();
if(typeof canvas === "undefined"){
mouse.mouseStart(canvas);
}else{
mouse.mouseStart();
}
/** MouseFull.js end **/
// unit size for rendering scale
var ep = canvas.height / 72;
// font constants
const FONT = "px Arial Black";
const FONT_SIZE = Math.ceil(3 * ep);
const GRAVITY = ep * (1/5);
const GROUND_AT = canvas.height - canvas.height * (1/20);
// Answer code.
//----------------------------------------------------------------------- // draw the jelly
function drawJelly(ctx){
var w,h;
w = this.w,
h = this.h;
h *= this.squashed;
// the width is ajusted so that the area of the rectagle remains constant
w = this.area / h; // to keep the area constant
ctx.drawImage(this.img,this.x - w / 2, this.y - h / 2, w, h);
}
function resetJelly(x,y){ // reset the jelly position
this.x = x;
this.y = y;
this.onGround = false;
this.dx = 0;
this.dy = 0;
}
// do the jelly math
function updateJelly(){
var h; // temp height
var hitG = false; // flag that the ground has just been hit
h = this.h * this.squashed; // get the height from squashed
if(!this.onGround){ // if not on the ground add grav
this.dy += GRAVITY;
}else{ // if on the ground move it so it touches correctly
this.dy = 0;
this.y = GROUND_AT - h / 2;
}
// update the position
this.x += this.dx;
this.y += this.dy;
// check if it has hit the ground
if(this.y + h / 2 >= GROUND_AT && this.dy >= 0){
this.hd += this.dy * this.react; // add the hit speed to the height delta
// multiply with react to inhance or reduce effect
this.force += this.dy * this.react;
hitG = true;
this.onGround = true; // flag that jelly is on the ground
}
if(this.force > 0){
this.hd += this.force;
this.force *= this.wobbla;
}
this.hd += (this.h - this.hr) * this.wobbla; // add wobbla to delta height
this.hd *= this.bouncy; // reduce bounce
this.hr += this.hd; // set the real height
this.squashed = this.h / this.hr; // calculate the new squashed amount
h = this.h * this.squashed; // recalculate hieght to make sure
// the jelly does not overlap the ground
// do the finnal position ajustment to avoid overlapping the ground
if(this.y + h / 2 >= GROUND_AT || hitG || (this.sticky && this.onGround)){
this.y = GROUND_AT - h / 2;
}
}
// create a jelly box
function createJellyBox(image,x, y, wobbla, bouncy, react){
return {
img:image,
x : x, // position
y : y,
dx : 0, // movement deltas
dy : 0,
w : image.width, // width
h : image.height, // height
area : image.width * image.height, // area
hr : image.height, // squashed height chaser
hd : 0, // squashed height delta
wobbla : wobbla, // higher values make it wobble more
bouncy : bouncy, // higher values make it react to change in speed
react : react, // additional reaction multiplier. < 1 reduces reaction > 1 increases reaction
onGround : false, // true if on the ground
sticky : true, // true to stick to the groun. false to let it bounce
squashed : 1, // the amount of squashing or streaching along the height
force : 0,
draw : drawJelly, // draw function
update : updateJelly, // update function
reset : resetJelly, // reset function
}
}
// --------------------------------------------------------------------------------------------
// END OF ANSWER CODE.
// FIND the usage at the bottom inside the main loop function.
// --------------------------------------------------------------------------------------------
// The following code is just helpers and UI stuff and are not related to the answer.
var createImage = function (w, h ){
var image = document.createElement("canvas");
image.width = w;
image.height = h;
image.ctx = image.getContext("2d");
return image;
}
var drawSky = function (img, col1, col2){
var c, w, h;
c = img.ctx;
w = img.width;
h = img.height;
var g = c.createRadialGradient(w * (1 / 2), h * (3 / 2), h * (1 / 2) +w * (1 / 4), w * (1 / 2), h * (3 / 2), h * (3 / 2) + w * ( 1 / 4));
g.addColorStop(0,col1);
g.addColorStop(1,col2);
c.fillStyle = g;
c.fillRect(0, 0, w, h);
return img;
}
var drawGround = function (img, col1, col2,lineColour, lineWidth) {
var c, w, h, lw;
c = img.ctx;
w = img.width;
h = img.height;
lw = lineWidth;
var g = c.createLinearGradient(0, 0, 0, h + lineWidth);
g.addColorStop(0, col1);
g.addColorStop(1, col2);
c.fillStyle = g;
c.lineWidth = lw;
c.strokeStyle = lineColour;
c.strokeRect(-lw * 2, lw / 2, w + lw * 4, h + lw * 4);
c.fillRect(-lw * 2, lw / 2, w + lw * 4, h + lw * 4);
return img;
}
/** CanvasUI.js begin **/
var drawRoundedBox = function (img, colour, rounding, lineColour, lineWidth) {
var c, x, y, w, h, r, p
p = Math.PI/2; // 90 deg
c = img.ctx;
w = img.width;
h = img.height;
lw = lineWidth;
r = rounding ;
c.lineWidth = lineWidth;
c.fillStyle = colour;
c.strokeStyle = lineColour;
c.beginPath();
c.arc(w - r - lw / 2, h - r - lw / 2, r, 0, p);
c.lineTo(r + lw / 2, h - lw / 2);
c.arc(r + lw / 2, h - r - lw / 2, r, p, p * 2);
c.lineTo(lw / 2, h - r - lw / 2);
c.arc(r + lw / 2, r + lw / 2, r, p * 2, p * 3);
c.lineTo(w-r - lw / 2, lw / 2);
c.arc(w - r - lw / 2, r + lw / 2, r, p * 3, p * 4);
c.closePath();
c.stroke();
c.fill();
return img;
}
var drawTick = function (img , col, lineColour, lineWidth){
var c, w, h, lw, m, l;
m = function (x, y) {c.moveTo(lw / 2 + w * x, lw / 2 + h * y);};
l = function (x, y) {c.lineTo(lw / 2 + w * x, lw / 2 + h * y);};
lw = lineWidth;
c = img.ctx;
w = img.width - lw;
h = img.height - lw;
c.fillStyle = col;
c.strokeStyle = lineColour;
c.lineWidth = lw;
c.beginPath();
m(1, 0);
l(5 / 8, 1);
l(0, 3 / 4);
l(1 / 4, 2 / 4);
l(2 / 4, 3 / 4);
l(1, 0);
c.stroke();
c.fill();
return img;
}
var setFont = function(ctx,font,align){
ctx.font = font;
ctx.textAlign = align;
}
var measureText = function(ctx,text){
return ctx.measureText(text).width;
}
var drawText = function(ctx,text,x,y,col,col1){
var of;
of = Math.floor(FONT_SIZE/10);
ctx.fillStyle = col1;
ctx.fillText(text,x+of,y+of);
ctx.fillStyle = col;
ctx.fillText(text,x,y);
}
var drawSlider = function(ctx){
var x,y;
x = this.owner.x;
y = this.owner.y;
ctx.drawImage(this.image, this.x + x, this.y + y);
ctx.drawImage(this.nob, this.nx + x, this.ny + y);
}
var updateSlider = function(mouse){
var mx, my;
mx = mouse.x - this.owner.x;
my = mouse.y - this.owner.y;
this.cursor = "";
if(this.owner.dragging === -1 || this.owner.dragging === this.id ){
if(mx >= this.x && mx < this.x + this.w &&
my >= this.y && my <= this.y + this.h){
this.mouseOver = true;
this.cursor = "pointer"
}else{
this.mouseOver = false;
}
if(mx >= this.nx && mx < this.nx + this.nw &&
my >= this.ny && my <= this.ny + this.nh){
this.mouseOverNob = true;
this.cursor = "ew-resize"
}else{
this.mouseOverNob = false;
}
if((mouse.buttonRaw&1) === 1 && (this.mouseOver||this.mouseOverNob) && !this.dragging){
this.owner.dragging = this.id;
this.dragging = true;
this.cursor = "ew-resize"
}else
if(this.dragging){
this.cursor = "ew-resize"
if((mouse.buttonRaw & 1)=== 0){
this.dragging = false;
this.owner.dragging = -1;
this.cursor = "pointer";
}
var p = mx- (this.x+this.nw/2);
p /= (this.w-this.nw);
p *= this.range;
p += this.min;
this.value = Math.min(this.max, Math.max(this.min, p));
}
if(this.mouseOver || this.mouseOverNob || this.dragging){
this.owner.toolTip = this.toolTip.replace("##",this.value.toFixed(this.decimals));
}
}
this.nx = (this.value - this.min) / this.range * (this.w - this.nw) + this.x;
}
var createSlider = function(image,nobImage, x, y, value, min, max, toolTip) {
var decimals = 0;
if(toolTip.indexOf("#.") > -1){
if(toolTip.indexOf(".DDD") > -1){
decimals = 3;
toolTip = toolTip.replace("#.DDD","##");
}else
if(toolTip.indexOf(".DD") > -1){
decimals = 2;
toolTip = toolTip.replace("#.DD","##");
}else
if(toolTip.indexOf(".D") > -1){
decimals = 1;
toolTip = toolTip.replace("#.D","##");
}else{
toolTip = toolTip.replace("#.","##");
}
}
return {
id : undefined,
image : image,
nob : nobImage,
min : min,
max : max,
x : x,
y : y + (nobImage.height - image.height)/2,
ny : y ,
nx : ((value - min) / (max - min)) * (image.width - nobImage.width) + x,
range : max - min,
w : image.width,
h : image.height,
nw : nobImage.width,
nh : nobImage.height,
value : value,
maxH : Math.max( image.height, nobImage.height),
mouseOver : false,
mouseOverNob : false,
toolTip:toolTip,
decimals:decimals,
dragging : false,
update : updateSlider,
draw : drawSlider,
position : function (x, y){
this.x += x;
this.y += y;
this.nx += x;
this.ny += y;
},
}
}
var drawTickCont = function(ctx){
var x,y, ofx, ofy;
x = this.owner.x;
y = this.owner.y;
ctx.drawImage(this.image, this.x + x, this.y + y);
ofy = this.h / 2 - this.textImage.height / 2;
ofx = this.w / 2;
ctx.drawImage(this.textImage, this.x + x + this.w + ofx, this.y + y + ofy);
if(this.value){
x -= this.tickImage.width * ( 1/ 4);
y -= this.tickImage.height * ( 2/ 5);
ctx.drawImage(this.tickImage, this.x + x, this.y + y);
}
}
var updateTick = function(mouse){
var mx, my;
mx = mouse.x - this.owner.x;
my = mouse.y - this.owner.y;
this.cursor = "";
if(this.owner.dragging === -1 || this.owner.dragging === this.id ){
if(mx >= this.x && mx < this.x + this.w &&
my >= this.y && my <= this.y + this.h){
this.mouseOver = true;
this.cursor = "pointer"
}else{
this.mouseOver = false;
}
if((mouse.buttonRaw&1) === 1 && this.mouseOver && !this.dragging){
this.owner.dragging = this.id;
this.dragging = true;
}else
if(this.dragging){
if((mouse.buttonRaw & 1)=== 0){
if(this.mouseOver){
this.value = ! this.value;
}
this.dragging = false;
this.owner.dragging = -1;
this.cursor = "pointer";
}
}
if(this.mouseOver || this.dragging){
this.owner.toolTip = this.toolTip;
}
}
}
var createTick= function(image,tickImage,textImage, x, y, value, toolTip) {
return {
id : undefined,
image : image,
tickImage : tickImage,
textImage : textImage,
x : x,
y : y,
w : image.width,
h : image.height,
value : value,
maxH : Math.max( image.height, tickImage.height),
mouseOver : false,
mouseOverNob : false,
toolTip:toolTip,
dragging : false,
update : updateTick,
draw : drawTickCont,
position : function (x, y){
this.x += x;
this.y += y;
},
}
}
function UI(ctx, mouse, x, y){
this.dragging = -1;
var ids = 0;
var controls = [];
var length = 0;
this.x = x;
this.y = y;
var posX = 0;
var posY = 0;
this.addControl = function (control, name) {
control.id = ids ++;
control.owner = this;
control.position(posX, posY);
posY += control.maxH + ep;
length = controls.push(control)
this[name] = control;
}
this.update = function(){
var i, cursor, c;
cursor = "";
this.toolTip = "";
for(i = 0; i < length; i ++){
c = controls[i];
c.update(mouse);
if(c.cursor !== ""){
cursor = c.cursor;
}
c.draw(ctx);
}
if(cursor === ""){
ctx.canvas.style.cursor = "default";
}else{
ctx.canvas.style.cursor = cursor;
}
if(this.toolTip !== ""){
if(mouse.y - FONT_SIZE * (5 / 3) < 0){
drawText(ctx, this.toolTip, mouse.x, mouse.y + FONT_SIZE * (4 / 3), "#FD4", "#000");
}else{
drawText(ctx, this.toolTip, mouse.x, mouse.y - FONT_SIZE * (2 / 3), "#FD4", "#000");
}
}
}
}
/** CanvasUI.js end **/
//-----------------------------
// create UI
//-----------------------------
setFont(ctx, FONT_SIZE + FONT, "left");
// images for UI
var tickBox = drawRoundedBox(createImage(4 * ep, 4 * ep), "#666", (3 / 2) * ep, "#000", (1 / 2) * ep);
var tickBoxTick = drawTick(createImage(6 * ep, 6 * ep), "#0D0", "#000", (1 / 2) * ep);
var w = measureText(ctx, "Sticky");
var tickBoxText = createImage(w, FONT_SIZE);
setFont(tickBoxText.ctx, FONT_SIZE + FONT, "left");
drawText(tickBoxText.ctx, "Sticky", 0, FONT_SIZE * (3 / 4), "white", "black");
var sliderBar = drawRoundedBox(createImage(20 * ep, 2 * ep), "#666", ep * 0.9, "#000", (1 / 2) * ep);
var sliderNob = drawRoundedBox(createImage(3 * ep, 4 * ep), "#AAA", ep, "#000", (1 / 2) * ep);
// UI control
var controls = new UI(ctx, mouse, 10, 10);
controls.addControl(createSlider(sliderBar, sliderNob, 0, 0, 0.3, 0, 1, "Wobbla #.DD"), "wobbla");
controls.addControl(createSlider(sliderBar, sliderNob, 0, 0, 0.8, 0, 1, "Bouncy #.DD"), "bouncy");
controls.addControl(createSlider(sliderBar, sliderNob, 0, 0, 1.5, 0, 2, "React #.DD"), "react");
controls.addControl(createTick(tickBox, tickBoxTick, tickBoxText, 0, 0, true, "Activate / Deactivate sticky option."), "sticky");
//-----------------------------
// create playfield
//-----------------------------
var skyImage = drawSky(createImage(32, 32), "#9EF", "#48D");
var groundImage = drawGround(createImage(100, canvas.height - GROUND_AT), "#5F5", "#5A5", "#181", 4);
//-----------------------------
// create jelly
//-----------------------------
var jellyImage = drawRoundedBox(createImage(ep * 20, ep * 20), "#FA4", ep * 2, "black", ep * (3 / 5));
var jelly = createJellyBox(
jellyImage,
canvas.width / 2,
100,
0.1,
0.8,
1.2
);
// some more settings
ctx.imageSmoothingEnabled = true;
setFont(ctx, FONT_SIZE + FONT, "left");
//-----------------------------
// Main animtion loop
//-----------------------------
function updateAnim(){
// draw the background and ground
ctx.drawImage(skyImage, 0, 0, canvas.width, canvas.height)
ctx.drawImage(groundImage, 0, GROUND_AT, canvas.width, canvas.height - GROUND_AT)
// update and draw jelly
jelly.update();
jelly.draw(ctx);
// update and draw controls
controls.update();
// update jelly setting from controls.
jelly.wobbla = controls.wobbla.value;
jelly.bouncy = controls.bouncy.value;
jelly.react = controls.react.value;
jelly.sticky = controls.sticky.value;
// if the mouse is not busy then use left mouse click and drag to position jellu
if(controls.dragging < 0 && mouse.buttonRaw === 1){
controls.dragging = -2;
jelly.reset(mouse.x,mouse.y);
}else
if(controls.dragging === -2){ // release mouse
controls.dragging = -1;
}
if(!STOP){
requestAnimationFrame(updateAnim);
}else{
STOP = false;
}
}
updateAnim();
};
function resizeEvent(){
var waitForStopped = function(){
if(!STOP){ // wait for stop to return to false
jellyApp();
return;
}
setTimeout(waitForStopped,200);
}
STOP = true;
setTimeout(waitForStopped,100);
}
window.addEventListener("resize",resizeEvent);
jellyApp();