Cocos2d Animation inside a Sprite Object - javascript

In a Cocos2d-x V 3.81 project, I am trying to animate a sprite inside an object which extends Sprite, but it does not seem to do anything. Is it even possible to have an animated sprite inside such a node, or does it have to extend Layer to have animation?
var Player = cc.Sprite.extend ({
ctor: function () {
this._super(res.Player_png);
this.UP = false;
this.DOWN = false;
this.LEFT = false;
this.RIGHT = false;
this.ACTION = false;
this.speed = 5;
cc.spriteFrameCache.addSpriteFrame(res.Player_Left_plist);
var leftFrames = [];
for(var i = 0; i < 4; i++)
{
var str = "Left" + i + ".png";
var frame = cc.spriteFrameCache.getSpriteFrame(str);
leftFrames.push(frame);
}
this.leftAnim = new cc.Animation(leftFrames, 0.3);
this.runLeft = new cc.repeatForever(new cc.Animate(this.leftAnim));
this.state = "nothing";
this.nothing = "nothing";
this.scheduleUpdate();
cc.eventManager.addListener (
cc.EventListener.create ({
event: cc.EventListener.KEYBOARD ,
onKeyPressed: function(key, event)
{
if(key == 87) this.UP = true;
else if(key == 65) this.LEFT = true;
else if(key == 83) this.DOWN = true;
else if(key == 68) this.RIGHT = true;
else if (key == 69 || key == 32) this.ACTION = true;
}.bind(this),
onKeyReleased: function(key, event)
{
if(key == 87) this.UP = false;
else if(key == 65) this.LEFT = false;
else if(key == 83) this.DOWN = false;
else if(key == 68) this.RIGHT = false;
else if (key == 69 || key == 32) this.ACTION = false;
}.bind(this)
}),this);
return true;
},
update:function(dt) {
if(this.UP)
{
this.y += this.speed;
this.runAction(this.runLeft);
}
else if(this.DOWN)
{
this.y -= this.speed;
}
if(this.LEFT)
{
this.x -= this.speed;
this.runAction(this.runLeft);
}
else if(this.RIGHT)
{
this.x += this.speed;
}
}
});

I think the problem is this line:
cc.spriteFrameCache.addSpriteFrame(res.Player_Left_plist);
It should read
cc.spriteFrameCache.addSpriteFrames(res.Player_Left_plist);
where SpriteFrames is plural. The method without an 's' on the end is used to load a single cc.SpriteFrame object into the cache, after you've created that SpriteFrame manually. the method WITH an 's' on the end is the one that takes a URL for a plist to load a whole spritesheet at once.
http://www.cocos2d-x.org/reference/html5-js/V3.8/symbols/cc.spriteFrameCache.html

This code works for you outside the sprite class? For example in a regular sprite?
I think this is wrong but I have not tested it:
this.leftAnim = new cc.Animation(leftFrames, 0.3);
this.runLeft = new cc.repeatForever(new cc.Animate(this.leftAnim));
With your code what I'd do:
var leftAnim = new cc.Animation();
for(var i = 0; i < 4; i++)
{
var str = "Left" + i + ".png";
var frame = cc.spriteFrameCache.getSpriteFrame(str);
leftAnim.addSpriteFrame(frame);
}
leftAnim.setDelayPerUnit(0.08);
this.runAction(cc.animate(leftAnim)); //or this.runAction(cc.animate(leftAnim).repeatForever());
Hope it helps

The pluralization was largely the problem.
For those curious, here is the block of functional code:
You are correct. Thank you very much. For those interested, this is the block of functional code:
cc.spriteFrameCache.addSpriteFrames(res.playerRun_plist);
var i,f;
var frames=[];
for (i=1; i <= 4; i++) {
f=cc.spriteFrameCache.getSpriteFrame("playerRun"+i+".png");
frames.push(f);
}
var playerRunAnim = new cc.Animation(frames, 0.1);
this.playerAction = new cc.RepeatForever(new cc.Animate(playerRunAnim));
this.runAction(this.playerAction);

Related

JavaScript page causes computer to become unresponsive

I am completely new to JavaScript so please be patient with me
I have been following a tutorial to display images from a folder in JavaScript but when I add the script that iterates it causes the computer viewing the page to lock up completely
The following in inside my tags:
var canvas = document.getElementById("canvas");
var graphics_context = canvas.getContext("2d");
var rightPressed = false;
var leftPressed = false;
var currentpage = 0;
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if ((e.key == "Right" || e.key == "ArrowRight") && !rightPressed) {
rightPressed = true;
currentpage++;
}
else if ((e.key == "Left" || e.key == "ArrowLeft") && !leftPressed) {
leftPressed = true;
currentpage--;
}
}
function keyUpHandler(e) {
if (e.key == "Right" || e.key == "ArrowRight") {
rightPressed = false;
}
else if (e.key == "Left" || e.key == "ArrowLeft") {
leftPressed = false;
}
}
function draw() {
var img = new Array();
for(let i = 0; true; i++) {
try {
var image = new Image();
image.src = "img/" + i + ".jpg";
img[i] = image;
}
catch(err) {
break;
}
}
if(currentpage <= 0)
currentpage = 0;
if(currentpage >= img.length)
currentpage = img.length - 1;
ctx.drawImage(img[currentpage], 0, 0, 800, 800);
}
setInterval(draw, 10);
I do realise that reading from a folder in a loop is incredibly inefficient but I really don't see how it would cause my entire PC to lock up (it is a separate PC to the one running the page)
Any help is appreciated!

Collision Checking With JavaScript

I'm creating a game where the user wanders around a cemetery and collects stories from different graves. It's a classic top-down game. I'm building a script where if the user walks into a grave their movement stops, but I'm having trouble setting up collisions. I am using jQuery. Here is what I have so far:
var position = -1;
var $char = $('#char');
var keyCode = null;
var fired = false;
var $stones = $('.stones div');
var collision = null;
document.onkeydown = function(e) {
keyCode = e.which || e.keyCode;
if (!fired) {
position = -1;
fired = true;
switch (keyCode) {
case 38: position = 0; break; //up
case 40: position = 1; break; //down
case 37: position = 2; break; //left
case 39: position = 3; break; //right
}
walking();
stepping = setInterval(walking,125);
}
};
document.onkeyup = function(e) {
//standing
clearInterval(stepping);
stepping = 0;
fired = false;
};
function walking() {
$stones.each(function() { //check all the stones...
collision = collision($(this), $char, position); ...for collisions
if (collision) { //if any, then break loop
return false;
}
});
if (!collision) { //check if there was a collision
//if no collision, keep walking x direction
}
function collision($el, $charEl, position) {
var $el = $el[0].getBoundingClientRect();
var $charEl = $charEl[0].getBoundingClientRect();
var elBottom = parseInt($el.bottom);
var elRight = parseInt($el.right);
var elLeft = parseInt($el.left);
var elTop = parseInt($el.top);
var charBottom = parseInt($charEl.bottom);
var charRight = parseInt($charEl.right);
var charLeft = parseInt($charEl.left);
var charTop = parseInt($charEl.top);
//this is where I'm stuck
}
}
I've tried various different codes, but nothing seems to work. I keep having an issue where if I'm going forward and then I bump into a headstone and I turn around, I'm stuck. Here's an example code of what I mean:
if (position == 0 &&
!(elTop > charBottom ||
elBottom < charTop ||
elRight < charLeft + 1 ||
elLeft > charRight - 1)
) {
return true;
}
if (position == 1 &&
!(elTop > charBottom ||
elBottom < charTop ||
elRight < charLeft + 1 ||
elLeft > charRight - 1)
) {
return true;
}
return false;
I have looked this question and this question and this question and so far I'm not having any luck. Can somebody help me with the logic or supply an example code of what I need to do?
Thank you.
Your game is looking good man!
I recently wrote some collision detection and had the exact same problem. The issue is that once your coordinates are true of the case of the collision then they will always be true on any other movement.
You need to store the previous position your character was in and revert back to it OR perform the check before you change your characters coordinates.
I managed to find the following solution, thanks to stwitz' about idea, as well as this script: https://magently.com/blog/detecting-a-jquery-collision-part-iv/
var position = -1;
var $char = $('#char');
var keyCode = null;
var fired = false;
var stepSize = 32;
var $stones = $('.stones div');
//new
var cancelTop = cancelRight = cancelLeft = cancelBottom = false;
var charEl = $char[0].getBoundingClientRect();
var charLeft = parseInt(charEl.left);
var charRight = parseInt(charEl.right);
var charTop = parseInt(charEl.top);
var charBottom = parseInt(charEl.bottom);
function walking() {
if (position == 0 && !cancelTop) {
//if moving up & is safe to move up
} else if (position == 1 && !cancelBottom) {
//if moving down & is safe to move down
} else if (position == 2 && !cancelLeft) {
//if moving left and is safe to move left
} else if (position == 3 && !cancelRight) {
//if moving right and is safe to move right
}
cancelTop = cancelRight = cancelLeft = cancelBottom = false; //mark all as safe until we check
$stones.each(function() {
collision($(this));
});
}
document.onkeydown = function(e) {
keyCode = e.which || e.keyCode;
if (!fired) {
position = -1;
fired = true;
switch (keyCode) {
case 38: position = 0; break; //up
case 40: position = 1; break; //down
case 37: position = 2; break; //left
case 39: position = 3; break; //right
}
walking();
stepping = setInterval(walking,125);
}
};
document.onkeyup = function(e) {
//standing
clearInterval(stepping);
stepping = 0;
fired = false;
};
function collision($el) {
var el = $el[0].getBoundingClientRect();
var elBottom = parseInt(el.bottom);
var elRight = parseInt(el.right);
var elLeft = parseInt(el.left);
var elTop = parseInt(el.top);
if (
(elRight == charLeft) &&
(elBottom - stepSize >= charBottom && charBottom >= elTop + stepSize)
) {
cancelLeft = true;
return true;
}
if (
(elLeft == charRight) &&
(elBottom - stepSize >= charBottom && charBottom >= elTop + stepSize)
) {
cancelRight = true;
return true;
}
if (
(elTop + stepSize > charBottom) &&
(elTop <= charBottom) &&
(elLeft < charRight) &&
(elRight > charLeft)
)
{
cancelBottom = true;
return true;
}
if (
(elBottom - stepSize < charTop) &&
(elBottom >= charTop) &&
(elLeft < charRight) &&
(elRight > charLeft)
)
{
cancelTop = true;
return true;
}
return false;
}

