Related
I am currently making a small platformer game, where the player jumps up infinitely, much like the android game "Abduction". I have managed to create platforms in random locations on a timed interval and adding it to an array. However i can only get the player sprite to collide with 1 of the platform arrays, which is this.walls array that i have made so i have a set starting place for the player. Does anyone know what the issue might be.
Ugly code alert by the way, i am quite new at this.
I have checked update: function to see if i had forgot to add some stuff there. ive spellchecked the code and all sorts of things but i am at a completel loss.
var playState = {
preload: function () {
},
create: function () {
game.add.image (0, 0,'bg');
game.physics.startSystem(Phaser.Physics.ARCADE);
game.renderer.renderSession.roundPixels = true;
this.cursor = game.input.keyboard.createCursorKeys();
game.input.keyboard.addKeyCapture(
[Phaser.Keyboard.UP, Phaser.Keyboard.DOWN, Phaser.Keyboard.LEFT, Phaser.Keyboard.RIGHT]);
this.wasd = {
up: game.input.keyboard.addKey(Phaser.Keyboard.W), left: game.input.keyboard.addKey(Phaser.Keyboard.A), right: game.input.keyboard.addKey(Phaser.Keyboard.D)
};
this.player = game.add.sprite(game.width/2, game.height/1.2, 'player');
this.player.anchor.setTo(0.5, 0.5);
game.physics.arcade.enable(this.player);
this.player.body.gravity.y = 800;
this.scoreLabel = game.add.text(30, 30, 'score: 0',
{ font: '18px Arial', fill: '#ffffff' });
game.global.score = 0;
game.time.events.loop(1000, this.updateScore);
game.time.events.loop(4000, this.addPlatform);
this.createWorld();
},
update: function () {
game.physics.arcade.collide(this.player, this.walls);
game.physics.arcade.collide(this.player, this.platforms);
if (!this.player.inWorld) {
this.playerDie();
}
this.movePlayer();
},
updateScore: function(){
this.score +=1;
game.global.score +=1;
//fix this at some point
},
createWorld: function() {
this.walls = [];
this.walls.push(game.add.sprite(170, 750, 'platform', 0));
this.walls.push(game.add.sprite(70, 650, 'platform', 0));
this.walls.push(game.add.sprite(320, 550, 'platform', 0));
this.walls.push(game.add.sprite(200, 450, 'platform', 0));
this.walls.push(game.add.sprite(10, 550, 'platform', 0));
this.walls.push(game.add.sprite(70, 350, 'platform', 0));
this.walls.push(game.add.sprite(310, 300, 'platform', 0));
this.walls.push(game.add.sprite(230, 200, 'platform', 0));
this.walls.push(game.add.sprite(100, 100, 'platform', 0));
this.walls.push(game.add.sprite(270, 0, 'platform', 0));
for (var x=0; x< this.walls.length; x++) {
game.physics.arcade.enable(this.walls[x]);
this.walls[x].enableBody = true;
this.walls[x].body.immovable = true;
this.walls[x].body.velocity.y = 20;
}
},
addPlatform: function() {
this.platforms = [];
this.platforms.push(game.add.sprite(game.rnd.integerInRange(0, 350),-20,'platform',0));
for (var x=0; x< this.platforms.length; x++) {
game.physics.arcade.enable(this.platforms[x]);
this.platforms[x].enableBody = true;
this.platforms[x].body.immovable = true;
this.platforms[x].body.velocity.y = 20;
}
},
movePlayer: function() {
if (this.cursor.left.isDown || this.wasd.left.isDown) {
this.player.body.velocity.x = -250;
}
else if (this.cursor.right.isDown || this.wasd.right.isDown) {
this.player.body.velocity.x = 250;
}
else {
this.player.body.velocity.x = 0;
}
if ((this.cursor.up.isDown || this.wasd.up.isDown)
&& this.player.body.touching.down){
this.player.body.velocity.y = -450;
}
},
playerDie: function() {
this.player.kill();
//this.deadSound.play();
//this.emitter.x = this.player.x;
//this.emitter.y = this.player.y;
//this.emitter.start(true, 800, null, 15);
game.time.events.add(1000, this.startMenu, this);
game.camera.shake(0.02, 300);
},
startMenu: function() {
game.state.start('menu');
},
};
this.walls is so i have a starting ground of set platforms and this.platforms is the randomly generated platforms.
I want to be able to actually jump on those platforms and not just
fall through, which i do at the moment
Your platform is an array of sprites, so you have to parse through each sprite inside your array.
Or, you can make a "Group" object, instead of plain array. You can make a Group of each plaform, then do collision with this Group and player.
According to the Phaser 3 examples I've created a tilemap from JSON file and added firing bullets with a left mouse clicking in a cursor's direction. Also a platform was added. My problem is that there are no collisions detected between a bullet and a tilemap's objects. But collisions work fine between the bullet and a platform.
Here is my demo code:
var config = {
type: Phaser.CANVAS,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: {
preload: preload,
create: create
}
};
var game = new Phaser.Game(config);
var bullets;
var platforms;
function preload ()
{
this.load.tilemapTiledJSON('map', 'assets/tilemaps/maps/impact-tilemap.json');
this.load.image('kenney', 'assets/tilemaps/tiles/kenney.png');
this.load.image('ground', 'src/games/firstgame/assets/platform.png');
this.load.image('bullet', 'src/games/firstgame/assets/star.png');
}
function create ()
{
var map = this.make.tilemap({ key: 'map' });
var tileset = map.addTilesetImage('kenney');
var layer = map.createStaticLayer(0, tileset, 0, 0);
layer.setCollisionByExclusion([-1]);
this.physics.world.bounds.width = layer.width;
this.physics.world.bounds.height = layer.height;
platforms = this.physics.add.staticGroup();
platforms.create(400, 268, 'ground');
// Fires bullet on left click of mouse
this.input.on('pointerdown', function() {
fire(this);
}, this);
var Bullet = new Phaser.Class({
Extends: Phaser.GameObjects.Image,
initialize: function Bullet(scene)
{
Phaser.GameObjects.Image.call(this, scene, 0, 0, 'bullet');
this.speed = Phaser.Math.GetSpeed(300, 1);
this.velocity = new Phaser.Geom.Point(0, 0);
},
fire: function (x, y, direction)
{
this.setPosition(x, y);
this.setActive(true);
this.setVisible(true);
this.velocity.setTo(0, -this.speed);
Phaser.Math.Rotate(this.velocity, direction);
},
update: function (time, delta)
{
// Update position based on velocity
this.x += this.velocity.x * delta;
this.y += this.velocity.y * delta;
}
});
bullets = this.physics.add.group({
classType: Bullet,
maxSize: 30,
runChildUpdate: true
});
this.physics.add.collider(bullets, platforms, callbackFunc, null, this);
this.physics.add.collider(bullets, layer, callbackFunc, null, this);
}
function callbackFunc(bullet, target)
{
if ( bullet.active === true ) {
console.log("Hit!");
bullet.setActive(false);
bullet.setVisible(false);
}
}
function fire(that)
{
var bullet = bullets.get();
if (bullet) {
bullet.body.allowGravity = false;
var angle = Math.atan2(that.input.activePointer.y - 400, that.input.activePointer.x - 300);
bullet.fire(300, 400, angle + (3.14/2));
}
}
You can copy-paste it to any example at https://labs.phaser.io and start clicking to fire at any direction.
I've tried to add a standard player from examples too and collisions work fine with the tilemap's objects. So the problem is with bullets only.
Please help to solve this. Thanks!
If anyone has used Phaser, perhaps you can help me with my code. I am trying to create a Flappy Bird clone, and so far it is working pretty well. However, whenever I open the game the first time, the sprites of the pipes don't seem to show up. I've preloaded both the bird and the pipe sprites, and only the bird sprite loads on the first attempt. As soon as the game restarts (when the bird dies), the pipes load normally. I am using WAMP to host a local server.
Here is my code:
var game = new Phaser.Game(400, 490, Phaser.AUTO, 'game_div');
var main_state = {
preload: function() {
this.game.stage.backgroundColor = '#66CCFF';
this.game.load.image('pipe', 'assets/pipe.png');
this.game.load.image('bird', 'assets/bird.png');
this.pipes = game.add.group();
this.pipes.createMultiple(20, 'pipe');
},
add_one_pipe: function(x, y) {
var pipe = this.pipes.getFirstDead();
pipe.reset(x, y);
pipe.body.velocity.x = -200
pipe.outOfBoundsKill = true;
},
add_row_of_pipes: function() {
var hole = Math.floor(Math.random()*5) + 1;
for (var i = 0; i < 8; i++) {
if (i != hole && i != hole + 1) {
this.add_one_pipe(400, i * 60 + 10);
}
}
this.score += 1;
this.label_score.content = this.score;
},
create: function() {
this.bird = this.game.add.sprite(100, 245, 'bird');
this.bird.body.gravity.y = 1000;
var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
space_key.onDown.add(this.jump, this);
this.timer = this.game.time.events.loop(1500, this.add_row_of_pipes, this);
this.score = 0;
var style = { font: "30px Arial", fill: "#ffffff" };
this.label_score = this.game.add.text(20, 20, "0", style);
},
update: function() {
if (this.bird.inWorld == false) {
this.restart_game();
}
this.game.physics.overlap(this.bird, this.pipes, this.restart_game, null, this);
},
jump: function() {
this.bird.body.velocity.y = -350;
},
restart_game: function() {
this.game.time.events.remove(this.timer);
this.game.state.start('main');
},
};
// Add and start the 'main' state to start the game
game.state.add('main', main_state);
game.state.start('main');
As in the tutorial, try to put the creation of the group in the create function:
create: function() {
this.bird = this.game.add.sprite(100, 245, 'bird');
this.bird.body.gravity.y = 1000;
var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
space_key.onDown.add(this.jump, this);
this.pipes = game.add.group();
this.pipes.createMultiple(20, 'pipe');
this.timer = this.game.time.events.loop(1500, this.add_row_of_pipes, this);
this.score = 0;
var style = { font: "30px Arial", fill: "#ffffff" };
this.label_score = this.game.add.text(20, 20, "0", style);
},
I am newbie. I can't sprite animation using jquery..
What's the problem?
How can make progressing the sprite animation on the spot loop as scroll??
$(window).scroll('scroll',function(e){
parallaxScroll();
});
function parallaxScroll() {
var ani_data = [0, -120, -240, -480];
var frame_index = 0;
if ( ScrollCount == 3 ) {
ScrollCount = 1;
$('#fatherwalk').css('background-position', ani_data[frame_index] + 'px 0px');
frame_index++;
if ( frame_index >= ani_data.length ) {
frame_index = 0;
}
}
scrollcount++;
}
Why you don't get a shortcut and try SpinJS?
http://fgnass.github.io/spin.js/
It's so easy to implement and works fine.
Here is a Sample that I've made on JSFiddle
Below a quick implementation of the JS:
$.fn.spin = function (opts) {
this.each(function () {
var $this = $(this),
spinner = $this.data('spinner');
if (spinner) spinner.stop();
if (opts !== false) {
opts = $.extend({
color: $this.css('color')
}, opts);
spinner = new Spinner(opts).spin(this);
$this.data('spinner', spinner);
}
});
return this;
};
$(function () {
$(".spinner-link").click(function (e) {
e.preventDefault();
$(this).hide();
var opts = {
lines: 12, // The number of lines to draw
length: 7, // The length of each line
width: 5, // The line thickness
radius: 10, // The radius of the inner circle
color: '#fff', // #rbg or #rrggbb
speed: 1, // Rounds per second
trail: 66, // Afterglow percentage
shadow: true // Whether to render a shadow
};
$("#spin").show().spin(opts);
});
});
Hope this helps.
I have a javascript game that uses drag and drop of images to create words. Currently if the word has repeating letters, I have to name the letters differently:
Example word: Alphabet,
images: a.png, l.png, p.png, h.png, a1.png, b.png, e.png and t.png.
As you can imagine when you drag a.png to spell the word, it has to be on its own defined block or it wont lock in place.
How can i edit the script to use the same image more than once and be able to drag on any of the correct placements.
See this fiddle for a demo: http://jsfiddle.net/Q89Ck/
<script defer="defer">
function loadImages(sources, callback) {
var assetDir = 'http://kidnplay.co.uk/spelling/alphabet/';
var images = {};
var loadedImages = 0;
var numImages = 0;
for(var src in sources) {
numImages++;
}
for(var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = assetDir + sources[src];
}
}
function isNearOutline(animal, outline) {
var a = animal;
var o = outline;
var ax = a.getX();
var ay = a.getY();
if(ax > o.x - 20 && ax < o.x + 20 && ay > o.y - 20 && ay < o.y + 20) {
return true;
}
else {
return false;
}
}
function drawBackground(background, backImg, text) {
var canvas = background.getCanvas();
var context = background.getContext();
context.drawImage(backImg, 0, 0);
context.font = '18pt georgia,palatino';
context.textAlign = 'center';
context.fillStyle = 'white';
context.fillText(text, background.getStage().getWidth() / 2, 32);
}
function initStage(images) {
var stage = new Kinetic.Stage({
container: 'container',
width: 940,
height: 600
});
var background = new Kinetic.Layer();
var animalLayer = new Kinetic.Layer();
var animalShapes = [];
var score = 0;
// image positions
var animals = {
a: {
x: 50,
y: 70
},
e: {
x: 150,
y: 70
},
b: {
x: 250,
y: 70
},
t: {
x: 350,
y: 70
},
a2: {
x: 450,
y: 70
},
p: {
x: 550,
y: 70
},
l: {
x: 650,
y: 70
},
h: {
x: 750,
y: 70
},
};
var outlines = {
a_black: {
x: 30,
y: 300
},
l_black: {
x: 135,
y: 300
},
p_black: {
x: 240,
y: 300
},
h_black: {
x: 345,
y: 300
},
a2_black: {
x: 450,
y: 300
},
b_black: {
x: 555,
y: 300
},
e_black: {
x: 660,
y: 300
},
t_black: {
x: 765,
y: 300
},
};
// create draggable animals
for(var key in animals) {
// anonymous function to induce scope
(function() {
var privKey = key;
var anim = animals[key];
var animal = new Kinetic.Image({
image: images[key],
x: anim.x,
y: anim.y,
draggable: true
});
animal.createImageHitRegion();
animal.on('dragstart', function() {
this.moveToTop();
animalLayer.draw();
});
/*
* check if animal is in the right spot and
* snap into place if it is
*/
animal.on('dragend', function() {
var outline = outlines[privKey + '_black'];
if(!animal.inRightPlace && isNearOutline(animal, outline)) {
animal.setPosition(outline.x, outline.y);
animalLayer.draw();
animal.inRightPlace = true;
if(++score >= 8) {
var text = 'Well done! The correct word is alphabet!'
drawBackground(background, images.back, text);
}
// disable drag and drop
setTimeout(function() {
animal.setDraggable(false);
}, 50);
}
});
// make animal glow on mouseover
animal.on('mouseover', function() {
animal.setImage(images[privKey + '_glow']);
animalLayer.draw();
document.body.style.cursor = 'pointer';
});
// return animal on mouseout
animal.on('mouseout', function() {
animal.setImage(images[privKey]);
animalLayer.draw();
document.body.style.cursor = 'default';
});
animal.on('dragmove', function() {
document.body.style.cursor = 'pointer';
});
animalLayer.add(animal);
animalShapes.push(animal);
})();
}
// create animal outlines
for(var key in outlines) {
// anonymous function to induce scope
(function() {
var imageObj = images[key];
var out = outlines[key];
var outline = new Kinetic.Image({
image: imageObj,
x: out.x,
y: out.y
});
animalLayer.add(outline);
})();
}
stage.add(background);
stage.add(animalLayer);
drawBackground(background, images.back, 'Rearrange the letters to spell the word');
}
var sources = {
back: 'back.png',
a: 'a.png',
a_glow: 'a-glow.png',
a_black: 'a-black.png',
b: 'b.png',
b_glow: 'b-glow.png',
b_black: 'b-black.png',
e: 'e.png',
e_glow: 'e-glow.png',
e_black: 'e-black.png',
h: 'h.png',
h_glow: 'h-glow.png',
h_black: 'h-black.png',
l: 'l.png',
l_glow: 'l-glow.png',
l_black: 'l-black.png',
p: 'p.png',
p_glow: 'p-glow.png',
p_black: 'p-black.png',
t: 't.png',
t_glow: 't-glow.png',
t_black: 't-black.png',
a2: 'a2.png',
a2_glow: 'a2-glow.png',
a2_black: 'a2-black.png',
};
loadImages(sources, initStage);
</script>
For using same image for both As:
You need to separate out the dependency of image names with the key you use.
One possible way is to add another attribute in the arrays which have the value of actual alphabet and use that value to source from your images array. This basically solves your issue with using same images for 2 variables.
For snapping either A's in either of the possible positions:
You can use suggestion from Barmar in the comments :)
To allow fitting either “A” into an outline, assign both the animal and outline a “letter” property.
Add a “letter” property to each animal object:
animal.letter=”A”;
Add a “correct” letter property to each outline object:
outline.letter=”A”;
Then you can check if a correct letter is in a specified outline:
if( outline.letter == animal.letter ) {
// a valid animal is in the outline
}
This also allows you to use the same A.png in both the “A-animals”.