I have to do a mini video game for a practice. I have coded in Phaser, JavaScript and Java. The canvas is drawn in Phaser.
I need to put collisions in the borders of the world or something when my spaceship touch the canvas limit for my spaceship doesn't go out to the screen.
My teacher forbidden do something with physics like arcade, ninja, or P2.
Its doesn't matter if the solution is in JavaScript or Phaser. Only I need to put limits in the canvas' border.
I have this for drawing the world in Phaser:
game = new Phaser.Game(1024, 600, Phaser.AUTO, 'gameDiv'
I have my sprite in the world in the preload:
game.global.myPlayer.image = game.add.sprite(0, 0, 'spacewar', game.global.myPlayer.shipType);
In the create function I have the keyboard control:
this.wKey = game.input.keyboard.addKey(Phaser.Keyboard.UP);
this.sKey = game.input.keyboard.addKey(Phaser.Keyboard.DOWN);
this.aKey = game.input.keyboard.addKey(Phaser.Keyboard.LEFT);
this.dKey = game.input.keyboard.addKey(Phaser.Keyboard.RIGHT);
this.spaceKey = game.input.keyboard.addKey(Phaser.Keyboard.CONTROL);
this.shiftKey = game.input.keyboard.addKey(Phaser.Keyboard.SHIFT);
In the update function the movement:
if (this.wKey.isDown)
msg.movement.thrust = true;
if (this.sKey.isDown)
msg.movement.brake = true;
if (this.aKey.isDown)
msg.movement.rotLeft = true;
if (this.dKey.isDown)
msg.movement.rotRight = true;
if (this.spaceKey.isDown) {
msg.bullet = this.fireBullet()
}
if (this.shiftKey.isDown) {
msg.push = true;
}
Not sure how asking for the solution to a school project will help you learn anything..
But anyway, the update() function is called for every frame (60 times per second), so inside that function you can do something like this to prevent the player from moving outside the game area:
// cannot move outside game area, left and right
if (game.global.myPlayer.image.x < 0) {
game.global.myPlayer.image.x = 0;
}
if (game.global.myPlayer.image.x > game.world.width) {
game.global.myPlayer.image.x = game.world.width;
}
// cannot move outside game area, top and bottom
if (game.global.myPlayer.image.y < 0) {
game.global.myPlayer.image.y = 0;
}
if (game.global.myPlayer.image.y > game.world.height) {
game.global.myPlayer.image.y = game.world.height;
}
Related
I'm trying to get the collision to work in Phaser.
I'm using the p2 physics and I want a function to get called, when the player hits a door:
//Load player
playerSprite = this.game.add.sprite(50, 900, 'player-front');
player = new Player(playerSprite);
//1
//Enter door
door = this.game.add.sprite(350, 865, 'player-back');
Then i start the physics:
this.game.physics.startSystem(Phaser.Physics.P2JS);
//Setting up witch tiles needs colliders
map.setCollision(261, true, 'Collisions');
this.game.physics.p2.convertTilemap(map, 'Collisions');
this.game.physics.p2.enable([player.sprite, door], false);
player.sprite.body.fixedRotation = true;
//Physics engine create collision bodies from the tiles
this.game.physics.arcade.enable(map);
this.game.physics.setBoundsToWorld();
//
this.game.physics.p2.setImpactEvents(true);
this.game.physics.p2.updateBoundsCollisionGroup();
Then I make 2 variables and set on the collsision to the player
var playerCollisionGroup = this.game.physics.p2.createCollisionGroup();
var doorCollisionGroup = this.game.physics.p2.createCollisionGroup();
door.physicsBodyType = Phaser.Physics.P2JS;
door.body.setCollisionGroup(doorCollisionGroup);
door.body.collides(playerCollisionGroup);
player.sprite.body.setCollisionGroup(playerCollisionGroup);
player.sprite.body.collides(doorCollisionGroup, this.hitDoor, this);
And the hitDoor function looks like this:
hitDoor: function(body1, body2){
console.log("Collision works");
},
I dont know why it's now working.
Someone that can see the problem?
Ty
I have been practicing using sprites for a game I am going to make and have watched and read a few tutorials, I thought I was close to getting my sprite to appear so I could finally start my game but while practicing I cant get it to work, I have dont 2 seperate tutorials where I can get the sprite and the background to appear by themselfs but cannot get them to work together, I have been using EaselJS too. some of the sprite animation code has been copied from tutorials too.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>sprite prac<title>
<!-- EaselJS library -->
<script src="lib/easel.js"></script>
<script>
// Initialize on start up so game runs smoothly
function init() {
canvas = document.getElementById("canvas");
stage = new Stage(canvas);
bg = new Image();
bg.src = "img/grassbg.jpg";
bg.onload = setBG;
stage.addChild(background);
imgMonsterARun = new Image();
imgMonsterARun.onload = handleImageLoad;
imgMonsterARun.onerror = handleImageError;
imgMonsterARun.src = "img/MonsterARun.png";
stage.update();
}
function handleImageLoad(e) {
startGame();
}
// Simple function for setting up the background
function setBG(event){
var bgrnd = new Bitmap(bg);
stage.addChild(bgrnd);
stage.update();
}
function startGame() {
// create a new stage and point it at our canvas:
stage = new createjs.Stage(canvas);
// grab canvas width and height for later calculations:
screen_width = canvas.width;
screen_height = canvas.height;
// create spritesheet and assign the associated data.
var spriteSheet = new createjs.SpriteSheet({
// image to use
images: [imgMonsterARun],
// width, height & registration point of each sprite
frames: {width: 64, height: 64, regX: 32, regY: 32},
animations: {
walk: [0, 9, "walk"]
}
});
// create a BitmapAnimation instance to display and play back the sprite sheet:
bmpAnimation = new createjs.BitmapAnimation(spriteSheet);
// start playing the first sequence:
bmpAnimation.gotoAndPlay("walk"); //animate
// set up a shadow. Note that shadows are ridiculously expensive. You could display hundreds
// of animated rats if you disabled the shadow.
bmpAnimation.shadow = new createjs.Shadow("#454", 0, 5, 4);
bmpAnimation.name = "monster1";
bmpAnimation.direction = 90;
bmpAnimation.vX = 4;
bmpAnimation.x = 16;
bmpAnimation.y = 32;
// have each monster start at a specific frame
bmpAnimation.currentFrame = 0;
stage.addChild(bmpAnimation);
// we want to do some work before we update the canvas,
// otherwise we could use Ticker.addListener(stage);
createjs.Ticker.addListener(window);
createjs.Ticker.useRAF = true;
createjs.Ticker.setFPS(60);
}
//called if there is an error loading the image (usually due to a 404)
function handleImageError(e) {
console.log("Error Loading Image : " + e.target.src);
}
function tick() {
// Hit testing the screen width, otherwise our sprite would disappear
if (bmpAnimation.x >= screen_width - 16) {
// We've reached the right side of our screen
// We need to walk left now to go back to our initial position
bmpAnimation.direction = -90;
}
if (bmpAnimation.x < 16) {
// We've reached the left side of our screen
// We need to walk right now
bmpAnimation.direction = 90;
}
// Moving the sprite based on the direction & the speed
if (bmpAnimation.direction == 90) {
bmpAnimation.x += bmpAnimation.vX;
}
else {
bmpAnimation.x -= bmpAnimation.vX;
}
// update the stage:
stage.update();
}
</script>
</head>
<body onload="init();">
<canvas id="canvas" width="500" height="500" style="border: thin black solid;" ></canvas>
</body>
</html>
There are a few places where you are using some really old APIs, which may or may not be supported depending on your version of EaselJS. Where did you get the easel.js script you reference?
Assuming you have a version of EaselJS that matches the APIs you are using, there are a few issues:
You add background to the stage. There is no background, so you are probably getting an error when you add it. You already add bgrnd in the setBackground method, which should be fine. If you get an error here, then this could be your main issue.
You don't need to update the stage any time you add something, just when you want the stage to "refresh". In your code, you update after setting the background, and again immediately at the end of your init(). These will fire one after the other.
Are you getting errors in your console? That would be a good place to start debugging. I would also recommend posting code if you can to show an actual demo if you continue to have issues, which will help identify what is happening.
If you have a newer version of EaselJS:
BitmapAnimation is now Sprite, and doesn't support direction. To flip Sprites, use scaleX=-1
Ticker no longer uses addListener. Instead it uses the EventDispatcher. createjs.Ticker.addEventListener("tick", tickFunction);
You can get new versions of the CreateJS libraries at http://code.createjs.com, and you can get updated examples and code on the website and GitHub.
I have problem with resize windows game. I've read various posts on the forum but I could not get the correct resize the view of the game.
If you rotate the device screen size, I would like to display the game has adapted to the width / height of the display device both horizontally and vertically.
When the game started, it is properly scaled up, just turning your exchange device scaling is incorrect. Return to the previous screen orientation device retains its proportions.
In template html I add:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
First script:
function preload() {
...
Global.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
Global.game.scale.pageAlignHorizontally = true;
Global.game.scale.pageAlignVertically = true;
Global.game.scale.forceOrientation(true, false);
Global.game.scale.setMaximum();
Global.game.scale.setScreenSize(true);
...
}
function resize() {
Global.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
Global.game.scale.pageAlignHorizontally = true;
Global.game.scale.pageAlignVertically = true;
Global.game.scale.forceOrientation(true, true);
Global.game.scale.setShowAll();
Global.game.scale.refresh();
}
When I use this code, game scale correct when game started. When in device:
change position with horizontal on vertical, game is bigges and show
scroll
change position with vertical on horizontal, game is flat
Second script:
function preload() {
...
Global.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
Global.game.scale.parentIsWindow = true;
...
}
function resize () {
Global.game.scale.refresh();
}
When I use this code, game scale correct when game started. When in device:
1. change position with horizontal on vertical, game is scaled but on left and right is see white background
2. change position with vertical on horizontal, game is scaled but on bottom I see white background
I use Phaser 2.3
Does anyone know the solution to my problem?
Thank you =)
BEST SOLUTION
Phaser 2.3 have a bug - not change resize site. I download 2.4.3 version.
I've added features that is loaded at the beginning, which guards the resolution change
var attacks.base.x = 110;
var attacks.base.y = 190;
$(document).ready(function () {
handleScreenResize();
});
function handleScreenResize() {
$(window).resize(function () {
clearTimeout(timeoutResize);
timeoutResize = setTimeout(function () {
var xButtonBase;
var yButtonBase;
/* resize game */
game.scale.scaleMode = Phaser.ScaleManager.RESIZE;
game.scale.pageAlignHorizontally = true;
game.scale.pageAlignVertically = true;
game.scale.forceLandscape = true;
game.scale.parentIsWindow = true;
game.scale.refresh();
/* get new width and height*/
var gameWidth = game.width < game.world.width ? game.width : game.world.width;
/** If you have static button you have change position use "cameraOffset.x" and "cameraOffset.y" set new position*/
/* change position buttons attack */
if(settings.control_option === 'RIGHTHAND') {
xButtonBase = attacks.base.x;
yButtonBase = game.height - attacks.base.y;
} else {
xButtonBase = gameWidth - attacks.base.x;
yButtonBase = game.height - attacks.base.y;
}
/** set position buttons with attack and assist (down screen)*/
attacks.base.button.cameraOffset.x = xButtonBase;
attacks.base.button.cameraOffset.y = yButtonBase;
}, 1000);
});
}
In preload add this script
function preload() {
...
Global.game.scale.scaleMode = Phaser.ScaleManager.RESIZE;
Global.game.scale.pageAlignHorizontally = true;
Global.game.scale.pageAlignVertically = true;
Global.game.scale.forceLandscape = true;
Global.game.scale.parentIsWindow = true;
Global.game.scale.refresh();
...
}
This sounds like an issue that my friend and I were getting when we were trying to re-size our game to a larger resolution if our window changed size.
See this issue: https://github.com/photonstorm/phaser/issues/1881
It should be fixed in Phaser 2.4 (RC1 is out now).
I'm making a game using CreateJS. On desktop my FPS is good but when I try to play this game on mobile (for example : iPhone 4) the FPS drops seriously.
I'm trying to figure out why but
Some code
My Canvas
<canvas id="gameCanvas"></canvas>
Setup
this.canvas = "gameCanvas";
this.stage = new createjs.Stage(this.canvas);
var context = this.stage.canvas.getContext("2d");
context.imageSmoothingEnabled = false;
createjs.Ticker.setFPS(30);
this.gameLoopBind = this.gameLoop.bind(this);
createjs.Ticker.addEventListener('tick', this.gameLoopBind);
GameLoop
// some extra code
this.stage.update();
When I comment the code 'this.stage.update()' my FPS on mobile/tablet is good...
I've no idea what I'm doing wrong...
EXTRA CODE
Play the game here => f.cowb.eu/mora/chick-ins
Gameloop Function
Game.prototype.gameLoop = function (e) {
if (this.running) {
this.timer++;
this.timer2++;
if (this.timer2 > 30) {
if (this.lastSnack + this.timeBewteen < this.stopwatch.seconds) {
var height = (this.topSnack) ? 150 : 300;
this.lastSnack = this.stopwatch.seconds;
new Snack(this, this.timer, height);
this.topSnack = this.topSnack ? false : true;
}
if (this.timer > (this.lastPostive + 300)) {
this.lastPostive = this.timer;
publisher.publish('showMessage',
this.positiveImages[Math.floor(Math.random() * this.positiveImages.length)],
common.lang,
'right');
}
this.timer2 = 0;
}
}
this.stage.update();
};
New Snack
You can find the code for creating a new snack here => http://jsfiddle.net/9ofpqq3z/
Here we create a new snack and animate it.
From looking at the architecture of the game, I would suggest that you draw the game elements on separate canvases as opposed to the way you have it right now where everything is on one canvas.
Place the TV parts that don't get redrawn often (or at all) on one canvas, and then the moving elements on a separate canvas.
That should help bring the frame rate up.
Also, you can take a look at the following set of slides on how to improve performance on mobile devices when using the canvas:
http://www.slideshare.net/DavidGoemans/html5-performance-optimization
Ok I got 2 images one of a player that I make jump and another one of a barrel that rolls towards the player. I searched on google to get all the code that I have together. The problem is I can't find a code that can detect collisions. I need that code so when the barrel hits the player its game over.
GamePlay press the start button and the barrel rolls towards the player , press anywhere onscreen to make player jump. The source code is here if you want to try it http://sourceforge.net/projects/pfbw/files/Platformer.zip/download Thanks for any help you can afford me. Every code I tried didnt work for collision detection.
<!DOCTYPEhtml>
<html>
<head>
<script>
function jump() { // controls player jump
document.getElementById("m").style.top = "250px";
setTimeout(function () {
document.getElementById("m").style.top = "390px";
}, 1500)
}
function moving() { // controls barrel movement
var pp = document.getElementById("b");
var left = parseInt(pp.style.left);
var tim = setTimeout("moving()", 50); // controls the speed
left = left - 25; // move by 50 pixels
pp.style.left = left + "px";
}
</script>
</head>
<body>
<img src="back.png" onclick="jump()" style="position:absolute;top:0;left:0; height:570px;width:1200px;zdepth:1;" />
<img id="m" src="Mario.png" style="position:absolute;top:390px;left:75px;height:80px;width:80px;zdepth:2;" />
<img id="b" src="barrel.png" style="position:absolute;top:390px;left:1000px;height:80px;width:80px;zdepth:2;" />
<img id="s" src="start.png" onclick="moving()" style="position:absolute;top:0px;left:500px;height:80px;width:80px;zdepth:2;" />
</body>
</html>
You need to check if they are in the same position on the page. You're using top and left to set the coordinates of the images, so you need to check to see if they are at the same top and the same left offsets:
var topEq = document.getElementById('m').style.top === document.getElementById('b').style.top;
var leftEq = document.getElementById('m').style.left === document.getElementById('b').style.left;
if(topEq && leftEq){
//game over
}
Alternatively, you can run the whole game in a while loop like this:
var playing = true;
while(playing){
//game
if(topEq && leftEq){
playing = false;
}
}
you will need to manually check that the items do not overlap. The simplest way I know of doing this is to test to see that the rectangle of the one does not overlap with the rectangle of the other.
element.getClientRects() which provides top/bottom/left/right. a sample collision detection function might look like this:
function colides(elem1, elem2){
var cr1 = elem1.getClientRects()[0]; // get the rectangle for the image
var cr2 = elem2.getClientRects()[0]; // ''
var heightOffset = (cr1.bottom - cr2.top); // calculate relative positions vert
var widthOffset = (cr1.right - cr2.left ); // calculate relative positions horiz
if ( heightOffset < (elem1.clientHeight + elem2.clientHeight) // bottom of one below top of other
&& heightOffset > 0 // and not below bottom of other
&& widthOffset < (elem1.clientWidth + elem2.clientWidth) // left of one further right than right of other
&& widthOffset > 0) // and not to the right of it
return true; // this is a collision.
return false; // we didn't return true, so it must be false.
}
this will give false positives because your actors do not take up the whole rectangle, but it is a start.
insert the above function into your code, and use it in your moving function like this:
function moving() // controls barrel movement
{
var barrel = document.getElementById("b"); // get the barrel image
var mario = document.getElementById("m"); // get the mario image
var left = parseInt(pp.style.left); // figure out how far left the barrel is
if (colides(barrel, mario)){ // if there is a collision
barrel.style.left = "1000px" // reset position
alert ("game over"); // notify player
} else { // else
var tim = setTimeout("moving()",50); // run this code again in 50ms
left = left-25; // move by 25 pixels // set the left coordinate down by 25px
if (left < 0) left = 1000; // if we would go off the screen, reset
barrel.style.left = left+"px"; // set the position of the image to match our variable
}
}
Edit added comments. these should explain the code.