S2
jS
Learn
Create Your Own
Split Screen
Go to Live Site
Next Page
Use the arrow-keys
on your keyboard to drive the hero around the canvas.
See how well the legs work?
<html> <head> <title>2D scroller</title> </head> <body> <canvas id="myCanvas" width=300 height=300 style="background-color:lightgreen" > </canvas> <script> var ctx = myCanvas.getContext("2d"); // Get the drawing context for the canvas var FPS = 40; // How many frames per second var keys = []; // which keys are down function MySprite (img_url, width) { // This function creates a MySprite this.x = 0; this.y = 0; // Where is it? Start it at x=0, y=0 this.costume = 0; // Which costume is displayed ? this.costume_width = width; // How wide is each costume this.visible= true; this.velocity_x = 0; // How fast is it moving? this.velocity_y = 0; this.MyImg = new Image(); // Store the image in an Image object this.MyImg.src = img_url ; // Load the image from a url this.angle = 0; // How many degrees we are rotated this.flipV = false; // Are we flipped vertically this.flipH = false; // Are we flipped horizontally this.animation_rate = 0; // change costume every this many frames this.animation_first_costume = 0; // what costume the animation starts on this.animation_final_costume = null; // what costume the animation finish on this.animation_counter = 0; // how many frames since last change this.animation_continuous = true; // does it auto-repeat or just stop } MySprite.prototype.Do_Frame_Things = function() { ctx.save(); // Save the drawing context state if (!this.costume_width) this.costume_width = this.MyImg.width; // If no costumes, width is full image var num_costumes = this.MyImg.width / this.costume_width; // How many costumes provided? if (!this.animation_final_costume && num_costumes) this.animation_final_costume = num_costumes-1; // if final not set, use them all this.h = this.MyImg.height; // height of the image file this.w = this.costume_width; // width of a costume ctx.translate(this.x + this.w/2, this.y + this.h/2); // positioning ctx.rotate(this.angle * Math.PI / 180); // rotating if (this.flipV) ctx.scale(1,-1); // flipping if (this.flipH) ctx.scale(-1,1); if (this.visible) ctx.drawImage(this.MyImg, this.costume * this.w, 0, this.w, this.h, -this.w/2, -this.h/2, this.w, this.h); this.x = this.x + this.velocity_x; this.y = this.y + this.velocity_y; // move the thing if (this.animation_rate > 0) { this.animation_counter++; // count frames if (this.animation_counter > this.animation_rate) { // is it time for the next costume? this.animation_counter = 0; // reset the counter this.costume++; // select the next costume if (this.costume > this.animation_final_costume) // check if past last costume if (this.animation_continuous) this.costume = this.animation_first_costume // if continuous, loop back else this.costume = this.animation_final_costume; // otherwise stay on the last costume } // time for next costume } // we are animating ctx.restore(); // unwarp the context } var hero = new MySprite("http://www.s2js.com/img/etc/spider.png", 50); hero.x = 100; hero.y = 100; addEventListener('keydown', MyKeyDownHandler); addEventListener('keyup', MyKeyUpHandler); function MyKeyUpHandler(MyEvent) { keys[MyEvent.keyCode] = false; MyEvent.preventDefault(); } function MyKeyDownHandler(MyEvent) { keys[MyEvent.keyCode] = true; MyEvent.preventDefault(); } var hero_speed = 3; // How fast the hero goes function handle_keys_that_are_pressed() { var prev_x = hero.x; var prev_y = hero.y; if (keys[37]) { // Left hero.x -= hero_speed; } if (keys[39]) { // Right hero.x += hero_speed; } if (keys[38]) { // Up hero.y -= hero_speed; } if (keys[40]) { // Down hero.y += hero_speed; } if (hero.x == prev_x && hero.y == prev_y) hero.animation_rate= 0 // not moving else hero.animation_rate= 2; // wriggling legs } function Do_a_Frame () { ctx.clearRect(0, 0, myCanvas.width, myCanvas.height); handle_keys_that_are_pressed(); hero.Do_Frame_Things(); } setInterval(Do_a_Frame, 1000/FPS); // set my frame renderer </script> </body> </html>