mirror of
https://github.com/wassname/phaser.git
synced 2026-06-27 16:10:15 +08:00
253 lines
8.4 KiB
JavaScript
253 lines
8.4 KiB
JavaScript
/**
|
|
* Created by JP on 07.02.14.
|
|
* The course1.tmx to course3.tmx files can be edited using the free map editor "tiled" (www.mapeditor.org)
|
|
* Use export to create the .json files that are loaded by this game
|
|
* The grass and wood textures are CC0 licensed files from openGameArt.org (grass.png, tiles.png)
|
|
* The ball, arrow and hole are are drawn by Jan Peter Simonsen and licensed CC0 (ball.png, arrow.png, hole.png)
|
|
* CC0: http://creativecommons.org/publicdomain/zero/1.0/
|
|
*/
|
|
|
|
//create the phaser game object
|
|
var game = new Phaser.Game(800, 576, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render});
|
|
|
|
//setup variables, they are explained (commented) as they get used for the first time
|
|
var ball, arrow, layer, map, mode, downTime, holes, inputPressed, level, maxLevel, swingCount, infoText;
|
|
|
|
function preload() {
|
|
//load all images
|
|
game.load.image('ball', 'assets/games/golf/ball.png');
|
|
game.load.image('grass', 'assets/games/golf/grass.png');
|
|
game.load.image('tiles', 'assets/games/golf/tiles.png');
|
|
game.load.image('arrow', 'assets/games/golf/arrow.png');
|
|
game.load.image('hole', 'assets/games/golf/hole.png');
|
|
|
|
//Set the level count to 3
|
|
maxLevel = 3;
|
|
|
|
//load all levels (filename for the levels is assumed to be "course" followed by the number of the level)
|
|
var i;
|
|
for (i = 1; i <= maxLevel; i++ ) {
|
|
game.load.tilemap('course' + i, 'assets/games/golf/course' + i + '.json', null, Phaser.Tilemap.TILED_JSON);
|
|
}
|
|
}
|
|
|
|
function create() {
|
|
//create a background tiledSprite (so the empty areas of the level are grassy)
|
|
game.add.tileSprite(0, 0, game.width, game.height, 'grass');
|
|
|
|
//set the current level to 1
|
|
level = 1;
|
|
|
|
//create the ball
|
|
ball = game.add.sprite(100, 100, 'ball', '');
|
|
ball.anchor.setTo(0.5, 0.5);
|
|
//bounce to 0.9 means the ball loses 10% speed on impact
|
|
ball.body.bounce.setTo(0.9, 0.9);
|
|
//the "hitbox" for the ball is a circle with 12 pixel radius
|
|
ball.body.setCircle(12, 12, 12);
|
|
|
|
//the ball slows down by itself at this rate
|
|
ball.body.linearDamping = 1.0;
|
|
|
|
//used to check if the ball has come to a hold
|
|
ball.body.minVelocity.setTo(1, 1);
|
|
|
|
//Set the game to display the level
|
|
loadLevel(level);
|
|
|
|
//variable for sprite that holds the arrow, but we don't need it right away
|
|
arrow = null;
|
|
|
|
//flag to check if mousekey is down (or if finger is touching down on mobile)
|
|
inputPressed = false;
|
|
|
|
//setting up a callback, so that the function inputDown is called every time the screen is touched/the mouse is pressed
|
|
game.input.onDown.add(inputDown, this);
|
|
//call inputUp every time the mouse button is let go / the finger is lifted
|
|
game.input.onUp.add(inputUp, this);
|
|
|
|
//On mobiles set the game to scale to fullscreen
|
|
if (!game.device.desktop) {
|
|
this.game.stage.scale.minWidth = game.width / 2;
|
|
this.game.stage.scale.minHeight = game.width / 2;
|
|
this.game.stage.scale.maxWidth = game.width * 2;
|
|
this.game.stage.scale.maxHeight = game.height * 2;
|
|
this.game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL;
|
|
}
|
|
|
|
//the counter for the amounts of swings it took to complete the game
|
|
swingCount = 0;
|
|
|
|
//a short welcome text
|
|
infoText = game.add.text(game.world.centerX - 80, game.world.centerY - 40, 'Let\'s go!', { font: "42pt Arial", fill: "#ff1111", align: "center" });
|
|
|
|
mode = -1;
|
|
//initialize current game mode
|
|
setMode(0);
|
|
}
|
|
|
|
function loadLevel(number) {
|
|
//if a level is displayed already we clear up everything
|
|
if (map != null) {
|
|
holes.destroy();
|
|
layer.destroy();
|
|
map.destroy();
|
|
}
|
|
//create a group for the holes (there can be multiple holes in a single level)
|
|
holes = game.add.group();
|
|
//creat the map for the current level
|
|
map = game.add.tilemap('course' + number);
|
|
//create the tileset
|
|
map.addTilesetImage('tiles');
|
|
//set all tiles to collide
|
|
map.setCollisionByExclusion([]);
|
|
//create a layer for the "walls" part of the tileset
|
|
layer = map.createLayer('walls');
|
|
//create holes from the "holes" object-layer of the tileset
|
|
map.createFromObjects('holes', 1, 'hole', '', true, true, holes);
|
|
holes.forEach(function(hole) {
|
|
//set the body for each hole to be only a circle with radius 8,
|
|
//so the ball does not collide if it just touches the outside of the (bigger) hole sprite
|
|
hole.body.setCircle(8, 16, 16);
|
|
}, this);
|
|
//make sure the ball is displayed ontop of everything else
|
|
ball.bringToTop();
|
|
}
|
|
|
|
function inputDown(pointer) {
|
|
inputPressed = true;
|
|
}
|
|
|
|
function inputUp(pointer) {
|
|
inputPressed = false;
|
|
}
|
|
|
|
//adds the arrow to the game (called when the ball is laying still and the player can make his move)
|
|
function createArrow() {
|
|
//create the direction arrow
|
|
arrow = game.add.sprite(0, 0, 'arrow');
|
|
arrow.anchor.setTo(0.5, 0.5);
|
|
arrow.pivot.x = 0;
|
|
arrow.pivot.y = +35;
|
|
//add it as a child to the ball, so that it circles the ball
|
|
ball.addChild(arrow);
|
|
}
|
|
|
|
//removes the arrow from the game
|
|
function removeArrow() {
|
|
ball.removeChild(arrow);
|
|
arrow.destroy();
|
|
}
|
|
|
|
//set the mode variable and create / destroy the arrow depending on the mode
|
|
//mode 1 means the ball is moving
|
|
//mode 2 means the ball is laying stil
|
|
function setMode(newMode) {
|
|
if (mode != newMode) {
|
|
if (mode == 1) {
|
|
removeArrow();
|
|
} else if (mode == 0) {
|
|
//make sure the ball does not move
|
|
ball.body.velocity.setTo(0,0);
|
|
createArrow();
|
|
downTime = 0;
|
|
}
|
|
mode = newMode;
|
|
}
|
|
}
|
|
|
|
//win is called when the ball hits the hole at the right amount of speed
|
|
function win() {
|
|
setMode(0);
|
|
//reset the ball to the start position
|
|
ball.reset(100, 100);
|
|
//if there are more levels, increase the level counter otherwhise reset it to level 1
|
|
if (level < maxLevel) {
|
|
level++
|
|
} else {
|
|
level = 1;
|
|
}
|
|
//load the next (or first) level
|
|
loadLevel(level);
|
|
|
|
//if the level is level 1 it means we have played through all levels, display the win message with the swing counter
|
|
if (level == 1) {
|
|
infoText = game.add.text(game.world.centerX-160, game.world.centerY - 40, 'The end - ' + swingCount + ' swings', { font: "32pt Arial", fill: "#ff1111", align: "center" });
|
|
swingCount = 0;
|
|
}
|
|
}
|
|
|
|
//calculate a number between 0 and 500 based on how long the mousebutton/finger is pressed
|
|
//this number goes from 0 to 500 and then back down again to 0 and then starts over.
|
|
function power() {
|
|
return Math.abs(((game.time.time - downTime + 500) % 1000) -500);
|
|
}
|
|
|
|
//this is the callback for the overlap function between ball and holes
|
|
function fallInHole(ball, hole) {
|
|
//if the balls combined x+y speed is below 100 it can fall into the hole
|
|
if ( (ball.body.velocity.x + ball.body.velocity.y) < 100) {
|
|
ball.visible = false; //make the ball invisible (it's in the hole after all), the reset in win makes it visible again
|
|
win();
|
|
}
|
|
}
|
|
|
|
function update() {
|
|
//mode 0 means the ball is moving
|
|
if (mode == 0) {
|
|
|
|
//if the ball is moving, remove all info texts if there are any
|
|
if (infoText != null) {
|
|
infoText.destroy();
|
|
infoText = null;
|
|
}
|
|
|
|
//collide the ball with the walls
|
|
game.physics.collide(ball, layer);
|
|
|
|
//check for the ball hitting the hole
|
|
game.physics.overlap(ball, holes, fallInHole);
|
|
|
|
//Check if the ball is moving so slow that we can make it stop completly and switch to swing-mode
|
|
if (Math.abs(ball.body.velocity.x) < ball.body.minVelocity.x && Math.abs(ball.body.velocity.y) < ball.body.minVelocity.y) {
|
|
setMode(1);
|
|
}
|
|
|
|
} else if (mode == 1) {
|
|
//mode 1 is the swing mode, the ball is laying still
|
|
|
|
//rotate the arrow according to mouse/finger position
|
|
arrow.rotation = game.math.angleBetween(ball.body.x, ball.body.y, game.input.x, game.input.y) + Math.PI/2;
|
|
|
|
if (inputPressed) {
|
|
if (downTime == 0) {
|
|
//input has just been pressed, note the time this happend
|
|
downTime = game.time.time;
|
|
} else {
|
|
//scale the arrow lengh according ot the result of the power function (power 0-500) -> arrow size 1.0 to 3.0
|
|
arrow.scale.y = 1.0 + power()/500 * 2;
|
|
}
|
|
} else if (downTime != 0) {
|
|
//the mousebutton has been released (or the finger lifted) now get the ball moving
|
|
ball.body.velocity = game.physics.accelerationFromRotation(arrow.rotation - Math.PI/2, power() + 50);
|
|
//and count it as a swing
|
|
swingCount++;
|
|
//and switch to ball-moving-mode
|
|
setMode(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
function render() {
|
|
//optional debug displays
|
|
/*
|
|
game.debug.renderPhysicsBody(ball.body);
|
|
|
|
holes.forEach(function(hole) {
|
|
game.debug.renderPhysicsBody(hole.body);
|
|
}, this);
|
|
|
|
game.debug.renderBodyInfo(ball, 16, 24);
|
|
*/
|
|
}
|