Compare commits

..

No commits in common. "bd7080d1630fd3123dcc4172421c55254a1a16af" and "f02b76d301f22cc0f74e4d2263830047fdf2e8c9" have entirely different histories.

17 changed files with 246 additions and 309 deletions

14
ball.js
View file

@ -1,14 +0,0 @@
Object.assign(self, {
collider: circle2d.clone({radius:5}),
img: sprite.clone({path:"ball.png"}),
phys: 0,
elasticity: 1,
friction: 0,
tag: 'ball',
collide(hit) {
Sound.play("bump.wav");
},
});
self.img.pos = sprite.POS_MID;

View file

@ -3,8 +3,8 @@ var score = 0;
var highscore = 0; var highscore = 0;
var lives = 3; var lives = 3;
/* Spawn & kill a brick to get its width and height */ Log.warn(gameobjects['brick'].boundingbox);
var brick = prototypes.get_ur('brick').make(World); var brick = World.spawn(gameobjects['brick']);
var brickbb = brick.char.boundingbox; var brickbb = brick.char.boundingbox;
var bwidth = brickbb.r - brickbb.l; var bwidth = brickbb.r - brickbb.l;
var bheight = brickbb.t-brickbb.b; var bheight = brickbb.t-brickbb.b;
@ -16,19 +16,16 @@ var cols = 13;
var lvlwidth = bwidth*cols; var lvlwidth = bwidth*cols;
var lvlheight = 600; var lvlheight = 600;
var f = prototypes.get_ur('edge2d').make(World); //var frameworld = World
var f = World.spawn(gameobjects['edge2d']);
f.edge2d.thickness = 10; f.edge2d.thickness = 10;
f.edge2d.cpoints = Geometry.box(lvlwidth+f.edge2d.thickness*2,lvlheight-30); f.edge2d.cpoints = Geometry.box(lvlwidth+f.edge2d.thickness*2,lvlheight);
f.edge2d.degrees = 1;
f.scale = 1;
f.edge2d.sync();
var drawColor = Color.green.slice();
drawColor.a = 100;
f.draw = function() { f.draw = function() {
Debug.line(f.edge2d.points, drawColor, 0, f.edge2d.thickness*2); Debug.line(f.edge2d.points, Color.green, 0, f.edge2d.thickness*2);
}; };
Register.draw.register(f.draw,f); register_draw(f.draw,f);
var fitbricks = Math.floor(lvlwidth/bwidth); var fitbricks = Math.floor(lvlwidth/bwidth);
@ -37,7 +34,7 @@ var wingame = function() {
Log.warn("WINNER"); Log.warn("WINNER");
Player.players[0].uncontrol(paddle); Player.players[0].uncontrol(paddle);
Register.gui.register(function() { register_gui(function() {
GUI.text("WINNER", Window.dimensions.scale(0.5)); GUI.text("WINNER", Window.dimensions.scale(0.5));
}); });
} }
@ -80,14 +77,14 @@ Color.Arkanoid.Powerups = {
gray: [143,143,143] /* 1up */ gray: [143,143,143] /* 1up */
}; };
var lvl = JSON.parse(IO.slurp("lvl1.json")); var lvl = JSON.parse(IO.slurp("lvlsparse.json"));
for (var row = 0; row < rows; row++) { for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) { for (var col = 0; col < cols; col++) {
if (lvl.bricks[row][col] === 0) if (lvl.bricks[row][col] === 0)
continue; continue;
var brick = prototypes.get_ur('brick').make(World); var brick = World.spawn(gameobjects['brick']);
brick.powerup = function() { brick.powerup = function() {
if (Math.random() < 0.1) if (Math.random() < 0.1)
spawn_random_powerup(this.pos); spawn_random_powerup(this.pos);
@ -105,28 +102,27 @@ for (var row = 0; row < rows; row++) {
} }
var flashtimer = timer.make(function() { var flashtimer = timer.make(function() {
if (prototypes.get_ur('brick').instances.length === 0) { if (gameobjects['brick'].instances.length === 0) {
flashtimer.kill(); flashtimer.kill();
return; return;
} }
var idx = Math.randomint(prototypes.get_ur('brick').instances.length); var idx = Math.randomint(gameobjects['brick'].instances.length);
prototypes.get_ur('brick').instances[idx].flash(); gameobjects['brick'].instances[idx].flash();
flashtimer.time = Math.random_range(1,3); flashtimer.time = Math.random_range(1,3);
}, Math.random_range(1,3)); }, Math.random_range(1,3));
var paddle = prototypes.get_ur('paddle').make(self); 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+50]; paddle.lasership();
paddle.pos = [0,-lvlheight/2+paddle.height*4];
paddle.setgrow(3); paddle.setgrow(3);
Player.players[0].control(paddle);
paddle.inputs.space();
Gamestate.spawnball = function() { Gamestate.spawnball = function() {
var bb = prototypes.get_ur('ball').make(self); var bb = World.spawn(gameobjects['ball']);
bb.pos = bb.pos.add([0,-200]); bb.pos = bb.pos.add([0,-200]);
bb.velocity = [30,200]; bb.velocity = [30,200];
bb.draw_layer = 3; bb.draw_layer = 3;
bb.tag = 'ball';
} }
var powerups = {}; var powerups = {};
@ -149,7 +145,7 @@ powerups.catch = mk_pup(Color.Arkanoid.Powerups.green, function() {
}); });
powerups.slow = mk_pup(Color.Arkanoid.Powerups.orange, function() { powerups.slow = mk_pup(Color.Arkanoid.Powerups.orange, function() {
/* Slow all balls */ /* Slow all balls */
prototypes.get_ur('ball').instances.forEach(function(x) { gameobjects['ball'].instances.forEach(function(x) {
x.velocity = x.velocity.scale(0.5); x.velocity = x.velocity.scale(0.5);
}); });
}); });
@ -157,7 +153,7 @@ powerups.break = mk_pup(Color.Arkanoid.Powerups.purple, function() {
clear_level(); clear_level();
}, 0.5); }, 0.5);
powerups.disruption = mk_pup(Color.Arkanoid.Powerups.cyan, function() { powerups.disruption = mk_pup(Color.Arkanoid.Powerups.cyan, function() {
var ball = prototypes.get_ur('ball').instances[0]; var ball = gameobjects['ball'].instances[0];
if (!ball) return; if (!ball) return;
ball.instandup(); ball.instandup();
@ -211,8 +207,8 @@ var last_powerup = {};
function spawn_random_powerup(pos) function spawn_random_powerup(pos)
{ {
if (prototypes.get_ur('upgrade_drop').instances.length !== 0) return; if (gameobjects['upgrade_drop'].instances.length !== 0) return;
var p = prototypes.get_ur('upgrade_drop').make(self); var p = World.spawn(gameobjects['upgrade_drop']);
p.pos = pos; p.pos = pos;
var power = select_weighted(powerups.array()); var power = select_weighted(powerups.array());
@ -226,7 +222,7 @@ function spawn_random_powerup(pos)
} }
function spawn_powerup(pos, fn) { function spawn_powerup(pos, fn) {
var p = prototypes.get_ur('upgrade_drop').make(self); var p = World.spawn(gameobjects['upgrade_drop']);
p.pos = pos; p.pos = pos;
p.upgrade = fn; p.upgrade = fn;
return p; return p;
@ -239,7 +235,7 @@ function multiball(n) {
function lostball() function lostball()
{ {
if (prototypes.get_ur('ball').instances.length === 0) if (gameobjects['ball'].instances.length === 0)
lostlife(); lostlife();
}; };
@ -259,7 +255,7 @@ function lostlife() {
}; };
Gamestate.spawnball(); Gamestate.spawnball();
var killbox = prototypes.get_ur('polygon2d').make(self); var killbox = World.spawn(gameobjects['polygon2d']);
killbox.polygon2d.points = Geometry.box(lvlwidth,30); killbox.polygon2d.points = Geometry.box(lvlwidth,30);
killbox.pos = [0,-lvlheight/2]; killbox.pos = [0,-lvlheight/2];
@ -272,8 +268,6 @@ killbox.register_hit(hit => {
}, killbox); }, killbox);
killbox.polygon2d.sync();
//Sound.play("start.wav"); //Sound.play("start.wav");
var pause = { var pause = {
@ -284,7 +278,7 @@ var pause = {
}, },
unpause() { unpause() {
Register.gui.unregister(pause.gui); unregister_gui(pause.gui);
sim_start(); sim_start();
}, },
@ -298,7 +292,7 @@ var pause = {
var gamepawn = var gamepawn =
{ {
pause() { pause() {
Register.gui.register(pause.gui); register_gui(pause.gui);
sim_pause(); sim_pause();
}, },
@ -316,7 +310,7 @@ var gamepawn =
} }
function clear_level() { function clear_level() {
var bricks = prototypes.get_ur('brick').instances.slice(); var bricks = gameobjects['brick'].instances.slice();
bricks.forEach(function(x) { x.kill(); }); bricks.forEach(function(x) { x.kill(); });
}; };
@ -327,8 +321,8 @@ function gamegui() {
GUI.text_fn(`${score}`), GUI.text_fn(`${score}`),
GUI.text_fn("HIGH SCORE", {color: Color.red}), GUI.text_fn("HIGH SCORE", {color: Color.red}),
GUI.text_fn(`${highscore}`), GUI.text_fn(`${highscore}`),
GUI.text_fn(`BRICKS: ${prototypes.get_ur('brick').instances.length}`), GUI.text_fn(`BRICKS: ${gameobjects['brick'].instances.length}`),
GUI.text_fn(`BALLS IN PLAY: ${prototypes.get_ur('ball').instances.length}`), GUI.text_fn(`BALLS IN PLAY: ${gameobjects['ball'].instances.length}`),
GUI.text_fn(`LIVES: ${lives}`), GUI.text_fn(`LIVES: ${lives}`),
GUI.text_fn("YARKANOID", {color: [5,120,240,255]}), GUI.text_fn("YARKANOID", {color: [5,120,240,255]}),
@ -339,7 +333,7 @@ function gamegui() {
}).draw(Window.dimensions.scale([0.8,0.8])); }).draw(Window.dimensions.scale([0.8,0.8]));
} }
Register.gui.register(gamegui, this); register_gui(gamegui);
Player.players[0].control(gamepawn); Player.players[0].control(gamepawn);
@ -347,7 +341,6 @@ let backtomain = function()
{ {
World.clear(); World.clear();
run("startmenu.js"); run("startmenu.js");
Register.gui.unregister(gamegui); unregister_gui(gamegui);
Player.players[0].uncontrol(gamepawn); Player.players[0].uncontrol(gamepawn);
} }

View file

@ -1,35 +0,0 @@
Object.assign(self, {
char: char2d.clone({
flash:Resources.load("brick.png"),
}),
points: 50,
getshot() {
this.kill();
},
start() {
this.char.stop();
this.flash();
this.char.color = Color.Rainbow.red;
},
flash() {
this.char.play("flash");
},
collide(hit) {
if (hit.obj.tag !== 'ball')
return;
this.powerup?.();
this.kill();
},
});
self.collider = polygon2d.clone();
self.collider.points = [[-8,4]];
self.collider.flipx = true;
self.collider.flipy = true;
self.char.pos = [-0.5, -0.5];

View file

@ -8,5 +8,3 @@
- Specifically, want to monitor for screen change - Specifically, want to monitor for screen change
- Look up collision functions dynamically instead of with registry - Look up collision functions dynamically instead of with registry
-Missiles flash for one frame where previous

BIN
bump.wav

Binary file not shown.

186
config.js
View file

@ -1,5 +1,17 @@
gameobject.elasticity = 1; gameobject.elasticity = 1;
gameobject.clone("ball", {
collider: circle2d.clone(),
img: sprite.clone(),
phys: 0,
elasticity: 1,
friction: 0,
collide(hit) {
Sound.play("bump.wav");
},
});
Color.Gameboy = { Color.Gameboy = {
darkest: [15,56,15], darkest: [15,56,15],
dark: [48,98,48], dark: [48,98,48],
@ -15,3 +27,177 @@ Color.Rainbow = {
green: [0,153,1], green: [0,153,1],
blue: [53,51,255] blue: [53,51,255]
}; };
gameobject.clone("brick", {
collider: polygon2d.clone(),
char: char2d.clone({
flash:Resources.load("brick.png"),
}),
points: 50,
start() {
this.char.stop();
this.flash();
this.char.color = Color.Rainbow.red;
},
flash() {
this.char.play("flash");
},
collide(hit) {
if (hit.obj.from !== 'ball')
return;
this.powerup?.();
this.kill();
},
});
var act_x = Action.add_new("move");
act_x.inputs.push("axis_ljoy");
var paddle = gameobject.clone("paddle", {
collider: polygon2d.clone(),
img: sprite.clone(),
phys: 1,
elasticity: 1,
speed: 1000,
length: 50,
height: 28,
lengths: [16,24,32,40,48],
growlvl: 1,
maxgrow: 5,
max_x: 0,
extents: 300,
input_larrow_down() { this.input_a_down(); },
frame_vel: [0,0],
input_a_down() {
this.frame_vel = this.frame_vel.add([-1,0]);
},
input_d_down() {
this.frame_vel = this.frame_vel.add([1,0]);
},
update(dt) {
this.angle = 0;
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];
if (this.stickball)
this.stickball.pos = this.pos.add(this.stickpos);
},
physupdate(dt) { this.velocity = [0,0]; },
gamepad_ljoy_axis(v) {
v[1] = 0;
this.pos = this.pos.add(v.scale(this.speed*Yugine.dt));
},
setup() {
Player.players[0].control(this);
this.length = this.lengths[0];
},
grow() {
this.setgrow(this.growlvl + 1);
},
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;
},
lasership() {
this.laser = true;
},
shoot() {
Log.warn("SHOOTING MISSILES");
},
sticky: false,
stored_vel: [0,0],
stickball: {},
stickpos: [0,0],
input_space_pressed() {
if (this.sticky && this.stickball) {
this.stickball.velocity = this.stored_vel;
this.stickball = {};
}
if (this.laser) {
this.shoot();
}
},
collide(hit) {
if (!(hit.obj.from === 'ball')) return;
var xdiff = hit.pos.x - this.pos.x;
var hitangle = xdiff/this.length - 0.5;
var speed = Vector.length(hit.obj.velocity);
hit.obj.velocity = [Math.cos(hitangle)*speed, Math.sin(hitangle)*speed];
hit.obj.velocity = hit.obj.velocity.scale(-1);
var oldvel = hit.obj.velocity;
var scaler = Math.max(Math.abs(xdiff)/30, 1.01);
hit.obj.velocity = hit.obj.velocity.scale(scaler);
if (this.sticky) {
this.stored_vel = hit.obj.velocity;
hit.obj.velocity = [0,0];
this.stickball = hit.obj;
this.stickpos = hit.obj.pos.sub(this.pos);
}
},
});
gameobject.clone("upgrade_drop", {
fallspeed: 150,
tag: "ball",
upgrade: function() {},
size: 12,
phys:1,
collider: circle2d.clone(),
color: Color.Rainbow.blue,
start() {
this.collider.radius = this.size;
this.collider.sensor = true;
},
draw() {
Shape.circle(this.pos,this.size,this.color);
},
collide(hit) {
if (!(hit.obj.from === 'paddle'))
return;
this.upgrade();
this.kill();
},
update(dt) {
this.pos = this.pos.add([0,-this.fallspeed*dt]);
},
});

View file

@ -1,5 +1 @@
Window.icon("powerup.png"); load("startmenu.js");
gameobject.scale = 2;
//World.load(prototypes.get_ur("startmenu"));
World.run("startmenu.js");

View file

@ -1,29 +0,0 @@
var def = {
collider: polygon2d.clone(),
phys: 1,
bwidth: 5,
bheight: 15,
speed: 200,
start() {
this.collider.points = Geometry.box(this.bwidth, this.bheight);
this.collider.sensor = true;
},
collide(hit) {
if ('getshot' in hit.obj) {
hit.obj.getshot();
this.kill();
}
},
draw() {
Debug.box(this.pos, [this.bwidth, this.bheight], Color.cyan);
},
update(dt) {
this.pos = this.pos.add([0,this.speed*dt]);
},
};
Object.assign(self, def);

125
paddle.js
View file

@ -1,125 +0,0 @@
Object.assign(self, {
collider: polygon2d.clone(),
img: sprite.clone(),
phys: 1,
elasticity: 1,
tag: 'paddle',
speed: 1000,
length: 50,
height: 28,
lengths: [16,24,32,40,48],
growlvl: 1,
maxgrow: 5,
max_x: 0,
extents: 300,
frame_vel: [0,0],
update(dt) {
this.angle = 0;
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];
},
physupdate(dt) { this.velocity = [0,0]; },
gamepad_ljoy_axis(v) {
v[1] = 0;
this.pos = this.pos.add(v.scale(this.speed*Yugine.dt));
},
setup() {
this.length = this.lengths[0];
},
grow() {
this.setgrow(this.growlvl + 1);
},
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;
},
lasership() {
this.laser = true;
this.img.color = Color.Gameboy.light;
},
unlasership() {
this.laser = false;
this.img.color = Color.white;
},
shoot() {
var m1 = World.spawn(prototypes.get_ur("missile"));
var m2 = m1.dup();
m1.pos = this.pos.add([(this.length/2)-5,0]);
m2.pos = this.pos.add([5-(this.length/2),0]);
},
sticky: false,
stored_vel: [0,0],
start() {
this.collider.sensor = true;
},
collide(hit) {
if (!(hit.obj.tag === 'ball')) return;
var xdiff = hit.pos.x - this.pos.x;
var hitangle = (xdiff/this.length + 0.5) * Math.PI;
hitangle = Math.clamp(hitangle, Math.PI/6, 5*Math.PI/6);
var speed = Vector.length(hit.obj.velocity);
hit.obj.velocity = [Math.cos(hitangle)*speed, -Math.sin(hitangle)*speed];
hit.obj.velocity = hit.obj.velocity.scale(-1);
var oldvel = hit.obj.velocity;
var scaler = Math.max(Math.abs(xdiff)/30, 1.01);
hit.obj.velocity = hit.obj.velocity.scale(scaler);
if (this.sticky) {
this.stored_vel = hit.obj.velocity;
hit.obj.velocity = [0,0];
hit.obj.reparent(this);
this.stickball = hit.obj;
}
},
});
self.inputs = {};
self.inputs.space = function() {
if (this.sticky && this.stickball) {
this.stickball.velocity = this.stored_vel;
this.stickball.reparent(World);
delete this.stickball;
}
if (this.laser) {
this.shoot();
}
};
self.inputs.a = function(){};
self.inputs.a.down = function() {
this.frame_vel = this.frame_vel.add([-1,0]);
};
self.inputs.d = {};
self.inputs.d.down = function() {
this.frame_vel = this.frame_vel.add([1,0]);
};
self.img.pos = sprite.POS_MID;

