Exercises for Week 1 - Player Input


Task 2 part 1 (Easy) - Make a character move around the page in response to the arrow keys.

Modify the code you wrote in the signup task.  Add an <img> of a player character avatar to the page. (Your choice - either draw something - stick figures are fine if you're not an artist! - or use a creative-commons-licensed image file from the web).  Make it so that when a user hits an arrow key, instead of adding text to the screen, the image moves in the appropriate direction.

Hint - you'll probably want to use variables for the x and y coordinates of the image, and change the CSS properties of the image node to set its position.

 

Task 2 part 2 (A little harder) - Make the character follow the mouse around the page.

Copy the code from assignment 1 and modify it so that the avatar is controlled by the mouse instead of the keyboard.  You'll need to respond to "mousemove" events.  When the mouse position is outside of the avatar image, your code will need to figure out which direction the image needs to move in to get closer to the mouse position.  The image should then move smoothly in that direction until it reaches the mouse position, then stop.

Hint - you'll need to store the mouse x and y coordinates in response to mousemove events, but you'll find that if you try to move the avatar image in your mousemove event handler, then it will stop moving as soon as the player stops moving the mouse.  That's not what you want, so you'll have to have another function that moves the avatar, and make sure this function gets called repeatedly whether the mouse is moving or not.

Task Discussion


  • Tiago Garcia   May 10, 2011, 1:18 a.m.

    Hello there, I have just finished task2 a and b and commited to this URL:

    Demo: http://tgarcia.net78.net/task2/index.html

    Source: https://github.com/tiagorg/HTML5/tree/master/task2

    Actually my approach is based a little on CG programmim. I created the "live" avatar image which will constantly go to any destination which can be set by mouse or keyboard. It will draw a movement line towards its destination based on a CG algorithm and will move the avatar over this line.

    It works very interestingly.

  • Jono Xia   May 12, 2011, 9:07 p.m.
    In Reply To:   Tiago Garcia   May 10, 2011, 1:18 a.m.

    Hi Tiago,

    Man, I hate that guy!  He's always plowing me off the road in Mario Kart Wii!

    I'm not familiar with the acronym CG you used - does that stand for "computer graphics" or something else?  (pardon my ignorance).

    Anyway, your code is very clean, well-organized and well-documented.  And you have a very elegant way of combinging the two input methods.

  • Tiago Garcia   May 21, 2011, 8:46 a.m.
    In Reply To:   Jono Xia   May 12, 2011, 9:07 p.m.

    Haha, I have also chosen him due to Mario Kart Wii :)

    Yes, in my context CG stands for Computer Graphics, and it is basically an algorithm I learned on my undergraduation course, which will draw the most straight line between 2 points, which will also perform the shortest path between them. 

    I would like, in the future, to improve Boo's movement to perform little waves up and down while he moves, to make it closer to what we see in the videogame. I think I would need to adjust this algorithm to change the Y axis variation to pretend some sinusoid.

    Thanks for your words!

  • Krabat   May 8, 2011, 9:27 a.m.

    Task2b is also finished.... wohooo :-)

    http://www.darkfluid.com/html5/task2b/

  • Jono Xia   May 12, 2011, 8:54 p.m.
    In Reply To:   Krabat   May 8, 2011, 9:27 a.m.

    Hi Krabat,

    I love your Muppet user icon and it's fun steering it around the screen ;-)

    I really like how you respond to window resize events by changing the playable area to match the new window size.  Everybody - take a look at the $(window).resize() method at the bottom of Krabat's core.js file if you want to see an easy way to do this.

    I've never heard of the "head.js" library you're using - do you find it helpful?  What does it do for you?

    Right now you're using a lot of global variables -- you will probably want to start grouping your functions and variables into objects in order to keep it organized and maintainable as it grows more complex.  (This goes for nearly everybody.)

    My only other comment is that if you want to chase the mouse even when the mouse isn't moving, you'd need to have some sort of timer driving the animation and not only respond to mousemove events.  (You can see some of the other participants' code for examples of how to do this.)

    Anyway, good start!

  • Krabat   May 13, 2011, 1:51 a.m.
    In Reply To:   Jono Xia   May 12, 2011, 8:54 p.m.

    Regarding head.js: Some people argue js files should be put at the bottom to speed up page loading, so your page can be rendered/shown while the js files are still loading. With head.js you pass all your scripts to it, which get loaded in parallel and asynchronously while the rest of the html is processed. I guess right now it's not necessary for us, but as the js file count increases we may benefit from it...

    The Resize function seems ok, but is triggered several times on resize. It may be better to trigger it only for a finished window resize, but that's a irrelevant detail.

    Regarding the global vars: I put them in the anonymous function "head.ready"(same as jquery's "document.ready"), so I thought they will be local vars of that function!? Besides that: is it advisable to put all the code in the document.ready block or just start the execution there?

    I will definitely use Objects for grouping my vars.

    Jono, thanks for the feedback. Next I will do the Canvas lesson and think about my game structure. This course is really great!!

  • Kajan Sivaramalingam   May 5, 2011, 8:32 p.m.

    Hey guys (and gals),

     

    There is my attempt for the task 2 :

    http://kajan.siva.free.fr/game_dev/task2/task2a.html

    http://kajan.siva.free.fr/game_dev/task2/task2b.html

     

    For the moment I didn't use jQuery. Because I want to learn a little bit the standard Javascript.

    I almost suceeded in those exercices but there are some points that can be improved :

    For the task 2a :

    - Using two arrow keys at the same time is not perfect.

    - I tried to animate my sprite. But it don't work well.

     

    For the task 2b :

    - The image follow the mouse only if it move at least once.

     

    So I would be glad to hear your ideas for those issues. wink

     

    Kajan

  • Jono Xia   May 11, 2011, 6:32 p.m.
    In Reply To:   Kajan Sivaramalingam   May 5, 2011, 8:32 p.m.

    Hi Kajan!  I really like the walking animation you've done. I am planning to introduce sprite animations in this week's lesson but you're already ahead of me. And I like how you use CSS to slice a single image up into individual frames -- it's a very good technique. Nice work!  (Other participants -- you should take a look at Kajan's code and see how this was done.)

    That said, here's some tips for improving your code:

    1. g_n, g_e, g_w, and g_s would probably make more sense as boolean values instead of integers.  You can say gn = true;  or gn = false;  etc.  It makes the code easier to read.

    2. You should declare your variables with var.  Even if some browsers' Javascript engines will let you get away with leaving out the var, it's not correct and it might not always work.  It also makes your code more readable if you declare your variables with var because the reader can instantly tell the difference between a variable they've seen before and one tht's being used for the first time. (And if perso1 is a global variable - it seems to be since it's used in multiple functions - it should be declared at the top of the file with your other global variables.  You can set it to null initially.)

    3. It's probably better to keep the player position in variables rather than parseInt() it from the tag properties every time you need it.

    4. Very clever using the CSS transitions properties in the mouse assignment!  (At first I read your code and scratched my head since I couldn't figure out how it was doing what it was doing... until I read the CSS.)  But if (if!) you want more control over the sprite's movement you might want to do the animation yourself (moving and redrawing step by step) instead of leaving it up to the browser's implementation of CSS transitions.

    5. The multiple arrow keys at the same time actually work fine for me.  As for making sprite animation smoother, we'll cover that in the next lesson.

    6. You asked about making the image follow the mouse when the mouse hasn't been moved; unfortunately I actually don't know if there's a way to find out the mouse location before there are any mouse move events, sorry. (You can always work around this by... not starting the game until the user clicks a button.  Sneaky.)

  • Kajan Sivaramalingam   May 14, 2011, 12:29 p.m.
    In Reply To:   Jono Xia   May 11, 2011, 6:32 p.m.

    Thank you very much.

     

    I did apply your advices and ameliorated my code, using objet programming and adding some comments.

  • Jay   May 4, 2011, 11:32 p.m.

    I have completed the assignments... I have been getting the same error with git as Rick, so I don't have that set up.

    For 2a, I wrote a simple program that only looked at keydown.  After learning about the setInterval function and looking at Tyler's code, the program runs a lot smoother.

    For 2b, I cheated using the draggable function with jquery's ui interface.  :)  It works smoothly, but I'll spend some more time on it so I can learn more about mouse interactions with javascript.

  • Jay   May 4, 2011, 11:37 p.m.
    In Reply To:   Jay   May 4, 2011, 11:32 p.m.

    forgot the link.

  • Jay   May 6, 2011, 11:53 a.m.
    In Reply To:   Jay   May 4, 2011, 11:32 p.m.

    I updated assignment 2a code.  I realized that the draggable will be perfect for my cards in the card game, but not quite what the assignment was looking for.  I did it without using animate.

  • Jono Xia   May 11, 2011, 9:09 p.m.
    In Reply To:   Jay   May 6, 2011, 11:53 a.m.

    Hi Jay,

    For 2a - diagonal movement with multiple keys works really well.  But I think using four different timers is overkill -- you could use just one timer together with four variables that track which keys are down.

     

    For 2b - you've kind of got the man teleporting instantly to the mouse location, when I was actually thinking of the character being animated to the new location at a fixed speed (which you could do by adapating your timer code from 2a).

     

    Not asking you to re-do the assignment (unless you want to!)  -- if you think .draggable() is going to be a better way to implement your game, then it makes more sense to move ahead with that!

  • Krabat   May 4, 2011, 2:36 p.m.

    After doing a quick beginner course in JavaScript and JQuery, I was able do the Task2a:

    http://www.darkfluid.com/html5/task2a/

    First I tried to improve the input event handling to be more robust, which was kind of hard and finally managed to accomplish it quite easy with JQuery. This is really a swiss army knife :)

    Now the code runs fine in FireFox4, Chrome11 and IE8. Still I have to watch Jono's lesson on browser compability...

    Also I have a good idea for the final game, it's a simple remake of a C64 classic game :)

  • Rick E   May 3, 2011, 6:30 p.m.

    OK, I'm spending all of my time trying to push my work to Github, and none of my time working on course material. This stinks! I have Github set up, but it only contains a readme file. I have Git set up on my computer, and I have files staged for commit, but when I try 'git push Crusoe master', I get this...

     

    To Crusoe
     ! [rejected]        master -> master (non-fast-forward)
    error: failed to push some refs to 'Crusoe'
    To prevent you from losing history, non-fast-forward updates were rejected
    Merge the remote changes (e.g. 'git pull') before pushing again.  See the
    'Note about fast-forwards' section of 'git push --help' for details.
     
    I went there and followed the instructions, which led to more errors. I'm getting really pissed now and could use a SIMPLE set of instructions on EXACTLY how to upload files to Github. I know it must be much easier than it appears. I've looked at two tutorials that I thought were easy to understand, but I still can't upload anything.
     
    Hopefully someone here can help...and hopefully it won't take 5 minutes to spell this out for me.
  • Tyler Cipriani   May 3, 2011, 6:44 p.m.
    In Reply To:   Rick E   May 3, 2011, 6:30 p.m.

    Did you do an amend? Any local destructive changes'll cause this problem.

     

    First try 'git fetch origin' then issue 'git merge origin/master'

    If that fails 'git push --force origin master' will work - but it's considered bad practice and generally should be avoided.

     

    Check out 'Dealing with non-fast-forward errors' here

  • Tyler Cipriani   May 3, 2011, 7:02 p.m.
    In Reply To:   Rick E   May 3, 2011, 6:30 p.m.
  • Rick E   May 4, 2011, 10:03 p.m.
    In Reply To:   Tyler Cipriani   May 3, 2011, 7:02 p.m.

    Tyler,

    I appreciate your efforts to help. But I'm still unable to upload files to Github, and I think I've wasted enough of my life on this. Maybe some day I'll take a course on how to use Github...apparently that's what it'll take. None of the documentation I've seen makes this understandable, and none of it provides examples that have proved effective.

  • Slava   May 3, 2011, 12:35 p.m.

    For you guys who use jQuery, don't miss release 1.6 which came out today: animations are now synced and smooth, and relative CSS values are kinda nice.

  • Rick E   May 2, 2011, 12:30 p.m.

    Here's my version of #2a on Github. (I'm new to Github and hope I've done things right so that link works). 

    I've got the player icon moving around the screen in response to button clicks. Haven't worked out the functionality for clicking on arrow keys yet. 

    I'm having trouble with the timer: I want this to be more of a "counter" than a timer. It should allow 6 player actions (moves, etc) per day, then advance the day. I'll have to spend more time on this one... I believe I just need to count clicks or keyUp events rather than use an actual timer.

    I also would like to build in functionality so that once a space is entered by the player icon, the terrain in that space is revealed. I think I'll need an underlying graphic for this, set to "display=none", and then change the css for each entered space to "display=block". I'll need to set variables for each space on the map. 

  • Rick E   May 2, 2011, 1:26 p.m.
    In Reply To:   Rick E   May 2, 2011, 12:30 p.m.

    Spending way too much time learning Github...time I'd rather spend learning material from this course.

    Try this link instead of the Github link I provided above.

  • Rick E   May 2, 2011, 1:26 p.m.
    In Reply To:   Rick E   May 2, 2011, 12:30 p.m.

    Spending way too much time learning Github...time I'd rather spend learning material from this course.

    Try this link instead of the Github link I provided above.

  • Anonym   May 2, 2011, 10:44 a.m.

    Hi,

    I've finished the task 2A. I used javascript and a little bit of jQuery.

    Page - Code

    After looking at others participants' code, i think i'll have to redo it. Anyway this is my approach and any comment is welcome to improve it.

    Update:

    Here is the second part of the task:

    Page - Code

  • carrie   May 1, 2011, 11:20 a.m.

    Hi I started off using jQuery animate, but I added a setInterval just to try it. 

    http://carrielicious.com/html5/WebContent/

    I tried to add the setInterval to the mousemove handler, but it seems like jQuery's animate doesn't call the complete callback if it's stopped before the animation is complete, which leads to my fish acting epilectic with a bunch of setIntervals that can't be cleared anymore. So I just use a flag instead.

  • Andrew Shindyapin   April 30, 2011, 11:27 p.m.

    I've done assignment 2a using jQuery's animate method (demo code). However, upon taking a closer look at the assignment and the lesson, I'll redo it using x and y coordinates bit before moving on to assignment 2b.

  • Jono Xia   May 2, 2011, 1:23 a.m.
    In Reply To:   Andrew Shindyapin   April 30, 2011, 11:27 p.m.

    Yeah, you're going to need X and Y variables for the player anyway, once you start adding features to the game, so you might as well start using them now.  ;-)

  • Andrew Shindyapin   May 5, 2011, 8:20 a.m.
    In Reply To:   Andrew Shindyapin   April 30, 2011, 11:27 p.m.

    OK, got tasks 2a and 2b done. More improvements can be made, but it may be time to move on :~).

  • Slava   April 28, 2011, 10 a.m.

    My solutions are now on GitHub as well: https://github.com/uvarov/BGDH5-P2PU 

    I saw the posts you guys made before I had a chance to test my second task answers on Windows, you got me worried, so I went back and damn! the movement was choppy indeed. I thought hey, let's smooth things down with some CSS3 transitions. It works alright in Chrome, Firefox on Linux and Opera, glitches in Firefox on Windows (my guess is it has something to do with hardware acceleration) and IE... well it's IE.

    Simplicity of the first assignment turned out to be deceitful too. The first pitfall that got me was page scrolling: if the img element goes beyond body's right or bottom (is it different on right-to-left systems? I wonder) borders, the page widens to incorporate them, even with overflow set to hidden, and the browser srolls the page if you press arrow keys. The second time I've tripped on the fact that Opera deals with keys that are held down differently, so one have to catch keypress events too to stop them from scrolling the page.

    I didn't incorporate the idea of storing key states internally by watching both keydown and keyup, as I thought that movements were supposed to be discret. But I'll be sure to use it later.

  • Tyler Cipriani   April 27, 2011, 3:53 p.m.

    I've posted my responses to all tasks so far on my github (here)

    On task 2 Part 1 I used a switch/case statement to listen for keydown events then check if they existed in an array of keys (e.g. [37, 38, 39, 40]) - then I found that array index. The movement of my character on-screen is not super responsive. I'm wondering if there were better ways to listen for keys (?).

    On task 2 Part 2 I used the setinterval function since the instructions called for 'a function that's called repeatedly' (paraphrasing). I originally was using jQuery's animate inside of the mousemove function and getting good results (see my code comments for that iteration). I'm not too sure if I like what I have done now. Am I understanding this task correctly?

  • Jono Xia   April 28, 2011, 12:59 a.m.
    In Reply To:   Tyler Cipriani   April 27, 2011, 3:53 p.m.

    Hi Tyler,

    I just checked out your code. (It's very clear and readable!  Hooray!).  I think the issue with the keyboard movement is not the array lookup, but rather the fact that you're relying on the keyboard autorepeat.  That is, if I hold down a letter key long enough, it will repeat: kkkkkkkkkkkkkkkkk  -- this means that the page keeps getting many keyDown events as long as the key is held.  However, the timing of these auto-repeated events usually isn't what you want - you get an initial movement, then a pause, then more movement as the repeat kicks in.

    So I suggest not relying on autorepeat - respond to both keyUp and keyDown events, create your own state variables to tell whether a key is up or down,  move stuff at your own pace as long as the key is down and stop it when the key comes back up.  This way, you can even implement diagonal movement when two keys arrow keys are pressed together.

  • Jono Xia   April 28, 2011, 1:07 a.m.
    In Reply To:   Tyler Cipriani   April 27, 2011, 3:53 p.m.

    As for the mouse-following code, I just tried it out and I agree that the version based on setInterval is weirdly choppy and wildly inconsistent in speed.

    So maybe jQuery's animate() method is in fact the way to go!  I've never used it before and didn't know about it until you mentioned it, but now that I've read up on it (http://api.jquery.com/animate/?? it seems very useful!  (As I hoped, I'm learning new things from this study group too!)

    My only caveat for using animate() is that you should make sure you think about what happens when the user makes another mouse movement while the first animation is still in progress.  If the code starts a second animation on the same object that is already being animated, what happens?  Can you cancel the original animation partway through and start a new one from the object's intermediate position towards the new mouse location?

  • Tyler Cipriani   April 28, 2011, 6:55 p.m.
    In Reply To:   Jono Xia   April 28, 2011, 1:07 a.m.

    I've update my code - it's on the same github pages (overwritten)

    I'm much happier with the speed and behavior of my keypress exercise, but I feel like the code's a bit verbose. Maybe not...I don't know.

    With the mouse movement exercise I did end up using the animate function as part of my mousemove function - I start the function with jQuery's stop(); function so that inturrupts any animation from the previous mouse move.

    If I've missed anything or if anyone sees an opportunity to make my code more succinct/reliable/readable - reply here and I'll look at making revisions.