Don't understand addEventListener behaviour

I have wrote this code in JavaScript :
window.onload = function() {
var keyboard = new Keyboard();
var gameCanvas = document.getElementById("gameCanvas").getContext("2d");
var player = new Player(gameCanvas, keyboard);
player.Init();
setInterval(function() {
gameCanvas.clearRect(0, 0, 1200, 300);
player.Update();
}, 20);
}
class Player {
constructor(canvas, keyboard) {
this._canvas = canvas;
this._keyboard = keyboard;
this._x = 100;
this._y = 75;
this._dx = 1;
this.dy = 1;
}
Init() {
this.Draw();
}
Update() {
if (this._keyboard.GetIsArrowLeftDown())
this._x -= this._dx;
if (this._keyboard.GetIsArrowRightDown())
this._x += this._dx;
if (this._keyboard.GetIsArrowUpDown())
this._y -= this._dy;
if (this._keyboard.GetIsArrowDownDown())
this._y += this._dy;
this.Draw();
}
Draw() {
this._canvas.beginPath();
this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
this._canvas.closePath();
this._canvas.strokeStyle = "black";
this._canvas.stroke();
this._canvas.beginPath();
this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
this._canvas.closePath();
this._canvas.fillStyle = "red";
this._canvas.fill();
}
}
class Keyboard {
constructor() {
this.isArrowLeftDown = false;
this.isArrowRightDown = false;
this.isArrowUpDown = false;
this.isArrowDownDown = false;
window.addEventListener("keyup", keyboard.OnKeyUpEvent);
window.addEventListener("keydown", keyboard.OnKeyDownEvent);
}
OnKeyUpEvent(event) {
if (event.defaultPrevented) {
return;
}
var key = event.key || event.keyCode;
if (key == "ArrowLeft")
this.isArrowLeftDown = false;
if (key == "ArrowRight")
this.isArrowRightDown = false;
if (key == "ArrowUp")
this.isArrowUpDown = false;
if (key == "ArrowDown")
this.isArrowDownDown = false;
}
OnKeyDownEvent(event) {
if (event.defaultPrevented) {
return;
}
var key = event.key || event.keyCode;
if (key == "ArrowLeft")
this.isArrowLeftDown = true;
if (key == "ArrowRight")
this.isArrowRightDown = true;
if (key == "ArrowUp")
this.isArrowUpDown = true;
if (key == "ArrowDown")
this.isArrowDownDown = true;
}
GetIsArrowLeftDown() {
return this.isArrowLeftDown;
}
GetIsArrowRightDown() {
return this.isArrowRightDown;
}
GetIsArrowUpDown() {
return this.isArrowUpDown;
}
GetIsArrowDownDown() {
return this.isArrowDownDown;
}
}
I have a Keyboard object which remembers which keys the user pressed.
Player is an object that draw himself.
I expected that when I press left, the shape would move to the left of the screen. But it's not working as expected.
It seems my keyboard object hasn't the good property values when read by the player object.
What am I missing?
Some issues:
In the Player constructor you assign 1 to the dy property, but it is later referenced as _dy, so you should add the underscore here.
In the Keyboard constructor you use keyboard, but that is undefined; you intended this.
In those same lines you pass a reference to the OnKeyUpEvent and OnKeyDownEvent methods. But when they are called, they do not pass the current value of this, so you should bind(this) to make that happen.
Here is the corrected code:
window.onload = function() {
var keyboard = new Keyboard();
var gameCanvas = document.getElementById("gameCanvas").getContext("2d");
var player = new Player(gameCanvas, keyboard);
player.Init();
setInterval(function() {
gameCanvas.clearRect(0, 0, 1200, 300);
player.Update();
}, 20);
}
class Player {
constructor(canvas, keyboard) {
this._canvas = canvas;
this._keyboard = keyboard;
this._x = 100;
this._y = 75;
this._dx = 1;
this._dy = 1; /// add the underscore
}
Init() {
this.Draw();
}
Update() {
if (this._keyboard.GetIsArrowLeftDown())
this._x -= this._dx;
if (this._keyboard.GetIsArrowRightDown())
this._x += this._dx;
if (this._keyboard.GetIsArrowUpDown())
this._y -= this._dy;
if (this._keyboard.GetIsArrowDownDown())
this._y += this._dy;
this.Draw();
}
Draw() {
this._canvas.beginPath();
this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
this._canvas.closePath();
this._canvas.strokeStyle = "black";
this._canvas.stroke();
this._canvas.beginPath();
this._canvas.arc(this._x, this._y, 50, 0, 2 * Math.PI);
this._canvas.closePath();
this._canvas.fillStyle = "red";
this._canvas.fill();
}
}
class Keyboard {
constructor() {
this.isArrowLeftDown = false;
this.isArrowRightDown = false;
this.isArrowUpDown = false;
this.isArrowDownDown = false;
window.addEventListener("keyup", this.OnKeyUpEvent.bind(this)); // use this and bind
window.addEventListener("keydown", this.OnKeyDownEvent.bind(this));
}
OnKeyUpEvent(event) {
if (event.defaultPrevented) {
return;
}
var key = event.key || event.keyCode;
if (key == "ArrowLeft")
this.isArrowLeftDown = false;
if (key == "ArrowRight")
this.isArrowRightDown = false;
if (key == "ArrowUp")
this.isArrowUpDown = false;
if (key == "ArrowDown")
this.isArrowDownDown = false;
}
OnKeyDownEvent(event) {
if (event.defaultPrevented) {
return;
}
var key = event.key || event.keyCode;
if (key == "ArrowLeft")
this.isArrowLeftDown = true;
if (key == "ArrowRight")
this.isArrowRightDown = true;
if (key == "ArrowUp")
this.isArrowUpDown = true;
if (key == "ArrowDown")
this.isArrowDownDown = true;
}
GetIsArrowLeftDown() {
return this.isArrowLeftDown;
}
GetIsArrowRightDown() {
return this.isArrowRightDown;
}
GetIsArrowUpDown() {
return this.isArrowUpDown;
}
GetIsArrowDownDown() {
return this.isArrowDownDown;
}
}
<canvas id="gameCanvas"></canvas>
NB: You can detect such errors since they are reported in the console.

