Pārlūkot izejas kodu

Refonte du code pour préciser les objectifs de chaque classe et séparer leurs tâches

les classes game et tube servent à décrire et modifier les données du modèle du jeu
la classe drawer s'occupe d'afficher le jeu dans la page web via les méthodes fournies par la librairie p5js
la classe controller s'occupe de la logique interne aux régles du jeu
la classe main sert à déclarer le controller ainsi que les méthodes appelées par la librairie p5js
master
Figg 10 mēnešus atpakaļ
vecāks
revīzija
e7ea88f832
8 mainītis faili ar 243 papildinājumiem un 178 dzēšanām
  1. 8
    7
      index.html
  2. 120
    38
      js/controller.js
  3. 25
    29
      js/drawer.js
  4. 0
    102
      js/game.js
  5. 0
    0
      js/lib/p5.min.js
  6. 16
    0
      js/main.js
  7. 67
    0
      js/model/game.js
  8. 7
    2
      js/model/tube.js

+ 8
- 7
index.html Parādīt failu

@@ -4,13 +4,14 @@
4 4
 <head>
5 5
 	<meta charset="utf-8">
6 6
 	<meta name="viewport" content="width=device-width, initial-scale=1.0">
7
-	<title>p5.js example</title>
7
+	<title>Le jeu des tubes là</title>
8 8
 	<link href="./css/style.css" rel="stylesheet">
9
-	<script src="./js/p5.min.js"></script>
10
-	<script src="./js/tube.js"></script>
11
-	<script src="./js/game.js"></script>
9
+	<script src="./js/lib/p5.min.js"></script>
10
+	<script src="./js/model/tube.js"></script>
11
+	<script src="./js/model/game.js"></script>
12 12
 	<script src="./js/drawer.js"></script>
13 13
 	<script src="./js/controller.js"></script>
14
+	<script src="./js/main.js"></script>
14 15
 </head>
15 16
 
16 17
 <body>
@@ -28,10 +29,10 @@
28 29
 			<input type="number" size="5" id="padding" value="10">
29 30
 		</menuitem>
30 31
 		<menuitem>
31
-			<label>Tube Size</label>
32
-			<input type="number" size="5" id="tbSize" value="50">
32
+			<label>Tube Scale</label>
33
+			<input type="number" size="5" id="scale" value="50">
33 34
 		</menuitem>
34
-		<button type="button" onclick="newGame()">New game</button>
35
+		<button type="button" onclick="controller.initializeGame()">New game</button>
35 36
 	</menu>
36 37
 	<main oncontextmenu="return false;">
37 38
 	</main>

+ 120
- 38
js/controller.js Parādīt failu

@@ -1,50 +1,132 @@
1
-function setup()
1
+class Controller
2 2
 {
3
-	newGame();
4
-}
3
+	#game;
4
+	#drawer;
5
+	#colorsBank = ['black','silver','gray','maroon','red','purple','fuchsia','green','lime','olive','yellow','navy','blue','teal','aqua'];
6
+	
7
+	constructor()
8
+	{
9
+		this.initializeGame();
10
+	}
11
+	
12
+	initializeGame() {
13
+		let params = this.gatherMenuValues();
14
+		
15
+		this.game = new Game(params.TUBESNUMBERS, params.TUBESLEVELS);
16
+		this.drawer = new Drawer(params.PADDING, params.SCALE);
17
+		
18
+		this.drawer.computeGameParams(params.TUBESNUMBERS, params.TUBESLEVELS);
19
+		
20
+		this.initializeColorTubes(params.TUBESLEVELS - 1);
21
+		
22
+		this.needUpdate = true;
23
+	}
5 24
 
