Create a flash draw game like Line Rider or others – part 1

Read all posts about "" game

March 31st update: part 5 released
March 4th update: part 4 released
February 17th update: part 3 released
February 3rd update: part 2 released

In the last months I saw a lot of flash drawing games, like Line Rider and Softball.
The concept is very simple yet addictive because the player has the capability to draw the stage.
In the first part of this tutorial I’ll cover the drawing.

The first thing to do, in the first frame, is to create the object where we are going to draw.

Drawing lines in a movieclip

_root.createEmptyMovieClip("terrain", 1);

I have just created an empty movieclip called terrain (and, of course, instanced as terrain) at depth 1.

Now I have to decide the style of my line, I mean the color, the thickness and the transparency (alpha).

_root.terrain.lineStyle(10, 0xff0000, 100);

With this method I am telling flash that I want a line style of 10 pixel width, full red and completely opaque, because the lineStyle method has 3 parameters:

thickness, an integer that indicates the thickness of the line in points valid values are 0 to 255. If 0 (zero), then the style is the hairline, the line that never “grow” when we zoom a movie or movieclip.

rgb, a the hex color value.

alpha, an integer that indicates the alpha value of the line’s color; valid values are 0-100. If a value isn’t indicated, Flash uses 100 (solid). If the value is less than 0, Flash uses 0; if the value is greater than 100, Flash uses 100.

Now that I decided the style of the line, it’s time to draw. We are going to use two methods: moveTo and lineTo.
moveTo(x,y) moves the pen to x and y coordinates without drawing, and lineTo moves the pen to x and y coordinates drawing.

Our very first movieclip, where I draw a red box in the stage, is

createEmptyMovieClip("terrain", 1);
terrain.lineStyle(10, 0xff00ff, 100);
terrain.moveTo(100, 100);
terrain.lineTo(300, 100);
terrain.lineTo(300, 300);
terrain.lineTo(100, 300);
terrain.lineTo(100, 100);

Drawing with the mouse

Now I want to draw with the mouse and not by fixed coordinates.

This is even simpler

createEmptyMovieClip("terrain", 1);
terrain.lineStyle(10, 0xff00ff, 100);
onEnterFrame = function () {
	terrain.lineTo(_xmouse, _ymouse);
};

You are able to draw into the movie!

Now I have an issue… I cannot draw “real” curves and it seems to be a delay when I draw.
That’s due to the fps speed of the movie. If you want to make a draw game, you should raise the fps to at least 30 frames per second.

Here it is the same movie playing at 50fps

As you can see, you can create “curves” by adding short lines each close to each oterh.

Draw only when mouse button is pressed

To draw only when you press mouse button, I need a little more actionscript

createEmptyMovieClip("terrain", 1);
terrain.lineStyle(10, 0xff00ff, 100);
imdrawing = false;
onMouseDown = function () {
	if (imdrawing == false) {
		terrain.moveTo(_xmouse, _ymouse);
		imdrawing = true;
	}
	if (imdrawing == true) {
		onEnterFrame = function () {
			terrain.lineTo(_xmouse, _ymouse);
		};
	}
};
onMouseUp = function () {
	onEnterFrame = function () {
		imdrawing = false;
	};
};

Let’s analyze the script:
Line 1: create the movie clip instanced as “terrain”
Line 2: set the style of the line I am going to draw
Line 3: initialize a flag saying that I am not drawing
Line 4: Actions to perform when the mouse is “down” (when I click the mouse)
Lines 5-8: If i am not drawing, move the “pen” at current mouse location and set the drawing variable at true, to tell the script that now I am drawing
Lines 9-13: If I am drawing, every time I enter the frame a line is traced from the last line drawn to the actual mouse location
Lines 15-19: If the mouse is “up” (I am not clicking the mouse), the imdrawing variable is set back to false value each time I enter the frame. The onEnterFrame here may seem useles but without it, the script won’t work and if you start drawing, you will continue drawing even if the mouse button is not pressed.

Drawing with (more) style

As you noticed, I can decide the style of my lines declaring width, color and alpha.
But what if I want to give my lines some more style?

I have to use some filters Flash has. Flash has several filters you may apply to an object: BevelFilter, BlurFilter, ColorMatrixFilter, ConvolutionFilter, DisplacementMapFilter, DropShadowFilter, GlowFilter, GradientBevelFilter, and GradientGlowFilter.

I’ll examine the ones you may need to use in a draw game

Adding a Bevel

to add a Bevel you have to declare the following parameters:

