1st version of Working Game
14
.babelrc
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
["@babel/env", {
|
||||||
|
"targets": {
|
||||||
|
"browsers": [
|
||||||
|
">0.25%",
|
||||||
|
"not ie 11",
|
||||||
|
"not op_mini all"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"modules": false
|
||||||
|
}]
|
||||||
|
],
|
||||||
|
}
|
13
.gitignore
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# System and IDE files
|
||||||
|
Thumbs.db
|
||||||
|
.DS_Store
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.sublime-project
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# Vendors
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Build
|
||||||
|
/npm-debug.log
|
BIN
assets/1platform.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
assets/bg.png
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
assets/bg_music.mp3
Normal file
BIN
assets/bg_music.ogg
Normal file
BIN
assets/blankBG.png
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
assets/btn.png
Normal file
After Width: | Height: | Size: 1,015 B |
BIN
assets/cloud1.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/cloud2.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
assets/cloud3.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
assets/cloud4.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
assets/cloud5.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/hand.cur
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
assets/hand.png
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
assets/jump.mp3
Normal file
BIN
assets/jump.ogg
Normal file
BIN
assets/mountai1n.png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
assets/mountain.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
assets/ocean.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
assets/platform.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/platform2.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
assets/platforms.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
assets/player.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
assets/slide.ogg
Normal file
BIN
assets/title.png
Normal file
After Width: | Height: | Size: 124 KiB |
BIN
dist/assets/1platform.png
vendored
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
dist/assets/bg.png
vendored
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
dist/assets/bg_music.mp3
vendored
Normal file
BIN
dist/assets/bg_music.ogg
vendored
Normal file
BIN
dist/assets/blankBG.png
vendored
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
dist/assets/btn.png
vendored
Normal file
After Width: | Height: | Size: 1,015 B |
BIN
dist/assets/cloud1.png
vendored
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
dist/assets/cloud2.png
vendored
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
dist/assets/cloud3.png
vendored
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
dist/assets/cloud4.png
vendored
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
dist/assets/cloud5.png
vendored
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
dist/assets/hand.cur
vendored
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
dist/assets/hand.png
vendored
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
dist/assets/jump.mp3
vendored
Normal file
BIN
dist/assets/jump.ogg
vendored
Normal file
BIN
dist/assets/mountai1n.png
vendored
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
dist/assets/mountain.png
vendored
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
dist/assets/ocean.png
vendored
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
dist/assets/platform.png
vendored
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
dist/assets/platform2.png
vendored
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
dist/assets/platforms.png
vendored
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
dist/assets/player.png
vendored
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
dist/assets/slide.ogg
vendored
Normal file
BIN
dist/assets/title.png
vendored
Normal file
After Width: | Height: | Size: 124 KiB |
1
dist/bundle.min.js
vendored
Normal file
30
dist/index.html
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>IPv6 Penguin</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, width=device-width, user-scalable=no, minimal-ui">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="full-screen" content="yes" />
|
||||||
|
<meta name="screen-orientation" content="portrait" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style media='screen' type='text/css'>
|
||||||
|
*{
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript" src="bundle.min.js"></script></body>
|
||||||
|
</html>
|
30
index.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>IPv6 Penguin</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, width=device-width, user-scalable=no, minimal-ui">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="full-screen" content="yes" />
|
||||||
|
<meta name="screen-orientation" content="portrait" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style media='screen' type='text/css'>
|
||||||
|
*{
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
7389
package-lock.json
generated
Normal file
38
package.json
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"name": "phaser3-project-template",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"description": "A Phaser 3 Project Template",
|
||||||
|
"main": "src/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack --config webpack/prod.js ",
|
||||||
|
"start": "webpack-dev-server --config webpack/base.js --open"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/photonstorm/phaser3-project-template.git"
|
||||||
|
},
|
||||||
|
"author": "Richard Davey <rdavey@gmail.com> (http://www.photonstorm.com)",
|
||||||
|
"license": "MIT",
|
||||||
|
"licenseUrl": "http://www.opensource.org/licenses/mit-license.php",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/photonstorm/phaser3-project-template/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/photonstorm/phaser3-project-template#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.2.2",
|
||||||
|
"@babel/preset-env": "^7.2.3",
|
||||||
|
"babel-loader": "^8.0.5",
|
||||||
|
"clean-webpack-plugin": "^1.0.0",
|
||||||
|
"file-loader": "^3.0.1",
|
||||||
|
"html-webpack-plugin": "^3.2.0",
|
||||||
|
"raw-loader": "^1.0.0",
|
||||||
|
"terser-webpack-plugin": "^1.2.1",
|
||||||
|
"webpack": "^4.28.3",
|
||||||
|
"webpack-cli": "^3.2.1",
|
||||||
|
"webpack-dev-server": "^3.1.14",
|
||||||
|
"webpack-merge": "^4.2.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"phaser": "^3.16.2"
|
||||||
|
}
|
||||||
|
}
|
22
src/Config/config.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import 'phaser';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 900,
|
||||||
|
height: 680,
|
||||||
|
scale: {
|
||||||
|
mode: Phaser.Scale.FIT,
|
||||||
|
autoCenter: Phaser.Scale.CENTER_BOTH,
|
||||||
|
width: 900,
|
||||||
|
height: 680
|
||||||
|
},
|
||||||
|
backgroundColor: 0xBDCDD1,
|
||||||
|
// backgroundColor: 0xCFEFFC,
|
||||||
|
physics: {
|
||||||
|
default: 'arcade',
|
||||||
|
arcade: {
|
||||||
|
gravity: { y: 0 },
|
||||||
|
debug: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
19
src/Config/options.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import 'phaser';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// platform speed range, in pixels per second
|
||||||
|
platformSpeedRange: [300, 300], // mountain speed, in pixels per second
|
||||||
|
mountainSpeed: 80, // spawn range, how far should be the rightmost platform from the right edge
|
||||||
|
// before next platform spawns, in pixels
|
||||||
|
spawnRange: [40, 100], // platform width range, in pixels
|
||||||
|
platformSizeRange: [90, 300], // a height range between rightmost platform and next platform to be spawned
|
||||||
|
platformHeightRange: [-5, 5], // a scale to be multiplied by platformHeightRange
|
||||||
|
platformHeighScale: 20, // platform max and min height, as screen height ratio
|
||||||
|
platformVerticalLimit: [0.75, 0.9], // player gravity
|
||||||
|
playerGravity: 900, // player jump force
|
||||||
|
jumpForce: 400, // player starting X position
|
||||||
|
playerStartPosition: 200, // consecutive jumps allowed
|
||||||
|
jumps: 2, // % of probability a coin appears on the platform
|
||||||
|
coinPercent: 25, // % of probability a fire appears on the platform
|
||||||
|
firePercent: 25,
|
||||||
|
};
|
31
src/Model.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
export default class Model {
|
||||||
|
constructor() {
|
||||||
|
this._soundOn = true;
|
||||||
|
this._musicOn = true;
|
||||||
|
this._bgMusicPlaying = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
set musicOn(value) {
|
||||||
|
this._musicOn = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get musicOn() {
|
||||||
|
return this._musicOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
set soundOn(value) {
|
||||||
|
this._soundOn = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get soundOn() {
|
||||||
|
return this._soundOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
set bgMusicPlaying(value) {
|
||||||
|
this._bgMusicPlaying = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get bgMusicPlaying() {
|
||||||
|
return this._bgMusicPlaying;
|
||||||
|
}
|
||||||
|
}
|
16
src/Scenes/BootScene.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import 'phaser';
|
||||||
|
// import Phaser from '../phaser.min';
|
||||||
|
|
||||||
|
export default class BootScene extends Phaser.Scene {
|
||||||
|
constructor () {
|
||||||
|
super('Boot');
|
||||||
|
}
|
||||||
|
|
||||||
|
preload () {
|
||||||
|
console.log('booting game...')
|
||||||
|
}
|
||||||
|
|
||||||
|
create () {
|
||||||
|
this.scene.start('Preloader');
|
||||||
|
}
|
||||||
|
};
|
316
src/Scenes/GameScene.js
Normal file
|
@ -0,0 +1,316 @@
|
||||||
|
import 'phaser';
|
||||||
|
// import Phaser from '../phaser.min';
|
||||||
|
import config from '../Config/config';
|
||||||
|
import gameOptions from '../Config/options';
|
||||||
|
|
||||||
|
export default class GameScene extends Phaser.Scene {
|
||||||
|
|
||||||
|
constructor () {
|
||||||
|
super('Game');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
create () {
|
||||||
|
|
||||||
|
//Sound
|
||||||
|
// this.input.setDefaultCursor('url(assets/cursor.cur), pointer');
|
||||||
|
this.model = this.sys.game.globals.model;
|
||||||
|
this.jumpS = this.sound.add('jump', { volume: 1, loop: false });
|
||||||
|
this.bgMusic = this.sound.add('bgMusic', { volume: 0.5, loop: true });
|
||||||
|
if (this.model.musicOn === true && this.model.bgMusicPlaying === false) {
|
||||||
|
// this.bgMusic = this.sound.add('bgMusic', { volume: 0.5, loop: true });
|
||||||
|
this.bgMusic.play();
|
||||||
|
// this.siren.stop();
|
||||||
|
this.model.bgMusicPlaying = true;
|
||||||
|
this.sys.game.globals.bgMusic = this.bgMusic;
|
||||||
|
this.sys.game.globals.siren = this.siren;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// group with all active mountains.
|
||||||
|
this.mountainGroup = this.add.group();
|
||||||
|
|
||||||
|
// group with all active platforms.
|
||||||
|
this.platformGroup = this.add.group({
|
||||||
|
// once a platform is removed, it's added to the pool
|
||||||
|
removeCallback: function(platform){
|
||||||
|
platform.scene.platformPool.add(platform)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// platform pool
|
||||||
|
this.platformPool = this.add.group({
|
||||||
|
// once a platform is removed from the pool, it's added to the active platforms group
|
||||||
|
removeCallback: function(platform){
|
||||||
|
platform.scene.platformGroup.add(platform)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// adding a mountain
|
||||||
|
this.addMountains()
|
||||||
|
|
||||||
|
// keeping track of added platforms
|
||||||
|
this.addedPlatforms = 0;
|
||||||
|
|
||||||
|
// number of consecutive jumps made by the player so far
|
||||||
|
this.playerJumps = 0;
|
||||||
|
|
||||||
|
var background = this.add.sprite(0, 680, 'ocean').setOrigin(0,1).setScale(.5,.5).setDepth(10);
|
||||||
|
|
||||||
|
// adding a platform to the game, the arguments are platform width, x position and y position
|
||||||
|
this.addPlatform(game.config.width, game.config.width / 2, game.config.height * gameOptions.platformVerticalLimit[1]);
|
||||||
|
|
||||||
|
// adding the player;
|
||||||
|
this.player = this.physics.add.sprite(gameOptions.playerStartPosition, game.config.height * 0.7, "player");
|
||||||
|
this.player.setGravityY(gameOptions.playerGravity);
|
||||||
|
this.player.setDepth(20);
|
||||||
|
// this.player.setScale(1.2);
|
||||||
|
|
||||||
|
// the player is not dying
|
||||||
|
this.dying = false;
|
||||||
|
|
||||||
|
// setting collisions between the player and the platform group
|
||||||
|
this.platformCollider = this.physics.add.collider(this.player, this.platformGroup, function(){
|
||||||
|
|
||||||
|
// play "run" animation if the player is on a platform
|
||||||
|
if(!this.player.anims.isPlaying){
|
||||||
|
this.player.anims.play("run");
|
||||||
|
}
|
||||||
|
}, null, this);
|
||||||
|
|
||||||
|
|
||||||
|
this.titleText = this.add.text(config.width/2, 250, "Game Over!", {
|
||||||
|
font: "68px Arial Black",
|
||||||
|
wordWrap: { width: 820, useAdvancedWrap: true },
|
||||||
|
color: '#4AB6F5',
|
||||||
|
align: 'center'
|
||||||
|
}).setOrigin(.5);
|
||||||
|
|
||||||
|
this.tutText = this.add.text(config.width/2, 250, "Click or Double Click\nto\nJump", {
|
||||||
|
font: "58px Arial Black",
|
||||||
|
wordWrap: { width: 720, useAdvancedWrap: true },
|
||||||
|
color: '#4AB6F5',
|
||||||
|
align: 'center'
|
||||||
|
}).setOrigin(.5);
|
||||||
|
|
||||||
|
var tutText = this.tutText;
|
||||||
|
this.tweens.add({
|
||||||
|
targets: this.tutText,
|
||||||
|
ease: 'Sine.easeInOut',
|
||||||
|
repeat: 4,
|
||||||
|
yoyo : true,
|
||||||
|
duration: 200,
|
||||||
|
alpha: 0,
|
||||||
|
onCompleteParams: [tutText],
|
||||||
|
onComplete: function(){
|
||||||
|
tutText.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.clouds = this.physics.add.group({
|
||||||
|
maxSize: 5,
|
||||||
|
allowGravity : false,
|
||||||
|
createCallback: function (cloud) {
|
||||||
|
cloud.setName('cloud' + this.getLength());
|
||||||
|
},
|
||||||
|
removeCallback: function (cloud) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.clouds.createMultiple({ key: ['cloud1','cloud2','cloud3','cloud4','cloud5'], active: false,visible: false,randomKey: true, max: 5,setScale:
|
||||||
|
{
|
||||||
|
x: .5,
|
||||||
|
y: .5,
|
||||||
|
} });
|
||||||
|
|
||||||
|
this.eventCloud = this.time.addEvent({ delay: 1000, loop: true, callback: this.addCloud ,callbackScope: this });
|
||||||
|
|
||||||
|
|
||||||
|
this.clouds.children.iterate(function (cloud) {
|
||||||
|
var distance = Phaser.Math.Between(50, 80);
|
||||||
|
var speed = Phaser.Math.GetSpeed(distance, 1);
|
||||||
|
cloud.setData('speed',speed );
|
||||||
|
},this);
|
||||||
|
|
||||||
|
this.btn = this.add.sprite(config.width/2, 520, 'btn').setDisplaySize(300, 80).setDepth(30);
|
||||||
|
this.btnText = this.add.text(this.btn.x, this.btn.y, "Restart", {
|
||||||
|
font: "52px Arial",
|
||||||
|
wordWrap: { width: 500, useAdvancedWrap: true },
|
||||||
|
color: '#4AB6F5',
|
||||||
|
align: 'center'
|
||||||
|
}).setOrigin(.5).setDepth(30);
|
||||||
|
this.btn.setInteractive();
|
||||||
|
this.btn.on('pointerdown', function () {
|
||||||
|
this.scene.start('Game');
|
||||||
|
}.bind(this));
|
||||||
|
this.btn.on('pointerover', function () {
|
||||||
|
this.btn.setDisplaySize(310, 110);
|
||||||
|
}.bind(this));
|
||||||
|
this.btn.on('pointerout', function () {
|
||||||
|
this.btn.setDisplaySize(300, 100);
|
||||||
|
}.bind(this));
|
||||||
|
this.btn.setVisible(false);
|
||||||
|
this.titleText.setVisible(false);
|
||||||
|
this.btnText.setVisible(false);
|
||||||
|
|
||||||
|
|
||||||
|
this.input.on("pointerdown", this.jump, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
addCloud()
|
||||||
|
{
|
||||||
|
console.log( "adding clouds" );
|
||||||
|
var cloud = this.clouds.get(Phaser.Math.Between(970, 1190), Phaser.Math.Between(10, 250));
|
||||||
|
|
||||||
|
if (!cloud) return;
|
||||||
|
|
||||||
|
cloud
|
||||||
|
.setActive(true)
|
||||||
|
.setVisible(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// adding mountains
|
||||||
|
addMountains(){
|
||||||
|
let rightmostMountain = this.getRightmostMountain();
|
||||||
|
if(rightmostMountain < game.config.width * 2){
|
||||||
|
let mountain = this.physics.add.sprite(rightmostMountain + Phaser.Math.Between(100, 350), game.config.height - Phaser.Math.Between(100, 125), "mountain").setScale(.5);
|
||||||
|
mountain.setOrigin(0.5, 1);
|
||||||
|
mountain.body.setVelocityX(gameOptions.mountainSpeed * -1)
|
||||||
|
this.mountainGroup.add(mountain);
|
||||||
|
if(Phaser.Math.Between(0, 1)){
|
||||||
|
mountain.setDepth(1);
|
||||||
|
}
|
||||||
|
var ind = Phaser.Math.Between(0, 200);
|
||||||
|
ind>150?ind=0:ind>80?ind=1:ind=2;
|
||||||
|
mountain.setFrame(ind);
|
||||||
|
this.addMountains()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getting rightmost mountain x position
|
||||||
|
getRightmostMountain(){
|
||||||
|
let rightmostMountain = -200;
|
||||||
|
this.mountainGroup.getChildren().forEach(function(mountain){
|
||||||
|
rightmostMountain = Math.max(rightmostMountain, mountain.x);
|
||||||
|
})
|
||||||
|
return rightmostMountain;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the core of the script: platform are added from the pool or created on the fly
|
||||||
|
addPlatform(platformWidth, posX, posY){
|
||||||
|
this.addedPlatforms ++;
|
||||||
|
let platform;
|
||||||
|
if(this.platformPool.getLength()){
|
||||||
|
platform = this.platformPool.getFirst();
|
||||||
|
platform.x = posX;
|
||||||
|
platform.y = posY;
|
||||||
|
platform.active = true;
|
||||||
|
platform.visible = true;
|
||||||
|
this.platformPool.remove(platform);
|
||||||
|
let newRatio = platformWidth / platform.displayWidth;
|
||||||
|
platform.displayWidth = platformWidth;
|
||||||
|
platform.tileScaleX = 1 / platform.scaleX;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// platformWidth<400?platformWidth = 400:platformWidth++;
|
||||||
|
platform = this.add.tileSprite(posX, posY, platformWidth, 53, "platform").setScale(.75,1);
|
||||||
|
|
||||||
|
|
||||||
|
this.physics.add.existing(platform);
|
||||||
|
platform.body.setImmovable(true);
|
||||||
|
platform.body.setVelocityX(Phaser.Math.Between(gameOptions.platformSpeedRange[0], gameOptions.platformSpeedRange[1]) * -1);
|
||||||
|
platform.setDepth(20);
|
||||||
|
this.platformGroup.add(platform);
|
||||||
|
}
|
||||||
|
this.nextPlatformDistance = Phaser.Math.Between(gameOptions.spawnRange[0], gameOptions.spawnRange[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the player jumps when on the ground, or once in the air as long as there are jumps left and the first jump was on the ground
|
||||||
|
// and obviously if the player is not dying
|
||||||
|
jump(){
|
||||||
|
if((!this.dying) && (this.player.body.touching.down || (this.playerJumps > 0 && this.playerJumps < gameOptions.jumps))){
|
||||||
|
if(this.player.body.touching.down){
|
||||||
|
this.playerJumps = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.jumpS.play();
|
||||||
|
this.player.setVelocityY(gameOptions.jumpForce * -1);
|
||||||
|
this.playerJumps ++;
|
||||||
|
|
||||||
|
// stops animation
|
||||||
|
this.player.anims.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update(time,delta){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// game over
|
||||||
|
if(this.player.y > game.config.height){
|
||||||
|
// this.scene.start("PlayGame");
|
||||||
|
|
||||||
|
this.btn.setVisible(true);
|
||||||
|
this.btnText.setVisible(true);
|
||||||
|
this.titleText.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.player.x = gameOptions.playerStartPosition;
|
||||||
|
|
||||||
|
// recycling platforms
|
||||||
|
let minDistance = game.config.width;
|
||||||
|
let rightmostPlatformHeight = 0;
|
||||||
|
this.platformGroup.getChildren().forEach(function(platform){
|
||||||
|
let platformDistance = game.config.width - platform.x - platform.displayWidth / 2;
|
||||||
|
if(platformDistance < minDistance){
|
||||||
|
minDistance = platformDistance;
|
||||||
|
rightmostPlatformHeight = platform.y;
|
||||||
|
}
|
||||||
|
if(platform.x < - platform.displayWidth / 2){
|
||||||
|
this.platformGroup.killAndHide(platform);
|
||||||
|
this.platformGroup.remove(platform);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
|
||||||
|
// recycling mountains
|
||||||
|
this.mountainGroup.getChildren().forEach(function(mountain){
|
||||||
|
if(mountain.x < - mountain.displayWidth){
|
||||||
|
let rightmostMountain = this.getRightmostMountain();
|
||||||
|
mountain.x = rightmostMountain + Phaser.Math.Between(100, 350);
|
||||||
|
mountain.y = game.config.height + Phaser.Math.Between(0, 100);
|
||||||
|
mountain.setFrame(Phaser.Math.Between(0, 3))
|
||||||
|
if(Phaser.Math.Between(0, 1)){
|
||||||
|
mountain.setDepth(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.clouds.children.iterate(function (cloud) {
|
||||||
|
// console.log( cloud );
|
||||||
|
cloud.x -= cloud.data.values.speed * delta;
|
||||||
|
if (cloud.x < -100 ) {
|
||||||
|
this.clouds.killAndHide(cloud);
|
||||||
|
}
|
||||||
|
},this);
|
||||||
|
|
||||||
|
// adding new platforms
|
||||||
|
if(minDistance > this.nextPlatformDistance){
|
||||||
|
let nextPlatformWidth = Phaser.Math.Between(gameOptions.platformSizeRange[0], gameOptions.platformSizeRange[1]);
|
||||||
|
let platformRandomHeight = gameOptions.platformHeighScale * Phaser.Math.Between(gameOptions.platformHeightRange[0], gameOptions.platformHeightRange[1]);
|
||||||
|
let nextPlatformGap = rightmostPlatformHeight + platformRandomHeight;
|
||||||
|
let minPlatformHeight = game.config.height * gameOptions.platformVerticalLimit[0];
|
||||||
|
let maxPlatformHeight = game.config.height * gameOptions.platformVerticalLimit[1];
|
||||||
|
let nextPlatformHeight = Phaser.Math.Clamp(nextPlatformGap, minPlatformHeight, maxPlatformHeight);
|
||||||
|
this.addPlatform(nextPlatformWidth, game.config.width + nextPlatformWidth / 2, nextPlatformHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
137
src/Scenes/PreloaderScene.js
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
import 'phaser';
|
||||||
|
// import Phaser from '../phaser.min';
|
||||||
|
import config from '../Config/config';
|
||||||
|
|
||||||
|
export default class PreloaderScene extends Phaser.Scene {
|
||||||
|
constructor () {
|
||||||
|
super('Preloader');
|
||||||
|
}
|
||||||
|
|
||||||
|
init () {
|
||||||
|
this.readyCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
preload () {
|
||||||
|
|
||||||
|
// var width = this.cameras.main.width;
|
||||||
|
// var height = this.cameras.main.height;
|
||||||
|
|
||||||
|
var width = config.width;
|
||||||
|
var height = config.height;
|
||||||
|
|
||||||
|
|
||||||
|
this.titleText = this.add.text(config.width/2, 250, "IPv6 Penguin", {
|
||||||
|
font: "68px Arial Black",
|
||||||
|
wordWrap: { width: 820, useAdvancedWrap: true },
|
||||||
|
color: '#4AB6F5',
|
||||||
|
align: 'center'
|
||||||
|
}).setOrigin(.5);
|
||||||
|
this.titleText.setStroke('#ffffff', 23);
|
||||||
|
|
||||||
|
// display progress bar
|
||||||
|
var progressBar = this.add.graphics().setDepth(10);
|
||||||
|
var progressBox = this.add.graphics();
|
||||||
|
progressBox.fillStyle(0x222222, 0.8);
|
||||||
|
progressBox.fillRect(225, config.height/2 + 200, (width / 2) + 10, 50);
|
||||||
|
|
||||||
|
var loadingText = this.make.text({
|
||||||
|
x: width / 2,
|
||||||
|
y: height / 2 + 50,
|
||||||
|
text: 'Loading...',
|
||||||
|
style: {
|
||||||
|
font: '60px monospace',
|
||||||
|
fill: '#ffffff'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
loadingText.setOrigin(0.5, 0.5);
|
||||||
|
|
||||||
|
var percentText = this.make.text({
|
||||||
|
x: width / 2,
|
||||||
|
y: height / 2 + 140,
|
||||||
|
text: '0%',
|
||||||
|
style: {
|
||||||
|
font: '38px monospace',
|
||||||
|
fill: '#ffffff'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
percentText.setOrigin(0.5, 0.5);
|
||||||
|
|
||||||
|
// update progress bar
|
||||||
|
this.load.on('progress', function (value) {
|
||||||
|
percentText.setText(parseInt(value * 100) + '%');
|
||||||
|
progressBar.clear();
|
||||||
|
progressBar.fillStyle(0xffffff, 1);
|
||||||
|
progressBar.fillRect(225 + 5, config.height/2 + 205, (width / 2) * value, 40);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// remove progress bar when complete
|
||||||
|
this.load.on('complete', function () {
|
||||||
|
progressBar.destroy();
|
||||||
|
progressBox.destroy();
|
||||||
|
loadingText.destroy();
|
||||||
|
percentText.destroy();
|
||||||
|
this.ready();
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
|
||||||
|
console.log('preloading game...');
|
||||||
|
|
||||||
|
this.load.image("bg", "assets/bg.png");
|
||||||
|
this.load.image("btn", "assets/btn.png");
|
||||||
|
this.load.image("hand", "assets/hand.png");
|
||||||
|
this.load.image("ocean", "assets/ocean.png");
|
||||||
|
this.load.image("title", "assets/title.png");
|
||||||
|
|
||||||
|
this.load.image("cloud1", "assets/cloud1.png");
|
||||||
|
this.load.image("cloud2", "assets/cloud2.png");
|
||||||
|
this.load.image("cloud3", "assets/cloud3.png");
|
||||||
|
this.load.image("cloud4", "assets/cloud4.png");
|
||||||
|
this.load.image("cloud5", "assets/cloud5.png");
|
||||||
|
|
||||||
|
this.load.image("platform", "assets/platform.png");
|
||||||
|
|
||||||
|
// player is a sprite sheet made by 24x48 pixels
|
||||||
|
this.load.spritesheet("player", "assets/player.png", {
|
||||||
|
frameWidth: 60,
|
||||||
|
frameHeight: 65
|
||||||
|
});
|
||||||
|
|
||||||
|
// mountains are a sprite sheet made by 512x512 pixels
|
||||||
|
this.load.spritesheet("mountain", "assets/mountain.png", {
|
||||||
|
frameWidth: 720,
|
||||||
|
frameHeight: 660
|
||||||
|
});
|
||||||
|
// mountains are a sprite sheet made by 512x512 pixels
|
||||||
|
// this.load.spritesheet("platform", "assets/platform.png", {
|
||||||
|
// frameWidth: 400,
|
||||||
|
// frameHeight: 200
|
||||||
|
// });
|
||||||
|
this.load.audio("jump", ["assets/jump.ogg","assets/jump.mp3"]);
|
||||||
|
this.load.audio('bgMusic', ['assets/bg_music.ogg','assets/bg_music.mp3']);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
create () {
|
||||||
|
|
||||||
|
|
||||||
|
// setting player animation
|
||||||
|
this.anims.create({
|
||||||
|
key: "run",
|
||||||
|
frames: this.anims.generateFrameNumbers("player", {
|
||||||
|
start: 0,
|
||||||
|
end: 10
|
||||||
|
}),
|
||||||
|
frameRate: 20,
|
||||||
|
repeat: -1
|
||||||
|
});
|
||||||
|
|
||||||
|
this.scene.start('Title');
|
||||||
|
}
|
||||||
|
|
||||||
|
ready () {
|
||||||
|
// this.scene.start('Result',{ point : 10, mistake : 1});
|
||||||
|
// this.scene.start('Title');
|
||||||
|
}
|
||||||
|
};
|
102
src/Scenes/ResultScene.js
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
import 'phaser';
|
||||||
|
// import Phaser from '../phaser.min';
|
||||||
|
import config from '../Config/config';
|
||||||
|
|
||||||
|
export default class GameScene extends Phaser.Scene {
|
||||||
|
|
||||||
|
constructor () {
|
||||||
|
super('Result');
|
||||||
|
}
|
||||||
|
|
||||||
|
init (data) {
|
||||||
|
this.point = data.point;
|
||||||
|
this.mistake = data.mistake;
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
// Get a reference to the database service
|
||||||
|
// var database = firebase.database();
|
||||||
|
|
||||||
|
// var ref = database.ref();
|
||||||
|
// // ref.child('mike').set({'firstName': "Test", 'lastName': "Test last name"}).then().catch();
|
||||||
|
// ref.push({'playerName': "Test___", 'point': this.point, 'mistake': this.mistake, 'locale': "Test___", 'platform': "Test___", 'playerID': "Test___", 'playerPhotoURL': "Test___", 'time': (new Date()).getTime()});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
create () {
|
||||||
|
|
||||||
|
var msg,msg2;
|
||||||
|
if(this.mistake>5){
|
||||||
|
msg = ` `;
|
||||||
|
msg2 = `Ditt resultat visar på en låg förmåga att para beteenden kopplade till hög respektive låg emotionell intelligens. Vill du lära dig mer om upphovet till ditt resultat och få möjlighet till en mer djupgående bedömning av dina emotionsförmågor så tryck på knappen`;
|
||||||
|
}
|
||||||
|
else if(this.mistake>2){
|
||||||
|
msg = `Bra jobbat!`;
|
||||||
|
msg2 = `Ditt resultat visar på en god förmåga att para beteenden kopplade till hög respektive låg emotionell intelligens. Vill du lära dig mer om upphovet till ditt resultat och få möjlighet till en mer djupgående bedömning av dina emotionsförmågor så tryck på knappen` ;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
msg = `Bra jobbat!`;
|
||||||
|
msg2 = `Ditt resultat visar på en mycket god förmåga att para beteenden kopplade till hög respektive låg emotionell intelligens. Vill du lära dig mer om upphovet till ditt resultat och få möjlighet till en mer djupgående bedömning av dina emotionsförmågor så tryck på knappen` ;
|
||||||
|
}
|
||||||
|
|
||||||
|
var text0 = this.add.text(30, 30, "Resultat: "+this.point+"p", {
|
||||||
|
font: "48px font1",
|
||||||
|
wordWrap: { width: 730, useAdvancedWrap: true },
|
||||||
|
color: '#ffffff',
|
||||||
|
align: 'left'
|
||||||
|
}).setDepth(3);
|
||||||
|
|
||||||
|
|
||||||
|
var text1 = this.add.text(config.width/2, config.height/2 - 180, msg , {
|
||||||
|
font: "42px Arial",
|
||||||
|
wordWrap: { width: 900, useAdvancedWrap: true },
|
||||||
|
color: '#F29B27',
|
||||||
|
align: 'center'
|
||||||
|
}).setDepth(3).setOrigin(.5);
|
||||||
|
|
||||||
|
var text2 = this.add.text(text1.getBottomCenter().x, text1.getBottomCenter().y + 20, msg2 , {
|
||||||
|
font: "42px Arial",
|
||||||
|
wordWrap: { width: 900, useAdvancedWrap: true },
|
||||||
|
color: '#ffffff',
|
||||||
|
align: 'center'
|
||||||
|
}).setDepth(3).setOrigin(.5,0);
|
||||||
|
|
||||||
|
var elogo = this.add.sprite(5, config.height, "elogo").setOrigin(0,1);
|
||||||
|
this.add.text(elogo.getBottomRight().x + 10, config.height - 5, "©" , {
|
||||||
|
font: "52px Arial",
|
||||||
|
color: '#ffffff',
|
||||||
|
align: 'center'
|
||||||
|
}).setDepth(3).setOrigin(0,1);
|
||||||
|
|
||||||
|
var btnClose = this.add.sprite(config.width/2, config.height - 100, "btn").setDisplaySize(300, 80).setDepth(1).setVisible(true);
|
||||||
|
this.tryText = this.add.text(config.width/2, config.height - 100, 'Nyfiken?', {
|
||||||
|
font: "52px Arial",
|
||||||
|
color: '#F29B27',
|
||||||
|
align: 'center'
|
||||||
|
}).setDepth(3).setOrigin(.5).setVisible(true);
|
||||||
|
|
||||||
|
btnClose.setInteractive();
|
||||||
|
btnClose.on('pointerdown', function () {
|
||||||
|
// this.scene.start('Game');
|
||||||
|
this.newTab();
|
||||||
|
}.bind(this));
|
||||||
|
btnClose.on('pointerover', function () {
|
||||||
|
btnClose.setDisplaySize(320, 120);
|
||||||
|
}.bind(this));
|
||||||
|
btnClose.on('pointerout', function () {
|
||||||
|
btnClose.setDisplaySize(300, 100);
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
console.log( btnClose );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
newTab(){
|
||||||
|
// var win = window.open("http://www.onlinetester.se/privatperson");
|
||||||
|
var win = window.location.replace("http://www.onlinetester.se/privatperson");;
|
||||||
|
//win.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
54
src/Scenes/TitleScene.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import 'phaser';
|
||||||
|
// import Phaser from '../phaser.min';
|
||||||
|
import config from '../Config/config';
|
||||||
|
|
||||||
|
export default class TitleScene extends Phaser.Scene {
|
||||||
|
|
||||||
|
constructor () {
|
||||||
|
super('Title');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
create () {
|
||||||
|
|
||||||
|
var background = this.add.sprite(config.width/2, config.height/2, 'bg');
|
||||||
|
|
||||||
|
var background = this.add.sprite(config.width/2, 340, 'title');
|
||||||
|
|
||||||
|
// this.titleText = this.add.text(config.width/2, 250, "IPv6 Penguin", {
|
||||||
|
// font: "58px Arial Black",
|
||||||
|
// wordWrap: { width: 520, useAdvancedWrap: true },
|
||||||
|
// color: '#4AB6F5',
|
||||||
|
// align: 'center'
|
||||||
|
// }).setOrigin(.5);
|
||||||
|
// // this.titleText.setStroke('#2E732C', 5);
|
||||||
|
// this.titleText.setStroke('#ffffff', 13);
|
||||||
|
|
||||||
|
var btn = this.add.sprite(config.width/2, 500, 'btn').setDisplaySize(300, 80);
|
||||||
|
this.btnText = this.add.text(btn.x, btn.y, "Start", {
|
||||||
|
font: "52px Arial",
|
||||||
|
wordWrap: { width: 500, useAdvancedWrap: true },
|
||||||
|
color: '#4AB6F5',
|
||||||
|
align: 'center'
|
||||||
|
}).setOrigin(.5);
|
||||||
|
btn.setInteractive();
|
||||||
|
btn.on('pointerdown', function () {
|
||||||
|
|
||||||
|
// this.scene.restart();
|
||||||
|
this.scene.start('Game');
|
||||||
|
}.bind(this));
|
||||||
|
btn.on('pointerover', function () {
|
||||||
|
btn.setDisplaySize(310, 110);
|
||||||
|
}.bind(this));
|
||||||
|
btn.on('pointerout', function () {
|
||||||
|
btn.setDisplaySize(300, 100);
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
28
src/index.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import Phaser from "phaser";
|
||||||
|
|
||||||
|
import config from './Config/config';
|
||||||
|
import BootScene from './Scenes/BootScene';
|
||||||
|
import PreloaderScene from './Scenes/PreloaderScene';
|
||||||
|
import TitleScene from './Scenes/TitleScene';
|
||||||
|
import GameScene from './Scenes/GameScene';
|
||||||
|
import ResultScene from './Scenes/ResultScene';
|
||||||
|
|
||||||
|
import Model from './Model';
|
||||||
|
|
||||||
|
|
||||||
|
class Game extends Phaser.Game {
|
||||||
|
constructor () {
|
||||||
|
super(config);
|
||||||
|
const model = new Model();
|
||||||
|
this.globals = { model, bgMusic: null };
|
||||||
|
this.scene.add('Boot', BootScene);
|
||||||
|
this.scene.add('Preloader', PreloaderScene);
|
||||||
|
this.scene.add('Title', TitleScene);
|
||||||
|
this.scene.add('Game', GameScene);
|
||||||
|
this.scene.add('Result', ResultScene);
|
||||||
|
this.scene.start('Preloader');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("initializing Game");
|
||||||
|
window.game = new Game();
|
38
webpack/base.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
const webpack = require("webpack");
|
||||||
|
const path = require("path");
|
||||||
|
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||||
|
const CleanWebpackPlugin = require("clean-webpack-plugin");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: "development",
|
||||||
|
devtool: "eval-source-map",
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: {
|
||||||
|
loader: "babel-loader"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: [/\.vert$/, /\.frag$/],
|
||||||
|
use: "raw-loader"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(gif|png|jpe?g|svg|xml)$/i,
|
||||||
|
use: "file-loader"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
"typeof PLUGIN_FBINSTANT": JSON.stringify(true),
|
||||||
|
CANVAS_RENDERER: JSON.stringify(true),
|
||||||
|
WEBGL_RENDERER: JSON.stringify(true),
|
||||||
|
}),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: "./index.html"
|
||||||
|
})
|
||||||
|
]
|
||||||
|
};
|
27
webpack/prod.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
const merge = require("webpack-merge");
|
||||||
|
const path = require("path");
|
||||||
|
const base = require("./base");
|
||||||
|
const TerserPlugin = require("terser-webpack-plugin");
|
||||||
|
|
||||||
|
module.exports = merge(base, {
|
||||||
|
mode: "production",
|
||||||
|
output: {
|
||||||
|
filename: "bundle.min.js"
|
||||||
|
},
|
||||||
|
devtool: false,
|
||||||
|
performance: {
|
||||||
|
maxEntrypointSize: 900000,
|
||||||
|
maxAssetSize: 900000
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
minimizer: [
|
||||||
|
new TerserPlugin({
|
||||||
|
terserOptions: {
|
||||||
|
output: {
|
||||||
|
comments: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|