First of all, hello.
I have to develop a simple game in flash, usign HTML5 Canvas and JavaScript. The game, however poor, is pretty much implemented. My problem is, that after you play the game, it shows a try again button, designed to go back to frame 1. When i click the button it goes to frame 1 and returns to frame 25. Any ideas?
The last frame has this code:
var root = this;
this.stop();
this.tryAgain_btn.addEventListener("click", mouseClickHandler);
function mouseClickHandler(e) {
root.gotoAndPlay(0);
};
And frame one has this code:
var self = this;
this.stop();
this.play_btn.addEventListener("click", go);
function go()
{
self.gotoAndPlay(1);
}
Any ideas on how to solve this? Thank you.
Are you developing this in html5 or in actionscript? Based on your picture of your timeline it looks like you're using actionscript, not a HTML5 Canvas with javascript.
Besides that, try using gotoAndStop(1); rather than gotoAndPlay(0) and removing your stop(); methods. Let me know in the comments if it works but since your question is slightly unclear I don't have a grasp on what you're doing.
EDIT
Example, in case you don't understand:
var root = this;
this.stop();
this.tryAgain_btn.addEventListener("click", mouseClickHandler);
function mouseClickHandler(e) {
root.gotoAndStop(1);
}
EDIT 2
Take a shot at using
this.tryAgain_btn.addEventListener("click", function (event)
{
this.gotoAndPlay(1);
});
Related
How to properly pause or stop audio track with javascript?, I tried this:
var track1 = new Audio('track1.mp3');
$('#play').click(function() {
track1.play();
});
$('#stop').click(function() {
track1.stop();
});
It plays but can't make it stop, I'm basically trying to make an small player with the basic options, super simple without using any framework.
Audio elements don't have a "stop" method. I think you may be looking for track1.pause() instead.
Reference to HTMLMediaElement methods and properties: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement
I'm an HTML5 newbie and I was wondering if someone could tell me what I'm doing wrong here. I would like to be able to use GSAP to animate a vector file I'd add to the stage and would need to be able to make it animate when I call a function, however when I try to do this I keep getting cannot tween a null object, but if it's not wrapped in a function the animation plays fine.
I created a new HTML5 canvas to see if the issue persisted and it did, so this is what I did:
Added a symbol to a blank HTML5 canvas, made it a Movie Clip and drew a circle. I called the instance mcThing
In the Timeline, I selected the first frame and went into Actions
I wrote:
function playAnimation() {
TweenMax.to(this.mcThing, 3, {y:500});
}
playAnimation();
When testing in Chrome, I get cannot tween a null object. If I reference it as mcThing (omitting the this. I instead get mcThing is not defined.
If I then remove the function and just have this:
TweenMax.to(this.mcThing, 3, {y:500});
It plays fine, but now I can't call it when I need to.
Some context:
Essentially what I currently have is a WebSocket listening for messages. When it receives a message, it's added to the queue. I am trying to get it to play an animation and insert the text from that message. The text itself should be okay: I used CreateJS to instantiate a text in the code and TweenMax works there, the problem is animating shapes/drawings. I suppose I could instantiate all the shapes in the code itself and TweenMax would work then but I don't think this is realistic as the animation/shapes are fairly complex, so I'm trying to target the stage. The animation would play out, stop, then the message would be removed from the queue and the next one would play (same animation, different text).
I think this is a scope issue, but I'm not sure what I need to change. Any help would be much appreciated!
This issue is because of the scope. Your playAnimation is not scoped to this, so it is called in the global scope.
Try this:
this.playAnimation = function() {
TweenMax.to(this.mcThing, 3, {y:500});
}
this.playAnimation();
Putting your mcThing into the function scope would also work:
var thing = this.mcThing;
function playAnimation() {
TweenMax.to(thing, 3, {y:500});
}
playAnimation();
Or you could scope the function call itself!
function playAnimation() {
TweenMax.to(this.mcThing, 3, {y:500});
}
playAnimation.call(this);
There are lots of ways to get around it once you understand how the scoping works. I recommend the first approach.
Hope that helps!
I have created a project in .fla that was exporting to .swf however I now require it in HTML5 format. So I change the file conversion type and now require my ActionScript3 to be converted to JavaScript. However, This is not my strong suit.
I am currently trying:
this.stop();
this.close1_btn.addEventListener("click", function (closebtn)
{
this.gotoAndPlay(1);
});
this.store1_btn.addEventListener("click", function (store1_btn)
{
this.gotoAndPlay(11);
});
this.store2_btn.addEventListener("click", function (store2_btn)
{
this.gotoAndPlay(12);
});
this.store3_btn.addEventListener("click", function (store3_btn)
{
this.gotoAndPlay(13);
});
OVERVIEW: trying to listen to a symbol e.g close1_btn for clicks. when clicked it will link to and stop at a specified frame.
I expect a few bits to be wrong *maybe near the function () part?
Its a fairly simple map so shouldn't be too hard for someone who knows what they are looking at! Thanks so much for any help you can give!
I believe the issue is the function scope, which is a common mistake.
The addEventListener method has no implied scope, so the functions will get called on window. If you output this in your console when those buttons are clicked, you will probably see Window. To solve this, you can:
Bind your methods (docs)
Example:
this.close1_btn.addEventListener("click", function (closebtn)
{
this.gotoAndPlay(1);
}.bind(this));
Use the CreateJS on shortcut, which takes a 3rd parameter (docs)
Example:
this.close1_btn.on("click", function (closebtn)
{
this.gotoAndPlay(1);
}, this);
One important note is that if you play frame 0 again, that frame script will run again, adding another listener to each button each time, resulting in the functions called multiple times when a button is clicked. I recommend something this this:
if (!this.inited) {
// Your code
this.inited = true;
}
Thanks for your response.
I am now using the code you provided:
this.stop();
if (!this.inited) {
// Your code
this.close1_btn.addEventListener("click", function (closebtn)
{
this.gotoAndPlay(1);
}.bind(this));
this.store1_btn.addEventListener("click", function (store1btn)
{
this.gotoAndStop(11);
}.bind(this));
this.inited = true;
}
However, I get this in the output
WARNINGS:
Frame numbers in EaselJS start at 0 instead of 1. For example, this affects gotoAndStop and gotoAndPlay calls. (5)
Content with both Bitmaps and Buttons may generate local security errors in some browsers if run from the local file system.
Any further advice you could give would be appreciated...
cheers for your continued assistance!
The preview doesn't work when it opens in my browser, is this just because I haven't exported it fully and hosted it online?
So I can ignore these errors?
^^ if that's all cleared up. Do you have recommended way to export and host it on a webpage?
Thanks again buddy, appreciate it!
I'm getting into game developing online. I am trying to make an online FPS game, and I've only gotten to the point where I need to update my character. I am trying to keep my code simple, using only a draw and update function. When the html loads, I execute both: (Is this necessary?)
<body onload='DRAW(); UPDATE();'>
The draw function draws the player to the screen, and the update is supposed to check for a keypress to move the character. I am trying to make the script update using this:
function UPDATE()
{
update = setInterval(UPDATE, 60);
}
and to my knowledge, it is working fine because when I try and edit code in my online IDE (c9.io) which I use to test the site, it freezes when the site is running. I am also calling eventListeners in the draw function. (Is this proper if I want to test for a key down every frame?)
function DRAW()
{
window.addEventListener('keydown', function (e) {
keys.keys = (keys.keys || []);
keys.keys[e.keyCode] = true;
});
window.addEventListener('keyup', function (e){
keys.keys[e.keyCode] = false;
});
}
My questions are:
Is there an easier way to make a script update every frame?
Is there a JavaScript addon (like Three.js) I can use to make
developing this easier on myself?
Any knowledge is greatly appreciated.
This makes everything crash:
function UPDATE()
{
update = setInterval(UPDATE, 60);
}
You are recursively creating a new interval every 60ms; the first time you call UPDATE, you create an interval that creates a new interval every 60ms. All newly create intervals do the same. Don't really know what you actually want to do here.
I am also calling eventListeners in the draw function. (Is this proper
if I want to test for a key down every frame?)
It's fine to create eventlisteners in the draw function, provided you only call this function once. Which I guess you don't. Each time you call DRAW() a new set of eventlisteners will be added, and you really don't want that.
What you need is a form of game loop. Explaining how to create an FPS game is a bit more than I can do, but you can start by looking at this article Anatomy of a video game
I am trying to learn JavaScript and I am wondering whether JavaScript has a event listener just like ActionScript's ENTER_FRAME. Basically, I want this event listener to listen "all the time" not just wait for any particular instance (mouse click, keyboard event) of event.
This would probably be worth a look too :
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
You're looking for setInterval(func, time). In the case of making it work like ENTER_FRAME, then you would make time very small. So, if you wanted to imitate a frame rate of say, 30 times a second:
// you will need to make sure you have good scoping around the function param.
setInterval(function(){console.log('enterframe')}, 33)
// 33 is about 1000 milliseconds / 30.
Actually, setInterval is in Flash too -- flash.utils.setInterval.
As a side note -- unfortunately, setInterval (in both Flash and JS) can work against the native refresh rate. In Flash ENTER_FRAME avoids this -- you render when the swf re-renders. In the browser, well, setInterval simply can't do that.
HTML5 provides access to the requestAnimationFrame()
<canvas id="canvas" width="400" height="400"></canvas>
<script>
window.onload = function () {
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
var counter = 0;
(function drawFrame () {
window.requestAnimationFrame(drawFrame, canvas);
context.clearRect(0, 0, canvas.width, canvas.height);
console.log(counter++);
// animation code goes here
}());
};
</script>
Credit goes to Keith Peters for helping sort this out. Highly recommend his book 'HTML5 animation with Javascript' by FriendsOfEd:
http://www.apress.com/9781430236658
I am still learning how to convert AS3 to JavaScript, but would it not be this function:
createjs.Ticker.addEventListener("tick", gameLoop);
gameLoop is the custom function that will be called on every 'tick'.
Check out this helpful example of writing a game in Adobe Animate CC using JavaScript instead of AS3: https://software.intel.com/en-us/html5/hub/blogs/flash-cc-to-html5
Nope. Not really. A good substitute would be setInterval or setTimeout:
function doAllTheTime() { }
function wrapper() {
doAllTheTime();
setTimeout(wrapper, 40);
}
wrapper();
But even then, you're pretty limited, because you don't have access to any of the event object properties.