distance:Number [optional] – The offset distance of the bevel, in pixels (floating point). The default value is 4.

angle:Number [optional] – The angle of the bevel, from 0 to 360 degrees. The default value is 45.

highlightColor:Number [optional] – The highlight color of the bevel, 0xRRGGBB. The default value is 0xFFFFFF.

highlightAlpha:Number [optional] – The alpha transparency value of the highlight color. Valid values are 0 to 1. For example, .25 sets a transparency value of 25%. The default value is 1.

shadowColor:Number [optional] – The shadow color of the bevel, 0xRRGGBB. The default value is 0x000000.

shadowAlpha:Number [optional] – The alpha transparency value of the shadow color. Valid values are 0 to 1. For example, .25 sets a transparency value of 25%. The default value is 1.

blurX:Number [optional] – The amount of horizontal blur in pixels. Valid values are 0 to 255 (floating point). The default value is 4. Values that are a power of 2 (such as 2, 4, 8, 16 and 32) are optimized to render more quickly than other values.

blurY:Number [optional] – The amount of vertical blur in pixels. Valid values are 0 to 255 (floating point). The default value is 4. Values that are a power of 2 (such as 2, 4, 8, 16 and 32) are optimized to render more quickly than other values.

strength:Number [optional] – The strength of the imprint or spread. The larger the value, the more color is imprinted and the stronger the contrast between the bevel and the background. Valid values are 0 to 255. The default value is 1.

quality:Number [optional] – The number of times to apply the filter. The default value is 1, which is equivalent to low quality. A value of 2 is medium quality, and a value of 3 is high quality.

type:String [optional] – The type of bevel. Valid values are “inner”, “outer”, and “full”. The default value is “inner”.

knockout:Boolean [optional] – Applies a knockout effect (true), which effectively makes the object’s fill transparent and reveals the background color of the document. The default value is false (no knockout).

You have to play a bit with the parameters to achieve the effect you prefer.

import flash.filters.BevelFilter;
var distance:Number = 2;
var angleInDegrees:Number = 45;
var highlightColor:Number = 0xff00ff;
var highlightAlpha:Number = 1;
var shadowColor:Number = 0xbb00bb;
var shadowAlpha:Number = 1;
var blurX:Number = 8;
var blurY:Number = 8;
var strength:Number = 10;
var quality:Number = 3;
var type:String = "inner";
var knockout:Boolean = false;
var my_bevel_filter:BevelFilter = new BevelFilter(distance, angleInDegrees, highlightColor, highlightAlpha, shadowColor, shadowAlpha, blurX, blurY, strength, quality, type, knockout);
createEmptyMovieClip("terrain", 1);
terrain.lineStyle(20, 0xdd00dd, 100);
terrain.filters = new Array(my_bevel_filter);
imdrawing = false;
onMouseDown = function () {
	if (imdrawing == false) {
		terrain.moveTo(_xmouse, _ymouse);
		imdrawing = true;
	}
	if (imdrawing == true) {
		onEnterFrame = function () {
			terrain.lineTo(_xmouse, _ymouse);
		};
	}
};
onMouseUp = function () {
	onEnterFrame = function () {
		imdrawing = false;
	};
};

Line 1: import the filter – it won’t work without this line
Lines 2-13: declaration of the various parameters
Line 14: creation of the filter itself
Line 17: the filter is applied to the movieclip instanced as terrain. Look at the array declaration: that’s because it’s possible to add several effect to a single movieclip

Adding a blur effect

to add a Bevel you have to declare the following parameters:

blurX:Number [optional] – The amount to blur horizontally. Valid values are from 0 to 255 (floating-point value). The default value is 4. Values that are a power of 2 (such as 2, 4, 8, 16 and 32) are optimized to render more quickly than other values.

blurY:Number [optional] – The amount to blur vertically. Valid values are from 0 to 255 (floating-point value). The default value is 4. Values that are a power of 2 (such as 2, 4, 8, 16 and 32) are optimized to render more quickly than other values.

quality:Number [optional] – The number of times to apply the filter. The default value is 1, which is equivalent to low quality. A value of 2 is medium quality, and a value of 3 is high quality and approximates a Gaussian blur.

