Tutorial level descriptions and objects setup
This commit is contained in:
parent
6921bd2cab
commit
88d26df984
165
game.js
165
game.js
@ -218,7 +218,10 @@ var MENU = {
|
||||
buttons:[CONVEYOR_BUILD_BUTTON,BRANCH_BUILD_BUTTON,WRITER_BUILD_BUTTON,ROTATE_COUNTERCLOCKWISE_BUTTON,ROTATE_CLOCKWISE_BUTTON,DELETE_BUTTON,PLAY_BUTTON,RESET_BUTTON,HOME_BUTTON]
|
||||
}
|
||||
|
||||
|
||||
var TUTORIALMENU={
|
||||
title:"Introduction to Conversion",
|
||||
levels:[]
|
||||
}
|
||||
|
||||
function saveLevelData() {
|
||||
completedStages[gameStage.name].data=deepCopy(gameGrid)
|
||||
@ -388,6 +391,51 @@ var STAGE2 = {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var TUTORIAL1 = {
|
||||
name:"Conveyors!",
|
||||
objective:"To convert your robots, you must send them from the entrance to the exit. Select a belt and send robots to where they truly belong.",
|
||||
level:createGrid(5,5,4,2),
|
||||
start:{x:0,y:2},
|
||||
locked:[BRANCH_BUILD_BUTTON,WRITER_BUILD_BUTTON],
|
||||
tutorial:true,
|
||||
accept:(tape)=>{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var TUTORIAL2 = {
|
||||
name:"Branches",
|
||||
objective:"We have to make sure we are sending robots that meet our needs! Use the branch to filter out robots that start with a red signal. Send only those to the exit!",
|
||||
level:createGrid(5,5,4,2),
|
||||
start:{x:0,y:2},
|
||||
locked:[WRITER_BUILD_BUTTON],
|
||||
tutorial:true,
|
||||
accept:(tape)=>{
|
||||
if (tape[0]===RED) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
var TUTORIAL3 = {
|
||||
name:"Writers",
|
||||
objective:"CONVERSION! It's time to convert robots to what they should be. Add 3 blue signals to every bot that comes through. We shall convert them all!",
|
||||
level:createGrid(5,5,4,2),
|
||||
start:{x:0,y:2},
|
||||
tutorial:true,
|
||||
accept:(tape)=>{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var TUTORIAL4 = {
|
||||
name:"More Colors",
|
||||
objective:"You may be required to use different colors, either for your purposes or mine. For this robot cycle, convert all blue and red signals to yellow signals.",
|
||||
level:createGrid(5,5,4,2),
|
||||
start:{x:0,y:2},
|
||||
accept:(tape)=>{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var gameGrid = []
|
||||
var completedStages = {"Blue Blue":{data:[],complete:false}} //Example completed structure.
|
||||
@ -467,7 +515,24 @@ function generateBotQueue() {
|
||||
RESULT=false
|
||||
BOT_QUEUE.push(tape)
|
||||
}
|
||||
if (BOT_QUEUE.length===3) {
|
||||
var reversedTape=tape.split("").reverse().join("")
|
||||
//console.log(tape)
|
||||
var wrongBot=false //Set to true if a bot that's supposed to pass fails, or a bot that's supposed to fail passes.
|
||||
var isSupposedToBeAccepted=gameStage.accept(reversedTape)
|
||||
var result=getSimulatedBotResult(reversedTape)
|
||||
if (result===isSupposedToBeAccepted) {
|
||||
wrongBot=false;
|
||||
} else {
|
||||
wrongBot=true;
|
||||
}
|
||||
if (wrongBot) {
|
||||
if (BOT_QUEUE.length===0) {
|
||||
EXPECTED = isSupposedToBeAccepted;
|
||||
}
|
||||
RESULT=false
|
||||
BOT_QUEUE.push(reversedTape)
|
||||
}
|
||||
if (BOT_QUEUE.length>=3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -645,8 +710,8 @@ function setupGame() {
|
||||
}
|
||||
}catch{}
|
||||
//console.log(completedStages)
|
||||
//loadStage(STAGE2)
|
||||
gameState=MAINMENU
|
||||
loadStage(TUTORIAL4)
|
||||
//gameState=MAINMENU
|
||||
}
|
||||
|
||||
function setupTitleScreen() {
|
||||
@ -706,28 +771,30 @@ function clickEvent(e) {
|
||||
|
||||
if (MENU.visible) {
|
||||
for (var button of MENU.buttons) {
|
||||
if (mouseOverButton(canvas,e,button)) {
|
||||
if (button.cb!==undefined) {
|
||||
button.cb()
|
||||
return;
|
||||
} else {
|
||||
DELETEMODE=false
|
||||
document.body.style.cursor="url('cursor.png') 8 8,auto"
|
||||
if (button.submenu_buttons&&button.submenu_buttons.length>0) {
|
||||
BUTTON_SELECTED=button;
|
||||
SUBMENU.visible=true;
|
||||
SUBMENU.buttons=[]
|
||||
var index = 0;
|
||||
for (var button2 of BUTTON_SELECTED.submenu_buttons) {
|
||||
var buttonX = ((index%3)*48)+16
|
||||
var buttonY = canvas.height*0.8-(Math.floor(index/3)*48)-40
|
||||
SUBMENU.buttons.push({def:button2,img:button2.img,x:buttonX,y:buttonY,w:32,h:32})
|
||||
index++;
|
||||
if (ButtonIsUnlocked(button)) {
|
||||
if (mouseOverButton(canvas,e,button)) {
|
||||
if (button.cb!==undefined) {
|
||||
button.cb()
|
||||
return;
|
||||
} else {
|
||||
DELETEMODE=false
|
||||
document.body.style.cursor="url('cursor.png') 8 8,auto"
|
||||
if (button.submenu_buttons&&button.submenu_buttons.length>0) {
|
||||
BUTTON_SELECTED=button;
|
||||
SUBMENU.visible=true;
|
||||
SUBMENU.buttons=[]
|
||||
var index = 0;
|
||||
for (var button2 of BUTTON_SELECTED.submenu_buttons) {
|
||||
var buttonX = ((index%3)*48)+16
|
||||
var buttonY = canvas.height*0.8-(Math.floor(index/3)*48)-40
|
||||
SUBMENU.buttons.push({def:button2,img:button2.img,x:buttonX,y:buttonY,w:32,h:32})
|
||||
index++;
|
||||
}
|
||||
}
|
||||
ITEM_SELECTED=button.lastselected
|
||||
//console.log(button)
|
||||
return
|
||||
}
|
||||
ITEM_SELECTED=button.lastselected
|
||||
//console.log(button)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -808,12 +875,14 @@ function releaseEvent(e) {
|
||||
function loadLevel(level,botx,boty) {
|
||||
placeBot(botx,boty)
|
||||
gameGrid = deepCopy(level)
|
||||
MENU.visible=true
|
||||
}
|
||||
|
||||
function loadStage(stage) {
|
||||
//gameGrid=deepCopy(stage.level)
|
||||
loadLevel(stage.level,stage.start.x,stage.start.y)
|
||||
gameStage=stage
|
||||
ITEM_SELECTED=undefined
|
||||
if (completedStages[stage.name]===undefined) {
|
||||
completedStages[stage.name]={}
|
||||
} else {
|
||||
@ -822,6 +891,7 @@ function loadStage(stage) {
|
||||
console.log(gameGrid)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function deepCopy(arr) {
|
||||
@ -1112,7 +1182,7 @@ function RenderSpeedbar(x,y,w,ctx) {
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
function DrawWrapText(text,x,y,w,fontHeight,ctx) {
|
||||
function DrawWrapText(text,x,y,w,fontHeight,ctx,topToBottom=false/*Set to true to draw from the position downward. Defaults to drawing upwards.*/) {
|
||||
var arr = text.split(" ")
|
||||
var finalText = []
|
||||
for (var i=0;i<arr.length;i++) {
|
||||
@ -1129,10 +1199,18 @@ function DrawWrapText(text,x,y,w,fontHeight,ctx) {
|
||||
}
|
||||
}
|
||||
for (var i=0;i<finalText.length;i++) {
|
||||
ctx.fillText(finalText[finalText.length-1-i],x,y-i*fontHeight+4)
|
||||
if (topToBottom) {
|
||||
ctx.fillText(finalText[i],x,y+i*fontHeight+4)
|
||||
} else {
|
||||
ctx.fillText(finalText[finalText.length-1-i],x,y-i*fontHeight+4)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function LevelIsBeat(levelName) {
|
||||
return completedStages[levelName]!==undefined&&completedStages[levelName].complete
|
||||
}
|
||||
|
||||
function RenderGameInfo(ctx) {
|
||||
if (MENU.visible) {
|
||||
ctx.fillStyle="#20424a"
|
||||
@ -1140,7 +1218,7 @@ function RenderGameInfo(ctx) {
|
||||
|
||||
RenderSpeedbar(canvas.width*0.75+(canvas.width*0.25)/2-32,8,64,ctx)
|
||||
|
||||
if (completedStages[gameStage.name]!==undefined&&completedStages[gameStage.name].complete) {
|
||||
if (LevelIsBeat(gameStage.name)) {
|
||||
drawImage(canvas.width-18,14,ID_COMPLETE_STAR,ctx,0,0.75)
|
||||
} else {
|
||||
drawImage(canvas.width-18,14,ID_INCOMPLETE_STAR,ctx,0,0.75)
|
||||
@ -1195,7 +1273,7 @@ function RenderGameInfo(ctx) {
|
||||
ctx.font="12px 'Zilla Slab', serif"
|
||||
ctx.fillStyle="white"
|
||||
ctx.textAlign ="left"
|
||||
DrawWrapText(gameStage.objective,(canvas.width*0.75)+8,canvas.height-66+levelDescriptionOffsetY,(canvas.width*0.25)*0.9,12,ctx)
|
||||
DrawWrapText(gameStage.objective,(canvas.width*0.75)+8,canvas.height-84+levelDescriptionOffsetY,(canvas.width*0.25)*0.9,12,ctx,true)
|
||||
|
||||
if (MOBILE&&gameState!==RUNNING) {
|
||||
drawImage(canvas.width*0.75-48,canvas.height*0.8-48,
|
||||
@ -1545,14 +1623,27 @@ function RenderSubmenu(ctx) {
|
||||
ctx.fillRect(0,canvas.height*0.8-submenuRows*48-16,submenuCols*48+16,submenuRows*48+16)
|
||||
var index = 0;
|
||||
for (var button of BUTTON_SELECTED.submenu_buttons) {
|
||||
var buttonX = ((index%3)*48)+16
|
||||
var buttonY = canvas.height*0.8-(Math.floor(index/3)*48)-40
|
||||
RenderIcon(buttonX,buttonY,ctx,button,ITEM_DIRECTION,(LAST_MOUSE_X>=buttonX&&LAST_MOUSE_X<=buttonX+32&&LAST_MOUSE_Y>=buttonY&&LAST_MOUSE_Y<=buttonY+32)?"#555555":"#b5b5b5")
|
||||
index++;
|
||||
if (SubmenuButtonIsUnlocked(button)) {
|
||||
var buttonX = ((index%3)*48)+16
|
||||
var buttonY = canvas.height*0.8-(Math.floor(index/3)*48)-40
|
||||
RenderIcon(buttonX,buttonY,ctx,button,ITEM_DIRECTION,(LAST_MOUSE_X>=buttonX&&LAST_MOUSE_X<=buttonX+32&&LAST_MOUSE_Y>=buttonY&&LAST_MOUSE_Y<=buttonY+32)?"#555555":"#b5b5b5")
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function SubmenuButtonIsUnlocked(button) {
|
||||
return gameStage.tutorial===undefined||!gameStage.tutorial||button.color1===RED||button.color1===BLUE
|
||||
}
|
||||
|
||||
function ButtonIsUnlocked(button) {
|
||||
if (button===HOME_BUTTON&&gameStage.tutorial&&!LevelIsBeat(gameStage.name)) {
|
||||
return false
|
||||
}
|
||||
return gameStage.locked===undefined||(!gameStage.locked.includes(button))
|
||||
}
|
||||
|
||||
function RenderMenu(ctx) {
|
||||
if (MENU.visible) {
|
||||
ctx.fillStyle="#20424a"
|
||||
@ -1560,10 +1651,12 @@ function RenderMenu(ctx) {
|
||||
var buttonX = 16
|
||||
var buttonY = canvas.height*0.8+16
|
||||
for (var button of MENU.buttons) {
|
||||
if (button.lastselected) {
|
||||
RenderIcon(buttonX,buttonY,ctx,button.lastselected,(button.cb===undefined)?ITEM_DIRECTION:0,"#b5b5b5")
|
||||
} else {
|
||||
AddButton(button.img,buttonX,buttonY,ctx,button,(button.cb===undefined)?ITEM_DIRECTION:0)
|
||||
if (ButtonIsUnlocked(button)) {
|
||||
if (button.lastselected) {
|
||||
RenderIcon(buttonX,buttonY,ctx,button.lastselected,(button.cb===undefined)?ITEM_DIRECTION:0,"#b5b5b5")
|
||||
} else {
|
||||
AddButton(button.img,buttonX,buttonY,ctx,button,(button.cb===undefined)?ITEM_DIRECTION:0)
|
||||
}
|
||||
}
|
||||
button.x=buttonX
|
||||
button.y=buttonY
|
||||
|
@ -319,7 +319,7 @@ function runTests() {
|
||||
expect(BOT_QUEUE.length===0&&gameState!==TESTING,true,"Bot queue should not be modified while state is not TESTING")
|
||||
gameState=TESTING
|
||||
generateBotQueue()
|
||||
expect(BOT_QUEUE.length===3,true,"There should be 3 bots in queue for an unbuilt level, as all bots are supposed to pass.")
|
||||
expect(BOT_QUEUE.length>=3,true,"There should be at least 3 bots in queue for an unbuilt level, as all bots are supposed to pass.")
|
||||
})
|
||||
.it("A stage should have an Exit.",()=>{
|
||||
loadStage(STAGE1)
|
||||
@ -417,7 +417,7 @@ function runTests() {
|
||||
expect(BOT_QUEUE.length===0&&gameState!==TESTING,true,"Bot queue should not be modified while state is not TESTING")
|
||||
gameState=TESTING
|
||||
generateBotQueue()
|
||||
expect(BOT_QUEUE.length===3,true,"There should be 3 bots in queue for an unbuilt level, as there are cases that do not pass.")
|
||||
expect(BOT_QUEUE.length>=3,true,"There should be at least 3 bots in queue for an unbuilt level, as there are cases that do not pass.")
|
||||
})
|
||||
.it("A stage should have an Exit.",()=>{
|
||||
loadStage(STAGE2)
|
||||
|
Loading…
x
Reference in New Issue
Block a user