xxxxxxxxxx
545
// this is a randomly generated maze with a player that can be freely navigated
// in this iteration I want to add a portal with a number on it, number pickups scattered around and the ability to pickup and drop items.
nunits = 5;
maxfactor = 10;
factormode = 1 ; // 0: look for factors. 1: look for products
//global constants
let space;
let rightborder, downboarder;
let rows, columns;
let winstate = 0; // 0 = playing 1 = win 2 = lose
let pickuplist = [];
let mazemap; //0 = empty -1 = portal other integers = index of pickup
let portal, hero;
// utility functions
function initArray(rows, columns, value){
//create a dynamic array of size rows x columns and fill it with values
let a = new Array(rows);
for (var i=0;i<a.length;i++){
a[i] = new Array(columns);
for (var j=0;j<a[i].length;j++){
a[i][j] = value;
}
}
return a;
}
function rand(maxval){
return ~~(Math.random()*maxval);
}
// classes
class Portal{
constructor(row, col, factor1, factor2){
this.row = row;
this.col = col;
this.toggle = 0;
this.blinkspeed = 10;
this.factor1 = factor1;
this.factor2 = factor2;
this.value = 1;
if (factormode==0){
this.string = (factor1*factor2).toString();
} else {
this.string = factor1.toString() + ' x ' + factor2.toString();
}
this.state = 0;//modes: 0: initial state 1: intermediate state (something in the portal but expecting more 2: correct state 3: wrong state)
this.intermediate='';
mazemap[row][col] = -1;
}
drop(value){
this.value = this.value*value;
if (this.value==this.factor1*this.factor2){
winstate = 1;
}
else {
if (factormode==1){
winstate = 2;
}
else {
if (this.state==0){
this.state = 1;
this.intermediate = value.toString();
}
else {
winstate = 2;
}
}
}
}
draw(){
mazemap[this.row][this.col] = -1;
[x1,y1] = topleftpoint(this.row, this.col);
[x2,y2] = bottomrightpoint(this.row, this.col);
x1 = x1 + space/10;
y1 = y1+space/10;
x2 = x2-space/10;
y2 = y2-space/10;
this.toggle++;
if (this.toggle<this.blinkspeed){
if (this.state==0){
stroke(0);
} else if (this.state==1){
stroke(100,0,200);
} else if (this.state==2){
stroke(0,200,100);
} else {
stroke(255,0,0);
}
fill(255);
}
else if (this.toggle<this.blinkspeed*2){
stroke(255);
fill(0);
}
else if (this.toggle==this.blinkspeed*2){
this.toggle=0;
}
strokeWeight(space/20);
//fill(100,0,255);
rectMode(CORNERS);
rect(x1,y1,x2,y2);
if (this.toggle<this.blinkspeed){
fill(0);
} else {
fill(255);
}
textAlign(CENTER);
[x1,y1] = middlepoint(this.row, this.col);
strokeWeight(space/30);
if (factormode==0){
textSize(space/2.5);
text(this.string,x1,y1+space/8);
}
else {
textSize(space/4);
text(this.string, x1, y1);
}
if (this.state==1){
textSize(space/4);
strokeWeight(0);
fill(0,200,100);
[x1,y1] = bottomrightpoint(this.row, this.col);
text(this.intermediate, x1-space/5, y1-space/5);
}
}
}
class Pickup{
constructor(string, index){
[row, col] = getEmpty();
this.row = row;
this.col = col;
this.string = string;
this.index = index;
this.portaled = 0; //determines if the pickup is in the portal or not
mazemap[row][col] = index;
}
draw(){
if (this.portaled==0){
mazemap[this.row][this.col] = this.index;
}
[x1, y1] = topleftpoint(this.row, this.col);
[x2, y2] = bottomrightpoint(this.row, this.col);
x1 = x1+space/5;
y1 = y1+space/5;
x2 = x2-space/5;
y2 = y2-space/5;
strokeWeight(space/7);
fill(150,100,0);
stroke(100,50,0);
rect(x1,y1, x2,y2);
[x1,y1] = middlepoint(this.row, this.col);
stroke(0);
strokeWeight(space/30);
fill(0);
textSize(space/3);
text(this.string, x1,y1+space/10);
}
}
class Hero{
constructor(row, col, orientation){
this.row = row;
this.col = col;
this.dir = orientation;
this.pickupstate = 0;
this.toggle=0;
this.blinkspeed = 10;
this.pickupindex = -1;
this.string = "";
}
goLeft(){
this.dir = 2;
if (this.col>0 && rightborder[this.row][this.col-1]==0){
if (this.pickupstate==0){
this.col = this.col-1;
} else {
if (mazemap[this.row][this.col-1]<=0){
this.col = this.col-1;
pickuplist[this.pickupindex].row = this.row;
pickuplist[this.pickupindex].col = this.col;
}
}
}
}
goRight(){
this.dir = 3;
if (this.col<columns-1 && rightborder[this.row][this.col]==0){
if (this.pickupstate==0){
this.col = this.col+1;
} else {
if (mazemap[this.row][this.col+1]<=0){
this.col = this.col+1;
pickuplist[this.pickupindex].row = this.row;
pickuplist[this.pickupindex].col = this.col;
}
}
}
}
goUp(){
this.dir = 0;
if (this.row>0 && downborder[this.row-1][this.col]==0){
if (this.pickupstate==0){
this.row = this.row-1;
} else {
if (mazemap[this.row-1][this.col]<=0){
this.row = this.row-1;
pickuplist[this.pickupindex].row = this.row;
pickuplist[this.pickupindex].col = this.col;
}
}
}
}
goDown(){
this.dir = 1;
if (this.row<rows-1 && downborder[this.row][this.col]==0){
if (this.pickupstate==0){
this.row = this.row+1;
} else {
if (mazemap[this.row+1][this.col]<=0){
this.row = this.row+1;
pickuplist[this.pickupindex].row = this.row;
pickuplist[this.pickupindex].col = this.col;
}
}
}
}
pickUp(){
if (mazemap[this.row][this.col]>0){
this.pickupstate = 1;
this.pickupindex = mazemap[this.row][this.col];
this.string = pickuplist[this.pickupindex].string;
}
}
drop(){
if (this.pickupstate==1){
this.pickupstate=0;
if (portal.row==this.row && portal.col == this.col){
portal.drop(pickuplist[this.pickupindex].string);
}
}
}
draw(){
// directions 0: top 1: bottom 2: left 3: right
let x,y;
[x,y] = middlepoint(this.row,this.col);
stroke(0);
strokeWeight(max(space/20,1));
fill(70,100,170);
if (this.dir==0){
x1 = x-space/8;
x2 = x+space/8;
y1 = y-space/2.5;
y2 = y-space/2.5;
}
if (this.dir==1){
x1 = x-space/8;
x2 = x+space/8;
y1 = y+space/2.5;
y2 = y+space/2.5;
}
if (this.dir==2){
x1 = x-space/2.5;
x2 = x-space/2.5;
y1 = y-space/8;
y2 = y+space/8;
}
if (this.dir==3){
x1 = x+space/2.5;
x2 = x+space/2.5;
y1 = y-space/8;
y2 = y+space/8;
}
triangle(x,y,x1,y1, x2,y2);
fill(50,250,250);
if (this.pickupstate==0){
stroke(0);
strokeWeight(max(space/20,1));
circle(x,y,space/1.5);
} else {
strokeWeight(max(space/10,1));
stroke(0,100,150)
circle(x,y, space/1.5);
[x,y] = middlepoint(this.row, this.col);
textAlign(CENTER);
strokeWeight(space/20);
fill(0);
textSize(space/3);
text(this.string.toString(), x, y);
}
}
}
// maze generation
function generateMaze(){
i = rand(rows);
j = rand(columns);
visited = initArray(rows,columns,0);
mazeiter(i,j,visited);
}
function mazeiter(r,c,visited){
visited[r][c] = 1;
while (true){
neighbours = [];
if (r>0){
if (visited[r-1][c]==0){
neighbours[neighbours.length] = [r-1,c];
}
}
if (c>0){
if (visited[r][c-1]==0){
neighbours[neighbours.length] = [r,c-1];
}
}
if (r<rows-1){
if (visited[r+1][c]==0){
neighbours[neighbours.length] = [r+1,c];
}
}
if (c<columns-1){
if (visited[r][c+1]==0){
neighbours[neighbours.length] = [r,c+1];
}
}
if (neighbours.length>0){
index = rand(neighbours.length);
[nr,nc] = neighbours[index];
if (r==nr){
rightborder[r][min(c,nc)] = 0;
}
if (c==nc){
downborder[min(r,nr)][c] = 0;
}
mazeiter(nr,nc,visited);
}
else {
break;
}
}
}
// drawing functions
function topleftpoint(row, col){
return [col*space,row*space];
}
function toprightpoint(row, col){
return [(col+1)*space, row*space];
}
function bottomleftpoint(row, col){
return [col*space, (row+1)*space];
}
function bottomrightpoint(row, col){
return [(col+1)*space, (row+1)*space];
}
function middlepoint(row, col){
return [col*space + space/2, row*space+space/2];
}
function drawWin(){
rectMode(CORNERS);
stroke(0,200,150);
strokeWeight(space/2);
fill(255,255,255);
rect(windowWidth/4, windowHeight/4, windowWidth*3/4, windowHeight*3/4);
textSize(windowWidth/10);
strokeWeight(0);
fill(0,200,150);
textAlign(CENTER);
text('You Win!', windowWidth/2, windowHeight/2);
}
function drawLose(){
rectMode(CORNERS);
stroke(255,0,0);
strokeWeight(space/2);
fill(255,255,255);
rect(windowWidth/4, windowHeight/4, windowWidth*3/4, windowHeight*3/4);
textSize(windowWidth/10);
strokeWeight(0);
fill(255,0,0);
textAlign(CENTER);
text('You Lose!', windowWidth/2, windowHeight/2);
}
function drawBorder(){
[x1,y1] = topleftpoint(0,0);
[x2,y2] = toprightpoint(0,columns-1);
[x3,y3] = bottomrightpoint(rows-1, columns-1);
[x4,y4] = bottomleftpoint(rows-1,0);
strokeWeight(space/4);
stroke(0);
line(x1,y1,x2,y2);
line(x2,y2,x3,y3);
line(x3,y3,x4,y4);
line(x4,y4,x1,y1);
}
function drawMaze(){
stroke(0);
strokeWeight(max(space/8,1));
for (var i=0;i<rows;i++){
for (var j=0;j<columns;j++){
if (rightborder[i][j]==1){
[x1,y1] = toprightpoint(i,j);
[x2, y2] = bottomrightpoint(i,j);
line(x1,y1,x2,y2);
}
if (downborder[i][j]==1){
[x1,y1] = bottomleftpoint(i,j);
[x2,y2] = bottomrightpoint(i,j);
line(x1,y1,x2,y2);
}
}
}
}
// game functions
// function checkGameState(){
// if (hero.row==portal.row && hero.col==portal.col){
// winstate = 1;
// }
// }
function getEmpty(){
while(true){
row = rand(rows);
col = rand(columns);
if (mazemap[row][col] ==0){
return [row, col];
}
}
}
//pygame functions
function setup() {
createCanvas(windowWidth, windowHeight);
// determine maze constants
var dimension = min(windowWidth, windowHeight);
space = dimension/nunits;
// rows go vertically and columns go horizontally
rows = ~~(windowHeight/space);
columns = ~~(windowWidth/space);
rightborder = initArray(rows, columns, 1);
downborder = initArray(rows, columns, 1);
mazemap = initArray(rows, columns,0);
generateMaze();
[heroRow, heroCol] = getEmpty();
hero = new Hero(heroRow, heroCol, 0);
factor1 = rand(maxfactor);
factor2 = rand(maxfactor);
[row, col] = getEmpty();
portal = new Portal(row, col, factor1, factor2);
pickuplist[0] = 0; //otherwise it will mess with mazemap
if (factormode==0){
pickuplist[pickuplist.length] = new Pickup(factor1, pickuplist.length);
pickuplist[pickuplist.length] = new Pickup(factor2, pickuplist.length);
while(pickuplist.length<rows){
pickuplist[pickuplist.length] = new Pickup(rand(maxfactor), pickuplist.length);
}
}
if (factormode==1){
pickuplist[pickuplist.length] = new Pickup(factor1*factor2, pickuplist.length);
while(pickuplist.length<rows){
pickuplist[pickuplist.length] = new Pickup(rand(maxfactor)*rand(maxfactor), pickuplist.length);
}
}
}
function draw() {
mazemap = initArray(rows, columns,0);
background(220);
drawMaze();
drawBorder();
for (var i=1;i<pickuplist.length;i++){
pickuplist[i].draw();
}
portal.draw();
hero.draw()
// checkGameState();
if (winstate==1){
drawWin();
}
if (winstate==2){
drawLose();
}
}
function keyPressed(){
if (winstate==0){
if (keyCode == LEFT_ARROW){
hero.goLeft();
}
if (keyCode == RIGHT_ARROW){
hero.goRight();
}
if (keyCode == UP_ARROW){
hero.goUp();
}
if (keyCode == DOWN_ARROW){
hero.goDown();
}
if (key=='e'){
if (hero.pickupstate==0){
hero.pickUp();
} else {
if (hero.pickupstate==1){
hero.drop();
}
}
}
}
}