import flash.filters.BlurFilter;
var blurX:Number = 30;
var blurY:Number = 30;
var quality:Number = 3;
var my_blur_filter:BlurFilter = new BlurFilter(blurX, blurY, quality);
createEmptyMovieClip("terrain", 1);
terrain.lineStyle(20, 0xdd00dd, 100);
terrain.filters = new Array(my_blur_filter);
imdrawing = false;
onMouseDown = function () {
	if (imdrawing == false) {
		terrain.moveTo(_xmouse, _ymouse);
		imdrawing = true;
	}
	if (imdrawing == true) {
		onEnterFrame = function () {
			terrain.lineTo(_xmouse, _ymouse);
		};
	}
};
onMouseUp = function () {
	onEnterFrame = function () {
		imdrawing = false;
	};
};

This script is similar to the previous one, and applies a blur instead of a bevel

Adding a Glow

Parameters:

color:Number [optional] – The color of the glow, in the hexadecimal format 0xRRGGBB. The default value is 0xFF0000.

alpha:Number [optional] – The alpha transparency value for the color. Valid values are 0 to 1. For example, .25 sets a transparency value of 25%. The default value is 1.

blurX:Number [optional] – The amount of horizontal blur. Valid values are 0 to 255 (floating point). The default value is 6. Values that are a power of 2 (such as 2, 4, 8, 16 and 32) are optimized to render more quickly than other values.

blurY:Number [optional] – The amount of vertical blur. Valid values are 0 to 255 (floating point). The default value is 6. Values that are a power of 2 (such as 2, 4, 8, 16 and 32) are optimized to render more quickly than other values.

strength:Number [optional] – The strength of the imprint or spread. The higher the value, the more color is imprinted and the stronger the contrast between the glow and the background. Valid values are 0 to 255. The default is 2.

quality:Number [optional] – The number of times to apply the filter. Valid values are 0 to 15. The default value is 1, which is equivalent to low quality. A value of 2 is medium quality, and a value of 3 is high quality.

inner:Boolean [optional] – Specifies whether the glow is an inner glow. The value true indicates an inner glow. The default is false, an outer glow (a glow around the outer edges of the object).

knockout:Boolean [optional] – Specifies whether the object has a knockout effect. The value true makes the object’s fill transparent and reveals the background color of the document. The default is false (no knockout effect).

import flash.filters.GlowFilter;
var color:Number = 0x33CCFF;
var alpha:Number = .8;
var blurX:Number = 35;
var blurY:Number = 35;
var strength:Number = 2;
var quality:Number = 3;
var inner:Boolean = false;
var knockout:Boolean = false;
var my_glow_filter:GlowFilter = new GlowFilter(color, alpha, blurX, blurY, strength, quality, inner, knockout);
createEmptyMovieClip("terrain", 1);
terrain.lineStyle(20, 0xdd00dd, 100);
terrain.filters = new Array(my_glow_filter);
imdrawing = false;
onMouseDown = function () {
	if (imdrawing == false) {
		terrain.moveTo(_xmouse, _ymouse);
		imdrawing = true;
	}
	if (imdrawing == true) {
		onEnterFrame = function () {
			terrain.lineTo(_xmouse, _ymouse);
		};
	}
};
onMouseUp = function () {
	onEnterFrame = function () {
		imdrawing = false;
	};
};

Same as before…

Adding a shadow

distance:Number [optional] – The offset distance for the shadow, in pixels. The default value is 4 (floating point).

angle:Number [optional] – The angle of the shadow, 0 to 360Ëš (floating point). The default value is 45.

color:Number [optional] – The color of the shadow, in hexadecimal format 0xRRGGBB. The default value is 0x000000.

alpha:Number [optional] – The alpha transparency value for the shadow color. Valid values are 0 to 1. For example, .25 sets a transparency value of 25%. The default value is 1.

blurX:Number [optional] – The amount of horizontal blur. Valid values are 0 to 255 (floating point). The default value is 4. Values that are a power of 2 (such as 2, 4, 8, 16 and 32) are optimized to render more quickly than other values.

blurY:Number [optional] – The amount of vertical blur. Valid values are 0 to 255 (floating point). The default value is 4. Values that are a power of 2 (such as 2, 4, 8, 16 and 32) are optimized to render more quickly than other values.

strength:Number [optional] – The strength of the imprint or spread. The higher the value, the more color is imprinted and the stronger the contrast between the shadow and the background. Valid values are 0 to 255. The default is 1.

quality:Number [optional] – The number of times to apply the filter. Valid values are 0 to 15. The default value is 1, which is equivalent to low quality. A value of 2 is medium quality, and a value of 3 is high quality.

inner:Boolean [optional] – Indicates whether or not the shadow is an inner shadow. A value of true specifies an inner shadow. The default is false, an outer shadow (a shadow around the outer edges of the object).