Binary file not shown.

View file

@ -26,11 +26,11 @@
"ball": { "ball": {
"mass": 0.00001, "mass": 0.00001,
"collider": { "collider": {
"radius": 4.39338754070273,
"ofset": [ "ofset": [
0, 0,
0 0
], ]
"radius": 2
}, },
"img": { "img": {
"pos": [ "pos": [
@ -104,7 +104,7 @@
"pos": [ -0.5, -0.5 ] "pos": [ -0.5, -0.5 ]
}, },
"angle": 0, "angle": 0,
"scale": 2, "scale": 2.91,
"from": "gameobject" "from": "gameobject"
} }
} }

View file

@ -1,5 +0,0 @@
# Breakout
Breakout, implemented with the Yugine. Classic Arkanoid style gameplay!
To play, just put the yugine executable the home directory and run.

Binary file not shown.

BIN
start.wav

Binary file not shown.

View file

@ -1,16 +1,13 @@
var startgame = function() var startgame = function()
{ {
self.kill();
run("breakout.js"); run("breakout.js");
Player.players[0].uncontrol(startcontroller);
// Player.players[0].uncontrol(startcontroller); unregister_gui(startmenu);
//Register.gui.unregister(startmenu,this);
// Register.gui.unregister_obj(this);
}; };
var exitgame = function() var exitgame = function()
{ {
Game.quit(); quit();
}; };
var colorshifter = { var colorshifter = {
@ -28,6 +25,7 @@ var options = GUI.column({
GUI.text_fn("START", {action: startgame}), GUI.text_fn("START", {action: startgame}),
GUI.text_fn("EXIT", {action: exitgame}), GUI.text_fn("EXIT", {action: exitgame}),
], ],
hovered: {},
}); });
Tween.embed(options, 'hovered', [colorshifter, colorshiftend], {time: 0.35, loop: "yoyo", whole: false, ease: Ease.sine.out}); Tween.embed(options, 'hovered', [colorshifter, colorshiftend], {time: 0.35, loop: "yoyo", whole: false, ease: Ease.sine.out});
@ -70,28 +68,33 @@ function startmenu() {
options.draw(Window.dimensions.scale([0.5,0.5])); options.draw(Window.dimensions.scale([0.5,0.5]));
GUI.image_fn({path:"coin.png", anchor: [1,0.5]}).draw([item.bb.l, (item.bb.b + item.bb.t)/2].add([-3,1])); // GUI.image_fn({path:"arrow.png", anchor: [1,0.5]}).draw([item.bb.l, (item.bb.b + item.bb.t)/2].add([-3,1]));
} }
Register.gui.register(startmenu, this); register_gui(startmenu);
var startcontroller = {}; var startcontroller = {
startcontroller.inputs = {}; input_s_pressed() {
startcontroller.inputs.s = function() {
item.selected = false; item.selected = false;
idx = Math.clamp(idx+1, 0, options.items.length-1); idx = Math.clamp(idx+1, 0, options.items.length-1);
item = options.items[idx]; item = options.items[idx];
item.selected = true; item.selected = true;
}; },
startcontroller.inputs.w = function() { input_w_pressed() {
item.selected = false; item.selected = false;
idx = Math.clamp(idx-1, 0, options.items.length-1); idx = Math.clamp(idx-1, 0, options.items.length-1);
item = options.items[idx]; item = options.items[idx];
item.selected = true; item.selected = true;
}; },
startcontroller.inputs.enter = function() { item.action(); }; input_enter_pressed() {
item.action();
},
input_escape_pressed() {
quit();
},
};
Player.players[0].control(startcontroller); Player.players[0].control(startcontroller);
Game.play();

BIN
ting.wav

Binary file not shown.

View file

@ -1,31 +0,0 @@
Object.assign(self, {
fallspeed: 150,
tag: "ball",
upgrade: function() {},
size: 12,
phys:1,
collider: circle2d.clone(),
color: Color.Rainbow.blue,
tag: 'powerup',
start() {
this.collider.radius = this.size;
this.collider.sensor = true;
},
draw() {
Shape.circle(this.pos,this.size,this.color);
},
collide(hit) {
if (!(hit.obj.tag === 'paddle'))
return;
this.upgrade();
this.kill();
},
update(dt) {
this.pos = this.pos.add([0,-this.fallspeed*dt]);
},
});