arkanoid
This commit is contained in:
parent
180b51993c
commit
c83de00f1c
206
breakout.js
206
breakout.js
|
@ -1,19 +1,31 @@
|
||||||
|
/* Arkanoid level is 10x10 */
|
||||||
|
|
||||||
var score = 0;
|
var score = 0;
|
||||||
var highscore = 0;
|
var highscore = 0;
|
||||||
var lives = 3;
|
var lives = 3;
|
||||||
var balls = 0;
|
var balls = 0;
|
||||||
|
|
||||||
var lvlwidth = 450;
|
var brick = World.spawn(gameobjects['brick']);
|
||||||
|
var brickbb = brick.char.boundingbox;
|
||||||
|
var bwidth = brickbb.r - brickbb.l;
|
||||||
|
var bheight = brickbb.t-brickbb.b;
|
||||||
|
brick.kill();
|
||||||
|
|
||||||
|
var rows = 15;
|
||||||
|
var cols = 13;
|
||||||
|
|
||||||
|
var lvlwidth = bwidth*cols;
|
||||||
var lvlheight = 600;
|
var lvlheight = 600;
|
||||||
|
|
||||||
let bricks = 0;
|
let bricks = 0;
|
||||||
let allbricks = [];
|
let allbricks = [];
|
||||||
|
|
||||||
|
|
||||||
//var frameworld = World
|
//var frameworld = World
|
||||||
|
|
||||||
var f = World.spawn(gameobjects['edge2d']);
|
var f = World.spawn(gameobjects['edge2d']);
|
||||||
f.edge2d.cpoints = Geometry.box(lvlwidth,lvlheight);
|
|
||||||
f.edge2d.thickness = 10;
|
f.edge2d.thickness = 10;
|
||||||
|
f.edge2d.cpoints = Geometry.box(lvlwidth+f.edge2d.thickness*2,lvlheight);
|
||||||
f.draw = function() {
|
f.draw = function() {
|
||||||
Debug.line(f.edge2d.points, Color.green, 0, f.edge2d.thickness*2);
|
Debug.line(f.edge2d.points, Color.green, 0, f.edge2d.thickness*2);
|
||||||
};
|
};
|
||||||
|
@ -22,15 +34,9 @@ register_draw(f.draw,f);
|
||||||
|
|
||||||
Debug.draw_phys(true);
|
Debug.draw_phys(true);
|
||||||
|
|
||||||
var brick = World.spawn(gameobjects['brick']);
|
|
||||||
var brickbb = brick.char.boundingbox;
|
|
||||||
var bwidth = brickbb.r - brickbb.l;
|
|
||||||
var bheight = brickbb.t-brickbb.b;
|
|
||||||
brick.kill();
|
|
||||||
|
|
||||||
var fitbricks = Math.floor(lvlwidth/bwidth);
|
var fitbricks = Math.floor(lvlwidth/bwidth);
|
||||||
|
|
||||||
let wingame = function() {
|
var wingame = function() {
|
||||||
allballs.forEach(x=>x.kill());
|
allballs.forEach(x=>x.kill());
|
||||||
Log.warn("WINNER");
|
Log.warn("WINNER");
|
||||||
Player.players[0].uncontrol(paddle);
|
Player.players[0].uncontrol(paddle);
|
||||||
|
@ -40,63 +46,77 @@ let wingame = function() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let killbrick = function() {
|
var killbrick = function() {
|
||||||
bricks--;
|
bricks--;
|
||||||
|
|
||||||
if (bricks <= 0)
|
if (bricks <= 0)
|
||||||
wingame();
|
wingame();
|
||||||
};
|
};
|
||||||
|
|
||||||
var rowbricks = 8;
|
/* Spawn bricks */
|
||||||
for (var row = 0; row < rowbricks; row++) {
|
if (!IO.exists('lvl1.json')) {
|
||||||
for (var col = 0; col < 6; col++) {
|
var lvl1 = {};
|
||||||
var brick = World.spawn(gameobjects['brick']);
|
lvl1.bricks = [];
|
||||||
allbricks.push(brick);
|
|
||||||
brick.stop = function() { killbrick(); };
|
|
||||||
bricks++;
|
|
||||||
|
|
||||||
var bcolor = Rainbow.red;
|
for (var i = 0; i < rows; i++) {
|
||||||
switch (col) {
|
lvl1.bricks.push([]);
|
||||||
case 0:
|
for (var j = 0; j < cols; j++) {
|
||||||
bcolor = Rainbow.red;
|
lvl1.bricks[i].push(1);
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
bcolor = Rainbow.orange;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
bcolor = Rainbow.darkorange;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
bcolor = Rainbow.yellow;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
bcolor = Rainbow.green;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
bcolor = Rainbow.blue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
brick.char.color = bcolor;
|
|
||||||
var startcol = lvlheight/2-50; // 50 pixel gap between top and brick start
|
|
||||||
let x = -(rowbricks/2) * bwidth;
|
|
||||||
var pos = [x+bwidth*row+bwidth/2, startcol-bheight*col];
|
|
||||||
brick.pos = pos;
|
|
||||||
|
|
||||||
if (Math.random() < 0.1) {
|
|
||||||
if (Math.random() < 0.5) {
|
|
||||||
brick.powerup = function() {
|
|
||||||
var p = spawn_powerup(this.pos, () => Gamestate.spawnball());
|
|
||||||
p.color = Rainbow.blue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
brick.powerup = function() {
|
|
||||||
var p = spawn_powerup(this.pos, () => paddle.grow());
|
|
||||||
p.color = Rainbow.green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IO.slurpwrite(JSON.stringify(lvl1), 'lvl1.json');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color.Arkanoid = {
|
||||||
|
white: [0,0,0,255],
|
||||||
|
orange: [255,143,0,255],
|
||||||
|
teal: [0,255,255,255],
|
||||||
|
green: [0,255,0,255],
|
||||||
|
red: [255,0,0,255],
|
||||||
|
blue: [0,112,255,255],
|
||||||
|
purple: [255,0,255,255],
|
||||||
|
yellow: [255,255,0],
|
||||||
|
silver: [157,157,157],
|
||||||
|
gold: [188,174,0],
|
||||||
|
};
|
||||||
|
|
||||||
|
Color.Arkanoid.Powerups = {
|
||||||
|
red: [174,0,0], /* laser */
|
||||||
|
blue: [0,0,174], /* enlarge */
|
||||||
|
green: [0,174,0], /* catch */
|
||||||
|
orange: [224,143,0], /* slow */
|
||||||
|
purple: [210,0,210], /* break */
|
||||||
|
cyan: [0,174,255], /* disruption */
|
||||||
|
gray: [143,143,143] /* 1up */
|
||||||
|
};
|
||||||
|
|
||||||
|
var lvl = JSON.parse(IO.slurp("lvl1.json"));
|
||||||
|
|
||||||
|
for (var row = 0; row < rows; row++) {
|
||||||
|
for (var col = 0; col < cols; col++) {
|
||||||
|
if (lvl.bricks[row][col] === 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var brick = World.spawn(gameobjects['brick']);
|
||||||
|
allbricks.push(brick);
|
||||||
|
brick.powerup = function() {
|
||||||
|
if (Math.random() < 0.1)
|
||||||
|
spawn_random_powerup(this.pos);
|
||||||
|
|
||||||
|
killbrick();
|
||||||
|
};
|
||||||
|
|
||||||
|
bricks++;
|
||||||
|
|
||||||
|
// brick.char.color = bcolor;
|
||||||
|
var startrow = lvlheight/2-bheight*2; // one brick gap between top and brick start
|
||||||
|
var x = -(cols/2) * bwidth;
|
||||||
|
var pos = [x+bwidth*col+bwidth/2, startrow-bheight*row];
|
||||||
|
brick.pos = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var paddle = World.spawn(gameobjects['paddle']);
|
var paddle = World.spawn(gameobjects['paddle']);
|
||||||
paddle.extents = lvlwidth/2 - f.edge2d.thickness;
|
paddle.extents = lvlwidth/2 - f.edge2d.thickness;
|
||||||
paddle.pos = [0,-lvlheight/2+paddle.height*4];
|
paddle.pos = [0,-lvlheight/2+paddle.height*4];
|
||||||
|
@ -114,6 +134,80 @@ Gamestate.spawnball = function() {
|
||||||
allballs.push(bb);
|
allballs.push(bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var powerups = {};
|
||||||
|
|
||||||
|
function mk_pup(color, fn, weight) {
|
||||||
|
weight ??= 1;
|
||||||
|
var o = {};
|
||||||
|
o.color = color;
|
||||||
|
o.fn = fn;
|
||||||
|
o.weight = weight;
|
||||||
|
return o;
|
||||||
|
};
|
||||||
|
|
||||||
|
powerups.laser = mk_pup(Color.Arkanoid.Powerups.red, null);
|
||||||
|
powerups.enlarge = mk_pup(Color.Arkanoid.Powerups.blue, null);
|
||||||
|
powerups.catch = mk_pup(Color.Arkanoid.Powerups.green, null);
|
||||||
|
powerups.slow = mk_pup(Color.Arkanoid.Powerups.orange, null);
|
||||||
|
powerups.break = mk_pup(Color.Arkanoid.Powerups.purple, null, 0.5);
|
||||||
|
powerups.disruption = mk_pup(Color.Arkanoid.Powerups.cyan, null);
|
||||||
|
powerups.player = mk_pup(Color.Arkanoid.Powerups.gray, null, 0.5);
|
||||||
|
|
||||||
|
function select_weighted(objs)
|
||||||
|
{
|
||||||
|
var total = 0;
|
||||||
|
var total = objs.reduce(function(acc, item) { acc += item.weight; return acc; }, 0);
|
||||||
|
var selection = Math.random() * total;
|
||||||
|
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < objs.length-1; i++) {
|
||||||
|
selection -= objs[i].weight;
|
||||||
|
if (selection <= 0)
|
||||||
|
return objs[i];
|
||||||
|
};
|
||||||
|
|
||||||
|
return objs.last;
|
||||||
|
}
|
||||||
|
|
||||||
|
function select_weighted_binary(objs)
|
||||||
|
{
|
||||||
|
var mobjs = objs.slice();
|
||||||
|
mobjs[0].total = 0;
|
||||||
|
for (var i = 1; i < mobjs.length; i++)
|
||||||
|
mobjs[i].total = mobjs[i-1].total + mobjs[i].weight;
|
||||||
|
|
||||||
|
var select = Math.random() * mobjs.last.total
|
||||||
|
var obj = Math.floor((mobjs.length-1)/2);
|
||||||
|
|
||||||
|
while (mobjs.length > 0) {
|
||||||
|
if (select < mobjs[obj].total) {
|
||||||
|
mobjs.splice(obj,obj-1);
|
||||||
|
obj = Math.floor((mobjs.length-1)/2);
|
||||||
|
} else if (select > mobjs[obj+1].total) {
|
||||||
|
mobjs.splice(0,obj-1);
|
||||||
|
obj = Math.floor((mobjs.length-1)/2);
|
||||||
|
} else
|
||||||
|
return mobjs[obj];
|
||||||
|
}
|
||||||
|
|
||||||
|
return mobjs[obj];
|
||||||
|
}
|
||||||
|
|
||||||
|
var last_powerup = {};
|
||||||
|
|
||||||
|
function spawn_random_powerup(pos)
|
||||||
|
{
|
||||||
|
var p = World.spawn(gameobjects['upgrade_drop']);
|
||||||
|
p.pos = pos;
|
||||||
|
|
||||||
|
var power = select_weighted(powerups.array());
|
||||||
|
if (last_powerup === power)
|
||||||
|
power = powerups.disruption;
|
||||||
|
|
||||||
|
p.color = power.color;
|
||||||
|
p.upgrade = power.fn;
|
||||||
|
}
|
||||||
|
|
||||||
function spawn_powerup(pos, fn) {
|
function spawn_powerup(pos, fn) {
|
||||||
var p = World.spawn(gameobjects['upgrade_drop']);
|
var p = World.spawn(gameobjects['upgrade_drop']);
|
||||||
p.pos = pos;
|
p.pos = pos;
|
||||||
|
|
12
config.js
12
config.js
|
@ -25,14 +25,14 @@ gameobject.clone("ball", {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var Gameboy = {
|
Color.Gameboy = {
|
||||||
darkest: [15,56,15],
|
darkest: [15,56,15],
|
||||||
dark: [48,98,48],
|
dark: [48,98,48],
|
||||||
light: [139,172,15],
|
light: [139,172,15],
|
||||||
lightest: [155,188,15]
|
lightest: [155,188,15]
|
||||||
};
|
};
|
||||||
|
|
||||||
var Rainbow = {
|
Color.Rainbow = {
|
||||||
red: [204,0,1],
|
red: [204,0,1],
|
||||||
orange: [255,102,0],
|
orange: [255,102,0],
|
||||||
darkorange: [205,102,1],
|
darkorange: [205,102,1],
|
||||||
|
@ -55,17 +55,13 @@ gameobject.clone("brick", {
|
||||||
this.timer.time = Math.random_range(2,10);
|
this.timer.time = Math.random_range(2,10);
|
||||||
}, Math.random_range(2,10));
|
}, Math.random_range(2,10));
|
||||||
|
|
||||||
this.char.color = Rainbow.red;
|
this.char.color = Color.Rainbow.red;
|
||||||
},
|
},
|
||||||
|
|
||||||
flash() {
|
flash() {
|
||||||
this.char.play("flash");
|
this.char.play("flash");
|
||||||
},
|
},
|
||||||
|
|
||||||
stop() {
|
|
||||||
Log.warn("killed a brick");
|
|
||||||
},
|
|
||||||
|
|
||||||
collide(hit) {
|
collide(hit) {
|
||||||
if (hit.obj.from !== 'ball')
|
if (hit.obj.from !== 'ball')
|
||||||
return;
|
return;
|
||||||
|
@ -164,7 +160,7 @@ gameobject.clone("upgrade_drop", {
|
||||||
size: 12,
|
size: 12,
|
||||||
phys:1,
|
phys:1,
|
||||||
collider: circle2d.clone(),
|
collider: circle2d.clone(),
|
||||||
color: Rainbow.blue,
|
color: Color.Rainbow.blue,
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
this.collider.radius = this.size;
|
this.collider.radius = this.size;
|
||||||
|
|
58
lvl1.lvl
58
lvl1.lvl
|
@ -1,58 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"from": "brick",
|
|
||||||
"pos": [
|
|
||||||
-363,
|
|
||||||
51
|
|
||||||
],
|
|
||||||
"angle": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "brick",
|
|
||||||
"pos": [
|
|
||||||
3,
|
|
||||||
52
|
|
||||||
],
|
|
||||||
"angle": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "brick",
|
|
||||||
"pos": [
|
|
||||||
336,
|
|
||||||
52
|
|
||||||
],
|
|
||||||
"angle": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "brick",
|
|
||||||
"pos": [
|
|
||||||
-197,
|
|
||||||
138
|
|
||||||
],
|
|
||||||
"angle": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "brick",
|
|
||||||
"pos": [
|
|
||||||
175,
|
|
||||||
133
|
|
||||||
],
|
|
||||||
"angle": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "brick",
|
|
||||||
"pos": [
|
|
||||||
-18,
|
|
||||||
222
|
|
||||||
],
|
|
||||||
"angle": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from": "paddle",
|
|
||||||
"pos": [
|
|
||||||
2.264005184173584,
|
|
||||||
-241.11599731445312
|
|
||||||
],
|
|
||||||
"angle": 0
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -57,8 +57,9 @@ var stt = Tween.embed(menuopts, 'superpos', [Window.dimensions.scale([0.4,0.9]),
|
||||||
|
|
||||||
Tween.embed(menuopts, 'color', rainbowchain, {time: 1, loop: "circle", whole: false});
|
Tween.embed(menuopts, 'color', rainbowchain, {time: 1, loop: "circle", whole: false});
|
||||||
|
|
||||||
var background_gui = GUI.image_fn({path:"hexagon_pattern_gray.png", color: Color.blue, width: Window.width, height: Window.height, image_repeat: true});
|
var background_gui = GUI.image_fn({path:"hexagon_pattern_gray.png", color: Color.red, width: Window.width, height: Window.height, image_repeat: true});
|
||||||
Tween.embed(background_gui, 'image_repeat_offset', [[0,0], [1,1]], {time: 1, loop: "repeat"});
|
Tween.embed(background_gui, 'image_repeat_offset', [[0,0], [1,1]], {time: 1, loop: "repeat"});
|
||||||
|
Tween.embed(background_gui, 'color', [Color.red, Color.blue], {time: 3, loop: "circle"});
|
||||||
|
|
||||||
function startmenu() {
|
function startmenu() {
|
||||||
background_gui.draw([0,0]);
|
background_gui.draw([0,0]);
|
||||||
|
|
Loading…
Reference in a new issue