breakout
This commit is contained in:
parent
0cad186c56
commit
a2ef1481b3
200
breakout.js
Normal file
200
breakout.js
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
var score = 0;
|
||||||
|
var highscore = 0;
|
||||||
|
var lives = 3;
|
||||||
|
var balls = 0;
|
||||||
|
|
||||||
|
var lvlwidth = 450;
|
||||||
|
var lvlheight = 600;
|
||||||
|
|
||||||
|
let bricks = 0;
|
||||||
|
|
||||||
|
//var frameworld = World
|
||||||
|
|
||||||
|
var f = World.spawn(gameobjects['edge2d']);
|
||||||
|
f.edge2d.cpoints = Geometry.box(lvlwidth,lvlheight);
|
||||||
|
f.edge2d.thickness = 10;
|
||||||
|
f.draw = function() {
|
||||||
|
Debug.line(f.edge2d.points, Color.green, 0, f.edge2d.thickness*2);
|
||||||
|
};
|
||||||
|
|
||||||
|
register_draw(f.draw,f);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
let towin = function()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let wingame = function() {
|
||||||
|
towin();
|
||||||
|
}
|
||||||
|
|
||||||
|
let killbrick = function() {
|
||||||
|
bricks--;
|
||||||
|
|
||||||
|
if (bricks <= 0)
|
||||||
|
wingame();
|
||||||
|
};
|
||||||
|
|
||||||
|
var rowbricks = 8;
|
||||||
|
for (var row = 0; row < rowbricks; row++) {
|
||||||
|
for (var col = 0; col < 6; col++) {
|
||||||
|
var brick = World.spawn(gameobjects['brick']);
|
||||||
|
brick.stop = function() { killbrick(); };
|
||||||
|
bricks++;
|
||||||
|
|
||||||
|
var bcolor = Rainbow.red;
|
||||||
|
switch (col) {
|
||||||
|
case 0:
|
||||||
|
bcolor = Rainbow.red;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var paddle = World.spawn(gameobjects['paddle']);
|
||||||
|
paddle.extents = lvlwidth/2 - f.edge2d.thickness;
|
||||||
|
paddle.pos = [0,-lvlheight/2+paddle.height*4];
|
||||||
|
paddle.setgrow(1);
|
||||||
|
|
||||||
|
Gamestate.spawnball = function() {
|
||||||
|
var bb = World.spawn(gameobjects['ball']);
|
||||||
|
bb.pos = bb.pos.add([0,-200]);
|
||||||
|
bb.velocity = [30,300];
|
||||||
|
bb.draw_layer = 3;
|
||||||
|
bb.tag = 'ball';
|
||||||
|
balls++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function spawn_powerup(pos, fn) {
|
||||||
|
var p = World.spawn(gameobjects['upgrade_drop']);
|
||||||
|
p.pos = pos;
|
||||||
|
p.upgrade = fn;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
function multiball(n) {
|
||||||
|
for (var i = 0; i < n; i++)
|
||||||
|
Gamestate.spawnball();
|
||||||
|
};
|
||||||
|
|
||||||
|
function lostball()
|
||||||
|
{
|
||||||
|
balls--;
|
||||||
|
if (balls === 0)
|
||||||
|
lostlife();
|
||||||
|
};
|
||||||
|
|
||||||
|
function lostgame()
|
||||||
|
{
|
||||||
|
Log.warn("LOSER");
|
||||||
|
backtomain();
|
||||||
|
}
|
||||||
|
|
||||||
|
function lostlife() {
|
||||||
|
lives--;
|
||||||
|
|
||||||
|
if (lives === 0)
|
||||||
|
lostgame();
|
||||||
|
else
|
||||||
|
Gamestate.spawnball();
|
||||||
|
};
|
||||||
|
|
||||||
|
Gamestate.spawnball();
|
||||||
|
var killbox = World.spawn(gameobjects['polygon2d']);
|
||||||
|
|
||||||
|
killbox.polygon2d.points = Geometry.box(lvlwidth,30);
|
||||||
|
killbox.pos = [0,-lvlheight/2];
|
||||||
|
killbox.polygon2d.sensor = true;
|
||||||
|
killbox.register_hit(hit => {
|
||||||
|
if (hit.obj.tag !== 'ball')
|
||||||
|
return;
|
||||||
|
|
||||||
|
hit.obj.kill();
|
||||||
|
lostball();
|
||||||
|
}, killbox);
|
||||||
|
|
||||||
|
//Sound.play("start.wav");
|
||||||
|
|
||||||
|
let gamepawn =
|
||||||
|
{
|
||||||
|
input_escape_pressed() {
|
||||||
|
backtomain();
|
||||||
|
},
|
||||||
|
|
||||||
|
input_o_pressed() {
|
||||||
|
/* Get all bricks and kill */
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function gamegui() {
|
||||||
|
var xpos = 1000;
|
||||||
|
|
||||||
|
GUI.text("SCORE", [xpos,500],1,Color.red);
|
||||||
|
GUI.text(`${score}`, [xpos,480],1);
|
||||||
|
|
||||||
|
GUI.text("HIGH SCORE", [xpos,450],1, Color.red);
|
||||||
|
GUI.text(`${highscore}`, [xpos,430],1);
|
||||||
|
|
||||||
|
GUI.text(`LIVES: ${lives}`, [xpos, 400], 1, Color.white);
|
||||||
|
|
||||||
|
GUI.text("YARKANOID", [xpos,300], 1,[5,120,240]);
|
||||||
|
|
||||||
|
GUI.text("ODPLOT GAMES", [xpos,250],1);
|
||||||
|
GUI.text("[C] 2023", [xpos,230]);
|
||||||
|
}
|
||||||
|
|
||||||
|
register_gui(gamegui);
|
||||||
|
|
||||||
|
Player.players[0].control(gamepawn);
|
||||||
|
|
||||||
|
let backtomain = function()
|
||||||
|
{
|
||||||
|
World.clear();
|
||||||
|
run("startmenu.js");
|
||||||
|
unregister_gui(gamegui);
|
||||||
|
Player.players[0].uncontrol(gamepawn);
|
||||||
|
}
|
5
bugs.md
Normal file
5
bugs.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
* Changing img of sprite sometimes changes different sprite
|
||||||
|
* Bounding box calculates incorrect width
|
||||||
|
* Calculate bounding box without instantiating first
|
||||||
|
|
||||||
|
- Look up collision functions dynamically instead of with registry
|
65
config.js
65
config.js
|
@ -32,8 +32,6 @@ var Gameboy = {
|
||||||
lightest: [155,188,15]
|
lightest: [155,188,15]
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.freeze(Gameboy);
|
|
||||||
|
|
||||||
var Rainbow = {
|
var Rainbow = {
|
||||||
red: [204,0,1],
|
red: [204,0,1],
|
||||||
orange: [255,102,0],
|
orange: [255,102,0],
|
||||||
|
@ -43,9 +41,6 @@ var Rainbow = {
|
||||||
blue: [53,51,255]
|
blue: [53,51,255]
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.freeze(Rainbow);
|
|
||||||
Object.freeze(Rainbow.yellow);
|
|
||||||
|
|
||||||
gameobject.clone("brick", {
|
gameobject.clone("brick", {
|
||||||
collider: polygon2d.clone(),
|
collider: polygon2d.clone(),
|
||||||
char: char2d.clone({
|
char: char2d.clone({
|
||||||
|
@ -68,27 +63,22 @@ gameobject.clone("brick", {
|
||||||
},
|
},
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
this.timer.kill();
|
Log.warn("killed a brick");
|
||||||
},
|
},
|
||||||
|
|
||||||
collide(hit) {
|
collide(hit) {
|
||||||
var obj = Game.object(hit.id);
|
if (hit.obj.from !== 'ball')
|
||||||
// this.timer.kill();
|
return;
|
||||||
// this.kill();
|
|
||||||
},
|
|
||||||
|
|
||||||
draw() {
|
this.powerup?.();
|
||||||
// var cl = Object.create(Rainbow.yellow);
|
this.timer.kill();
|
||||||
// Debug.box(this.pos, [100,30], cl);
|
this.kill();
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var act_x = Action.add_new("move");
|
var act_x = Action.add_new("move");
|
||||||
act_x.inputs.push("axis_ljoy");
|
act_x.inputs.push("axis_ljoy");
|
||||||
|
|
||||||
var max_x = 450;
|
|
||||||
|
|
||||||
var paddle = gameobject.clone("paddle", {
|
var paddle = gameobject.clone("paddle", {
|
||||||
collider: polygon2d.clone(),
|
collider: polygon2d.clone(),
|
||||||
img: sprite.clone(),
|
img: sprite.clone(),
|
||||||
|
@ -99,8 +89,11 @@ var paddle = gameobject.clone("paddle", {
|
||||||
|
|
||||||
length: 50,
|
length: 50,
|
||||||
height: 28,
|
height: 28,
|
||||||
lengths: [50,70,100,130,150],
|
lengths: [16,24,32,40,48],
|
||||||
size: 0,
|
growlvl: 1,
|
||||||
|
maxgrow: 5,
|
||||||
|
max_x: 0,
|
||||||
|
extents: 300,
|
||||||
|
|
||||||
input_larrow_down() { this.input_a_down(); },
|
input_larrow_down() { this.input_a_down(); },
|
||||||
|
|
||||||
|
@ -116,10 +109,15 @@ var paddle = gameobject.clone("paddle", {
|
||||||
|
|
||||||
update(dt) {
|
update(dt) {
|
||||||
this.angle = 0;
|
this.angle = 0;
|
||||||
this.pos = this.pos.add(this.frame_vel.scale(this.speed*dt)).map(p => Math.clamp(p, -max_x, max_x));
|
var fpos = this.pos;
|
||||||
|
fpos.x += this.frame_vel.x * this.speed * dt;
|
||||||
|
fpos.x = Math.clamp(fpos.x,-this.max_x,this.max_x);
|
||||||
|
this.pos = fpos;
|
||||||
this.frame_vel = [0,0];
|
this.frame_vel = [0,0];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
physupdate(dt) { this.velocity = [0,0]; },
|
||||||
|
|
||||||
gamepad_ljoy_axis(v) {
|
gamepad_ljoy_axis(v) {
|
||||||
v[1] = 0;
|
v[1] = 0;
|
||||||
this.pos = this.pos.add(v.scale(this.speed*Yugine.dt));
|
this.pos = this.pos.add(v.scale(this.speed*Yugine.dt));
|
||||||
|
@ -130,13 +128,23 @@ var paddle = gameobject.clone("paddle", {
|
||||||
this.length = this.lengths[0];
|
this.length = this.lengths[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
input_p_pressed() {
|
input_p_pressed() { this.grow(); },
|
||||||
this.grow();
|
input_l_pressed() { Gamestate.spawnball(); },
|
||||||
},
|
|
||||||
|
|
||||||
grow() {
|
grow() {
|
||||||
this.size++;
|
this.setgrow(this.growlvl + 1);
|
||||||
this.length = this.lengths[this.size];
|
},
|
||||||
|
|
||||||
|
setgrow(n) {
|
||||||
|
this.growlvl = Math.clamp(n,1,this.maxgrow);
|
||||||
|
this.length = this.lengths[this.growlvl];
|
||||||
|
this.img.path = "pill" + this.growlvl + ".png";
|
||||||
|
this.img.sync();
|
||||||
|
var d = this.img.dimensions;
|
||||||
|
this.collider.points = Geometry.box(d.x, d.y);
|
||||||
|
this.collider.sync();
|
||||||
|
|
||||||
|
this.max_x = this.extents - (d.x*this.scale)/2;
|
||||||
},
|
},
|
||||||
|
|
||||||
collide(hit) {
|
collide(hit) {
|
||||||
|
@ -144,7 +152,7 @@ var paddle = gameobject.clone("paddle", {
|
||||||
var xdiff = hit.pos.x - this.pos.x;
|
var xdiff = hit.pos.x - this.pos.x;
|
||||||
if (Math.sign(xdiff) === Math.sign(hit.obj.velocity)) return;
|
if (Math.sign(xdiff) === Math.sign(hit.obj.velocity)) return;
|
||||||
var oldvel = hit.obj.velocity;
|
var oldvel = hit.obj.velocity;
|
||||||
var scaler = Math.max(Math.abs(xdiff)/30, 0.9);
|
var scaler = Math.max(Math.abs(xdiff)/30, 1);
|
||||||
hit.obj.velocity = hit.obj.velocity.mult([-1,1]).scale(scaler);
|
hit.obj.velocity = hit.obj.velocity.mult([-1,1]).scale(scaler);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -153,17 +161,18 @@ gameobject.clone("upgrade_drop", {
|
||||||
fallspeed: 150,
|
fallspeed: 150,
|
||||||
tag: "ball",
|
tag: "ball",
|
||||||
upgrade: function() {},
|
upgrade: function() {},
|
||||||
size: 30,
|
size: 12,
|
||||||
phys:1,
|
phys:1,
|
||||||
collider: circle2d.clone(),
|
collider: circle2d.clone(),
|
||||||
|
color: Rainbow.blue,
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
this.collider.radius = 15;
|
this.collider.radius = this.size;
|
||||||
this.collider.sensor = true;
|
this.collider.sensor = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
draw() {
|
draw() {
|
||||||
Shape.circle(this.pos,this.size/3,Color.white);
|
Shape.circle(this.pos,this.size,this.color);
|
||||||
},
|
},
|
||||||
|
|
||||||
collide(hit) {
|
collide(hit) {
|
||||||
|
|
85
game.js
85
game.js
|
@ -1,84 +1 @@
|
||||||
var lvlwidth = 300;
|
load("startmenu.js");
|
||||||
var lvlheight = 500;
|
|
||||||
|
|
||||||
Debug.draw_phys(true);
|
|
||||||
sim_start();
|
|
||||||
World.loadfile("lvl1.lvl");
|
|
||||||
|
|
||||||
function spawnball() {
|
|
||||||
var bb = World.spawn(gameobjects['ball']);
|
|
||||||
bb.pos = bb.pos.add([50,0]);
|
|
||||||
bb.pos.y += 200;
|
|
||||||
bb.draw_layer = 3;
|
|
||||||
bb.tag = 'ball';
|
|
||||||
}
|
|
||||||
|
|
||||||
function spawn_powerup(pos, fn) {
|
|
||||||
var p = World.spawn(gameobjects['upgrade_drop']);
|
|
||||||
|
|
||||||
p.pos = pos;
|
|
||||||
p.upgrade = fn;
|
|
||||||
}
|
|
||||||
|
|
||||||
spawn_powerup([0,300], () => {
|
|
||||||
for (var i = 0; i < 10; i++)
|
|
||||||
spawnball();
|
|
||||||
});
|
|
||||||
|
|
||||||
function lostlife() {
|
|
||||||
lives--;
|
|
||||||
spawnball();
|
|
||||||
}
|
|
||||||
|
|
||||||
spawnball();
|
|
||||||
|
|
||||||
|
|
||||||
var f = World.spawn(gameobjects['edge2d']);
|
|
||||||
f.edge2d.cpoints = Geometry.box(lvlwidth,lvlheight);
|
|
||||||
f.edge2d.thickness = 10;
|
|
||||||
f.mass = 50;
|
|
||||||
|
|
||||||
var killbox = World.spawn(gameobjects['polygon2d']);
|
|
||||||
|
|
||||||
killbox.polygon2d.points = Geometry.box(lvlwidth,30);
|
|
||||||
killbox.pos = [0,-lvlheight/2];
|
|
||||||
killbox.polygon2d.sensor = true;
|
|
||||||
killbox.register_hit(hit => {
|
|
||||||
if (hit.obj.tag !== 'ball')
|
|
||||||
return;
|
|
||||||
|
|
||||||
hit.obj.kill();
|
|
||||||
lostlife();
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
//Sound.play("start.wav");
|
|
||||||
|
|
||||||
var score = 0;
|
|
||||||
var highscore = 0;
|
|
||||||
var lives = 3;
|
|
||||||
|
|
||||||
function gamegui() {
|
|
||||||
var xpos = 1000;
|
|
||||||
|
|
||||||
GUI.text("SCORE", [xpos,500],1,Color.red);
|
|
||||||
GUI.text(`${score}`, [xpos,480],1);
|
|
||||||
|
|
||||||
GUI.text("HIGH SCORE", [xpos,450],1, Color.red);
|
|
||||||
GUI.text(`${highscore}`, [xpos,430],1);
|
|
||||||
|
|
||||||
GUI.text(`LIVES: ${lives}`, [xpos, 400], 1, Color.white);
|
|
||||||
|
|
||||||
GUI.text("YARKANOID", [xpos,300], 1,[5,120,240]);
|
|
||||||
|
|
||||||
GUI.text("ODPLOT GAMES", [xpos,250],1);
|
|
||||||
GUI.text("[C] 2023", [xpos,230]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function startmenu() {
|
|
||||||
GUI.text("Press ENTER to start", Window.dimensions.scale(0.5));
|
|
||||||
GUI.text("Press ESCAPE to exit", Window.dimensions.scale(0.5).add([0,-100]));
|
|
||||||
}
|
|
||||||
|
|
||||||
register_gui(gamegui);
|
|
||||||
|
|
||||||
register_gui(startmenu);
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
"from": "gameobject"
|
"from": "gameobject"
|
||||||
},
|
},
|
||||||
"ball": {
|
"ball": {
|
||||||
|
"mass": 0.00001,
|
||||||
"collider": {
|
"collider": {
|
||||||
"radius": 4.39338754070273,
|
"radius": 4.39338754070273,
|
||||||
"ofset": [
|
"ofset": [
|
||||||
|
@ -56,8 +57,7 @@
|
||||||
"pos": [
|
"pos": [
|
||||||
-0.5,
|
-0.5,
|
||||||
-0.5
|
-0.5
|
||||||
],
|
]
|
||||||
"path": "pill3.png"
|
|
||||||
},
|
},
|
||||||
"from": "gameobject",
|
"from": "gameobject",
|
||||||
"scale": 2.9100000858306885
|
"scale": 2.9100000858306885
|
||||||
|
@ -103,10 +103,6 @@
|
||||||
"path": "brick.png",
|
"path": "brick.png",
|
||||||
"pos": [ -0.5, -0.5 ]
|
"pos": [ -0.5, -0.5 ]
|
||||||
},
|
},
|
||||||
"pos": [
|
|
||||||
43,
|
|
||||||
-165
|
|
||||||
],
|
|
||||||
"angle": 0,
|
"angle": 0,
|
||||||
"scale": 2.91,
|
"scale": 2.91,
|
||||||
"from": "gameobject"
|
"from": "gameobject"
|
||||||
|
|
20
startmenu.js
Normal file
20
startmenu.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
function startmenu() {
|
||||||
|
GUI.text("Press ENTER to start", Window.dimensions.scale(0.5));
|
||||||
|
GUI.text("Press ESCAPE to exit", Window.dimensions.scale(0.5).add([0,-100]));
|
||||||
|
}
|
||||||
|
|
||||||
|
register_gui(startmenu);
|
||||||
|
|
||||||
|
var startcontroller = {
|
||||||
|
input_enter_pressed() {
|
||||||
|
run("breakout.js");
|
||||||
|
Player.players[0].uncontrol(startcontroller);
|
||||||
|
unregister_gui(startmenu);
|
||||||
|
},
|
||||||
|
|
||||||
|
input_escape_pressed() {
|
||||||
|
quit();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Player.players[0].control(startcontroller);
|
Loading…
Reference in a new issue