moving an object using Keydown Events

I'm trying to move a box in the canvas, all the functions work fine, but as soon as i press down on any of the 4 keys the box disappears, I can tell it is because i have a ctx.ClearRect after pressing any of the 4 keys, i managed to stop it from dispersing, the problem is now it does not move or disappear and the cosole does not show any errors so I am stuck again.
any help would be really really helpful, thank you.
function Player (row,col) {
this.isUpKey = false;
this.isRightKey = false;
this.isDownKey = false;
this.isLeftKey = false;
this.row = row;
this.col = col;
this.color = "#f00";
}
var players = new Array();
function drawPlayer() {
players[players.length] = new Player(2,2);
for (var p = 0; p < players.length; p++) {
ctxPlayer.fillStyle = players[p].color;
ctxPlayer.fillRect(players[p].row*25, players[p].col*25, 25, 25);
}
}
function doKeyDown(e){
if (e.keyCode == 87) {
ClearPlayer();
Player.isUpKey = true;
Player.col = Player.col - 1;
}
if (e.keyCode == 83) {
ClearPlayer();
Player.isDownKey = true;
Player.col = Player.col + 1;
}
if (e.keyCode == 65) {
ClearPlayer();
Player.isLeftKey = true;
Player.row = Player.row - 1;
}
if (e.keyCode == 68) {
ClearPlayer();
Player.isRightKey = true;
Player.row = Player.row + 1;
}
}
function ClearPlayer() {
ctxPlayer.clearRect(0,0,canvasWidth,canvasHeight);
}
I created a plnkr with an example of what I think you are trying to do:
// Code goes here
function Player(row, col) {
this.isUpKey = false;
this.isRightKey = false;
this.isDownKey = false;
this.isLeftKey = false;
this.row = row;
this.col = col;
this.color = "#f00";
}
var players = [];
var ctxPlayer;
var currentPlayer;
window.onload = function()
{
ctxPlayer = document.getElementById('c').getContext('2d');
currentPlayer = players[players.length] = new Player(2, 2);
setInterval(render, 25);
}
window.onkeypress = doKeyDown;
function render()
{
ClearPlayer();
drawPlayer();
}
function drawPlayer() {
for (var p = 0; p < players.length; p++) {
ctxPlayer.fillStyle = players[p].color;
ctxPlayer.fillRect(players[p].row * 25, players[p].col * 25, 25, 25);
}
}
function doKeyDown(e) {
console.log(e);
if (e.keyCode == 97) {
currentPlayer.isUpKey = true;
--currentPlayer.row;
}
if (e.keyCode == 100) {
currentPlayer.isDownKey = true;
++currentPlayer.row;
}
if (e.keyCode == 119) {
currentPlayer.isLeftKey = true;
--currentPlayer.col;
}
if (e.keyCode == 115) {
currentPlayer.isRightKey = true;
++currentPlayer.col;
}
}
function ClearPlayer() {
ctxPlayer.clearRect(0, 0, 600, 400);
}
http://plnkr.co/edit/XejZKCkshNiihdy8ui1u?p=preview
First I introduced a render function to call clear and draw. This render function will get called every 25 ms after the window has loaded.
Then you created a new Player every draw-call. I changed it so that one player is created onload. The key-events are respective to this player-object.
Last I changed the key-events for my testing purposes, but they should work with yours too.
Keep in mind that the plnkr is just a quick example on how it works. You probably need to adjust it to your needs.