6
-function newGame() {
7
-	let params = gatherMenuValues();
25
+	gatherMenuValues()
26
+	{
27
+		let inputTubesNumbers = parseInt(document.getElementById("tbNumber").value);
28
+		let inputTubesLevels = parseInt(document.getElementById("tbLevel").value);
29
+		let inputScale = parseInt(document.getElementById("scale").value);
30
+		let inputPadding = parseInt(document.getElementById("padding").value);
31
+		
32
+		return {
33
+			TUBESNUMBERS: inputTubesNumbers,
34
+			TUBESLEVELS: inputTubesLevels,
35
+			SCALE: inputScale,
36
+			PADDING: inputPadding
37
+		};
38
+	}
8 39
 	
9
-	this.game = new Game(params.TUBESNUMBERS, params.TUBESLEVELS);
10
-	this.drawer = new Drawer(params.PADDING);
40
+	initializeColorTubes(LayersPerTube)
41
+	{
42
+		let nbTubes = this.game.tubesNumber() - 1;
43
+		let allColors = [];
44
+		
45
+		for (let i = 0; i < nbTubes; i++)
46
+		{
47
+			let coloridx = i % this.#colorsBank.length;
48
+			for (let times = 0; times < LayersPerTube; times++)
49
+			{
50
+				allColors.push(this.#colorsBank[coloridx]);
51
+			}
52
+		}
53
+		
54
+		for (let index = allColors.length - 1; index >= 0; index--) {
55
+			let randomIndex = Math.floor(Math.random() * (index + 1));
56
+			let tubeIndex = Math.floor(index / LayersPerTube);
57
+			
58
+			this.game.tubeAt(tubeIndex).addColorLayer(allColors[randomIndex]);
59
+			
60
+			allColors[randomIndex] = allColors[index];
61
+		}
62
+	}
11 63
 	
12
-	this.drawer.setTubesParams(params.TUBESNUMBERS, params.TUBESLEVELS, params.TUBESIZE);
64
+	clickTube(tubeIndex)
65
+	{
66
+		let _clickedTube = this.game.tubeAt(tubeIndex);
67
+		if (_clickedTube == null) return;
68
+		
69
+		if (_clickedTube == this.game.selectedTube())
70
+			this.game.unselectTube();
71
+		else if (this.canPourInto(this.game.selectedTube(), _clickedTube))
72
+		{
73
+			this.pourColorInto(this.game.selectedTube(), _clickedTube);
74
+			this.game.unselectTube();
75
+		}
76
+		else if (!_clickedTube.isEmpty())
77
+			this.game.selectTubeAt(tubeIndex);
78
+	}
13 79
 	
14
-	this.needUpdate = true;
15
-}
16
-
17
-function mousePressed(e) 
18
-{
19
-	let tubeId = this.drawer.getTubeIdAt(mouseX, mouseY);
80
+	canPourInto(sourceTube, targetTube)
81
+	{
82
+		return sourceTube != null && targetTube != null
83
+			&& sourceTube != targetTube
84
+			&& (targetTube.isEmpty() || sourceTube.peekTopColor() == targetTube.peekTopColor())
85
+			&& !targetTube.isFull();
86
+	}
20 87
 	
21
-	if (tubeId != -1)
88
+	pourColorInto(sourceTube, targetTube)
22 89
 	{
23
-		this.game.selectTube(tubeId);
90
+		while (this.canPourInto(sourceTube, targetTube))
91
+		{
92
+			targetTube.addColorLayer(sourceTube.removeColorLayer());
93
+		}
94
+		
95
+		this.checkTubeCompletion(sourceTube);
96
+		this.checkTubeCompletion(targetTube);
24 97
 	}
25 98
 	
26
-	this.needUpdate = true;
27
-}
28
-
29
-function gatherMenuValues()
30
-{
31
-	let inputTubesNumbers = parseInt(document.getElementById("tbNumber").value);
32
-	let inputTubesLevels = parseInt(document.getElementById("tbLevel").value);
33
-	let inputTubeSize = parseInt(document.getElementById("tbSize").value);
34
-	let inputPadding = parseInt(document.getElementById("padding").value);
35
-	
36
-	return {
37
-		TUBESNUMBERS: inputTubesNumbers,
38
-		TUBESLEVELS: inputTubesLevels,
39
-		TUBESIZE: inputTubeSize,
40
-		PADDING: inputPadding
41
-	};
42
-}
43
-function draw()
44
-{
45
-	if (!this.needUpdate) return;
99
+	checkTubeCompletion(tube)
100
+	{
101
+		if (tube.isComplete())
102
+		{
103
+			this.game.removeTube(tube);
104
+			this.checkGameCompletion();
105
+		}
106
+	}
46 107
 	
47
-	this.drawer.draw(this.game);
108
+	checkGameCompletion()
109
+	{
110
+		if (this.game.tubesNumber() == 1 && this.game.tubeAt(0).isEmpty())
111
+		{
112
+			this.game.clean();
113
+		}
114
+	}
115
+
116
+	mousePressed(e) 
117
+	{
118
+		let clickedTubeId = this.drawer.getTubeIdAt(mouseX, mouseY);
119
+		this.clickTube(clickedTubeId);
120
+		
121
+		this.needUpdate = true;
122
+	}
48 123
 	
49
-	this.needUpdate = false;
124
+	runLoop()
125
+	{
126
+		if (!this.needUpdate) return;
127
+		
128
+		this.drawer.draw(this.game);
129
+		
130
+		this.needUpdate = false;
131
+	}
50 132
 }

+ 25
- 29
js/drawer.js Parādīt failu

@@ -1,64 +1,60 @@
1 1
 class Drawer
2 2
 {
3
-	#canvasWidth
4
-	#canvasHeight
3
+	#canvas;
5 4
 	
6
-	constructor(_padding)
5
+	constructor(_padding, _scale)
7 6
 	{
8 7
 		this.padding = _padding;
8
+		this.scale = _scale;
9 9
 		
10
-		createCanvas(0, 0);
10
+		this.#canvas = createCanvas(0, 0);
11 11
 	}
12 12
 	
13
-	setTubesParams(_tubesNumbers, _tubeLevels, _tubeSize)
13
+	computeGameParams(_tubesNumbers, _tubeLevels)
14 14
 	{
15
-		this.tubesNumbers = _tubesNumbers;
16
-		this.tubeLevels = _tubeLevels;
17
-		this.tubeSize = _tubeSize;
15
+		let canvasWidth = _tubesNumbers * (this.scale + this.padding) + this.padding;
16
+		let canvasHeight = 2 * this.padding + (_tubeLevels+1) * this.scale;
18 17
 		
19
-		this.#canvasWidth = this.tubesNumbers * (this.tubeSize + this.padding) + this.padding;
20
-		this.#canvasHeight = 2 * this.padding + (this.tubeLevels+1) * this.tubeSize;
21
-		
22
-		resizeCanvas(this.#canvasWidth, this.#canvasHeight);
18
+		resizeCanvas(canvasWidth, canvasHeight);
23 19
 	}
24 20
 	
25 21
 	draw(game)
26 22
 	{
27
-		let tubes = game.tubes;
28
-		let selectedTube = game.selectedTube;
29
-		
30
-		background('white');
23
+		background('orange');
31 24
 		
32
-		this.drawTubes(this.padding, this.padding+this.tubeSize, tubes, selectedTube);
25
+		this.drawTubes(this.padding, this.padding+this.scale, game);
33 26
 	}
34 27
 
35
-	drawTubes(x, y, tubes, selectedTube)
28
+	drawTubes(x, y, game)
36 29
 	{
37 30
 		let tubeX = x;
38 31
 		let tubeY = y;
39 32
 		let selectionOffset = 0;
40 33
 		
41
-		tubes.forEach(tube => {
42
-			selectionOffset = (tube == selectedTube ? this.tubeSize : 0);
34
+		for (let i = 0; i < game.tubesNumber(); i++)
35
+		{
36
+			let tube = game.tubeAt(i);
37
+			selectionOffset = (tube == game.selectedTube() ? this.scale : 0);
43 38
 			
44 39
 			this.drawTube(tubeX, tubeY - selectionOffset, tube);
45
-			tubeX += this.padding + this.tubeSize;
46
-		});
40
+			tubeX += this.padding + this.scale;
41
+		}
47 42
 	}
48 43
 
49 44
 	drawTube(x, y, tube)
50 45
 	{
46
+		let tubeLevels = tube.height();
51 47
 		
52
-		y += (this.tubeLevels-1) * this.tubeSize;
48
+		y += (tubeLevels-1) * this.scale;
53 49
 		
54
-		for(let i = 0; i < this.tubeLevels; i++)
50
+		for(let i = 0; i < tubeLevels; i++)
55 51
 		{
56 52
 			color = tube.getColorAtLevel(i);
57 53
 			color == null ? noFill() : fill(color);
58 54
 			
59 55
 			if (i >= 0)
60 56
 			{
61
-				rect(x, y - i * this.tubeSize, this.tubeSize);
57
+				rect(x, y - i * this.scale, this.scale);
62 58
 			}
63 59
 		}
64 60
 	}
@@ -67,15 +63,15 @@ class Drawer
67 63
 	{
68 64
 		if (!this.isInboundsCanvas(x,y)) return -1;
69 65
 		
70
-		let idWithPadding = (x - this.padding) / (this.tubeSize + this.padding);
71
-		return idWithPadding % 1 > 1 - (this.padding / (this.tubeSize + this.padding)) ? -1 : int(idWithPadding);
66
+		let idWithPadding = (x - this.padding) / (this.scale + this.padding);
67
+		return idWithPadding % 1 > 1 - (this.padding / (this.scale + this.padding)) ? -1 : int(idWithPadding);
72 68
 	}
73 69
 	
74 70
 	isInboundsCanvas(x, y)
75 71
 	{
76 72
 		return x >= this.padding
77 73
 			&& y >= this.padding
78
-			&& x < this.#canvasWidth - this.padding
79
-			&& y < this.#canvasHeight - this.padding;
74
+			&& x < this.#canvas.width - this.padding
75
+			&& y < this.#canvas.height - this.padding;
80 76
 	}
81 77
 }

+ 0
- 102
js/game.js Parādīt failu

@@ -1,102 +0,0 @@
1
-class Game {
2
-	#colorsBank = ['black','silver','gray','maroon','red','purple','fuchsia','green','lime','olive','yellow','navy','blue','teal','aqua'];
3
-	
4
-	constructor(nbTubes, tubeLevel)
5
-	{
6
-		this.tubes = [];
7
-		this.selectedTube = null;
8
-		
9
-		for (let i = 0; i < nbTubes; i++)
10
-		{
11
-			this.tubes.push(new Tube(tubeLevel));
12
-		}
13
-		
14
-		this.initializeColorTubes(tubeLevel);
15
-	}
16
-	
17
-	/*	The goal is to have each tube filled with its own color. Thus, there
18
-		is (tubes minus one) different colors divided in (tubeLevel) layers
19
-		mixed in the tubes.
20
-		One tube is empty to allow movement.
21
-	*/
22
-	initializeColorTubes(tubeLevel)
23
-	{
24
-		let nbTubes = this.tubes.length - 1;
25
-		let allColors = [];
26
-		
27
-		for (let i = 0; i < nbTubes; i++)
28
-		{
29
-			let coloridx = i % this.#colorsBank.length;
30
-			for (let times = 0; times < tubeLevel-1; times++)
31
-			{
32
-				allColors.push(this.#colorsBank[coloridx]);
33
-			}
34
-		}
35
-		
36
-		for (let i = allColors.length - 1; i > 0; i--) {
37
-			let j = Math.floor(Math.random() * (i + 1));
38
-			let temp = allColors[i];
39
-			allColors[i] = allColors[j];
40
-			allColors[j] = temp;
41
-		}
42
-		
43
-		for (let index = 0; index < allColors.length; index++)
44
-		{
45
-			let tubeIndex = Math.floor(index/(tubeLevel-1));
46
-			this.tubes[tubeIndex].addColorLayer(allColors[index]);
47
-		}
48
-	}
49
-	
50
-	selectTube(tubeId)
51
-	{
52
-		let newSelectedTube = this.tubes[tubeId];
53
-		
54
-		if (this.selectedTube == newSelectedTube)
55
-			this.selectedTube = null;
56
-		else if (this.canPourInto(this.selectedTube, newSelectedTube))
57
-			this.pourColorInto(this.selectedTube, newSelectedTube);
58
-		else if (!newSelectedTube.isEmpty())
59
-			this.selectedTube = newSelectedTube;
60
-	}
61
-	
62
-	canPourInto(sourceTube, targetTube)
63
-	{
64
-		return sourceTube != null && targetTube != null
65
-			&& sourceTube != targetTube
66
-			&& (targetTube.isEmpty() || sourceTube.peekTopColor() == targetTube.peekTopColor())
67
-			&& !targetTube.isFull();
68
-	}
69
-	
70
-	pourColorInto(sourceTube, targetTube)
71
-	{
72
-		while (this.canPourInto(sourceTube, targetTube))
73
-		{
74
-			targetTube.addColorLayer(sourceTube.removeColorLayer());
75
-		}
76
-		
77
-		this.checkTubeCompletion(sourceTube);
78
-		this.checkTubeCompletion(targetTube);
79
-	}
80
-	
81
-	checkTubeCompletion(tube)
82
-	{
83
-		if (tube.isComplete()) 
84
-		{
85
-			let tubeIndex = this.tubes.indexOf(tube);
86
-			
87
-			this.tubes.splice(tubeIndex, 1);
88
-			
89
-			if (this.selectedTube == tube) this.selectedTube = null;
90
-			
91
-			this.checkGameCompletion();
92
-		}
93
-	}
94
-	
95
-	checkGameCompletion()
96
-	{
97
-		if (this.tubes.length == 1 && this.tubes[0].isEmpty())
98
-		{
99
-			this.tubes = [];
100
-		}
101
-	}
102
-}

js/p5.min.js → js/lib/p5.min.js Parādīt failu


+ 16
- 0
js/main.js Parādīt failu

@@ -0,0 +1,16 @@
1
+let controller;
2
+
3
+function setup()
4
+{
5
+	controller = new Controller();
6
+}
7
+
8
+function draw()
9
+{
10
+	controller.runLoop();
11
+}
12
+
13
+function mousePressed(e)
14
+{
15
+	controller.mousePressed(e);
16
+}

+ 67
- 0
js/model/game.js Parādīt failu

@@ -0,0 +1,67 @@
1
+class Game {
2
+	#tubes;
3
+	#selectedTube;
4
+	
5
+	constructor(nbTubes, tubeLevel)
6
+	{
7
+		this.#tubes = [];
8
+		this.#selectedTube = null;
9
+		
10
+		for (let i = 0; i < nbTubes; i++)
11
+		{
12
+			this.#tubes.push(new Tube(tubeLevel));
13
+		}
14
+	}
15
+	
16
+	tubeAt(tubeIndex)
17
+	{
18
+		if (!this.isInRange(tubeIndex)) return null;
19
+		
20
+		return this.#tubes[tubeIndex];
21
+	}
22
+	
23
+	selectedTube()
24
+	{
25
+		return this.#selectedTube;
26
+	}
27
+	
28
+	selectTubeAt(index)
29
+	{
30
+		if (this.isInRange(index))
31
+		{
32
+			this.#selectedTube = this.#tubes[index];
33
+		}
34
+	}
35
+	
36
+	removeTube(tube)
37
+	{
38
+		let tubeIndex = this.#tubes.indexOf(tube);
39
+		
40
+		if (tubeIndex != -1)
41
+		{
42
+			let removed = this.#tubes.splice(tubeIndex, 1)[0];
43
+			if (removed = this.#selectedTube) this.unselectTube();
44
+		}
45
+	}
46
+	
47
+	clean()
48
+	{
49
+		this.#tubes = []
50
+		this.unselectTube();
51
+	}
52
+	
53
+	unselectTube()
54
+	{
55
+		this.#selectedTube = null;
56
+	}
57
+	
58
+	tubesNumber()
59
+	{
60
+		return this.#tubes.length;
61
+	}
62
+	
63
+	isInRange(index)
64
+	{
65
+		return index >= 0 && index < this.#tubes.length;
66
+	}
67
+}

js/tube.js → js/model/tube.js Parādīt failu

@@ -28,6 +28,11 @@ class Tube {
28 28
 		this.#colors = [];
29 29
 	}
30 30
 	
31
+	height()
32
+	{
33
+		return this.#maxLevels;
34
+	}
35
+	
31 36
 	isFull()
32 37
 	{
33 38
 		return this.#colors.length == this.#maxLevels;
@@ -38,7 +43,7 @@ class Tube {
38 43
 		return this.#colors.length == 0;
39 44
 	}
40 45
 	
41
-	emptySpaceSize()
46
+	remainingSpace()
42 47
 	{
43 48
 		return this.#maxLevels - this.#colors.length;
44 49
 	}
@@ -59,7 +64,7 @@ class Tube {
59 64
 
60 65
 	isComplete()
61 66
 	{
62
-		if (this.emptySpaceSize() != 1) return false;
67
+		if (this.remainingSpace() != 1) return false;
63 68
 		
64 69
 		let reference = this.#colors[0];
65 70
 		

Notiek ielāde…
Atcelt
Saglabāt