Talking about Hundreds game, Game development, HTML5, Javascript and Phaser.
My “Hundreds” tutorial series is dated back to 2013, a previous gaming era with Flash still on the run on desktop computers.
Time passed, Flash died and hyper casual games now are mostly played in portrait mode.
So I kept the original concept of making circles grow while avoiding collisions, but I changed some rules:
1 – Circles do not collide, they tun on their own and simply overlap. Having circles colliding and bounce would make the game too unpredictable.
2 – Each circle is bound to a button with the same number.
3 – Tap and hold a button to make corresponding circle grow.
4 – Release the button to stop circle growth.
5 – If a growing circle overlaps any other circle, both circles get halved
6- You can make a circle grow only once.
Does it sound complicate? Have a try:
Tap and hold a button to make the corresponding circle grow. Release before it overlaps another circle.
What’s your best score?
The source code is a bit more than 100 lines, still uncommented because I need to add a couple more features, but easy to understand:
let game;
let gameOptions = {
ballSpeed: 300,
balls: 8,
ballRadius: 50,
growRate: 1
}
window.onload = function() {
let gameConfig = {
type: Phaser.AUTO,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
parent: "thegame",
width: 750,
height: 1334
},
physics: {
default: "arcade",
},
scene: playGame
}
game = new Phaser.Game(gameConfig);
window.focus();
}
class playGame extends Phaser.Scene{
constructor(){
super("PlayGame");
}
preload(){
this.load.image("ball", "ball.png");
this.load.image("button", "button.png");
}
create(){
this.physics.world.setBounds(0, 0, game.config.width, game.config.width);
this.ballGroup = this.physics.add.group();
this.ballArray = [];
this.textArray = [];
this.score = 0;
let gameArea = new Phaser.Geom.Rectangle(0, 0, game.config.width, game.config.width);
let buttonsPerRow = gameOptions.balls / 2;
let buttonWidth = game.config.width / buttonsPerRow;
this.buttonGroup = this.add.group();
for(let i = 0; i < gameOptions.balls; i++){
let randomPosition = Phaser.Geom.Rectangle.Random(gameArea);
let directionVector = Phaser.Math.RandomXY(new Phaser.Math.Vector2, gameOptions.ballSpeed);
let ball = this.ballGroup.create(randomPosition.x, randomPosition.y, "ball");
this.ballArray.push(ball);
ball.setCircle(256);
ball.displayHeight = gameOptions.ballRadius;
ball.displayWidth = gameOptions.ballRadius;
ball.index = i;
ball.setCollideWorldBounds(true);
ball.setVelocity(directionVector.x, directionVector.y);
ball.setBounce(1);
let ballText = this.add.text(randomPosition.x, randomPosition.y, i, {
fontFamily: "Arial",
fontSize: 24,
color: "#000000"
});
ballText.setOrigin(0.5, 0.5)
this.textArray.push(ballText);
let button = this.add.sprite(buttonWidth * (i % (gameOptions.balls / 2)), game.config.width + buttonWidth * Math.floor(i / (gameOptions.balls / 2)), "button");
button.setOrigin(0, 0);
button.index = i;
button.displayWidth = buttonWidth;
button.displayHeight = buttonWidth;
this.buttonGroup.add(button);
let buttonText = this.add.text(button.getBounds().centerX, button.getBounds().centerY, i, {
fontFamily: "Arial",
fontSize: 64,
color: "#000000"
});
buttonText.setOrigin(0.5, 0.5)
}
this.ballToGrow = null
this.scoreText = this.add.text(0, game.config.height, "Score: 0", {
fontFamily: "Arial",
fontSize: 64
});
this.scoreText.setOrigin(0, 1);
this.input.on("pointerdown", this.startGrowing, this);
this.input.on("pointerup", this.stopGrowing, this);
this.physics.add.overlap(this.ballGroup, this.ballGroup, this.handleOverlap, null, this);
}
startGrowing(pointer){
this.buttonGroup.getChildren().forEach(function(button){
if(Phaser.Geom.Rectangle.Contains(button.getBounds(), pointer.x, pointer.y) && button.alpha == 1){
button.alpha = 0.5;
this.ballToGrow = button.index;
this.ballArray[this.ballToGrow].body.onOverlap = true;
}
}, this);
}
stopGrowing(){
this.ballToGrow = null;
}
handleOverlap(ball1, ball2){
if(this.ballToGrow != null && (ball1.index == this.ballToGrow || ball2.index == this.ballToGrow)){
this.cameras.main.flash();
ball1.displayWidth = Math.max(ball1.displayWidth / 2, gameOptions.ballRadius);
ball2.displayWidth = Math.max(ball1.displayWidth / 2, gameOptions.ballRadius)
ball1.displayHeight = ball1.displayWidth ;
ball2.displayHeight = ball2.displayWidth ;
this.ballToGrow = null;
}
}
update(){
this.score = 0;
for(let i = 0; i < gameOptions.balls; i++){
this.textArray[i].x = this.ballArray[i].x;
this.textArray[i].y = this.ballArray[i].y;
this.score += this.ballArray[i].displayWidth - gameOptions.ballRadius;
}
this.scoreText.text = this.score;
if(this.ballToGrow != null){
console.log("grow")
this.ballArray[this.ballToGrow].displayWidth += gameOptions.growRate;
this.ballArray[this.ballToGrow].displayHeight += gameOptions.growRate;
}
}
}
This is actually a pretty new concept as there isn’t that much of the original “Hundreds” game, but I can see some potential in it, especially if you consider you can play with one thumb.
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.