There is an ancient LaserAge toy that is written in Flash (on the very ancient Macromedia Flash 4) and works only under Windows. As a child, I really liked it, so I decided to port it for the soul so that you can play from the browser from all devices.


The goal of the game is to destroy opponents with your spaceship at various levels and receive bonuses, if you catch a bonus - the weapon improves. If an enemy torpedo hits, the player’s weapon downgrade.


When you destroy all opponents at a level, you switch to the next level. Only 100 levels.


In terms of the game, the level is a Wave, and several waves are combined into a large Level, which is simply a change in the background, i.e. Only 4 large levels in each of which 25 waves. In the last wave of a high level, there is usually a boss - an adversary with tremendous importance of life and powerful weapons.

https://github.com/EntityFX/laseroid/blob/master/doc/LaserAgeNext.png?raw=true


Business game logic


Game space


It is an ordinary rectangular area, in the upper part there are enemy ships, and below the player.


The player’s area of ​​movement is limited so that he cannot collide with enemy ships, and enemy ships with the player.


https://github.com/EntityFX/laseroid/blob/master/doc/Stage.png?raw=true


Weapons


Player’s spaceship and enemy ships possess weapons.
The player’s weapon can be manual (shoots when you click the mouse) and optional automatic (shoots with periods).


Weapons fire torpedoes, the movement algorithm of which is very primitive: enemy torpedoes move towards the player (from top to bottom), and player torpedoes move from bottom to top.
When an enemy torpedo hits the player, 1 level of life (upgrade) is deducted, at 0 the game ends in defeat.


Player’s spaceship weapon


  • Torpedo - shoots small rockets
    • Single Torpedo - 1st level upgrade
    • Double - Level 2 Upgrade
    • Triple - Level 3 Upgrade
  • Automatic guns
    • Additional automatic torpedo on the left side of the ship - upgrade level 4
    • Additional automatic torpedo on the right side of the ship - Level 5 upgrade
  • Green plasma - 6 and 7 upgrade level (rate of fire increases)
  • Purple Plasma - Level 8 Upgrade (deals damage to all enemies along the flight path)
  • Green laser - level 9 (deals damage to all enemies, as well as active for one second, thereby you can touch neighboring enemies)

Additional weapons:


  • Red plasma - level 15-19 (deals damage to all enemies, as well as active for one second, thereby you can touch neighboring enemies)
  • Green Plasma - Level 20-24
  • Blue Plasma - Level 25-29 Upgrade
  • Purple Plasma - Level 30-34 Upgrade
  • Purple Plasma - Level 30-34 Upgrade
  • Optional automatic torpedo on the left fires yellow plasma - level 35 - 39 upgrade
  • Optional automatic torpedo on the right shoots yellow plasma - 40+ upgrade level

Player Weapon Characteristics Table


Weapons Hit Points Sprite Speed ​​ Intensity Type Advanced View
Torpedo 1 5 25 Torpedo Single, double, triple ITKarma picture
Automatic Torpedo 1 5 50 Torpedo Left and Right ITKarma picture
Green Plasma 3 7 30 Torpedo ITKarma picture
Purple Plasma 2 8 30 Torpedo Attacks up to 3 targets ITKarma picture
Red Plasma 2 4 30 Torpedo ITKarma picture
Blue Plasma 4 4.5 30 Torpedo ITKarma picture
Yellow Plasma 2 3.8 40 Torpedo Automatic only ITKarma picture
Green Laser 4 - 15/55 Laser Attacks up to 5 targets at a time ITKarma picture

Table with the configuration of the player’s weapons depending on the standard of living


Standard of living Weapon Configuration
1 Torpedo
2 Torpedo + Torpedo
3 Torpedo + Torpedo + Torpedo
4 Torpedo + Torpedo + Torpedo + Automatic torpedo on the left
5 Torpedo + Torpedo + Torpedo + Automatic torpedo left + right
6 Green plasma + Automatic torpedo on the left + right
7 Green plasma + Automatic torpedo on the left + right
8 Violet plasma + Automatic torpedo on the left + right
9 Green laser + Automatic torpedo on the left + right
15 - 19 Green laser + Red plasma + Automatic torpedo on the left + right
20 - 24 Green laser + Red plasma + Automatic torpedo on the left + right
25 - 29 Green laser + Blue plasma + Auto torpedo on the left + right
30 - 34 Green laser + Violet plasma + Automatic torpedo on the left + right
35 - 39 Green laser + Violet plasma + Automatic yellow plasma on the left + torpedo on the right
40+ Green laser + Violet plasma + Automatic yellow plasma on the left + yellow plasma on the right

Weapons of opponents


Opponent Weapon Configuration Table


Weapons Sprite Speed ​​ Type
Torpedo 2.5 Torpedo
Red Plasma 3.5 Torpedo
Blue Plasma 4.5 Torpedo
Green Plasma 5 Torpedo
Blue Torpedo 3 Torpedo
Yellow Plasma 3.2 - 3.8 Torpedo
White Plasma 4 - 6 Torpedo
Green Laser - Laser

In order to exclude predictability of player’s weapon behavior, the intensity is pseudo-random.


The intensity of the weapon of the opponents can have one or more time slots, each separately sets the minimum and maximum time of frames and the number of repetitions. The slot can be a pause or an active state (shoots).


Weapon configuration example:


"torpedo": { "sprite": "Bullet1_1.png",//картинка спрайта "isRandomIntensity": false,//нужно ли переключать случайно слоты - true или по порядку - false "intensity": [//слот 0 { "min": 50,//минимальное число фреймов "max": 200,//максимальное число фреймов "type": "pause"//pause - оружие неактивно, shoot - активное (стреляет) },//слот 1 { "min": 100, "max": 200, "type": "shoot" }, { "min": 50, "max": 80, "type": "pause" }, { "min": 30, "max": 100, "repeat": 2 } ], "speed": 2.5,//скорость "type": "bullet",//тип оружия "sound": "alienTorpedo" } 

Actors


Player ship


A player’s ship can move in a limited area so as not to interfere with enemy ships.


Controlled by mouse movement or arrows CDMY0CDMY and CDMY1CDMY. On the screen of a mobile phone tap and swipe around the screen.


The weapon activates when you hold the left mouse button (tap and hold on the screen on a mobile phone).


Opponents


For a change, at each level there can be a different number of opponents, each of which has its own set of weapons, has its own meaning of life, a different trajectory of movement. opponents can be ordinary or bosses.


Enemy Ship Life Type Movements Weapons View
Alien 1 2 Regular Normal horizontal Torpedo ITKarma picture
Alien 2 4 Regular Normal all directions Torpedo ITKarma picture
Fast Alien 10 Regular Fast horizontal Torpedo (Intensive) ITKarma picture
Alien Frigate 10 Regular Normal fast all directions Red Plasma ITKarma picture
Alien Armored Car 10 Regular Slow Down Torpedo (Very Intense) ITKarma picture
Fast Alien Frigate 30 Regular Slow down (watching the player) Red Plasma (Very Intense) ITKarma picture
Red Fighter 30 Regular Slow down (watching the player) Blue Plasma ITKarma picture
Green Fighter 30 Regular Fast upright Blue Plasma ITKarma picture
Alien 1 modification 2 Regular Normal horizontal Blue Torpedo ITKarma picture
Bomber 30 Regular Normal all directions (watching the player) Green Plasma ITKarma picture
Heavy Alien 30 Regular Normal all directions Torpedo ITKarma picture
Alien Heavy Frigate 35 Regular Normal all directions Blue Torpedo + Blue Torpedo ITKarma picture
Heavy armored car 35 Regular Normal down Yellow Plasma + Yellow Plasma + Yellow Plasma + Yellow Plasma ITKarma picture
Battleship 100 Boss Normal all directions Blue plasma (very intense) + Green plasma (very intense) ITKarma picture
Cruiser 250 Boss Normal all directions Green plasma (super intense) ITKarma picture
Heavy Cruiser 500 Boss Fast all directions Yellow Plasma + Yellow Plasma + Blue Torpedo + Blue Torpedo + Blue Torpedo + Blue Torpedo + White Plasma + White Plasma ITKarma picture
Epic Heavy Cruiser 1000 (restored) Boss Fast all directions Yellow Plasma + Yellow Plasma + Blue Torpedo + Blue Torpedo + Blue Torpedo + Blue Torpedo + White Plasma + White Plasma + Green Plasma (very intense) ITKarma picture

Enemy JSON configuration:


"alien10": { "life": 35, "weapons": [ { "weapon": "blueTorpedo", "position": { "x": -6, "y": 0 } }, { "weapon": "blueTorpedo", "position": { "x": 6, "y": 0 } } ], "sprite": "AlienShip10_1.png", "movement": "horizontalFast", "killPoints": 2100 } 

JSON configuration of enemy movement:


"horizontalFast": { "movements": [ { "type": "freeMovement",//freeMovement - обычное, followPlayer - следит за игроком (движется в направление) "speedDelta": { "vx": -6, "vy": 0 }, "intensity": [//интенсивность движения в виде слотов { "min": 20, "max": 150 }, { "min": 150, "max": 350 } ] } ] } 

Bonuses


Special view of the enemy


https://raw.githubusercontent.com/EntityFX/laseroid/master/resources/laser-age/graphics/PowerUps_1.png, which has no weapons and when destroyed generates a sprite with a bonus


https://raw.githubusercontent.com/EntityFX/laseroid/master/resources/laser-age/graphics/Upgrade.png, which should catch the player’s ship.If a player catches a bonus, his level (life) increases.


Levels


Each level contains many different types of opponents, which are located in a certain way. Also, a level may contain one or more bonuses.


JSON level configuration:


"2": { "level": 1, "enemies": [//список противников { "id": "alien1", "position": { "x": 200, "y": 35 } },//... { "id": "alien1", "position": { "x": 525, "y": 40 } } ], "bonuses": [//список бонусов { "id": "bonus1", "position": { "x": 350, "y": 10 } } ] }, 

Choosing a JavaScript library to implement


I looked at a lot of JavaScript graphics libraries, but settled on Hexi JS: https://github.com/kittykatattack/hexi .


Library Features:


  • Simplicity
  • Drawing primitives
  • Drawing simple interfaces (buttons, events)
  • Move, scale, rotate
  • Drawing sprites
    • Animated Sprites
    • Work with sprites as objects
    • Loading sprites in the form of a large satin texture. You can place many images in one file and get one large texture and a JSON file with a description of sprites (region, offset) at the output
  • The logic of collisions
  • Working with input devices (keyboard), touch-screen.

An example of a texture atlas created using TexturePacker


https://github.com/EntityFX/laseroid/blob/master/doc/ships-atlas-texture.png?raw=true


Sound Library: https://github.com/kittykatattack/sound.js


Library Features:


  • Simplicity
  • Play Sounds
  • Play music
  • Effects

Architecture


General class diagram:


https://github.com/EntityFX/laseroid/blob/master/doc/diagrams/game.png?raw=true


The core of the game


https://github.com/EntityFX/laseroid/blob/master/doc/diagrams/core.png?raw=true


Main class


Is the entry point and container of the game code.


Fields :


  • resources - contains a list of all downloaded resources (textures, sound, json)
  • sounds - dictionary of sounds: Key - name, Value - path
  • gameScene - HexiJS object on
  • game - instance of the Game object
  • hexi - HexiJS instance
  • gameStorage - saves the game state in localStorage

Methods :


  • init () - initializes HexiJS
  • load () - loads resources (textures, sound, json)
  • setup () - sets the game area, button click events, starts background music
  • playLoop () - the point of change in the state of the game (counts movement, collisions, shells, redraws the space).
  • saveGame () - saves the game
  • loadGame () - loads the game

Example of a list of resources of the current implementation of the game:


Main.resources=[ "images/environment1.png", "images/environment2.png", "images/environment3.png", "images/environment4.png", "images/interface.png", "images/life-icon.png", "images/ships-texture.json", "images/bullet-texture.json", "sounds/alien-torpedo-shoot.wav", "sounds/alien-red-plasma-shoot.wav", "sounds/hero-torpedo-shoot.wav", "sounds/explode.wav", "sounds/hero-green-plasma-shoot.wav", "sounds/alien-green-plasma-shoot.wav", "sounds/alien-blue-torpedo-shoot.wav", "sounds/alien-yellow-laser.wav", "sounds/pulse-plasma.wav", "sounds/laser.wav", "sounds/track0.ogg", "sounds/track1.ogg", "sounds/track2.ogg", "sounds/track3.ogg", "sounds/track4.ogg", "data/hero-configuration.json", "data/levels-configuration.json", "data/enemy-configuration.json", "data/ui-configuration.json", ]; 

Game class


The main class of the game.


Fields :


  • level - information about the level. Value: CDMY2CDMY
  • score - information about points. Value: CDMY3CDMY
  • bulletsController - An instance of the BulletsController class. Controls the behavior of torpedoes and weapon lasers
  • enemyController - An instance of the EnemyController class. Controls the behavior of all opponents at the level (includingand bonuses)
  • player - Instance of Player
  • hexi - an instance of the Hexi class (link)
  • game - instance of the Game object
  • gameStorage - instance of the GameStorage object

Methods :


  • clearShips () - clear all members, bonuses
  • setupLevel () - adjust the level (add opponents, bonuses, placement)
  • nextLevel () - go to the next level
  • previousLevel () - go to the previous level
  • forwardLevel () - jump forward several levels (5)
  • rewindLevel () - jump a few levels back (5)
  • restoreState (gameState: JSON) - restore by gameState object
  • resetGame () - reset the game (start over)
  • update () - update the game world
  • enemyDestroyed () - the handler is triggered when all enemies are destroyed

GameStorage class


Saves and loads game state.


Fields :


  • game - instance of the Game object

Methods :


  • save () - save the state of the game
  • load () - load the state of the game

InputDevice class


Works with events of input devices: click and touch buttons, keystrokes.


Fields :


  • game - instance of the Game object

Methods :


  • init () - initializes all event handlers and callbacks
  • loadTapped () - the "Load" button
  • was pressed
  • storeTapped () - the Store button
  • was pressed
  • resetTapped () - the "Reset" button is pressed
  • pauseTapped () - the "Pause" button
  • was pressed

actor class hierarchy


https://github.com/EntityFX/laseroid/blob/master/doc/diagrams/actors.png?raw=true


Actor


Member Class.


Fields :


  • hexi - an instance of the Hexi class (link)
  • game - instance of the Game object
  • life - the current meaning of life
  • initialLife - the initial meaning of life
  • sprite - an instance of the Hexi.Sprite class
  • shipConfiguration - bonus configuration

Methods :


  • move () - move the actor
  • update () - update the actor
  • setPosition (position: {x, y}) - set by coordinates

WeaponedActor


The class of the participant (opponent or player) possessing a weapon.


Fields :


  • automatedWeapons - an array of automatic weapons
  • canShoot - can shoot
  • isWeaponShooting - is the weapon active

Methods :


  • startShoot () - launch shots with weapons
  • stopShoot () - stop gun shots
  • onShootStarted () - the handler of the event that gun shots were fired
  • onShootStopped () - an event handler that stopped gun shots
  • updateShooting () - performs shot algorithms

Enemy


Class of the adversary.


Fields :


  • type - enemy type
  • syncWeapons - an array of configurations for synchronous weapons
  • movementEngine - an instance of the MovementEngine class

Methods :


  • setWeapon () - install weapons using the current configuration
  • shootWithWeapon () - firing an adversary
  • setLifeLine () - draws the enemy’s life line
  • hit () - checks the collision of torpedoes (laser) of the player with the current enemy

MovementEngine


Motion control class.


To add complexity to the movement, a configuration with slots is used. In each slot, the direction vector vx, vy and intensity are specified. It is possible to turn off the reflection from the lower border and the tracking mode for the player (the enemy always moves behind the player).


Fields :


  • movementsConfiguration - movement configuration
  • firstMovementConfiguration - the first element from the list of configurations
  • movementItensity - movement intensity
  • movementItensityCounter - movement intensity counter
  • movementItensitySlot - intensity slot number
  • isBounceBottom - flag for checking reflection from the lower border. If false, then the enemy does not reflect from the lower border

Methods :


  • setMovement () - adjusts the movement
  • updateMovement () - updates the motion according to the motion configuration

Player


Player Class.


Fields :


  • weapons - an array of player’s weapons
  • collisionSprite - collision sprite (enemy torpedoes collide with a collision sprite, not a player’s sprite)
  • weaponLifeLevels - values ​​of the standard of living for checking for weapon upgrades
  • invisibilityCounter - counter of invisibility from torpedoes (needed to make the player temporarily out of reach of other torpedoes when colliding with an enemy torpedo)

Methods :


  • upgrade () - player upgrade (+1 life)
  • downgrade () - player downgrade (+1 life)
  • shootWithLaser (currentWeapon, weapon) - laser shot
  • shootWithBullets (currentWeapon, weapon) - torpedo shot
  • setWeapon () - install weapons using the current configuration
  • setLife (life: number) - set the value of life (changes weapons in accordance with the value of life)
  • hitUpgrade (upgradeItem) - check for collision with upgrade sprite

Bonus


Bonus class. Upon destruction generates a sprite upgrade.


Fields :


  • type - bonus type
  • movementEngine - an instance of the MovementEngine
  • class
  • upgradeBonus - upgrade configuration

Methods :


  • shootWithUpgrade (upgradeBonus: JSON) - spawn an upgrade sprite

EnemyController


Manages the status of opponents, bonuses, upgrades.


Fields :


  • enemies - an array of all enemies at the level
  • bonuses - an array of all bonus ships at the level
  • player - player object
  • upgrades - an array of all upgrade sprites

Methods :


  • isLevelCompleted () - check for completion of the level (all opponents and bonuses are destroyed, upgrades are caught)
  • update () - updates the status of all opponents
  • clear () - clearing the level of developers, bonuses

BulletsController


Controls the state of torpedoes (movement), lasers of the player and opponents.


Fields :


  • playerBullets - an array of player torpedoes
  • enemyBullets - an array of torpedoes of all enemies
  • explosionSplashes - an array of explosion sprites
  • playerLaser - the state of the player’s laser sprite (if weapons are available).

Methods :


  • update () - updates the status of all torpedoes, lasers
  • clear () - clears the level of all torpedoes, lasers
  • updatePlayerBullets () - changes the state of all player torpedoes
  • updatePlayerLaser () - changes the state of the player’s laser
  • updateEnemyBullets () - changes the state of all enemy torpedoes
  • updateExplosions () - changes the state of all explosions

Conclusions


I tried to tell in sufficient detail how to port an existing game to JavaScript.


The game can be modified and supplied with its own textures, music, make your own level configuration or a variation of the whole game.


I would very much like to receive comments from you on the architecture of the game, refactoring options, on naming methods, etc.


I agree, the architecture is not very ideal and there is much to strive for!


Thank you and interesting projects!


Links


http://laseroid.azurewebsites.net/ - the game itself
https://github.com/EntityFX/laseroid - the source code of the game

.

Source