Talking about Bejeweled game, Game development and Javascript.
Bejeweled is one of the best games to code to learn the basics of programming. I already showed you how to build a working prototype of the game in my book, and I also published a 2KB version of the game (you can also find a more legible version here).
This time I am going to show you a fully working jQuery version. Everything, from the containers div
s to the styles, have been made with jQuery, there isn’t a single HTML or CSS line.
This is the result, featuring gem swap, multiple combos, and everything you need to have in a Bejeweled game:
And this is the source code, without any comment, but quite clear. I can make a step by step tutorial if I receive a good feedback.
$(document).ready(function(){
$("body").append('').css({"background-color":"black","margin":"0"});
$("#marker").css({"width":"52px","height":"52px","border":"5px solid white","position":"absolute"}).hide();
var selectedRow=-1
var selectedCol=-1
var posX;
var posY;
var jewels=new Array();
var movingItems=0;
var gameState="pick";
var bgColors=new Array("magenta","mediumblue","yellow","lime","cyan","orange","crimson","gray");
for(i=0;i<8;i++){
jewels[i]=new Array();
for(j=0;j<8;j++){
jewels[i][j]=-1;
}
}
for(i=0;i<8;i++){
for(j=0;j<8;j++){
do{
jewels[i][j]=Math.floor(Math.random()*8);
}while(isStreak(i,j));
$("#gamefield").append('');
$("#gem_"+i+"_"+j).css({"top":(i*60)+10+"px","left":(j*60)+10+"px","width":"50px","height":"50px","position":"absolute","border":"1px solid white","cursor":"pointer","background-color":bgColors[jewels[i][j]]});
}
}
$(".gem").live("click",function(){
if(gameState=="pick"){
posY=$(this).position().top;
posX=$(this).position().left;
$("#marker").show();
$("#marker").css("top",posY-5).css("left",posX-5);
if(selectedRow==-1){
selectedRow=(posY-10)/60;
selectedCol=(posX-10)/60;
}
else{
posY=(posY-10)/60;
posX=(posX-10)/60;
if((Math.abs(selectedRow-posY)==1 && selectedCol==posX)||(Math.abs(selectedCol-posX)==1 && selectedRow==posY)){
$("#marker").hide();
gameState="switch";
gemSwitch();
}
else{
selectedRow=posY;
selectedCol=posX;
}
}
}
});
function checkMoving(){
movingItems--;
if(movingItems==0){
switch(gameState){
case "revert":
case "switch":
if(!isStreak(selectedRow,selectedCol) && !isStreak(posY,posX)){
if(gameState!="revert"){
gameState="revert";
gemSwitch();
}
else{
gameState="pick";
selectedRow=-1;
}
}
else{
gameState="remove";
if(isStreak(selectedRow,selectedCol)){
removeGems(selectedRow,selectedCol);
}
if(isStreak(posY,posX)){
removeGems(posY,posX);
}
gemFade();
}
break;
case "remove":
checkFalling();
break;
case "refill":
placeNewGems();
break;
}
}
}
function placeNewGems(){
var gemsPlaced = 0;
for(i=0;i<8;i++){
if(jewels[0][i]==-1){
jewels[0][i]=Math.floor(Math.random()*8);
$("#gamefield").append('');
$("#gem_0_"+i).css({"top":"10px","left":(i*60)+10+"px","width":"50px","height":"50px","position":"absolute","border":"1px solid white","cursor":"pointer","background-color":bgColors[jewels[0][i]]});
gemsPlaced++;
}
}
if(gemsPlaced){
gameState="remove";
checkFalling();
}
else{
var combo=0
for(i=0;i<8;i++){
for(j=0;j<8;j++){
if(j<=5 && jewels[i][j]==jewels[i][j+1] && jewels[i][j]==jewels[i][j+2]){
combo++;
removeGems(i,j);
}
if(i<=5 && jewels[i][j]==jewels[i+1][j] && jewels[i][j]==jewels[i+2][j]){
combo++;
removeGems(i,j);
}
}
}
if(combo>0){
gameState="remove";
gemFade();
}
else{
gameState="pick";
selectedRow=-1;
}
}
}
function checkFalling(){
var fellDown=0;
for(j=0;j<8;j++){
for(i=7;i>0;i--){
if(jewels[i][j]==-1 && jewels[i-1][j]>=0){
$("#gem_"+(i-1)+"_"+j).addClass("fall").attr("id","gem_"+i+"_"+j);
jewels[i][j]=jewels[i-1][j];
jewels[i-1][j]=-1;
fellDown++;
}
}
}
$.each($(".fall"),function(){
movingItems++;
$(this).animate({
top: "+=60"
},{
duration: 500,
complete: function(){
$(this).removeClass("fall");
checkMoving();
}
});
});
if(fellDown==0){
gameState="refill";
movingItems=1;
checkMoving();
}
}
function gemFade(){
$.each($(".remove"),function(){
movingItems++;
$(this).animate({
opacity:0
},{
duration: 500,
complete: function(){
$(this).remove();
checkMoving();
}
});
});
}
function gemSwitch(){
var yOffset=selectedRow-posY;
var xOffset=selectedCol-posX;
$("#gem_"+selectedRow+"_"+selectedCol).addClass("switch").attr("dir","-1");
$("#gem_"+posY+"_"+posX).addClass("switch").attr("dir","1");
$.each($(".switch"),function(){
movingItems++;
$(this).animate({
left: "+="+xOffset*60*$(this).attr("dir"),
top: "+="+yOffset*60*$(this).attr("dir")
},{
duration: 500,
complete: function(){
checkMoving();
}
}).removeClass("switch")
});
$("#gem_"+selectedRow+"_"+selectedCol).attr("id","temp");
$("#gem_"+posY+"_"+posX).attr("id","gem_"+selectedRow+"_"+selectedCol);
$("#temp").attr("id","gem_"+posY+"_"+posX);
var temp=jewels[selectedRow][selectedCol];
jewels[selectedRow][selectedCol]=jewels[posY][posX];
jewels[posY][posX]=temp;
}
function removeGems(row,col){
var gemValue = jewels[row][col];
var tmp = row;
$("#gem_"+row+"_"+col).addClass("remove");
if(isVerticalStreak(row,col)){
while(tmp>0 && jewels[tmp-1][col]==gemValue){
$("#gem_"+(tmp-1)+"_"+col).addClass("remove");
jewels[tmp-1][col]=-1;
tmp--;
}
tmp=row;
while(tmp<7 && jewels[tmp+1][col]==gemValue){
$("#gem_"+(tmp+1)+"_"+col).addClass("remove");
jewels[tmp+1][col]=-1;
tmp++;
}
}
if(isHorizontalStreak(row,col)){
tmp = col;
while(tmp>0 && jewels[row][tmp-1]==gemValue){
$("#gem_"+row+"_"+(tmp-1)).addClass("remove");
jewels[row][tmp-1]=-1;
tmp--;
}
tmp=col;
while(tmp<7 && jewels[row][tmp+1]==gemValue){
$("#gem_"+row+"_"+(tmp+1)).addClass("remove");
jewels[row][tmp+1]=-1;
tmp++;
}
}
jewels[row][col]=-1;
}
function isVerticalStreak(row,col){
var gemValue=jewels[row][col];
var streak=0;
var tmp=row;
while(tmp>0 && jewels[tmp-1][col]==gemValue){
streak++;
tmp--;
}
tmp=row;
while(tmp<7 && jewels[tmp+1][col]==gemValue){
streak++;
tmp++;
}
return streak>1
}
function isHorizontalStreak(row,col){
var gemValue=jewels[row][col];
var streak=0;
var tmp=col
while(tmp>0 && jewels[row][tmp-1]==gemValue){
streak++;
tmp--;
}
tmp=col;
while(tmp<7 && jewels[row][tmp+1]==gemValue){
streak++;
tmp++;
}
return streak>1
}
function isStreak(row,col){
return isVerticalStreak(row,col)||isHorizontalStreak(row,col);
}
});
Happy swapping. Would you add any feature?
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.