add beard extension

This commit is contained in:
Stefan Bühler 2012-07-15 04:16:36 +02:00
parent ed7bbb33dc
commit 669d0b1a3b
48 changed files with 155 additions and 44 deletions

View File

@ -1,5 +1,6 @@
MAPS= MAPS=
MAPS+=$(wildcard ../maps/beard*.map)
MAPS+=$(wildcard ../maps/trampoline*.map) MAPS+=$(wildcard ../maps/trampoline*.map)
MAPS+=$(wildcard ../maps/flood*.map) MAPS+=$(wildcard ../maps/flood*.map)
MAPS+=$(wildcard ../maps/contest?.map ../maps/contest10.map) MAPS+=$(wildcard ../maps/contest?.map ../maps/contest10.map)
@ -12,9 +13,10 @@ maps.js: FORCE
./mapsToJson.js $(MAPS) > maps.js.new ./mapsToJson.js $(MAPS) > maps.js.new
@if test ! -e maps.js || ! diff maps.js maps.js.new > /dev/null; then echo "new maps"; mv maps.js.new maps.js; else rm maps.js.new; fi @if test ! -e maps.js || ! diff maps.js maps.js.new > /dev/null; then echo "new maps"; mv maps.js.new maps.js; else rm maps.js.new; fi
SPRITES=earth.png empty.png lambda.png liftclosed.png liftopen.png robot.png rock.png wall.png SPRITES=earth.png empty.png lambda.png lift.png openlift.png miner.png rock.png bricks.png
SPRITES+=$(wildcard trampoline?.png) SPRITES+=$(wildcard trampoline?.png)
SPRITES+=$(wildcard target?.png) SPRITES+=$(wildcard target?.png)
SPRITES+=beard.png razor.png
sprites.png: $(SPRITES) sprites.png: $(SPRITES)
convert -background "#000000" -append $(SPRITES) tmp_sprites.png convert -background "#000000" -append $(SPRITES) tmp_sprites.png

BIN
js/beard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

BIN
js/bricks.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

View File

@ -16,7 +16,9 @@ var mineGui_spriteOffset = {
'.': 0, '.': 0,
' ': 1, ' ': 1,
'A': 8,'B': 9,'C':10,'D':11,'E':12,'F':13,'G':14,'H':15,'I':16, 'A': 8,'B': 9,'C':10,'D':11,'E':12,'F':13,'G':14,'H':15,'I':16,
'1':17,'2':18,'3':19,'4':20,'5':21,'6':22,'7':23,'8':24,'9':25 '1':17,'2':18,'3':19,'4':20,'5':21,'6':22,'7':23,'8':24,'9':25,
'W':26,
'!':27
}; };
var mineGui_images = {}; var mineGui_images = {};
@ -39,7 +41,7 @@ function mineGui_start() {
var selMap = document.getElementById("mineGui_selectMap"); var selMap = document.getElementById("mineGui_selectMap");
var inpMoves = document.getElementById("mineGui_moves"); var inpMoves = document.getElementById("mineGui_moves");
var customMapInput = document.getElementById("mineGui_data") var customMapInput = document.getElementById("mineGui_data")
var validMoves = {L:1,U:1,R:1,D:1,A:1,W:1}; var validMoves = {L:1,U:1,R:1,D:1,A:1,W:1,S:1};
var k; var k;
document.getElementById("mineGui_addData").onclick = mineGui_addCustomMap; document.getElementById("mineGui_addData").onclick = mineGui_addCustomMap;
selMap.onchange = function() { selMap.onchange = function() {
@ -256,5 +258,6 @@ function mineGui_show() {
document.getElementById("mineGui_score").textContent = mineGui_mine.score; document.getElementById("mineGui_score").textContent = mineGui_mine.score;
document.getElementById("mineGui_scoreMoves").textContent = mineGui_mine.moves; document.getElementById("mineGui_scoreMoves").textContent = mineGui_mine.moves;
document.getElementById("mineGui_scoreLambdas").textContent = mineGui_mine.found_lambdas; document.getElementById("mineGui_scoreLambdas").textContent = mineGui_mine.found_lambdas;
document.getElementById("mineGui_razors").textContent = mineGui_mine.razors;
document.getElementById("mineGui_belowWater").textContent = mineGui_mine.moves_below_water; document.getElementById("mineGui_belowWater").textContent = mineGui_mine.moves_below_water;
} }

2
js/gui.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -24,7 +24,8 @@
<div>Score: <b style="font:monospace" id="mineGui_score">0</b> <div>Score: <b style="font:monospace" id="mineGui_score">0</b>
<span style="font-size:80%"> <span style="font-size:80%">
(<b style="font:monospace" id="mineGui_scoreMoves">0</b> moves, (<b style="font:monospace" id="mineGui_scoreMoves">0</b> moves,
found <b style="font:monospace" id="mineGui_scoreLambdas">0</b> Lambdas) found <b style="font:monospace" id="mineGui_scoreLambdas">0</b> Lambdas,
have <b style="font:monospace" id="mineGui_razors">0</b> razors)
</span> </span>
</div> </div>
<div>Status: <b style="font:monospace" id="mineGui_state">0</b></div> <div>Status: <b style="font:monospace" id="mineGui_state">0</b></div>
@ -34,7 +35,7 @@
<br /> <br />
<pre>Help: <pre>Help:
(<b>L</b>)eft/(<b>U</b>)p/(<b>R</b>)ight/(<b>D</b>)own work as expected (letter and arrow keys), (<b>A</b>)bort and (<b>W</b>)ait too. (<b>L</b>)eft/(<b>U</b>)p/(<b>R</b>)ight/(<b>D</b>)own work as expected (letter and arrow keys), (<b>S</b>)have, (<b>A</b>)bort and (<b>W</b>)ait too.
Special keys: PageUp/PageDown for map select, Backspace for undo, (<b>C</b>)lear and (<b>T</b>)oggle text mode Special keys: PageUp/PageDown for map select, Backspace for undo, (<b>C</b>)lear and (<b>T</b>)oggle text mode
Be careful: a reload looses all custom maps and saved moves. Be careful: a reload looses all custom maps and saved moves.
Listed highscore can be outdated. Listed highscore can be outdated.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 139 B

BIN
js/lift.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 B

File diff suppressed because one or more lines are too long

2
js/maps.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -46,12 +46,21 @@ var Mine = function() {
this.lift = this.robot = false; this.lift = this.robot = false;
this.trampoline = { this.trampoline = {
sources: { }, // x, y and target sources: { }, // x, y and target
targets: { }, // x, y and sources targets: { } // x, y and sources
}; };
this.trampoline.targets = {}; this.beard = {
growth: 25,
razors: 0
};
map.splice(height, 0, repeat('#', width));
map.splice(0, 0, repeat('#', width), repeat('#', width));
height = height + 3;
width = width + 2;
for (i = 0; i < height; ++i) { for (i = 0; i < height; ++i) {
// padding // padding
if (map[i].length < width) map[i] += repeat(' ', width - map[i].length); if (map[i].length < width-2) map[i] += repeat(' ', width - map[i].length - 2);
// extra # padding:
map[i] = '#' + map[i] + '#';
line = map[i] = map[i].split(''); line = map[i] = map[i].split('');
// scan // scan
@ -61,6 +70,8 @@ var Mine = function() {
case '*': case '*':
case '#': case '#':
case '.': case '.':
case 'W':
case '!':
break; break;
case '\\': case '\\':
this.lambdas++; this.lambdas++;
@ -82,7 +93,7 @@ var Mine = function() {
if (this.trampoline.targets[line[x]]) throw "Can have only one trampoline target " + line[x]; if (this.trampoline.targets[line[x]]) throw "Can have only one trampoline target " + line[x];
this.trampoline.targets[line[x]] = { x: x, y: i, sources: [] }; this.trampoline.targets[line[x]] = { x: x, y: i, sources: [] };
} else { } else {
throw "Invalid character in map: '" + line[x] + "'"; throw "Invalid character in map: '" + line[x] + "'" + x;
} }
break; break;
} }
@ -99,13 +110,13 @@ var Mine = function() {
var words = lines[i].split(/ +/); var words = lines[i].split(/ +/);
switch (words[0]) { switch (words[0]) {
case 'Water': case 'Water':
this.water.level = words[1]; this.water.level = parseInt(words[1]);
break; break;
case 'Flooding': case 'Flooding':
this.water.flooding = words[1]; this.water.flooding = parseInt(words[1]);
break; break;
case 'Waterproof': case 'Waterproof':
this.water.proof = words[1]; this.water.proof = parseInt(words[1]);
break; break;
case 'Trampoline': case 'Trampoline':
if (words.length !== 4 || words[2] !== 'targets') if (words.length !== 4 || words[2] !== 'targets')
@ -120,6 +131,12 @@ var Mine = function() {
this.trampoline.sources[words[1]].target = words[3]; this.trampoline.sources[words[1]].target = words[3];
this.trampoline.targets[words[3]].sources.push(words[1]); this.trampoline.targets[words[3]].sources.push(words[1]);
break; break;
case 'Growth':
this.beard.growth = parseInt(words[1]);
break;
case 'Razors':
this.beard.razors = parseInt(words[1]);
break;
default: default:
this.meta[words[0]] = words.splice(1).join(" "); this.meta[words[0]] = words.splice(1).join(" ");
break; break;
@ -136,6 +153,8 @@ var Mine = function() {
} }
} }
this.water_level = this.water.level; this.water_level = this.water.level;
this.razors = this.beard.razors;
this.beard_growth = this.beard.growth;
this.state = ALIVE; this.state = ALIVE;
}; };
@ -152,19 +171,16 @@ var Mine = function() {
case 'L': case 'L':
case 'R': case 'R':
n = (command == 'L' ? -1 : 1); n = (command == 'L' ? -1 : 1);
if (this.robot.x + n < 0) return false;
if (this.robot.x + n >= this.width) return false;
c = this.map[this.robot.y][this.robot.x+n]; c = this.map[this.robot.y][this.robot.x+n];
switch (c) { switch (c) {
case '#': return false; case '#': return false;
case ' ': case ' ':
case '.': case '.':
case '!':
case '\\': return true; case '\\': return true;
case 'L': return false; case 'L': return false;
case 'O': return true; case 'O': return true;
case '*': case '*':
if (this.robot.x + 2*n < 0) return false;
if (this.robot.x + 2*n >= this.width) return false;
if (' ' == this.map[this.robot.y][this.robot.x+2*n]) return true; if (' ' == this.map[this.robot.y][this.robot.x+2*n]) return true;
default: default:
if (this.trampoline.sources.hasOwnProperty(c)) return true; if (this.trampoline.sources.hasOwnProperty(c)) return true;
@ -174,13 +190,12 @@ var Mine = function() {
case 'U': case 'U':
case 'D': case 'D':
n = (command == 'D' ? -1 : 1); n = (command == 'D' ? -1 : 1);
if (this.robot.y + n < 0) return false;
if (this.robot.y + n >= this.height) return false;
c = this.map[this.robot.y+n][this.robot.x]; c = this.map[this.robot.y+n][this.robot.x];
switch (c) { switch (c) {
case '#': return false; case '#': return false;
case ' ': case ' ':
case '.': case '.':
case '!':
case '\\': return true; case '\\': return true;
case 'L': return false; case 'L': return false;
case 'O': return true; case 'O': return true;
@ -191,6 +206,8 @@ var Mine = function() {
} }
break; break;
case 'W': case 'W':
case 'S':
return this.razors > 0;
case 'A': case 'A':
return true; return true;
} }
@ -200,22 +217,26 @@ var Mine = function() {
Mine.prototype.move = function(command) { Mine.prototype.move = function(command) {
if (this.state != ALIVE) return false; if (this.state != ALIVE) return false;
var n, c, s, t; var n, c, s, t;
var newMap, x, y, i, j, below, map = this.map, growBeard;
command = command.toUpperCase(); command = command.toUpperCase();
if (this.validMove(command)) { if (this.validMove(command)) {
switch (command.toUpperCase()) { switch (command.toUpperCase()) {
case 'L': case 'L':
case 'R': case 'R':
n = (command == 'L' ? -1 : 1); n = (command == 'L' ? -1 : 1);
this.map[this.robot.y][this.robot.x] = ' '; map[this.robot.y][this.robot.x] = ' ';
c = this.map[this.robot.y][this.robot.x+n]; c = map[this.robot.y][this.robot.x+n];
switch (c) { switch (c) {
case '*': case '*':
this.map[this.robot.y][this.robot.x+2*n] = '*'; map[this.robot.y][this.robot.x+2*n] = '*';
break; break;
case '\\': case '\\':
this.lambdas--; this.lambdas--;
this.found_lambdas++; this.found_lambdas++;
break; break;
case '!':
this.razors++;
break;
case 'O': case 'O':
this._foundLift(); this._foundLift();
break; break;
@ -225,7 +246,7 @@ var Mine = function() {
t = this.trampoline.targets[s.target]; t = this.trampoline.targets[s.target];
for (n = 0; n < t.sources.length; ++n) { for (n = 0; n < t.sources.length; ++n) {
s = this.trampoline.sources[t.sources[n]]; s = this.trampoline.sources[t.sources[n]];
this.map[s.y][s.x] = ' '; map[s.y][s.x] = ' ';
} }
this.robot.x = t.x; this.robot.x = t.x;
this.robot.y = t.y; this.robot.y = t.y;
@ -233,18 +254,21 @@ var Mine = function() {
} }
} }
this.robot.x += n; this.robot.x += n;
this.map[this.robot.y][this.robot.x] = 'R'; map[this.robot.y][this.robot.x] = 'R';
break; break;
case 'U': case 'U':
case 'D': case 'D':
n = (command == 'D' ? -1 : 1); n = (command == 'D' ? -1 : 1);
this.map[this.robot.y][this.robot.x] = ' '; map[this.robot.y][this.robot.x] = ' ';
c = this.map[this.robot.y+n][this.robot.x]; c = map[this.robot.y+n][this.robot.x];
switch (c) { switch (c) {
case '\\': case '\\':
this.lambdas--; this.lambdas--;
this.found_lambdas++; this.found_lambdas++;
break; break;
case '!':
this.razors++;
break;
case 'O': case 'O':
this._foundLift(); this._foundLift();
break; break;
@ -254,7 +278,7 @@ var Mine = function() {
t = this.trampoline.targets[s.target]; t = this.trampoline.targets[s.target];
for (n = 0; n < t.sources.length; ++n) { for (n = 0; n < t.sources.length; ++n) {
s = this.trampoline.sources[t.sources[n]]; s = this.trampoline.sources[t.sources[n]];
this.map[s.y][s.x] = ' '; map[s.y][s.x] = ' ';
} }
this.robot.x = t.x; this.robot.x = t.x;
this.robot.y = t.y; this.robot.y = t.y;
@ -262,7 +286,13 @@ var Mine = function() {
} }
} }
this.robot.y += n; this.robot.y += n;
this.map[this.robot.y][this.robot.x] = 'R'; map[this.robot.y][this.robot.x] = 'R';
break;
case 'S':
--this.razors;
for (var i = -1; i <= 1; ++i) for (var j = -1; j <= 1; ++j) {
if ('W' == map[this.robot.y+i][this.robot.x+j]) map[this.robot.y+i][this.robot.x+j] = ' ';
}
break; break;
case 'A': case 'A':
this._abort(); this._abort();
@ -276,35 +306,44 @@ var Mine = function() {
} }
} }
var newMap = [], x, y, below; newMap = [];
for (y = 0; y < this.height; ++y) { newMap[y] = this.map[y].slice(); } growBeard = false;
if (0 > --this.beard_growth) {
this.beard_growth = this.beard.growth;
growBeard = true;
}
for (y = 0; y < map.length; ++y) { newMap[y] = this.map[y].slice(); }
for (y = 0; y < this.height; ++y) { for (y = 2; y < 2+this.height; ++y) {
for (x = 0; x < this.width; ++x) { for (x = 1; x <= this.width; ++x) {
if ('*' == this.map[y][x]) { if ('*' == map[y][x]) {
below = this.get(x, y-1); below = map[y-1][x];
if (' ' == below) { if (' ' == below) {
// fall down // fall down
newMap[y-1][x] = '*'; newMap[y-1][x] = '*';
newMap[y][x] = ' '; newMap[y][x] = ' ';
if ('R' == this.get(x, y-2)) this._crushed(); if ('R' == map[y-2][x]) this._crushed();
} else if ((below == '*' || below == '\\') && ' ' == this.get(x+1, y-1) && ' ' == this.map[y][x+1]) { } else if ((below == '*' || below == '\\') && ' ' == map[y-1][x+1] && ' ' == map[y][x+1]) {
// fall right // fall right
newMap[y-1][x+1] = '*'; newMap[y-1][x+1] = '*';
newMap[y][x] = ' '; newMap[y][x] = ' ';
if ('R' == this.get(x+1, y-2)) this._crushed(); if ('R' == map[y-2][x+1]) this._crushed();
} else if ((below == '*') && ' ' == this.get(x-1, y-1) && ' ' == this.map[y][x-1]) { } else if ((below == '*') && ' ' == map[y-1][x-y] && ' ' == map[y][x-1]) {
// fall left // fall left
newMap[y-1][x-1] = '*'; newMap[y-1][x-1] = '*';
newMap[y][x] = ' '; newMap[y][x] = ' ';
if ('R' == this.get(x-1, y-2)) this._crushed(); if ('R' == map[y-2][x-1]) this._crushed();
}
} else if (growBeard && 'W' == map[y][x]) {
for (i = -1; i <= 1; ++i) for (j = -1; j <= 1; ++j) {
if (' ' == map[y+i][x+j]) newMap[y+i][x+j] = 'W';
} }
} }
} }
} }
this.map = newMap; this.map = newMap;
if (this.robot.y < this.water_level) { if (this.robot.y < this.water_level + 2) {
this.moves_below_water++; this.moves_below_water++;
if (this.moves_below_water > this.water.proof) this._drown(); if (this.moves_below_water > this.water.proof) this._drown();
} else { } else {
@ -357,7 +396,7 @@ var Mine = function() {
}; };
Mine.prototype.toString = function() { Mine.prototype.toString = function() {
return this.map.map(function(l) { return l.join(''); }).reverse().join("\n"); return this.map.slice(2,-1).map(function(l) { return l.slice(1,-1).join(''); }).reverse().join("\n");
}; };
Mine.prototype.metaText = function() { Mine.prototype.metaText = function() {
@ -372,6 +411,8 @@ var Mine = function() {
for (k = 0; k < keys.length; ++k) { for (k = 0; k < keys.length; ++k) {
lines.push("Trampoline " + keys[k] + " targets " + this.trampoline.sources[keys[k]].target); lines.push("Trampoline " + keys[k] + " targets " + this.trampoline.sources[keys[k]].target);
} }
if (this.beard.growth != 25) lines.push("Growth " + this.beard.growth);
if (this.beard.razors != 0) lines.push("Razors " + this.beard.razors);
keys = []; keys = [];
for (k in this.meta) { for (k in this.meta) {

2
js/mine.min.js vendored

File diff suppressed because one or more lines are too long

BIN
js/miner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

BIN
js/openlift.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

BIN
js/razor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 741 B

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 675 B

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 663 B

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 650 B

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 651 B

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 664 B

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 639 B

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 659 B

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 658 B

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 654 B

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 653 B

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 609 B

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 610 B

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 B

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 597 B

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 604 B

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 598 B

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 B

After

Width:  |  Height:  |  Size: 148 B

13
maps/beard1.map Normal file
View File

@ -0,0 +1,13 @@
##########
#** \\\\#
#.R.. #
# \ ..*\#
#! ..*!#
#### # #
#\\... # L
#\\.W... #
#\\. #
##########
Growth 15
Razors 0

19
maps/beard2.map Normal file
View File

@ -0,0 +1,19 @@
##############################
#R...........................#
#.........................W..#
#..\\\\\\\\\\\\\\\\\\\\\\\\..#
#............................#
#..*****.*\...*...*...*****..#
#..*\....*\....*\*..*.\\*\\..#
#..*\....****..!*!......*....#
#..*\....*\....*\*..*...*....#
#..*\....*\...*...*.....*....#
#............................#
#..\\\\\\\\\\\\\\\\\\\\\\\\..#
#................ ..... .....#
#................ W....L#
##############################
Growth 25
Razors 10
Flooding 20

16
maps/beard3.map Normal file
View File

@ -0,0 +1,16 @@
################
#*****#!! 1 #
#..\..# #
#########\\\\ # .\\\. #
#.............# * #
#.. .\\\#..!..#\** #
#.. LW\\#W ..##### ####
#..R\\\\#.. ..*\*\*W...#
#.......A.. ...\.\...\\#
#.......... ** #
############....\.######
#.....!#
########
Growth 10
Trampoline A targets 1

16
maps/beard4.map Normal file
View File

@ -0,0 +1,16 @@
####################
#W\\!#\\\**.\#W\\\W#
##*######..###..\\\#
#.......\.R ###...\#
#####.###.#.......##
#.......#.#\####.###
#\\##\###\#\\#...#.L
#\##\.###.####.#.#.#
#\W#####.....###.W.#
####\\...\\\...#.#.#
#W*######.######.#.#
#\\\\\\\\\.........#
############\###\###
#\\.. *..........\\#
#W... #.........##W#
####################

BIN
specs/beards.pdf Normal file

Binary file not shown.

BIN
specs/images/beard.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
specs/images/razor.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
specs/images/target.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
specs/images/trampoline.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB