Get the full commented source code of

HTML5 Suika Watermelon Game

Talking about Nodes game, Actionscript 3, Flash and Game development.

Today I want to point you on a very interesting prototype I made more than four years ago… Creation of the engine behind “Nodes” game with Flash.

It’s a basic prototype of Nodes, a puzzle game which got some success years ago.

Why am I publishing this prototype today? First, because I improved and now it’s a “complete” game, which means you can play for real, trying to beat infinite random-generated solvable levels.

Second, and probably most important reason, is the gameplay is perfect for a mobile porting, which I am currently making.

Anyway, this is the game:

Drag the red nodes to highlight all blue targets with the laser. Once a level is completed, you will face another random generated level.

And this is the short source code I used to make it:

package {
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	public class Main extends Sprite {
		private const DRAGGABLES:Number=4;
		private const TARGETS:Number=5;
		private var draggableNode:DraggableNode;
		private var target:Target;
		private var laserCanvas:Sprite=new Sprite();
		private var draggableVector:Vector.=new Vector.();
		private var targetVector:Vector.=new Vector.();
		private var isDragging:Boolean=false;
		public function Main() {
			addChild(laserCanvas);
			placeDraggables(false);
			placeTargets(false);
			shuffleDraggables();
			drawLaser();
			stage.addEventListener(MouseEvent.MOUSE_MOVE,moving);
		}
		private function placeDraggables(justMove:Boolean):void {
			for (var i:Number=0; i=0; j--) {
						if (getDistance(draggableVector[j],draggableVector[i])<150) {
							wellPlaced=false;
						}
					}
				} while (!wellPlaced);
			}
		}
		private function placeTargets(justMove:Boolean):void {
			for (var i:Number=0; i=0; j--) {
						if (getDistance(targetVector[j],targetVector[i])<50) {
							wellPlaced=false;
						}
					}
					for (j=0; j

Let's see the most interesting lines:

private const DRAGGABLES:Number=4;
private const TARGETS:Number=5;
private var draggableNode:DraggableNode;
private var target:Target;
private var laserCanvas:Sprite=new Sprite();
private var draggableVector:Vector.=new Vector.();
private var targetVector:Vector.=new Vector.();
private var isDragging:Boolean=false;

DRAGGABLES and TARGETS are respectively the amounts of red draggable nodes and blue targets.

draggableNode and target are variables to instantiate respectively DraggableNode and Target sprites, in the library

laserCanvas is the sprite we will use to draw the laser

draggableVector and targetVector are vectors we will fill respectively with draggable nodes and targets

isDragging is a Boolean variable to help us know whether the player is dragging a node.

addChild(laserCanvas);
placeDraggables(false);
placeTargets(false);
shuffleDraggables();
drawLaser();
stage.addEventListener(MouseEvent.MOUSE_MOVE,moving);

This is the game itself, which works this way: first, draggable nodes are randomly placed on the stage, then target are randomly placed over lasers, generating a solvable levels, then draggable nodes are shuffled and finally the laser is shown.

A listener is added to trigger mouse movements.

And this is how we place draggable nodes:

private function placeDraggables(justMove:Boolean):void {
	for (var i:Number=0; i=0; j--) {
				if (getDistance(draggableVector[j],draggableVector[i])<150) {
					wellPlaced=false;
				}
			}
		} while (!wellPlaced);
	}
}

The Boolean argument is used to let us know whether we just have to adjust nodes or we also have to physically add them to stage and fill draggableVector vector. When the game is run, we have to physically add the nodes, but when the player completes a level we just have to arrange nodes in different positions.

Look at the listeners attached to each node, and also look how we are ensuring there are at least 150 pixels of empty space around nodes.

private function placeTargets(justMove:Boolean):void {
	for (var i:Number=0; i=0; j--) {
				if (getDistance(targetVector[j],targetVector[i])<50) {
					wellPlaced=false;
				}
			}
			for (j=0; j

Targets are placed/moved in the same way, just keeping at least 50 pixels of empty space before we find another target or a draggable node.

The interesting part starts at line 52 where I choose a random laser segment where to place the target.

Lines 53-54: Given the segment, I determine the nodes which delimit such segment

Line 55: Finding the angle of the segment

Line 56: Finding segment length

Lines 57-58: Once I know the start and end points of the segment, as well as its length and angle, it's easy to place the target in a random point of the segment using trigonometry.

private function shuffleDraggables():void {
	for (var i:Number=0; i

This is how draggable nodes are shuffled... just placing them in a random position.

private function drawLaser():void {
	laserCanvas.graphics.clear();
	laserCanvas.graphics.lineStyle(5,0xff0000);
	laserCanvas.graphics.moveTo(draggableVector[0].x,draggableVector[0].y);
	for (var i:Number=1; i

And this is how the laser is placed on the stage, it's just a line connecting all nodes in sequence, also connecting the latest node with the first node.

private function moving(e:MouseEvent):void {
	var connected:Number=0;
	if (isDragging) {
		drawLaser();
		for (var i:Number=0; i

The last interesting function is the one which handles nodes movement. In this case, I just perform an hit test between nodes registration point and the laser line, so the strongest the line, the easier the game. Once all targets are touched by laser simultaneously, a new level starts.

And that's all, download the source code, hope you enjoyed this prototype and you will enjoy the mobile porting too.

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.