JavaScript - snake-game

 
Vista:

snake-game

Publicado por Trabajador_Turista (2 intervenciones) el 28/09/2023 09:41:25
Hola, Estoy empezando con el desarrollo de video juegos, como punto de partida para hacer el Snake-Game tengo al juego de "obtaculos" que esta en https://www.w3schools.com/graphics/game_intro.asp.
Y para poder terminar Snake-Game me falta hacer que la serpiente sea flexible, y quisiera terminarlo tal como vengo hasta ahora con puro js nativo, pido por favor alguna idea u orientación para codificar y dar por terminado al proyecto, un saludo desde París, France. Worker Tourist.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
    canvas {border:1px solid #d3d3d3;background-color: #f1f1f1;}
</style>
</head>
    <body onload="startGame()">
<script>
var componentPositionx;
var componentPositiony;
var myObstacleDown;
var myObstacleUp;
var myObstacleLeft;
var myObstacleRigth;
var eatsquard;
var myGamePiece;
var mostrarPuntos=0;
var crecimiento=0;
function startGame() {
    myGameArea.start();
    myGamePiece = new component(30, 30, "red", 70, 120);
    eatsquard = new componentEat(30, 30, "green", Math.floor(Math.random() * 400),Math.floor(Math.random() * 200));
    myObstacleLeft = new component(2, 270, "green", 1, 1);
    myObstacleRigth = new component(2, 270, "green", 478,1);
    myObstacleUp = new component(479, 2, "green", 2,2);
    myObstacleDown = new component(479,2, "green", 2,269);
}
 
var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 480;
        this.canvas.height = 270;
        this.context = this.canvas.getContext("2d");
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.interval = setInterval(updateGameArea, 20);
        window.addEventListener('keydown', function (e) {
            myGameArea.keys = (myGameArea.keys || []);
            myGameArea.keys[e.keyCode] = (e.type == "keydown");
        })
        window.addEventListener('keyup', function (e) {
            myGameArea.keys[e.keyCode] = (e.type == "keydown");
        })
    },
    clear : function(){
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    },
     stop : function() {
    clearInterval(this.interval);
  }
}
function component(width, height, color, x1, y1) {
    this.gamearea = myGameArea;
    this.width = width;
    this.height = height;
    this.speedX = 2;
    this.speedY = 2;
    this.x = x1;
    this.y = y1;
 
    this.update = function() {
        ctx = myGameArea.context;
        ctx.fillStyle = color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
 
   this.newPos = function() {
        this.x += this.speedX;
        this.y += this.speedY;
       componentPositionx = this.x;
       componentPositiony = this.y;
       console.log(componentPositionx);
       console.log(componentPositiony);
if (  componentPositionx==2 ) {ctx.font = "50px Arial"; ctx.fillText("jeu terminé", 170, 250);}
if (  componentPositionx==449 ) {ctx.font = "50px Arial"; ctx.fillText("jeu terminé", 170, 250);}
if (  componentPositiony==3 ) {ctx.font = "50px Arial"; ctx.fillText("jeu terminé", 170, 250) ;}
if (  componentPositiony==240 ) {ctx.font = "50px Arial"; ctx.fillText("jeu terminé", 170, 250);}
},
    this.crashWith = function(otherobj) {
    var myleft = this.x;
    var myright = this.x + (this.width);
    var mytop = this.y;
    var mybottom = this.y + (this.height);
    var otherleft = otherobj.x;
    var otherright = otherobj.x + (otherobj.width);
    var othertop = otherobj.y;
    var otherbottom = otherobj.y + (otherobj.height);
    var crash= true;
    if ((mybottom < othertop) ||
    (mytop > otherbottom) ||
    (myright < otherleft) ||
    (myleft > otherright)) {
      crash=false;
    }
    return crash;
  }
}
 
function componentEat(width, height, color, x1, y1) {
    this.gamearea = myGameArea;
    this.width = width;
    this.height = height;
    this.speedX = 0;
    this.speedY = 0;
    this.x = x1;
    this.y = y1;
 
     this.update = function() {
        ctx = myGameArea.context;
        ctx.fillStyle = color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
 
}
 
 function updateGameArea() {
 
if (myGamePiece.crashWith(eatsquard)){ myGameArea.stop();
    myGameArea.start();
    var factorCrecimiento=30;
    crecimiento=crecimiento+factorCrecimiento;
    myGamePiece = new component(30+crecimiento, 30, "red", 70, 120);
    eatsquard = new componentEat(30, 30, "green", Math.floor(Math.random() * 400),Math.floor(Math.random() * 200));
    myObstacleLeft = new component(2, 270, "green", 1, 1);
    myObstacleRigth = new component(2, 270, "green", 478,1);
    myObstacleUp = new component(479, 2, "green", 2,2);
    myObstacleDown = new component(479,2, "green", 2,269);
    myObstacleLeft.update();
    myObstacleRigth.update();
    myObstacleUp.update();
    myObstacleDown.update();
    eatsquard.update();
    myGamePiece.newPos();
    myGamePiece.update();
    myGamePiece.speedX=3;
    myGamePiece.speedY=3;
    mostrarPuntos = mostrarPuntos+10;
    ctx.font = "20px Arial";
    ctx.fillText("score: "+mostrarPuntos, 368, 50);
 
}
if (myGamePiece.crashWith(myObstacleLeft)) {myGameArea.stop();}
if (myGamePiece.crashWith(myObstacleRigth)){myGameArea.stop();}
if (myGamePiece.crashWith(myObstacleUp)){myGameArea.stop();}
if (myGamePiece.crashWith(myObstacleDown)){myGameArea.stop();}
    myGameArea.clear();
    myGamePiece.speedX=0;
    myGamePiece.speedY=0;
    if (myGameArea.keys && myGameArea.keys[37]) { myGamePiece.speedX = -1; console.log("izquierda");}
    if (myGameArea.keys && myGameArea.keys[39]) {myGamePiece.speedX = +1; console.log("derecha");}
    if (myGameArea.keys && myGameArea.keys[38]) {myGamePiece.speedY = -1; console.log("arriba");}
    if (myGameArea.keys && myGameArea.keys[40]) {myGamePiece.speedY = +1; console.log("abajo");}
    myObstacleLeft.update();
    myObstacleRigth.update();
    myObstacleUp.update();
    myObstacleDown.update();
    eatsquard.update();
    myGamePiece.newPos();
    myGamePiece.update();
    ctx.font = "20px Arial";
    ctx.fillText("score: "+mostrarPuntos, 368, 50);
}
</script>
<br>
<button>  <a href="copiagame.html">Jugar de nuevo</a></button>
<p></p>
<p></p>
</body>
</html>
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Ivan

snake-game

Publicado por Ivan (118 intervenciones) el 28/09/2023 12:35:53
Hola,

muy interesante y a la vez ilusionante tu pregunta!

Lo digo porque soy fanático del tema videojuegos con JavaScript puro y tengo publicados dos libros al respecto:

- Programando Videojuegos: JavaScript
- Programando Videojuegos 2.0: JavaScript

También puedes ver los videojuegos de los libros en mi blog:

https://fashehlabs.com/juegos/Endless%20Tunnel/
https://fashehlabs.com/juegos/Asteroids%20Return/

Dicho esto,la forma que enseñan en w3Schools es un intro muy básica que enseguida "choca" si quieres hacer algún videojuego más complejo, como por ejemplo tu Snake.

En tu ejemplo haces que tu Snake crezca simplemente creando un nuevo myGamePiece con un "width" mayor.
Si quieres hacerlo crecer de forma "jugable" debes hacerlo mediante un Array y cada posición del Array es un "cuadrito" de la serpiente.

Aquí habría que tener en cuenta diversas consideraciones:
- La posición [0] que sea siempre la cabeza (puedes añadir unos ojitos)
- La Snake añade un cuadrito al final del Array cada vez que crece.
- Para mejor fluidez reduce el tamaño de cada cuadrito a 5x5 por ejemplo y que empiece con 3 cuadrito o los giros se veran mal con menos tamaño.
- La forma de moverse es la siguiente: La cabeza gira con el teclado, pero antes debe pasar su posición al resto de cuadritos y estos a los otros: [0] -> [1] -> [2] -> etc. y después mueves la cabeza [0]

Estoy trabajando y no tengo tiempo para explicar mucho más, pero no dudes en contactar conmigo para cualquier otras dudas que tengas.

Un saludo y bienvenido a este apasionante mundillo ;)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

snake-game

Publicado por Trabajador_turista (2 intervenciones) el 28/09/2023 13:19:04
Muchas gracias, por tu respuesta, estaré trabajando con arreglos para conseguir el quiebre de la serpiente, y me parece muy bueno tu nivel, saludos y suerte.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar