I'm an EaselJS newbie. I'm running version 0.7.1. I have a simple game that generates tiles. I would like to remove those tiles whenever they are clicked on. I know my click handler is called for each click event, but my tiles aren't being removed. What am I doing wrong?
c99.Game = (function() {
function Count99Game(){
this.canvas = document.getElementById('game-canvas');
this.stage = new createjs.Stage(this.canvas);
var totalTiles = 10;
for(var i = totalTiles; i>0; i--){
var tile = new c99.Tile(i);
this.stage.addChild(tile);
tile.x = Math.random()*(this.canvas.width - tile.width);
tile.y = Math.random()*(this.canvas.height - tile.height);
tile.addEventListener("click", function(event){
alert("Clicked");
this.stage.removeChild(event.target);
this.stage.update();
}.bind(this));
}
this.stage.update();
}
return Count99Game;
})();
Related
edit: SOLVED
I'm a highschool student in Japan trying to learn how to program.
I recently viewed https://vimeo.com/105955605 this video, and decided I could use the beginning section to start building pong in javascript.
I'm pretty much a complete novice with programming and/or javascript and I still have a long way to go.
I got Player1 (left paddle) to work on its own, so I figured I could just copy paste, mess with a couple things, and make Player2. However, now Player2 moves when I press w/s, but Player1 no longer moves.
I've tried creating 2 separate keyboarder() functions, using this.keyboarder from Player1 in player2 (Player2.keyboarder = Player1.keyboarder() ), and declaring/calling keyboarder() before doing anything else.
HTML:
<html>
<head>
<meta charset="UTF-8">
<title>Pong</title>
<link type="text/css" rel="stylesheet" href="css/stylesheet.css">
</head>
<body>
<canvas id="screen" width="310" height="210"></canvas>
<script src="js/pong.js"></script>
</body>
</html>
JavaScript:
;(function(){
//Main game function
//tells objects in bodies array to update.
//stores gameSize pulled from canvasId
var Game = function(canvasId){
var canvas = document.getElementById(canvasId);
var screen = canvas.getContext('2d');
var gameSize = {x: canvas.width, y: canvas.height};
var self = this;
//bodies array
this.bodies = [new Player1(this, gameSize), new Player2(this, gameSize)];
//update function
var tick = function(){
self.update();
self.draw(screen,gameSize);
requestAnimationFrame(tick);
};
tick();
};
//constructer for game() function. tells bodies to update, and draw
Game.prototype = {
update: function(){
for(var i =0 ; i < this.bodies.length; i++){
this.bodies[i].update();
}
},
draw:function(screen,gameSize){
screen.clearRect(0,0,gameSize.x,gameSize.y);
for(var i =0 ; i < this.bodies.length; i++){
drawRect(screen, this.bodies[i]);
}
}
};
//P1 object, declares size and start position of P1
var Player1= function(game, gameSize){
this.size = {x:30,y:gameSize.y / 3};
this.game = game;
this.gameSize = gameSize;
this.center = {x: 0, y:gameSize.y/2};
this.keyboarder = new Keyboarder();
requestAnimationFrame(this.update);
};
//constructor for P1, updates position based on keyboard input
Player1.prototype = {
update:function(){
if (this.keyboarder.isDown(this.keyboarder.KEYS.DOWN) && this.center.y < (5*this.gameSize.y / 6)){
this.center.y += 4;
}else if(this.keyboarder.isDown(this.keyboarder.KEYS.UP) && this.center.y > this.size.y /2 ){
this.center.y -= 4;
}
}
};
//P2, same as P1 aside from position
var Player2= function(game, gameSize){
this.size = {x:30,y:gameSize.y / 3};
this.game = game;
this.gameSize = gameSize;
this.center = {x: gameSize.x, y:gameSize.y/2};
this.keyboarder = new Keyboarder();
requestAnimationFrame(this.update);
};
//constructor for P2, same as P1
Player2.prototype = {
update:function(){
if (this.keyboarder.isDown(this.keyboarder.KEYS.S) && this.center.y < (5*this.gameSize.y / 6)){
this.center.y += 4;
}else if(this.keyboarder.isDown(this.keyboarder.KEYS.W) && this.center.y > this.size.y /2 ){
this.center.y -= 4;
}
}
};
//Draw function, draws object
var drawRect = function(screen, body){
screen.fillRect(body.center.x - body.size.x /2,
body.center.y - body.size.y /2, body.size.x,body.size.y);
};
//Keyboard input function
//reads if keys are being pressed and takes the event code
//isDown() returns boolean of key down = true, key up = false
var Keyboarder = function(
){
var keyState = {};
window.onkeydown = function(e){
keyState[e.keyCode] = true;
};
window.onkeyup = function(e){
keyState[e.keyCode] = false;
};
this.KEYS = {DOWN: 37, UP:39,W:87 , S: 83};
this.isDown = function(keyCode){
return keyState[keyCode] === true;
};
};
//calls game() function when the page has loaded.
window.onload = function(){
new Game("screen")
};
})();
Sorry if this is bad protocol for using stackoverflow, I'm also new to asking questions here.
The problem is you have two Keyboarder instances, and they're both binding to the key events by assigning a handler directly to them - this will overwrite any other handlers. There's two ways to fix it:
1: Don't assign directly, instead use addEventListener, eg:
window.addEventListener('keydown', function(e){
keyState[e.keyCode] = true;
});
2: Use the same keyboarder instance for both players:
var kb = new Keyboarder();
this.bodies = [new Player1(this, gameSize, kb), new Player2(this, gameSize, kb)];
and in your player object assign it to this 3rd parameter. Even if you go this route, I would still advise on using addEventListener as well simply to ensure that the events can be bound to in multiple places if needed.
On another point, you should also be able to refactor your players into a single function and create two instances of it with different parameters, but that sort of thing is better dealt with over on Code Review.
When you create two Keyboarder instances, one collides with the other, because of this:
window.onkeydown = function(e){
keyState[e.keyCode] = true;
};
window.onkeyup = function(e){
keyState[e.keyCode] = false;
};
When you create one Keyboarder, the event listeners the previous one attached are overriden. Try something like this:
window.addEventListener('keydown', function(e){
keyState[e.keyCode] = true;
});
window.addEventListener('keyup', function(e){
keyState[e.keyCode] = false;
});
This ensures there are listeners for every instance of the Keyboarder.
I am working on a project where we can move an image like in google map,, it works perfectly in crome,ff and above ie9, but when i checked in ie8 the image is not moving smoothly,it takes a 2 to 3 sec of time to move.
/* Map dragging */
var previousX;
var previousY;
var previousLeft;
var previousTop;
var cids = self.data.cuLocation;
var lumids = self.data.lumLocation;
$('#MapView img').css( 'cursor', 'pointer' );
$("#MapView img").mousedown(function(e) {
//console.log("mousedown");
e.preventDefault();
drag.state = true;
previousX = e.originalEvent.clientX;
previousY = e.originalEvent.clientY;
previousLeft = $("#MapView img").position().left;
previousTop = $("#MapView img").position().top;
});
$("#MapView img").mousemove(function(e) {
var old_pos = self.getPosition();
if (drag.state) {
e.preventDefault();
drag.x = e.originalEvent.clientX - previousX;
drag.y = e.originalEvent.clientY - previousY;
var cur_position = $("#MapView img").position();
var new_left = cur_position.left + drag.x;
var new_top = cur_position.top + drag.y;
previousX = e.originalEvent.clientX;
previousY = e.originalEvent.clientY;
}
});
$("#MapView img").mouseleave(function(e) {
//console.log("mouseleave");
drag.state = false;
});
$(document).mouseup(function(e) {
// alert("mouseup");
drag.state = false;
});
Use the following Link for your better understanding in Draggable event so than you can use it to Drag your Image wherever you want.
http://jqueryui.com/draggable/
and for Drap & Drop of one element onto other element ::
http://jqueryui.com/draggable/#snap-to
I'm coding basic balloon game. Balloons are created dynamically into the canvas. Everything is ok but I could not add onclick event to hide the balloon. First function to start game is "Baslat()". Here is my codes
var canvas;
var sev = 1;
var zorluk = 3;
var ctx;
function Baslat() {
var x;
for (x = 1; x <= sev*zorluk; x++) {
BalonYap(x);
}
}
function seviye(a) {
sev = a.value;
}
function BalonYap(id) {
var img = new Image();
img.src = "balon.png";
img.id = "balon_"+id;
img.onload = BalonLoad(img); // works
img.onclick = Patlat(id); // doesn't work
}
function BalonLoad(img) {
var rnd1 = Math.floor(Math.random() * 750)+10;
var rnd2 = Math.floor(Math.random() *350)+10;
canvas = document.getElementById('myCanvas');
context = canvas.getContext("2d");
context.drawImage(img, rnd1, rnd2);
}
function Patlat(img) {
alert();
}
You need to assign function to event handlers. If you give arguments to a function it's called. You can try this factory method (you can give arbitrary parameters to the wrapping function and use them inside the returned function's closure):
function BalonLoad(img) {
return function() {
var rnd1 = Math.floor(Math.random() * 750)+10;
var rnd2 = Math.floor(Math.random() *350)+10;
canvas = document.getElementById('myCanvas');
context = canvas.getContext("2d");
context.drawImage(img, rnd1, rnd2);
}
}
Part of the issue here is that you are attempting to assign an event callback on an element that does not exist in the DOM. You are only drawing to the canvas. A click event will need to be applied to the canvas element. You will need to save the coordinates of each balloon, and use that to find the appropriate balloon when the canvas is clicked.
I am using node.js + socket.io to try and make a multiplier HTML5 canvas game. Unfortunately every time I go to draw all of the players, all the images end up on top of each other.
socket.on('drawPlayers', function(players){
context.clearRect ( 0 , 0 , gameWidth , gameHeight ); //clear canvas
for(var i=0; i<players.length; i++){
var cur = players[i];
var playerSprite = new Image();
playerSprite.onload = function() {
return context.drawImage(playerSprite, cur.x, cur.y);
};
playerSprite.src = 'images/sprite.png';
console.log("drawing player "+cur.un+" at ("+cur.x+","+cur.y+")");
}
});
The console.log() will log the different x and y values correctly, but all of the images end up on top of each other.
function player(id,username){
this.id = id;
this.un = username;
this.y = Math.floor(Math.random() * 501);
this.x = Math.floor(Math.random() * 801);
this.src = 'images/mobile_md_logo.png';
}
I
Jonathan Lonowski is right. For each of the onload triggers, cur points to the same player, the last one. There is only one cur that exists inside drawPlayers event handler.
Use this to separate the scope of cur from one that is in the loop:
function draw(sprite,cur){
return function() {
context.drawImage(sprite, cur.x, cur.y);
};
}
Then call it from inside the loop
for(var i=0; i<players.length; i++){
var cur = players[i];
var playerSprite = new Image();
playerSprite.onload = draw(playerSprite,cur);
playerSprite.src = 'images/sprite.png';
console.log("drawing player "+cur.un+" at ("+cur.x+","+cur.y+")");
}
Im trying to make an envelope generator for my oscillator using automation on the gainNode and I want to be able to trigger the envelope whenever an event happens ( in this case a button click ).
But it seems like its working only the first time I click.
http://jsfiddle.net/ehsanziya/T9mV2/
var context = new webkitAudioContext();
var osc = context.createOscillator();
var gain = context.createGainNode();
var now = context.currentTime;
osc.frequency.value = 100;
osc.type = "sine";
osc.connect(gain);
osc.noteOn(0);
gain.connect(context.destination);
gain.gain.value = 0;
var trigger = document.getElementById('play');
trigger.addEventListener('click', function(){
gain.gain.setValueAtTime(gain.gain.value, now);
gain.gain.linearRampToValueAtTime( 1.0, now + 2.0 );
gain.gain.linearRampToValueAtTime ( 0.0, now + 4.0 );
});
Why is it like that? And what is the best way to create envelope generators that can be triggered by events?
Just move the line retrieving context.currentTime inside the click event listener.
trigger.addEventListener('click', function(){
var now = context.currentTime;
...
The currentTime property exposes audio clock and so is updated in real time.
Found the solution.
But given that the oscillator is always on, there should be a way to reset the phase of the oscillator every time its being triggered ( Phase Bashing ).
$(document).ready(function(){
var context = new webkitAudioContext();
var osc = context.createOscillator();
var gain = context.createGain();
osc.connect(gain);
gain.connect(context.destination);
osc.start(0);
gain.gain.value = 0;
var oscStart = function(){
var now = context.currentTime;
gain.gain.cancelScheduledValues( now );
gain.gain.setValueAtTime(gain.gain.value, now);
gain.gain.linearRampToValueAtTime(1 , now + 0.2);
};
var oscOff = function(){
var now = context.currentTime;
gain.gain.cancelScheduledValues( now );
gain.gain.setValueAtTime(gain.gain.value, now);
gain.gain.linearRampToValueAtTime(0 , now + 0.2);
};
$('#button').hover(oscStart , oscOff);
});
http://jsfiddle.net/ehsanziya/JJqNU/