knockout:Boolean [optional] – Applies a knockout effect (true), which effectively makes the object’s fill transparent and reveals the background color of the document. The default is false (no knockout).

hideObject:Boolean [optional] – Indicates whether or not the object is hidden. A value of true indicates that the object itself is not drawn; only the shadow is visible. The default is false (show the object).

import flash.filters.DropShadowFilter;
var distance:Number = 20;
var angleInDegrees:Number = 45;
var color:Number = 0x000000;
var alpha:Number = .8;
var blurX:Number = 16;
var blurY:Number = 16;
var strength:Number = 1;
var quality:Number = 3;
var inner:Boolean = false;
var knockout:Boolean = false;
var hideObject:Boolean = false;
var my_shadow_filter:DropShadowFilter = new DropShadowFilter(distance, angleInDegrees, color, alpha, blurX, blurY, strength, quality, inner, knockout, hideObject);
createEmptyMovieClip("terrain", 1);
terrain.lineStyle(20, 0xdd00dd, 100);
terrain.filters = new Array(my_shadow_filter);
imdrawing = false;
onMouseDown = function () {
	if (imdrawing == false) {
		terrain.moveTo(_xmouse, _ymouse);
		imdrawing = true;
	}
	if (imdrawing == true) {
		onEnterFrame = function () {
			terrain.lineTo(_xmouse, _ymouse);
		};
	}
};
onMouseUp = function () {
	onEnterFrame = function () {
		imdrawing = false;
	};
};

Mixing all together

You can obviously mix all styles together, but pay attention: the more complex your line style, the more CPU expansive the movie, as you can see in this example

// bevel filter
import flash.filters.BevelFilter;
var distance:Number = 5;
var angleInDegrees:Number = 45;
var highlightColor:Number = 0xFFFF00;
var highlightAlpha:Number = .8;
var shadowColor:Number = 0x0000FF;
var shadowAlpha:Number = .8;
var blurX:Number = 5;
var blurY:Number = 5;
var strength:Number = 5;
var quality:Number = 3;
var type:String = "inner";
var knockout:Boolean = false;
var my_bevel_filter:BevelFilter = new BevelFilter(distance, angleInDegrees, highlightColor, highlightAlpha, shadowColor, shadowAlpha, blurX, blurY, strength, quality, type, knockout);
// blur filter
import flash.filters.BlurFilter;
var blurX:Number = 30;
var blurY:Number = 30;
var quality:Number = 3;
var my_blur_filter:BlurFilter = new BlurFilter(blurX, blurY, quality);
// shadow
import flash.filters.DropShadowFilter;
var distance:Number = 20;
var angleInDegrees:Number = 45;
var color:Number = 0x000000;
var alpha:Number = .8;
var blurX:Number = 16;
var blurY:Number = 16;
var strength:Number = 1;
var quality:Number = 3;
var inner:Boolean = false;
var knockout:Boolean = false;
var hideObject:Boolean = false;
var my_shadow_filter:DropShadowFilter = new DropShadowFilter(distance, angleInDegrees, color, alpha, blurX, blurY, strength, quality, inner, knockout, hideObject);
// glow
import flash.filters.GlowFilter;
var color:Number = 0x33CCFF;
var alpha:Number = .8;
var blurX:Number = 35;
var blurY:Number = 35;
var strength:Number = 2;
var quality:Number = 3;
var inner:Boolean = false;
var knockout:Boolean = false;
var my_glow_filter:GlowFilter = new GlowFilter(color, alpha, blurX, blurY, strength, quality, inner, knockout);
_root.createEmptyMovieClip("terrain", 1);
_root.terrain.lineStyle(10, 0xff00ff, 100);createEmptyMovieClip("terrain", 1);
terrain.lineStyle(20, 0xdd00dd, 100);
terrain.filters = new Array(my_shadow_filter,my_glow_filter,my_blur_filter,my_bevel_filter);
imdrawing = false;
onMouseDown = function () {
	if (imdrawing == false) {
		terrain.moveTo(_xmouse, _ymouse);
		imdrawing = true;
	}
	if (imdrawing == true) {
		onEnterFrame = function () {
			terrain.lineTo(_xmouse, _ymouse);
		};
	}
};
onMouseUp = function () {
	onEnterFrame = function () {
		imdrawing = false;
	};
};

That’s all at the moment, donwload all sources and give me feedback.
In the next step I’ll teach you how to save the drawing and add a bouncing ball to the stage…

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

214 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers