Function Tetris Game
This commit is contained in:
commit
77f86318c7
11 changed files with 443 additions and 0 deletions
13
Fraction.js
Normal file
13
Fraction.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
Fraction = {
|
||||||
|
decimalToFraction: function(decimal){
|
||||||
|
//example dec2Frac(2/9)
|
||||||
|
//reciprocal = 9/2 = 4.5
|
||||||
|
var reciprocal = 1/decimal;
|
||||||
|
|
||||||
|
var multiplier = 1;
|
||||||
|
while (reciprocal * multiplier % 1 != 0){
|
||||||
|
multipler++;
|
||||||
|
}
|
||||||
|
return {multiplier, multiplier*reciprocal};
|
||||||
|
}
|
||||||
|
}
|
15
Game.js
Normal file
15
Game.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
//variables and functions for game state
|
||||||
|
Game = {
|
||||||
|
currentLine: undefined,
|
||||||
|
currentLevel: undefined,
|
||||||
|
level: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Game.parabula = {
|
||||||
|
fh: function () {
|
||||||
|
return Math.floor(Math.random() * 9 - 4);
|
||||||
|
},
|
||||||
|
fk: function () {
|
||||||
|
return Math.floor(Math.random() * 5 - 3);
|
||||||
|
}
|
||||||
|
}
|
264
Graph.js
Normal file
264
Graph.js
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
function Graph(config) {
|
||||||
|
// user defined properties
|
||||||
|
this.minX = config.minX;
|
||||||
|
this.minY = config.minY;
|
||||||
|
this.maxX = config.maxX;
|
||||||
|
this.maxY = config.maxY;
|
||||||
|
this.unitsPerTick = config.unitsPerTick;
|
||||||
|
this.centerY = config.centerY; /*center x and y is the "origin" of the graph relative to canvas location*/
|
||||||
|
this.centerX = config.centerX;
|
||||||
|
// constants
|
||||||
|
this.canvas = document.getElementById('myCanvas');
|
||||||
|
this.tickSize = 20;
|
||||||
|
// relationships
|
||||||
|
this.context = this.canvas.getContext('2d');
|
||||||
|
this.rangeX = this.maxX - this.minX;
|
||||||
|
this.rangeY = this.maxY - this.minY;
|
||||||
|
this.unitX = this.canvas.width / this.rangeX;
|
||||||
|
this.unitY = this.canvas.height / this.rangeY;
|
||||||
|
this.iteration = (this.maxX - this.minX) / 1000;
|
||||||
|
this.scaleX = this.canvas.width / this.rangeX;
|
||||||
|
this.scaleY = this.canvas.height / this.rangeY;
|
||||||
|
this.XmaxUnit;
|
||||||
|
this.XminUnit;
|
||||||
|
/////////////change, added next 3 vars
|
||||||
|
this.shiftAmount;
|
||||||
|
this.shiftIncrement;
|
||||||
|
this.timeInterval;
|
||||||
|
// draw x and y axis
|
||||||
|
this.drawXAxis();
|
||||||
|
this.drawYAxis();
|
||||||
|
this.drawGrid();
|
||||||
|
this.getImage();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Graph.prototype.drawXAxis = function () {
|
||||||
|
var context = this.context;
|
||||||
|
context.save();
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(0, this.centerY);
|
||||||
|
context.lineTo(this.canvas.width, this.centerY);
|
||||||
|
context.strokeStyle = 'rgb(25,75,160)';
|
||||||
|
context.lineWidth = 4;
|
||||||
|
context.stroke();
|
||||||
|
context.restore();
|
||||||
|
};
|
||||||
|
|
||||||
|
Graph.prototype.drawYAxis = function () {
|
||||||
|
var context = this.context;
|
||||||
|
context.save();
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(this.centerX, 0);
|
||||||
|
context.lineTo(this.centerX, this.canvas.height);
|
||||||
|
context.strokeStyle = 'rgb(25,75,160)';
|
||||||
|
context.lineWidth = 4;
|
||||||
|
context.stroke();
|
||||||
|
context.restore();
|
||||||
|
};
|
||||||
|
|
||||||
|
Graph.prototype.drawGrid = function () {
|
||||||
|
var context = this.context;
|
||||||
|
context.save();
|
||||||
|
context.beginPath();
|
||||||
|
context.strokeStyle = '#8c8c8c';
|
||||||
|
context.fillStyle = 'white';
|
||||||
|
console.log(context.canvas.width)
|
||||||
|
context.fillRect(0, 0, context.canvas.width, context.canvas.length);
|
||||||
|
context.lineWidth = 2;
|
||||||
|
|
||||||
|
// Sets up x coordinate tick marks
|
||||||
|
var xPosIncrement = this.unitsPerTick * this.unitX;
|
||||||
|
var xPos, unit;
|
||||||
|
context.font = '12pt Ubuntu';
|
||||||
|
context.textAlign = 'left';
|
||||||
|
context.textBaseline = 'top';
|
||||||
|
|
||||||
|
// draws vertical lines before x = 0
|
||||||
|
xPos = this.centerX - xPosIncrement;
|
||||||
|
unit = -1 * this.unitsPerTick;
|
||||||
|
while (xPos > 0) {
|
||||||
|
context.moveTo(xPos, this.centerY - this.tickSize / 2);
|
||||||
|
context.lineTo(xPos, this.canvas.height);
|
||||||
|
context.lineTo(xPos, -this.canvas.height);
|
||||||
|
context.stroke();
|
||||||
|
context.fillText(unit, xPos, this.centerY + this.tickSize / 2 + 3);
|
||||||
|
unit -= this.unitsPerTick;
|
||||||
|
xPos = Math.round(xPos - xPosIncrement);
|
||||||
|
this.XminUnit = unit;
|
||||||
|
}
|
||||||
|
if (this.XminUnit === undefined) {
|
||||||
|
this.XminUnit = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// draws vertical lines after x = 0
|
||||||
|
xPos = this.centerX + xPosIncrement;
|
||||||
|
unit = this.unitsPerTick;
|
||||||
|
while (xPos < this.canvas.width) {
|
||||||
|
context.moveTo(xPos, this.centerY - this.tickSize / 2);
|
||||||
|
context.lineTo(xPos, this.canvas.height);
|
||||||
|
context.lineTo(xPos, -this.canvas.height);
|
||||||
|
context.stroke();
|
||||||
|
context.fillText(unit, xPos, this.centerY + this.tickSize / 2 + 3);
|
||||||
|
unit += this.unitsPerTick;
|
||||||
|
xPos = Math.round(xPos + xPosIncrement);
|
||||||
|
this.XmaxUnit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets up Y coordinate tick marks
|
||||||
|
var yPosIncrement = this.unitsPerTick * this.unitY;
|
||||||
|
var yPos, unit;
|
||||||
|
context.font = '12pt Ubuntu';
|
||||||
|
context.textAlign = 'right';
|
||||||
|
context.textBaseline = 'bottom';
|
||||||
|
// draws horizontal lines after y = 0
|
||||||
|
yPos = this.centerY - yPosIncrement;
|
||||||
|
unit = this.unitsPerTick;
|
||||||
|
while (yPos > 0) {
|
||||||
|
context.moveTo(this.centerX - this.tickSize / 2, yPos);
|
||||||
|
context.lineTo(this.canvas.width, yPos);
|
||||||
|
context.lineTo(-this.canvas.width, yPos);
|
||||||
|
context.stroke();
|
||||||
|
context.fillText(unit, this.centerX - this.tickSize / 2 - 3, yPos);
|
||||||
|
unit += this.unitsPerTick;
|
||||||
|
yPos = Math.round(yPos - yPosIncrement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draws horizontal lines before y = 0
|
||||||
|
yPos = this.centerY + yPosIncrement;
|
||||||
|
unit = -1 * this.unitsPerTick;
|
||||||
|
while (yPos < this.canvas.height) {
|
||||||
|
context.moveTo(this.centerX - this.tickSize / 2, yPos);
|
||||||
|
context.lineTo(this.canvas.width, yPos);
|
||||||
|
context.lineTo(-this.canvas.width, yPos);
|
||||||
|
context.stroke();
|
||||||
|
context.fillText(unit, this.centerX - this.tickSize / 2 - 3, yPos);
|
||||||
|
unit -= this.unitsPerTick;
|
||||||
|
yPos = Math.round(yPos + yPosIncrement);
|
||||||
|
}
|
||||||
|
context.restore();
|
||||||
|
};
|
||||||
|
|
||||||
|
Graph.prototype.drawEquation = function (equation) {
|
||||||
|
var context = this.context;
|
||||||
|
context.save();
|
||||||
|
this.transformContext();
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(this.XminUnit, equation(this.XminUnit));
|
||||||
|
for (var x = this.XminUnit + this.iteration; x <= this.XmaxUnit; x += this.iteration) {
|
||||||
|
context.lineTo(x, equation(x));
|
||||||
|
}
|
||||||
|
context.restore();
|
||||||
|
context.lineJoin = 'round';
|
||||||
|
context.lineWidth = 3;
|
||||||
|
context.strokeStyle = 'red';
|
||||||
|
/////////////--Added for no spacing in regular lines
|
||||||
|
context.setLineDash([1, 0]);
|
||||||
|
context.stroke();
|
||||||
|
context.restore();
|
||||||
|
};
|
||||||
|
Graph.prototype.drawdottedEquation = function (equation) {
|
||||||
|
var context = this.context;
|
||||||
|
context.save();
|
||||||
|
this.transformContext();
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(this.XminUnit, equation(this.XminUnit));
|
||||||
|
for (var x = this.XminUnit + this.iteration; x <= this.XmaxUnit; x += this.iteration) {
|
||||||
|
context.lineTo(x, equation(x));
|
||||||
|
}
|
||||||
|
context.restore();
|
||||||
|
context.lineJoin = 'round';
|
||||||
|
context.lineWidth = 3;
|
||||||
|
context.strokeStyle = 'red';
|
||||||
|
context.setLineDash([5]);
|
||||||
|
context.stroke();
|
||||||
|
context.restore();
|
||||||
|
};
|
||||||
|
|
||||||
|
Graph.prototype.drawPoint = function (goalx, goaly) {
|
||||||
|
var context = this.context;
|
||||||
|
context.save();
|
||||||
|
this.transformContext();
|
||||||
|
context.beginPath();
|
||||||
|
var c = document.getElementById("myCanvas");
|
||||||
|
var img = document.getElementById("balloon");
|
||||||
|
context.drawImage(img, goalx - 0.32, goaly - 0.48, 0.64, 0.96);
|
||||||
|
context.stroke();
|
||||||
|
context.restore();
|
||||||
|
};
|
||||||
|
|
||||||
|
//sets context to origin
|
||||||
|
Graph.prototype.transformContext = function () {
|
||||||
|
var context = this.context;
|
||||||
|
this.context.translate(this.centerX, this.centerY);
|
||||||
|
context.scale(this.scaleX, -this.scaleY);
|
||||||
|
};
|
||||||
|
///////////////deprecated
|
||||||
|
Graph.prototype.reset = function () {
|
||||||
|
var context = this.context;
|
||||||
|
context.save();
|
||||||
|
context.fillStyle = 'black';
|
||||||
|
context.fillRect(0, 0, myCanvas.width, myCanvas.height);
|
||||||
|
/*
|
||||||
|
this.drawXAxis();
|
||||||
|
this.drawYAxis();
|
||||||
|
this.drawGrid();*/
|
||||||
|
context.restore();
|
||||||
|
};
|
||||||
|
//////////////
|
||||||
|
Graph.prototype.printGrid = function () {
|
||||||
|
var context = this.context;
|
||||||
|
context.save();
|
||||||
|
var currentImage = context.getImageData(0, 0, context.canvas.width, context.canvas.height);
|
||||||
|
};
|
||||||
|
////////////
|
||||||
|
Graph.prototype.getImage = function () {
|
||||||
|
this.image = this.context.getImageData(0, 0, this.context.canvas.width, this.context.canvas.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////----First test animator, example
|
||||||
|
Graph.prototype.animateLine = function (line, mode, frameRate) {
|
||||||
|
console.log('animate');
|
||||||
|
line.falling = true;
|
||||||
|
var context = this.context
|
||||||
|
//for test, currentLevel is Quadratic; LEVEL NAME MUST MATCH DIV INPUT NAME
|
||||||
|
Game.currentLevel = 'Quadratic';
|
||||||
|
var divSelector = "#" + Game.currentLevel + " #";
|
||||||
|
Game.currentLine = line;
|
||||||
|
|
||||||
|
this.animator = window.setInterval(
|
||||||
|
function () {
|
||||||
|
//update vals in input boxes
|
||||||
|
$(divSelector + "vShift").val(Math.round(line.goalvShift * 10 + line.shiftAmount * 10) / 10);
|
||||||
|
$(divSelector + "vStretch").val(line.vStretch);
|
||||||
|
$(divSelector + "hStretch").val(line.hStretch);
|
||||||
|
$(divSelector + "hShift").val(line.goalhShift + line.hShift);
|
||||||
|
|
||||||
|
|
||||||
|
//setting up each frame of the graph
|
||||||
|
line.graph.context.putImageData(line.graph.image, 0, 0);
|
||||||
|
line.graph.drawdottedEquation(line.equation);
|
||||||
|
line.graph.drawEquation(function (x) {
|
||||||
|
return line.vStretch * line.equation(x / line.hStretch + line.hShift) + line.shiftAmount;
|
||||||
|
});
|
||||||
|
//line.shiftAmount = Math.round(line.shiftAmount - line.shiftIncrement);
|
||||||
|
|
||||||
|
line.shiftAmount = Math.round(line.shiftAmount * 10 - line.shiftIncrement * 10) / 10;
|
||||||
|
|
||||||
|
//ending the animation at bottom (before the curve goes one more increment below 0)
|
||||||
|
if (line.hShift == 0 && line.vShift == (line.shiftAmount + line.vShift + line.shiftIncrement)) {
|
||||||
|
window.clearInterval(line.graph.animator);
|
||||||
|
Game.currentLine = undefined;
|
||||||
|
line.falling = false;
|
||||||
|
Game.level++;
|
||||||
|
playLevel();
|
||||||
|
} else if (line.shiftAmount < 0 - line.shiftIncrement) {
|
||||||
|
window.clearInterval(line.graph.animator);
|
||||||
|
Game.currentLine = undefined;
|
||||||
|
line.falling = false;
|
||||||
|
alert("You lose . . . . You made it to Level " + Game.level);
|
||||||
|
Game.level = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 1000 / frameRate);
|
||||||
|
};
|
25
Line.js
Normal file
25
Line.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*an actual object for lines
|
||||||
|
includes equation with shifting
|
||||||
|
|
||||||
|
animation function is in Graph.js, accepts a line object and animates it
|
||||||
|
*/
|
||||||
|
function Line(config) {
|
||||||
|
|
||||||
|
this.equation = config.equation;
|
||||||
|
this.hShift = config.hShift; //specified like in regular graphing, positive goes to left, negative to right
|
||||||
|
this.vShift = config.vShift;
|
||||||
|
this.hStretch = 1;
|
||||||
|
this.vStretch = 1;
|
||||||
|
|
||||||
|
this.goalhShift = this.hShift;
|
||||||
|
this.goalvShift = this.vShift;
|
||||||
|
|
||||||
|
this.graph = config.graph;
|
||||||
|
//console.log('new line');
|
||||||
|
this.shiftIncrement = 0.2; //amount of change in animation frame
|
||||||
|
this.shiftAmount = 5; //starting vertical shift amount, height of falling graph above goal graph
|
||||||
|
this.stretchFactor;
|
||||||
|
//var for state
|
||||||
|
this.falling = false;
|
||||||
|
this.graph.drawdottedEquation(this.equation);
|
||||||
|
}
|
57
Script.js
Normal file
57
Script.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
var parabola;
|
||||||
|
var start = function () {
|
||||||
|
document.getElementById('myCanvas').width = window.innerWidth; //Sets size of Width
|
||||||
|
document.getElementById('myCanvas').height = window.innerHeight; //Sets size of Height
|
||||||
|
//Creates graph
|
||||||
|
myGraph = new Graph({
|
||||||
|
centerY: window.innerHeight / 2,
|
||||||
|
centerX: window.innerWidth / 2,
|
||||||
|
minX: 0,
|
||||||
|
minY: 0,
|
||||||
|
maxX: window.innerWidth / (window.innerHeight / 10),
|
||||||
|
maxY: 10,
|
||||||
|
unitsPerTick: 1
|
||||||
|
});
|
||||||
|
playLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
var playLevel = function () {
|
||||||
|
Game.parabula.h = Game.parabula.fh();
|
||||||
|
Game.parabula.k = Game.parabula.fk();
|
||||||
|
parabola = new Line({
|
||||||
|
equation: function (x) {
|
||||||
|
return Math.pow((x + Game.parabula.h), 2) + Game.parabula.k;
|
||||||
|
},
|
||||||
|
//positive, shift left to origin
|
||||||
|
hShift: Game.parabula.h,
|
||||||
|
vShift: Game.parabula.k,
|
||||||
|
graph: myGraph
|
||||||
|
})
|
||||||
|
myGraph.animateLine(parabola, 0, Game.level * 2 + 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
//document object checks for arrow key presses
|
||||||
|
$(document).on('keyup', function (e) {
|
||||||
|
//only works if a current line is set, and said line is falling (animating)
|
||||||
|
if (Game.currentLine.falling) {
|
||||||
|
switch (e.which) {
|
||||||
|
case 37: //left arrow
|
||||||
|
//shift the line one unit left
|
||||||
|
Game.currentLine.hShift += 1;
|
||||||
|
break;
|
||||||
|
case 38: //up arrow
|
||||||
|
//only if line is sliding horizontally
|
||||||
|
Game.currentLine.shiftAmount += 1;
|
||||||
|
break;
|
||||||
|
case 39: //right arrow
|
||||||
|
Game.currentLine.hShift -= 1;
|
||||||
|
break;
|
||||||
|
case 40: //down arrow
|
||||||
|
Game.currentLine.shiftAmount -= 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$(document).ready(start);
|
42
StyleSheet.css
Normal file
42
StyleSheet.css
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
html {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'ZeroesCondensed';
|
||||||
|
src: url('zeroes one.ttf');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Zeroes';
|
||||||
|
src: url('zeroes three.ttf');
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
background-color: black;
|
||||||
|
/*important for getting it to fit right*/
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
div.input {
|
||||||
|
z-index: 2;
|
||||||
|
position: fixed;
|
||||||
|
top: 6%;
|
||||||
|
left: 6%;
|
||||||
|
right: 0%;
|
||||||
|
text-align: center;
|
||||||
|
font-family: Zeroes;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 1.5em;
|
||||||
|
background-color: rgba(134, 238, 238, 0.6);
|
||||||
|
border-color: #BFBFBF;
|
||||||
|
border-radius: 15px;
|
||||||
|
border-width: medium;
|
||||||
|
padding: 5px;
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
div.input input {
|
||||||
|
width: 10%;
|
||||||
|
font-size: 1em;
|
||||||
|
font-family: Zeroes;
|
||||||
|
}
|
23
index.html
Normal file
23
index.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Tetris Game</title>
|
||||||
|
<link rel="stylesheet" href="StyleSheet.css"> </link>
|
||||||
|
<script src="jquery.js"> </script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="myCanvas" width="578" height="300"></canvas>
|
||||||
|
<div class="input" id="Quadratic">
|
||||||
|
<input id = "vStretch" type="text"/>
|
||||||
|
(<input id = "hStretch" type="text"/> X +
|
||||||
|
<input id = "hShift" type="text"/>)^2 +
|
||||||
|
<input id = "vShift" type="text"/>
|
||||||
|
</div>
|
||||||
|
<script src = "Game.js"></script>
|
||||||
|
<script src="Graph.js"></script>
|
||||||
|
<script src = "Line.js"></script>
|
||||||
|
<script src="Script.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
4
jquery.js
vendored
Normal file
4
jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
zeroes one.ttf
Normal file
BIN
zeroes one.ttf
Normal file
Binary file not shown.
BIN
zeroes three.ttf
Normal file
BIN
zeroes three.ttf
Normal file
Binary file not shown.
BIN
zeroes two.ttf
Normal file
BIN
zeroes two.ttf
Normal file
Binary file not shown.
Reference in a new issue