473,416 Members | 1,729 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes and contribute your articles to a community of 473,416 developers and data experts.

How to create a 3D snake game with Javascript (attached source code and game link)

Hightopo
Let's take a look at the final effect of the game at first:
Watch it on YouTube

Now let's talk about how to achieve it with Javascript.
The game is made using HT for Web, with about 100 lines of code.

Initialize the scene

First, let's do some initialization work, including initializing the 3D scene, setting the ground grid, and enabling event monitoring, etc. The main code and comments are as follows:
Expand|Select|Wrap|Line Numbers
  1. w = 40; // the grid gap
  2.   m = 20; // the count of rows/columns of grid
  3.   d = w * m / 2;
  4.   food = null;            
  5.   dm = new ht.DataModel(); // create one data model, which saves all the  grid, snake and food
  6.   g3d = new ht.graph3d.Graph3dView(dm); // initialize one 3d scene  
  7.   // config the grid on ground             
  8.   g3d.setGridVisible(true);
  9.   g3d.setGridColor('#29B098');
  10.   g3d.setGridSize(m);
  11.   g3d.setGridGap(w);    
  12.  
  13.   // add the 3d scene to body
  14.   view = g3d.getView();            
  15.   view.className = 'main';
  16.   document.body.appendChild(view);   
  17.  
  18.   // monitor the resize event and mouse click event
  19.   window.addEventListener('resize', function (e) {  g3d.invalidate(); }, false);                                                                                            
  20.   g3d.sm().setSelectionMode('none');
  21.   view.addEventListener(ht.Default.isTouchable ? 'touchstart' : 'mousedown', function(e){                
  22.       if(isRunning){
  23.           var p = g3d.getHitPosition(e); // get the position in scene when mousedown
  24.           // calculate the move direction with the click position 
  25.           if(Math.abs(p[0]) < d && Math.abs(p[2]) < d){
  26.               if(direction === 'up' || direction === 'down'){
  27.                   direction = p[0] > snake[0].p3()[0] ? 'right' : 'left';                       
  28.               }
  29.               else if(direction === 'left' || direction === 'right'){
  30.                   direction = p[2] > snake[0].p3()[2] ? 'down' : 'up';                                             
  31.               }                        
  32.           }
  33.       }else if(ht.Default.isDoubleClick(e)){
  34.           start(); // double click the scene to start the game
  35.       }                
  36.   }, false);                        
  37.   start();            
  38.   // the snake move forward every 200ms
  39.   setInterval(function(){ if(isRunning){ isRunning = next(); } }, 200);
Create the food

Every time the gluttonous snake eats a piece of food, its body will grow longer. At this point, new food needs to be created and randomly and placed in a new location. When creating food, its position should not coincide with the previous position, nor repeated with the current snake body.
Expand|Select|Wrap|Line Numbers
  1. /**
  2.  * Create the food and place it in a random position
  3.  * The food should not dup with snake or last food
  4.  *
  5.  */
  6. function createFood(){
  7.   var x = getRandom(), y = getRandom();
  8.   // skip the snake body and last food
  9.   while(touchFood(x, y) || touchSnake(x, y)){ x = getRandom(); y = getRandom(); }
  10.   if(food) dm.remove(food);            
  11.   food = createNode(x, y); 
  12.   food.s({'shape3d': 'sphere',  'shape3d.color': 'red'});
  13. }        
  14. /**
  15.  * whether the given position (x, y) is dup with the snake body
  16.  *
  17.  * @param {*} x
  18.  * @param {*} y
  19.  * @return {*} 
  20.  */
  21. function touchSnake(x, y){
  22.   for(var i=0; i<snake.length; i++){                
  23.       if(snake[i].a('x') === x && snake[i].a('y') === y){ return true; }
  24.   }
  25.   return false;
  26. }        
  27. /**
  28.  * whether the given position (x, y) is dup with the food
  29.  *
  30.  * @param {*} x
  31.  * @param {*} y
  32.  * @return {*} 
  33.  */
  34. function touchFood(x, y){
  35.   return food && food.a('x') === x && food.a('y') === y;
  36. }     
Create the snake