How can I change background-position with arrow-keys?

Hi just started trying to learn a little javascript, now for my first programm I wanted to write code that moves the "background-position" when pressing arrow-keys.
So I hope one of you guys can help me to fix my code.
My (not so fancy) Code:
var x = 0;
var y = 0;
function GetChar (event){
var keyCode = ('which' in event) ? event.which : event.keyCode;
posy(move(keyCode, x, y))
posx(move(keyCode, x, y))
}
function move (key, x, y){
if (key === 38){
return y ++;
} if else (key === 40){
return y --;
} if else (key === 39){
return x ++;
} if else (key === 37){
return x --;
} else{
}
}
function posy(movy) {
return body.style.background-position-y + movy * 100;
}
function posx(movx) {
return body.style.background-position-x + movx * 100;
}
I ended up solving it with jQuery:
$(document).ready(function(){
var posx = 0;
var posy = 0;
$(document).keydown(function(e){
if(e.keyCode==40){
posy--;
console.log('down');
}else if(e.keyCode==38){
posy++;
console.log('up');
}else if(e.keyCode==39){
posx--;
console.log('right');
}else if(e.keyCode==37){
posx++;
console.log('left');
}else{
};
console.log(posy);
console.log(posx);
$('body').css('background-position-y', ''+posy*100+'px');
$('body').css('background-position-x', ''+posx*100+'px');
});
});

Categories