In the first step, we set the grid size and gap. In this way, the length and width of the entire grid and the size of each block of the snake are determined. In this step, we add boundaries to the mesh and then generate the snake.
Expand|Select|Wrap|Line Numbers
  1. /**
  2.  * clear the scene, create the snake and wall
  3.  *
  4.  */
  5. function start(){
  6.   dm.clear(); snake = []; score = 0; direction = 'up'; isRunning = true;
  7.   // create wall
  8.   shape = new ht.Shape();
  9.   shape.setPoints(new ht.List([
  10.       {x: -d, y: d},
  11.       {x: d, y: d},
  12.       {x: d, y: -d},
  13.       {x: -d, y: -d},
  14.       {x: -d, y: d}
  15.   ]));
  16.   shape.setThickness(4);
  17.   shape.setTall(w);
  18.   shape.setElevation(w/2);
  19.   shape.s({'all.color': 'rgba(20, 120, 120, 0.5)', 'all.transparent': true, 'all.reverse.cull': true});
  20.  
  21.   dm.add(shape);                 
  22.   // create the snake       
  23.   for(var i=0; i<m/2; i++) { snake.push(createNode(m/2 + i, m/2)); }            
  24.   createFood();                        
  25. }        
Make the snake move forward

After having the snake and the food, the next step is to deal with the logic of the snake walking. include:

1. whether the snake has reached the border or touched its body
2. when the snake touched the food, its body gets longer
3. in other cases, move forward
Expand|Select|Wrap|Line Numbers
  1. /**
  2.  * calculate nest position based on direction. and check:
  3.  * 1. whether the snake has reached the border or touched its body
  4.  * 2. when the snake touched the food, its body gets longer
  5.  * 3. in other cases, move forward
  6.  *
  7.  * @return {*} 
  8.  */
  9. function next(){
  10.   var node = snake[0], x = node.a('x'), y = node.a('y');
  11.   if(direction === 'up') y--;
  12.   if(direction === 'down') y++;       
  13.   if(direction === 'left') x--;
  14.   if(direction === 'right') x++;
  15.   if(x < 0 || x >= m || y < 0 || y >= m || touchSnake(x, y)){ return false; }                        
  16.   if(touchFood(x, y)){
  17.       score++;                
  18.       snake.splice(0, 0, createNode(x, y));                
  19.       createFood();
  20.   }else{
  21.       snake.splice(0, 0, createNode(x, y));
  22.       dm.remove(snake.pop());                
  23.   }
  24.   return true;
  25. }
At this point, the whole snake game is complete. Quite simple, right? Double click on the scene to start the game or click on the scene to change the direction of the snake movement.

You can also directly click the link below to try the game:
3D Gluttonous Snake

To get the source code, just open the game link and press F12.
Nov 30 '22 #1
1 13475
HarrySto
10 Byte
By the way, a little off-topic, but it may be useful. There are good resources for code review and analysis - AppRefactoring and Code Scene
Dec 14 '22 #2

Sign in to post your reply or Sign up for a free account.

Similar topics

1
by: Gina | last post by:
I need to add the cell generation to a templated program. I am using graphics magician, but my problem is with the math. I cannot figure out my cell generations. I do know that I need two...
15
by: Enzo | last post by:
Hi Ng, It's possible to protect the source code of a js file? With PHP? Thanks in advance! Enzo
7
by: Prashanth Badabagni | last post by:
Hi , I'm Prashanth Badabagni .. I have and idea how a program prints it's own source code .. void main() { FILE *P; char *file,c; strcpy(file,__FILE__); p=fopen(file,"r");
16
by: André | last post by:
Hi all, I am contructing a class derived of DataGridTextBoxColumn with very much modification. However, I need to see the code of base class to know what should I in some inherited methods. ...
15
by: Fady Anwar | last post by:
Hi while browsing the net i noticed that there is sites publishing some software that claim that it can decompile .net applications i didn't bleave it in fact but after trying it i was surprised...
2
by: -Lost | last post by:
I have been watching code execution in various situations and I have noticed something. On the first test my example gave me obvious results. One method was far faster than the other. However,...
2
by: pavanpolineni | last post by:
hi, I want to create a "namedpipe". so, iwant to know how to create a named pipe.and also source code for it.
19
by: foolsmart2005 | last post by:
I have written a snake game. There are 2 levels in the game(I finished 1st level). It can run in VC++ without problem but, when I run it on the dev C++ 4.9.9.2, it cannot run. I want to...
18
by: amritpalpathak | last post by:
I have made the html+javascript code.According to which when the page loaded the image size gets reduced to 50,50 and onclicking on it ,size increases to 500,500,but i done it with the one copy of ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.