LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Creating Games? Developing something for fun?

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Sun Oct 03, 2021 5:58 am

ShmupSampleScreen.png
ShmupSampleScreen.png (57.2 KiB) Viewed 8499 times
DEFENSIVE_RELEASE_1.zip
Final release stack for this tutorial.
(44.15 KiB) Downloaded 175 times

Get the complete game at itch.io

This is a very simple game: you fly, you dodge bullets and enemies, you shoot, you score. Good times.
Code, 'art' and sounds free to use. If you want to be a Youtube celebrity and demonstrate this tutorial with your Hollywood good looks go right ahead.

I'm running into some issues as I get deeper so maybe the tutorial will reveal why and the final result will be better than the current version. It took about five days to get where I'm at with the project now. I never made a 'game' in Livecode before, except Hangman way back in 2007. I'm using the community version Nine Point Six Point One** ( Putting version number digits results in forum error "You can’t post image, email or url links that are external to this domain. Please remove 9.") My bank account was hacked recently so I won't be spending any money online to upgrade or subscribe any time soon.

Old Tutorial Stacks 1- 7, Missile, Enemy Factory and SHMUP Resource remain in thread as they are super simple beginnings of any shoot things game you might make with mistakes included for their learning value.
I'll attach latest and greatest stack to my first and last posts on thread for easy access to a more complete and tested project file.
Right after I fix afew things in stack 18....

Tutorial Index:
1. Local Variables
A note about Directory Structure
2. Directory and Dimensions Functions
  • Tutorial Stack 01
3. Title Screen Card Script
Tutorial Stack 02, Theme Music & Sounds
4. Mountain Making Script
  • Tutorial Stack 03
5. Warp
  • Tutorial Stack 04
6. Player Graphic and Flight
7. Play Game Loop & Move Playe Handler
  • Tutorial Stack 05
8. PlayerMove & View Handlers
  • Tutorial Stack 06
8b. PlayerMove handler in one code block
9. Missile Factory
  • Missile Factory Stack
10. SHMUP GAME TUTORIAL STACK 07
  • Tutorial Stack 7 w/ missiles
10b. Review of Missile Script Handler of Game Stack
11.Enemy Factory
  • Enemey Factory Stack version 4, feature complete for tutorial parts 11 through 14
11b. Enemy Factory: Enemy Handlers
11c. Enemy Script and Enemy Factory stack script in 2 code boxes
12. Enemy Bullets
13. Explosions
13b. Explosions : The Script of button "ExplosionScript" in one big code block.
14. Collisions
Step 14b. The CheckFactoryCollisions handler in one code box for quick copy/paste. ...Note CheckCollisions method seen here is Deprecated in stack 17.
Step 14c. Crash Test Dummy
Step 15. SHMUP RESOURCE: Enemy & Missile Factory all in one
  • SHMUP_RESOURCE stack
Part 16.Step 16. SHMUP GAME TUTORIAL STACK 08
Part 16b. PlayGame Handler
Part 16c. PlayerCrash, PlayerRespawn, GameOver & LoadingScreen Handlers
Part 17. Tutorial Stack 9: PauseGame, ResumeGame, EscapeKey & CheckMouseInWindow
Part 18. PartTutorial Stack 10 Music players, expanded view handler, big change to warppoints...more?
Part18b. Part 18b. Scripts Review: Music Additions/Fixes
Part 18c. More Music scripts review
Part 18d. Viewer Button, Loading Screen, PlayerLives
Part 18e. Warps Re-Do
Part19. Tutorial Stack 11: Pause Menu, Options Group, Fullscreen, Screen Size, Volume Contro
Part 19b. Pause Menu Group
Part 19b. Options Button of PauseMenuGroup, the OptionsGroup and associated handlers, variables and custom properties
PPart 20. Tutorial Stack 12: Anti-Aliasing & Graphic Effects Toggles in Options Group
Part 21. Tutorial Stack 13: Move Any Mountain, Mostly
Part 21b. More Mountain Magic.
Part 21b. Big Warp, Little Warp
Part 22. Tutorial Stack 14. Bug Hunt
Part22b. Tutorial Stack 14: New Player Move Handeling and Ping Pong Warps
Part 23. Tutorial Stack 15: More Sound Effects!
Part23b. Tutorial Stack 15. PlaySoundEffects , ClearActiveSoundPlayers, OptionsApplies, OptonsGrouSetup, InitFiles
Part 24. Tutorial Stack 16. Updates & Improvements
Part 24b. Tutorial Stack 16, Handlers for graphics, effects, & more interesting enemies
Part 25. Tutorial Stack 17: More Efficient Collisions, Warp sounds, and other stuff
Part 26. Tutorial Stack 18. Enemy Decorations. Less Player Objects. Touch up on collisions, and more
Part 27. Tutorial Stack 19: RandomizeEnemies, sound bug fix,
Last edited by xAction on Wed Nov 24, 2021 9:22 pm, edited 25 times in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Sun Oct 03, 2021 6:10 am

PART 1
Okay the first thing our game needs, is some local variables that will be passed around the script without relying on the customProperties, which I started out using out of habit but I'm 98% certain that slowed things down at least 30%.

So for this game, and probably any spaceshippy type game the local/global variables are as follows,(with extra commenting to explain why they are needed). I'll spread the variables out into multi-line for forum readability, but they are generaly grouped in the script "local a=1,b=2,c="three"" etc
I'm placing this text without forum "code" mark up so I can bold the variable names.

Code: Select all

---------- BEGIN CODE ----------
-- booleans
local cheatMode = false -- the enemies kill the developer before they can test various game bits, unless you turn on the cheat
local playerCrash = false -- an "ENUM", ie 3 states, true, null, false. It is the state of our player, "null" while the destruction animation plays
local warpActivated = false -- enables the fancy sci-fi warp gate animation
local inProgress = false --tells the card script if we've completed InitGame and run PlayGame yet.

-- integers (ints)
local score = 0

-- player ship variables
local playerLives = 3
local playerDirAngle = 0 -- player is a "regular" graphic object with 3 sides, Angle 0 faces right, 180 faces left
local playerMoveDir = 0 -- player heading up (-1) or down (1)
local speedMult = 2 -- multipy the base movement speed when mouse is outside a rectanle the surrounds the player

-- "players" for playing music
local delayCheck = 0 --if the currentTime of the current player is the same for 100 of this, then change songs
local currentPlayer = 1 -- there are 8 player objects, one for each music file, loading music during game causes delay, so preload
local songCount = 1 -- the total number of songs found in the music folder at init time
local lastTime =- 1 -- the currentTime of the player object the last time it was checked, testing to see if we've reached end of song

-- parallax scrolling variables
local cycleDelay = 1 -- probably don't need a variable anything other than one 1 is jerky, but I tried to find alternative values with this
local lastParallax = 0 -- either 0 or 1, every other iteration the far background of the scene scrolls 1 hScroll unit

-- projectiles
local missileDelay = 0 -- either 1 or 0, every other iteration of the fire missile command a missile is launched,
local lastMissile = 0, -- the last missile of 20 that the player fired

-- game timing
local timeOfInit = 0 -- 'the seconds' when the Init handler was run
local timePassed = 0 -- the current seconds subtracted from timeOfInit
local timeLevel = 0 -- (timePassed/60)+2 ; 2 enemies at start then an additional enemy on screen (up to 10) every minute

-- integer item list
local lastRect = "200,200,1210,800"-- smallish game window dimensions; had issues with groups freaking out on resize of stack
local stackSize ="0,0" -- the height and width of the stack window, half these values is Center Screen

-- string single word
local flyDir = "right" -- direction player is flying, landscape scrolls opposite direction

-- string lists
local activeEnemies = empty -- a list of active enemies, iterate through this to check collisions, and fire bullets
local activeBullets = empty -- a list of active Enemy Bullets, use this to check player collision with bullets

-- colors -- used when generating objects via script
local colorList = "BlueViolet,Violet,PaleVioletRed,Red,OrangeRed,Orange,Yellow,LimeGreen,Green,Cyan,CornflowerBlue,Blue,Purple,Magenta,SpringGreen,Pink, HotPink,Lavender,SkyBlue,White"

-- set some directory globals
global gStackDirectory -- the folder path to our stack, without the filename
global gSoundDirectory -- the folder path to the sounds folder

Code: Select all

---------- END CODE ----------


Ok next up some starter Stack level functons.
Last edited by xAction on Fri Oct 29, 2021 3:13 am, edited 1 time in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Sun Oct 03, 2021 7:07 am

Before we go into the functions let me explain the folder structure of the game
SMHUPTUTORIAL_FOLDERSTRUCTUREpng.png
StackDirectory Livecode_Stack or Game exe or app & Data folder live here
. . . Data/ Keep things tidy
. . . . . . Sounds/ pew pew noises
. . . . . . Music/ Theme song, etc

The following aren't used in this example game but in other games the Data folder might contain:
. . . . . . CSV/ <--- Comma Separated Values for text based modification of game elements, we might use this
. . . . . . Fonts/
. . . . . . Icons/
. . . . . . Images/
. . . . . . Models/
. . . . . . Preferences/
. . . . . . Stacks/
. . . . . . Scripts/
. . . . . . Text/

Okay onto those functions and handlers then.
Last edited by xAction on Fri Oct 08, 2021 11:32 pm, edited 1 time in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Sun Oct 03, 2021 7:42 am

Part 2: Directory & Dimensions Functions & a starter stack

I tend to use the directory functions more than the globals that they set, I have little faith in variables.

Ouch a single forum code box is horrendous for tutorials, I'll break it up, easy copy/paste be damned.

Assume all the local and global variables described previously are ahead of the following code in the script of the Stack
StackDirectory

Code: Select all

-- // the folder path to the location of the stack file
function StackDirectory
   put word 2 the long name of stack (the mainStack of this stack) into myStack
   replace quote with empty in myStack
   set itemDel to "/" 
   put item 1 to -2 of myStack into gStackDirectory
   return gStackDirectory
end StackDirectory
SoundDirectory

Code: Select all

-- // the folder path to the location of the sounds folder
function SoundDirectory
   put word 2 the long name of stack (the mainStack of this stack) into myStack
   replace quote with empty in myStack
   set itemDel to "/" 
   put item 1 to -2 of myStack & "/Data/Sounds" into gSoundDirectory
   return gSoundDirectory
end SoundDirectory
preOpenStack

Code: Select all

-- // set the  directory globals and go to the Title card
on preOpenStack
   set the name of card 1 of stack(the mainStack of this stack) to "Title"
   put StackDirectory() into gStackDirectory
   put SoundDirectory() into gSoundDirectory
   go card "Title"
end preOpenStack
StackDepth

Code: Select all

-- // the height and width of the stack window
function StackDepth
   put the width of stack (the mainStack of this stack) into H
   put the height of stack (the mainStack of this stack) into W
   put H & comma & W into stackSize
   return stackSize
end StackDepth
CenterScreen

Code: Select all

-- // the center x,y coordinates inside the stack window
function CenterScreen XY
   put StackDepth() into HW
   put floor(item 1 of HW/2) & comma & floor(item 2 of HW/2) into screenCenter
   if XY is "x" then return floor(item 1 of HW/2)
   if XY is "y" then return floor(item 2 of HW/2)
   return screenCenter
end CenterScreen
LoadingScreen

Code: Select all

-- // a simple loading screen show with message "show" or hide by default
on LoadingScreen S
   if S is "show" then
      put stackDepth() into HW
      put "0,0,"   & HW into stackRect 
      set the rect of graphic "loading" to stackRect
   else
      set the loc of graphic "loading" to -1200,-1200
   end if
end LoadingScreen
createLoadingScreen

Code: Select all

-- // not pretty but simple loading screen graphic, there when you need it
on createLoadingScreen
   create graphic
   set the style of the last graphic to rectangle
   set the backgroundColor of the last graphic to 0,0,0
   set the foregroundColor of the last graphic to 0,255,0
   set the textSize of the last graphic to ""
   set the name of the last graphic to "LOADING"
   set the textStyle of the last graphic to "Bold"
   set the textSize of the last graphic to 38
   set the opaque of the last graphic to true
   set the showName of the last graphic to true
end createLoadingScreen
ShmupStack01Preview.png
Tutorial Stack 01:
ShmupStack01Preview.png (9.81 KiB) Viewed 8497 times
SHMUP_GAME_TUTORIAL_STACK01.zip
Simple stack with local variables and basic utility functions to get started.
(2.42 KiB) Downloaded 175 times
Last edited by xAction on Tue Oct 05, 2021 10:36 am, edited 6 times in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Sun Oct 03, 2021 9:14 am

Part 3: TITLE Screen Card Script

FORUM PITA: You can’t post image, email or url links that are external to this domain. Please remove GameStart.
Can't use filenames in the text of this forum? Script adapted for this tragedy

Now that we have the basic file directory functions working we can make a card script for the Title screen card.

Changes to this stack are as follows:
  1. added the card script
  2. added the "ThemeSong" player object
  3. added an 'edit card script' button
  4. set the stack backgroundColor to black
  5. added Outer Glow to text fields
  6. added Outer Glow & Color Overlay To Play Button
  7. added script to Play Button
  8. grouped Title,Play,Instructions elements into group called "Title"
  9. changed the stack dimensions to loosely represent standard screen ratio
  10. added card "Play" to the stack.
  11. added "changes_log" custom property to the stack for lists like this

ThemeSong player object gets shoved off screen by the ThemSong handler.
I commented that part out so you can see the thing in this example.

------------------The Script of Card "Title" of a SHMUP game:------------------
openCard

Code: Select all

-- // When the card opens, enter "browse" mode, run CardIdle & Theme Song Handlers, create loading graphic
on openCard
   set the tool to "browse tool"
   if the currentCard of this stack is  "Title" then 
      put false into inProgress -- that unused variable
      if exists(graphic "Loading") is false then  createLoadingScreen 
      LoadingScreen -- hide that thing we just might have made
      Cardidle
      ThemeSong
   end if
end openCard
resetCard

Code: Select all

-- // while doing developer work get test openCard message without changing cards
on resetCard
   openCard
end resetCard
ThemeSong

Code: Select all

-- // Look in the Music folder and load the song with 'theme' in the name
on ThemeSong
   put the folder into oldFolder
   put  stackDirectory() &"/Data/Music/" into tFolder
   set the folder to tFolder
   put files() into mFiles
   -- // might have some licenses in there
   filter Mfiles without "*txt"   
   -- //  use "theme" in a song name to use in game
   filter mFiles with "*theme*"  
   if mFiles is not empty then
      put number of lines of mFiles into FN
      -- // prevent game song fatigue with random
      put line random(FN) of mFiles into theSong  
      --set the loc of player "themeSong" to -100,-100
      set the filename of player "themeSong" to tFolder &"/" & theSong 
      set the currentTime of player "themeSong" to 0
      set the playLoudness of player "themeSong" to 75
      start player "themeSong"
   end if
end ThemeSong
Cardidle

Code: Select all

[code]-- // loops to animate text effects &  keep Title group centered if we change stack size
on Cardidle
   lock screen
   set the loc of group "Title" of card "Title" to CenterScreen()
   unlock screen
   if the tool is not "browse tool" then exit Cardidle
   if the currentCard of this stack is not "Title" then exit Cardidle
   TitleGlow
   send Cardidle to this card in 100 milliseconds
end Cardidle
[/code]
TitleGlow

Code: Select all

-- // throbbing color changing text effects
on TitleGlow
   put the glowInc of field "Title" into gInc
   put the outerGlow["size"] of field "Title" into ogS
   add gInc to ogs
   if ogs > 35 then put -2 into gInc
   if ogs <22 then put 2 into gInc
   set the outerGlow["size"] of field "Title" to ogs
   set the glowInc of field "Title" to gInc
   put the outerGlow["color"] of field "Title" into rgb
   add random(4)*ginc to item 1 of rgb
   add random(4)*ginc to item 2 of rgb
   add random(4)*ginc to item 3 of rgb
   set the outerGlow["color"] of field "Title" to rgb
end TitleGlow
PlayButtonPressed

Code: Select all

-- //  play a response sound to button press, show the loading screen ,  switch to card "Play"
on PlayButtonPressed
   if exists(graphic "Loading") is false then
      send createLoadingScreen to stack (the mainStack of this stack)  in 0  milliseconds
   end if
   LoadingScreen "show"
   wait for 1 seconds
   stop player "themeSong"
   play SoundDirectory() &"/" & "GameStart" & "." & "wav"  <-- ridiculous
   go card "Play"
end PlayButtonPressed
------------- END "TITLE" CARD SCRIPT -------------

------------------The Script of button "PLAY" of Card "Title"------------------
mouseEnter

Code: Select all

--// increase glow when MouseEnters
on mouseEnter
   set the outerGlow["spread"] of me to 90
end mouseEnter
[b]mouseLeave[/b]
--// decrease glow when mouse leaves
on mouseLeave
   set the outerGlow["spread"] of me to 55
end mouseLeave
[b]mouseDown[/b]
--// send PlayButtonPresssed to script of Card "Title"
on mouseDown
 PlayButtonPressed
end mouseDown
SHMUP_GAME_TUTORIAL_STACK02.zip
Shmup game tutorial stack 02, title screen, player object, card "play"
(3.56 KiB) Downloaded 176 times
Sounds.zip
Shmup game sounds, place Sounds folder in a Data folder in same directory as stack
(181.39 KiB) Downloaded 169 times
Music.zip
Shmup game theme song mp3, place Music folder in Data folder in same folder as stack
(130.58 KiB) Downloaded 169 times
Can't upload the whole bundle as one file so:
Just to clarify your folder should look something like:
Tutorial Stack Folder/
Tutorial_Stack_02.livecode
. . . . . Data/
. . . . . . . . Music/
. . . . . . . . Sounds/
Last edited by xAction on Tue Oct 05, 2021 11:31 am, edited 4 times in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Sun Oct 03, 2021 10:48 am

Part 4: Mountain Making Scripts
ShmupStack03Previewpng.png
On the card "Play" we're going to build scenic mountains to create the illusion of flight
We'll add the handler for this to the stack script.
We'll also add an init handler that calls the mountain creation, some other parts of the init sequence are commented out for now.

Changes to this stack:
  1. Added InitForeground, InitMountains & ResetForegroundGroup handlers to stack script
  2. Added Make Mountain button to test the Init
  3. Added Test Flight button to test the mountain scrolling
Steps of mountain script:
  1. draw a line from left to right
  2. jut forward randomly
  3. go up and down randomly
  4. give a retro vector graphics glow
  5. set the center x of the graphic to the center of the stack
  6. set the bottom of the graphic to the bottom of the stack
  7. group it
  8. set the group width to the stack width
  9. clean up the various stack properties
  10. set the group horizontal scroll to the center of our mountain graphic
InitForeground

Code: Select all

--// initialize game element setup
on InitForeground
   -- clear out previous mountains and group
   if exists(graphic "mountains") then delete graphic "Mountains"
   if exists(group "MGroup") then delete group "Mgroup"
   -- create a dummy group because some weird stuff happens otherwise
   create group
   set the name of it to "dummy"
   -- create the mountain foreground
   InitMountains
   set the name of the last graphic to "mountains"
   group graphic "mountains"  
   set the name of the last group to "MGroup"
   put the loc of graphic "mountains" into mLoc
   -- InitWarpPoints  --<<< in upcoming  tutorial step
   -- set up scrolling group for landscape
   ResetForegroundGroup
   delete group "dummy"
end InitForeground
InitMountains

Code: Select all

--// create a vector graphic mountain range
on InitMountains 
   repeat with c = 1 to 200
      put random(50)+random(100)into nextX
      add nextX to x
      put random(20)- random(100) into y
      put  x,y & cr after tPoints
   end repeat
   put line -1 of tPoints  after tPoints
   create graphic
   set the style of the last graphic to "line"
   set the points of the last graphic to tPoints
   put random(128)+128 into mColor
   set the foregroundColor of the last graphic to mColor,255,0
   set the outerGlow of the last graphic to true
   set the outerGlow["color"] of the last graphic to mColor,255,0
   set the outerGlow["size"] of the last graphic to 15
   set the outerGlow["spread"] of the last graphic to 63
   set the loc of the last graphic to CenterScreen()
   set the bottom of the last graphic to item 2 of StackDepth()
end InitMountains
ResetForegroundGroup

Code: Select all

--// since we delete the group when reinitializing the mountain, get the group back into shape
on ResetForegroundGroup
   set the width of group "MGroup" to item 1 of StackDepth()
   set the lockLoc of group "Mgroup" to true
   set the hScrollbar of group "MGroup" to true
   set the scrollBarwidth of group "Mgroup" to 0
   put the width of graphic "mountains" into hW
   set the hScroll of group "MGroup" to hW/2
   set the radioBehavior of group "MGroup" to false
   set the traversalOn of group "Mgroup" to false
   set the threeD of group "Mgroup" to false
end ResetForegroundGroup
mouseWithin
--- Script of "Test Flight" button ---

Code: Select all

-- // scroll the mountain left or right depending on  which side of the button the mouse is on
on mouseWithin
   if the mouseloc < item 1 of the loc of me then
      put -4 into tDir
   else
      put 4 into tDir
   end if
   put the hScroll of group "Mgroup" into mScr
   add tDir to mScr
   set the hScroll of group "Mgroup" to mScr
end mouseWithin
Note the mountain scroll is pretty janky, the polling time of "mouseWithin" isn't the speediest.
SHMUP_GAME_TUTORIAL_STACK03.zip
Shmup Tutorial Stack 03, make mountains and scroll 'em
(5.39 KiB) Downloaded 159 times
Get music and sounds in the post above this one, if you haven't already
Last edited by xAction on Tue Oct 05, 2021 11:22 am, edited 3 times in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Sun Oct 03, 2021 12:29 pm

Part 5. Warp
ShmupStack04Preview.png
Shmup Stack 04 preview
SHMUP_WARP_REWORKED_STACK04b.zip
REUPLOAD Oct.08.2021 Group scripts removed, ChecKWarp and InitWarpPoints in line with Stack 11
(7.52 KiB) Downloaded 163 times
Eventually we'll reach the end of the horizontal scroll of the mountain group, with the warp we'll pop back to the center.
My super sci-fi animation warp script stalled the game a bunch, I'll simplify the warp here to just fade in/out
The warp group is larger than the warp so we can reveal the warp by entering the rect of the group before we reach the actual gate.

ATTENTION:
I Reworked the warps later in development, see this post!
Okay this part of the tutorial has relevant changes that coincide with later parts of the tutorial.
The lagging graphic effects are left on in this stack because not much is going on and the slowdown that happens doesnt interfere with any gameplay.

To make the warp graphic:
  1. Drag an Oval graphic into the stack,
  2. Make it almost as tall as the stack, other wise the player can fly right past it.
  3. Decrease the width to create a false perspective
  4. Set the line size high
  5. Set the dashes to 1to create a moire effect
  6. Add dropShadow, innerShadow, outerGlow, innerGlow to achieve glowing sci-fi effect
  7. Drag a rectangel graphic into the stack, call it "WarpFrame"
  8. Disable its opaque property, scale it to the full size of the stack.
  9. Give the box a foreground color and set alphablend to 50 while you are working on the game,
  10. Select the WarpBox and the WarpGate graphic and group them
  11. Call the group "WarpPointSource"
  12. Add the InitWarpPoints, Warpjump, CheckWarp, FadeWarpPoint handlers to the stack script
Add InitWarpPoints handler to Stack Script, this is called at start of game to copy the gate into the foreground group where it is placed at each far end of the mountains/ ends of the horizontal scroll of the group.

InitWarpPoints

Code: Select all

--// copy group "WarpPointSource" to create "WarpPointLeft" & "WarpPointRight", place into group "MGroup" and set to closed state
--// copy group "WarpPointSource" to create "WarpPointLeft" & "WarpPointRight", place into group "MGroup" and set to closed state
on InitWarpPoints
   -- WARP POINTS
   lock screen
   show group "WarpPointSource"
   set the blendLevel of group "WarpPointSource" to 0
   --// fix the warp size for the stack size
   put stackDepth() into HW
   put item 2 of HW into SH
   put item 1 of HW into SW
   set the width of graphic "WarpFrame" to SH +200
   set the height of graphic WarpFrame to SW
   set the height of graphic "WarpGate" to SH-200
   set the loc of graphic "WarpFrame" to CenterScreen()
   set the loc of graphic "WarpGate" to CenterScreen()
   set the rect of group "WarpPointSource" to the rect of graphic "WarpFrame"
   set the locklock of group "WarpPointSource" to true
   --// copy the warp template into "Mgroup"
   copy group "WarpPointSource" to group "mGroup"
   set the name of the last group of group "MGroup" to "WarpPointLeft"
   copy group "WarpPointSource" to group "mGroup"
   set the name of the last group of group "MGroup" to "WarpPointRight"
   --// position the foreground landscape
   put "0,0," & HW into stackRect
   set the rect of group "mGroup" to stackRect
   set the lockLoc of group "mGroup" to true
   --// center the main mountains based on our screen based rectangle
   set the loc of graphic "mountains" to item 1 of CenterScreen(), SH-Height of graphic "Mountains"/2
   --// position the warp points
   put the points of graphic "mountains" into tPoints
   put item 1 of line 20 of tPoints into LeftWarpX
   put item 1 of line -20 of tPoints into RightWarpX
   --// place the warps at either far end of the mountains
   set the loc of group "WarpPointLeft" to LeftWarpX,SH/2
   set the loc of group "WarpPointRight" to RightWarpX,SH/2
   show group "WarpPointLeft"
   show group "WarpPointRight"
   --// put warps into closed state
   set the blendLevel of Group "WarpPointLeft" to 0
   set the blendLevel of Group  "WarpPointRight"  to 0
   set the lineSize of graphic "WarpGate"of group "WarpPointLeft" to 0
   set the lineSize of graphic "WarpGate"of group "WarpPointRight" to 0
   --// hide the original warpoints group, used  later as warp exit point
   hide group "WarpPointSource"
end InitWarpPoints
Add three more handlers for this to all work correctly.

Add the WarpJump handler to the stack script
We haven't created the background group "Backgroup" yet, so that's commented out for now
Oh and there's a HideEnemies handler we don't need yet either, so that's commented out.
Hrmm I have two handlers for hiding the enemies, I'll haveto look into that.
There's also a call to hide the enemy bullets, but it never seems to work, commented out for now as well.
WarpJump

Code: Select all

-- // reset the Horizontal Scrolls of the landscape groups (Mgroup & Backgroup)
on WarpJump
   lock screen
   --stageEnemies
   --stageBullets
   put the height of stack (the mainStack of this stack) into howHi
   put the loc of graphic "Player" into pxy
   set the loc of group "WarpPointSource" to item 1 of pxy,howHi/2
   --put the width of graphic "background" into bhW
   --set the hScroll of group "backgroup" to bhW/2
   --set the vScroll of group "Backgroup" to 152
   put the width of graphic "mountains" into hW
   set the hScroll of group "MGroup" to hW/2
   set the blendLevel of group "WarpPointSource" to 0
   show group "WarpPointSource"
   unlock screen
   send fadeWarpPoint to stack (the mainStack of this stack) in 7 milliseconds
end WarpJump
FadeWarpPoint

Code: Select all

--// fade group "WarpPointSource" and push it away from the player after the jump
on FadeWarpPoint
   if flyDir is "left" then put 10 into tMov
   if flyDir is "right" then put -10 into tMov
   put the blendLevel of group "WarpPointSource" into BL
   if BL < 100 then 
      add 5 to BL
      set the blendLevel of group "WarpPointSource" to BL
      put the loc of group "WarpPointSource" into WPLoc
      add tMov to item 1 of WPLoc
      set the loc of group "WarpPointSource" to WPLoc
   else
      hide group "WarpPointSource"
   end if
   if the visible of group "WarpPointSource" then send fadeWarpPoint to stack (the mainStack of this stack) in 2 milliseconds
end FadeWarpPoint
CheckWarp

Code: Select all

--// test if player is within the rect of the warp groups, and activate/deactive the warp if necessary
on CheckWarp
   put the loc of graphic "Player" into playerXY
   put false into warpActivated
   --put  rect of group "WarpPointLeft"  into WPLRect
   --put the rect of group "WarpPointRight"  into WPRRect
   --// if we have warped, fade the warp object
   if the visible of group "WarpPointSource" then
      put true into warpActivated
      fadeWarpPoint
   end if
   --// left warp
   if item 1 of playerXY < the right of group "WarpPointLeft" then 
      set the lineSize of graphic "WarpGate" of group "WarpPointLeft" to (abs(item 1 of playerXY -the right of group "WarpPointLeft"))/10
      if  item 1 of playerXY < item 1 of the loc of group "WarpPointLeft"  then WarpJump 
      put true into warpActivated
   end if
   --// right warp
   if item 1 of playerXY > the left of group "WarpPointRight" then 
      set the lineSize of graphic "WarpGate" of group "WarpPointRight" to (abs(item 1 of playerXY -the left of group "WarpPointRight"))/12
      if  item 1 of playerXY > item 1 of the loc of group "WarpPointRight" then WarpJump 
      put true into warpActivated
   end if
end CheckWarp
Now to see about fixing this stack
Okay Warp points are made, but now we have to fly to them!
Last edited by xAction on Sat Oct 09, 2021 11:53 am, edited 21 times in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Sun Oct 03, 2021 1:46 pm

Part 6. Player Graphic and Flight Test
It's going to be difficult to test the warp without some additonal elements:

Create the player:
  1. Drag a "regular" style Graphic onto the stack and call it "Player"
  2. Set its lineSize to 2
  3. Set it's polySides to 3
  4. Dab some outerGlow and InnerGlow on it for effect
  5. Place it in the middle of the stack
  6. For now set the size to 36 x 36

Add the ScrollLandScape handler to the stack, note the parrallax scrolling of the background is commented out for now. I tried that in a separate handler at first but got stuttered results, we'll try again when we make the background.

Oh the script calls for a graphic "sMultBox" ie, Speed Multiplier Box, which surrounds the player, if the mouse is outside of the box scrolling increases on account of the speedMult variable.
Lets make that happen by dragging a rectangle graphic into the scene and naming it sMultBox
Turn it's Opaque property off, give it a colored outline for now so you don't lose it at this stage of development. Its location will be controlled by scripts later.

Add ScrollLandScape to stack script

Code: Select all

--// scroll the landscape in the opposite direction that our ship is facing
on ScrollLandScape 
   if the mouseLoc is not within the rect of graphic "sMultBox" then 
      put 6 into speedMult
   else
      put 3 into speedMult
   end if
   put the hScroll of group "Mgroup" into hScr
   if flyDir is "right" then add 1*speedMult to hScr
   if flyDir is "left" then add -1*speedMult to hScr
   set the hScroll of group "Mgroup" to hScr
 -- parallax background moves every other cycle
--   put 1 into cycleDelay
-- if lastParallax < cycleDelay then 
--  add 1 to lastParallax
-- else
--      put 0 into lastParallax
--     put the hscroll of group "Backgroup" into pHS
--    if flyDir is "right" then add 1 to pHS
--      if flyDir is "left" then add -1 to pHS
--      set the hscroll of group "BackGroup" to pHS
--   end if
end ScrollLandScape
I've modfied the flying test button from the last example, called it "Flight Test"
it will activate the FlightTest handler that we'll add temporarily to the Stack script.
The handler will run as long as the mouse is within the rect of the Flight Test button.
It will set the angle/direction of the player ship, set the flyDir variable and trigger the ScrollLandscape handler.
The FlightTest handler will also call the CheckWarp handler to see if the player object has entered the rect of a WarpPoint____ group and send the group a message to activate and open the warp if that has occured.

Add FlightTest to stack script

Code: Select all

-- //  scroll the landscape while mouse is within the button rect, test for player to warp
on FlightTest
   put the loc of button "Flight Test" into tLoc
   if item 1 of the mouseloc < item 1 of  tLoc  then
      put "left" into flyDir
      set the angle of graphic "Player" to 180
   else
      put "right" into flyDir
      set the angle of graphic "Player" to 0
   end if
   CheckWarp
   ScrollLandScape
   if the mouseloc is within the rect of button "Flight Test" then send  FlightTest to stack (the mainStack of this stack) in 2 milliseconds
end FlightTest
Add CheckWarpto stack script

Code: Select all

--// test if player is within the rect of the warp groups, and activate/deactive the warp if necessary
on CheckWarp
   put the loc of graphic "Player" into pXY
   put  rect of group "WarpPointLeft"  into WPLRect
   put the rect of group "WarpPointRight"  into WPRRect
   if pXY is within WPLRect or pXY is within WPRRect then
      if warpActivated is false then
         put true into warpActivated
         if pXY is within WPLRect then send activateWarp to group "WarpPointLeft" in 0 milliseconds
         if pXY is within WPRRect then send activateWarp to group "WarpPointRight" in 0 milliseconds
      end if
   else
      put false into warpActivated
   end if
end CheckWarp
A quick review of what's changed in this stack in Steps 5 & 6:
Tutorial Stack 04
  • 1. Added WarpPointSource graphics, Group and Group Script
    2. Added InitWarp, WarpJump, FadeWarp handlers to main stack
    3. Added graphic "Player"
    4. Added graphic "sMultBox"
    5. Added FlightTest & CheckWarp handlers to stack
    6.Changed "Test Flight" button to "Flight Test" Inits FlightTest handler
    7. Changed "Make Mountains" button to "Init Foreground"
See step 5 for stack download.
Last edited by xAction on Tue Oct 05, 2021 11:41 am, edited 2 times in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Sun Oct 03, 2021 3:56 pm

Step 7. Play Game Loop & Move Player Handler

We are using the mouse to control the player because I got horrible results with the keyboard, ie, the keyboard didn't respond while "send someHandler in x milliseconds" was used and then the keyboard buffered 128 characters or something while not responding.

So, because we use the mouse to guide the player if the player object is on the mouse xy coordiates, it spazzes out trying move 1 pixel and stay on the spot. To calm the player graphic down we add some boxes to the screen that follow the player and if the mouse is not outside of those boxes, the player won't react.

The boxes are called "MouseLocTargetV" and "MouseLocTargetH" and maybe we can just use virtual version from variables representing big boxes?

Code: Select all

 put the loc of graphic "Player" into pXY
   put   item 1 of pXY-10 ,0 , item 1 of PXy+10, item 2 of StackDepth()  into MouseLocTargetV
   put  0, item 2 of pXY-10, item 1 of StackDepth(), item 2 of pXY+10 into MouseLocTargetH
We'll give it a shot.

Okay here I've updated the FlightTest handler to follow the player anywhere within the stack rect after you press the Flight Test button. The player moves up and down with angle changes according to the mouse position, you can see some freaky vibration occur because I haven't tested against the MouseLocTargetV or MouseLoceTargetH variables yet.

Code: Select all

-- //  scroll the landscape while mouse is within the screen rect, move player up and down, test for player to warp
on FlightTest
   put the loc of graphic "Player" into pXY
   put   item 1 of pXY-10 ,0 , item 1 of PXy+10, item 2 of StackDepth()  into MouseLocTargetV
   put  0, item 2 of pXY-10, item 1 of StackDepth(), item 2 of pXY+10 into MouseLocTargetH
   
   if item 1 of the mouseloc < item 1 of  CenterScreen()  then
      put "left" into flyDir
      put 180 into playerDirAngle 
   else
      put "right" into flyDir
      put 0 into playerDirAngle 
   end if
   
   -- up and down action
   if item 2 of the mouseLoc < item 2 of pXy then
      put -1 into playerMoveDir
      if flyDir is "left" then 
         add 10 to playerDirangle
      else
         subtract 10 from playerDirAngle
      end if
   end if
   
   if item 2 of the mouseLoc > item 2 of pXy then
      put 1 into playerMoveDir
      if flyDir is "left" then 
         subtract 10 from playerDirangle
      else
         add 10 to playerDirAngle
      end if
   end if
   
   add playerMoveDir to item 2 of pXY
   set the loc of graphic "Player" to pXY
   set the angle of graphic "Player" to playerDirAngle
   
   CheckWarp
   ScrollLandScape
   put "0,0," & StackDepth() into sRect
   if the mouseloc is within sRect  then send  FlightTest to stack (the mainStack of this stack) in 2 milliseconds
end FlightTest
SHMUP_GAME_TUTORIAL_STACK05.zip
SHMUP tutorial stack 05, player follows mouse, scenery scrolls, warps resets the hScroll.
(8.46 KiB) Downloaded 160 times
Last edited by xAction on Tue Oct 05, 2021 12:01 pm, edited 2 times in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Mon Oct 04, 2021 3:46 am

Part 8. PlayerMove & View Handlers
ShmupStack06Preview.png
Shmup Stack 06 preview
Changes made to stack #06
  • 1. Changed FlightTest handler to PlayerMove
    2. Removed Test Flight button
    3. Added script ot card "Play" to call InitForeground & PlayerMove on OpenCard
    4. Added virtual *Borders, and virtual mouseLocTargetH and imouselocTargetV variables to PlayerMove
    5. Added MouseEnter call to PlayerMove in card "Play" script
    6. Added temporary "MV","MH","PlayerStage" graphics to visualize the virtual elements of PlayerMove
    7. changed shorthand variables pXY in PlayerMove to playerXY
    8. used playerX and playerY variables instead of 'item 1 of" etc
    9. added View handler and "viewer" button for troubleshooting variables without sending to Message Box
    10. added graphic "PlayerHitBox" to detect collision later
First the View handler, sending to Message Box can be slow and sometimes I need to keep my eye on the game screen when I broke something. I think there's a better way of doing this, something about args?

Code: Select all

on View a,b,c,d
   put a,b,c,d into tViewed
   replace ",," with empty in tViewed
   set the label of button "viewer" to tViewed
end View
Ok PlayerMove handler, (previously FlightTest) got very long so I'm going to break it down in separate forum code boxes.
----------------------BEGIN PlayerMove Handler of Game Stack Script--------------------------

Code: Select all

-- //  scroll the landscape while mouse is within the button rect, move player, test for player to warp
on PlayerMove
   set itemDel to comma
   set the layer of graphic "Player" to top
   put the loc of graphic "Player" into playerXY
   set the loc of graphic "sMultBox" to playerXY
   put item 1 of playerXY into playerX
   put item 2 of playerXY into playerY

The borders represent the area the player is allowed to move on screen.
This looks really small at the moment, but expands as the stack rect expands, later.

Code: Select all

   put item 2 of StackDepth()-130 into bottomBorder
   put item 1 of CenterScreen()-100 into leftBorder
   put item 1 of CenterScreen()+100 into rightBorder
   --// temporarty graphic to illustrate the flyable area
   set the rect of graphic "playerStage" to leftBorder,75,rightBorder,bottomBorder

Code: Select all

--// virtual rectangles prevent the player from reacting if mouse is too close
   put   playerX-10 ,0, playerX+10, item 2 of StackDepth()  into mouseLocTargetV
   put  0, playerY-10, item 1 of StackDepth(), playerY+10 into mouseLocTargetH
--// temporary graphics to visualize the things
   set the rect of graphic "MH" to mouseLocTargetV
   set the rect of graphic "MV" to mouseLocTargetH
Player movement in X direction

Code: Select all

--// if the mouse is not too close to the player X modify the angle and X movement
   if the mouseLoc is not within MouseLocTargetV then 
      if item 1 of the mouseLoc < playerX then
         put -1 into pXM
         put 180  into playerDirAngle
         put "left" into flyDir 
      else
         put 1 into pXM
         put 0 into playerDirAngle
         put "right"into flyDir
      end if
   end if

Player speed control

Code: Select all

--// sMultBox is like a player speed control, mouse in the box = less thrust
   if the mouseLoc is within the rect of graphic "sMultBox" then 
      put 1 into speedMult
   else
      put 2 into speedmult
   end if
Player movement in Y direction

Code: Select all

--// up and down movement
   if item 2 of the mouseLoc+1 < playerY then 
      put -2 into playerMoveDir
   else
      put 2 into playerMoveDir
   end if
 --// mouseLoctargetH prevents the ship from jittering
   if  the mouseLoc is within mouseLocTargetH then put 0 into playerMoveDir
   
Apply intention to player X position, adjust for border limits

Code: Select all

  --// adjust player location intention
   add  pXM*speedMult  to playerX
  --// prevent going too far left or right on screen
   if  playerX  < LeftBorder then put LeftBorder into playerX
  --// prevent going too far right on screen
   if  playerX  > RightBorder then put RightBorder into playerX

Apply intention to player Y position, adjust for border limits

Code: Select all

  add playerMoveDir*speedMult to playerY
--// prevent going too high on screen
   if  playerY  < 75 then put 75 into playerY
--// prevent going too low on screen
   if  playerY  > bottomBorder then put bottomBorder into playerY

Move the graphic "player" and set the graphic Angle for course direction

Code: Select all

   -- // now move the player and adjust angles
   set the loc of graphic "Player" to playerX,playerY
   set the angle of graphic "Player" to playerDirAngle

Adjust the graphic angle to represent intent of altitude adjustment

Code: Select all

   --// change angle to match altitude intent
   if playerMoveDir <0 then set the angle of graphic "Player" to playerDirAngle-10
   if playerMoveDir >0  then set the angle of graphic "Player" to playerDirAngle+10

Needed an additional hitbox graphic tracking the player positon to detect collision, not sure why.

Code: Select all

   --// additional hitbox so we can detect crash with enemy
   set the loc of graphic "PlayerHitbox" to the loc of graphic "Player"

Finally Check for warps, scroll the landscape and refresh the handler if the mouse is still within the window

Code: Select all

   if exists (group "WarpPointLeft" ) then CheckWarp
   ScrollLandScape
   put "0,0," & StackDepth() into sRect
   if the mouseloc is within sRect  then send  PlayerMove to stack (the mainStack of this stack) in 2 milliseconds
end PlayerMove
----------------------END PlayerMove Handler of Game Stack Script-------------------------

Alrighty, that took hours because I broke things. It's all working now, stack is hideous with extraneous visible graphics, but at least you can tell what the hell is happening, if you sort the spaghetti.
Attachments
SHMUP_GAME_TUTORIAL_STACK06.zip
Illustrated MouseTargetLocV, MouseTargetLocH, sMultBox, PlayerHitbox,playerStage areas.
(9.66 KiB) Downloaded 155 times
Last edited by xAction on Tue Oct 05, 2021 12:12 pm, edited 4 times in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Mon Oct 04, 2021 3:58 am

Part 8b. PlayerMove handler, just one big post
I'll post the whole PlayerMove handler here in one code box in case you've come to copy/paste on the quick.

Code: Select all

-- //  scroll the landscape while mouse is within the button rect, test for player to warp
on PlayerMove
   set itemDel to comma
   set the layer of graphic "Player" to top
   put the loc of graphic "Player" into playerXY
   set the loc of graphic "sMultBox" to playerXY
   put item 1 of playerXY into playerX
   put item 2 of playerXY into playerY
   
   put item 2 of StackDepth()-130 into bottomBorder
   put item 1 of CenterScreen()-100 into leftBorder
   put item 1 of CenterScreen()+100 into rightBorder
   
   --// virtual rectangles prevent the player from reacting if mouse is too close
   put   playerX-10 ,0, playerX+10, item 2 of StackDepth()  into mouseLocTargetV
   put  0, playerY-10, item 1 of StackDepth(), playerY+10 into mouseLocTargetH
   --// temporary graphics to visualize the things
   set the rect of graphic "MH" to mouseLocTargetV
   set the rect of graphic "MV" to mouseLocTargetH
   set the rect of graphic "playerStage" to leftBorder,75,rightBorder,bottomBorder
   
   --// if the mouse is not too close to the player X modify the angle and X movement
   if the mouseLoc is not within MouseLocTargetV then 
      if item 1 of the mouseLoc < playerX then
         put -1 into pXM
         put 180  into playerDirAngle
         put "left" into flyDir 
      else
         put 1 into pXM
         put 0 into playerDirAngle
         put "right"into flyDir
      end if
   end if
   
   --// sMultBox is speed control, out of the box = more speed
   if the mouseLoc is within the rect of graphic "sMultBox" then 
      put 1 into speedMult
   else
      put 2 into speedmult
   end if
   --// up and down movement
   if item 2 of the mouseLoc+1 < playerY then 
      put -2 into playerMoveDir
   else
      put 2 into playerMoveDir
   end if
   
   --// mouseLoctargetH prevents the ship from jittering
   if  the mouseLoc is within mouseLocTargetH then put 0 into playerMoveDir
   
   --// adjust player location intention
   add  pXM*speedMult  to playerX
   --// prevent going too far left or right on screen
   if  playerX  < LeftBorder then put LeftBorder into playerX
   --// prevent going too low on screen
   if  playerX  > RightBorder then put RightBorder into playerX
   
   add playerMoveDir*speedMult to playerY
   --// prevent going too high on screen
   if  playerY  < 75 then put 75 into playerY
   --// prevent going too low on screen
   if  playerY  > bottomBorder then put bottomBorder into playerY
   
   -- // now move the player and adjust angles
   set the loc of graphic "Player" to playerX,playerY
   set the angle of graphic "Player" to playerDirAngle
   
   --// change angle to match altitude intent
   if playerMoveDir <0 then set the angle of graphic "Player" to playerDirAngle-10
   if playerMoveDir >0  then set the angle of graphic "Player" to playerDirAngle+10
   
   --// additional hitbox so we can detect crash with enemy
   set the loc of graphic "PlayerHitbox" to the loc of graphic "Player"
   
   if exists (group "WarpPointLeft" ) then CheckWarp
   ScrollLandScape
   put "0,0," & StackDepth() into sRect
   if the mouseloc is within sRect  then send  PlayerMove to stack (the mainStack of this stack) in 2 milliseconds
end PlayerMove
Last edited by xAction on Tue Oct 05, 2021 9:54 am, edited 1 time in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Mon Oct 04, 2021 7:08 am

Part 9. Missile Factory
MissileFactoryPreview.png
Now as my mother used to always say "It's time to make some missiles"
Before we throw all the missile magic into our game stack I've created a separate self contained stack for experimenting.
Elements of the Missile Factory stack:
graphic "Player" -- simple representation of a player ship
button "MissileStyle" -- choose the graphic style of the missiles
button "MissileScript" -- the script that each missile will contain is housed here
button "Edit Missile Script" -- open script editor to the script of button "MissileScript"
button "MakeMissiles" -- if missiles exist calls ClearMissiles Handler else calls MakeMissile Handler
button "StageMissiles" -- calls StageMissiles handler
button "GetMissiles" -- calls GetMissiles handler
button "FireMissiles" -- calls MouseFireMissiles handler

scrollbar "MissileSpeed" -- passes scrollbar value to updateMissileSpeed and calls MouseFireMissiles handler

Handlers of the Missile Factory not duplicated in the game stack
MouseFireMissiles --calls FireMissilehandler flips the graphic "Player" left and right
ClearMissiles -- deletes 20 graphics named "Missile" & a number

The Missile Handlers: of the game stack
-- which are duplicated in Missile Factory for function testing.
GetMissiles -- displays 20 missiles on the screen while also setting their script to the script of button "MissileScript"
StageMissiles -- hides 20 missiles offscreen while also setting their scripts to the script of button "MissileScript"
UpdateMissiles -- simply sets the scripts of 20 missiles to the script of button "MissileScript" without moving them around
FireMissile -- sends ActivateMissile to the script of objects named "Missile" & a number
updateMissileSpeed -- inserts the given value into the "local misssileSpeed = " line of the script of button "MissileScript", calls UpdateMissiles

The Script of Button "Missile Script" in 3 parts.

Local Variables:

Code: Select all

local missileDir = "right"
local activeRect = "0,0,900,900"  
local missileSpeed =6
local mxDir=0
Activation stage:

Code: Select all

on ActivateMissile pDir
   put pDir into missileDir
   put  "0,0," &  stackDepth() into activeRect
   put loc of graphic "player" into pXY
   set the loc of me to pXY
   send MissileFly to me in 0 milliseconds
end ActivateMissile
The missile flight

Code: Select all

on MissileFly
   if the tool is not "browse tool" then  exit MissileFly
   if the mouseLoc is not within the rect of this card then exit MissileFly
   if missileDir is "left" then put missileSpeed*-1 into mxDir
   if missileDir is "right" then put missileSpeed into mxDir
   put the loc of me into miXY
   add mxDir to item 1 of miXY
   set the loc of me to miXY
   if the loc of me is within activeRect then 
      send MissileFly to me in 2 milliseconds
   else
      set the loc of me to -2200,-2200
   end if
end MissileFly
Note the 'exits' in the flight handler as well as many places in my handlers. While testing scripts, Livecode can get locked up in these 'send to me in x milliseconds' commands without some way to escape them.

The idea behind the Missile Factory stack is you make your missiles, test your missiles, then you use button "Get Missiles" to get them all in one place on the screen, select the lot of them and then copy/paste into your game stack.
But you still need the most of the local variables and handlers in this stack to make them do anything.

These will of course be included in the Shmup Game Tutorial Stack that accompanies thist step. Once I can attach files.

You'll note the speed of the missiles is mind blowingly fast in the Missile Factory, that changes significantly when we are moving the player, scrolling the foreground and background, moving x enemies, who are firing a bunch of bullets and then the biggest slow down of all is the repeat loops that test for collision of up to or more than 40 objects on screen at a time. Maybe an updateMissileSpeed handler would be handy for faster iterations? Sure why not. Added to the list above.
MissileFactory.zip
SHMUP Game Missile Factory stack
(4.17 KiB) Downloaded 167 times
Last edited by xAction on Tue Oct 05, 2021 12:17 pm, edited 2 times in total.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Mon Oct 04, 2021 8:44 am

Part 10. SHMUP GAME TUTORIAL STACK 07
ShmupStack07Preview.png
SHMUP tutorial Stack 07 preview
Changes made to Tutorial Stack 7
1. added 20 graphics called "Missile" & a number
2. added Missile scripting handlers to stack script
3. created PlayTest handler, set card script to run it on OpenCard
4. added button "MissileScript" to stack
5. bumped the blendLevel of sMultBox & playerHitbox graphics
6. removed the "MH',"MV", and uh...border graphics
7. removed script lines of PlayerMove setting those graphics
8. placed PlayerMove, ScrollLandscape & FireMissile calls into PlayTest loop
9. found redundancy of sMult setting in PlayerMove handler and removed it
10. discovered crazy timing issue with FireMissile, moved the missileDelay to PlayTest Handler
11. moved check for WarpPointSource to trigger FadeWarpPoint into PlayTest, much faster
12. BUG: Experiencing weird speed issues, PC fan is running crazy. <<< was being probed by 8 IP addresses

Okay first of all the script of card "Play" looks like this now.

Code: Select all

on MouseEnter
   if the tool is "browse tool" then PlayTest
end MouseEnter

on OpenCard
   set the tool to "browse tool"
   set the loc of graphic "player" to CenterScreen()
   send InitForeground to stack (the mainStack of this stack) in 0 milliseconds
   send PlayTest to stack (the mainStack of this stack) in 6 seconds
end OpenCard
The six second delay to call PlayTest leaves InitForeground enough time to create the WarpPoints before PlayerMove goes looking for them. Later loading music files creates a delay for us.

PlayTest handler of the stack script looks like this:

Code: Select all

on PlayTest
   if the tool is not "browse tool" then exit PlayTest
   if the mouseloc is not within the rect of this card then exit PlayTest
   PlayerMove
   ScrollLandScape
   if the mouse is down then
      if missileDelay < 6 then 
         add 1 to missileDelay
      else
         put 0 into missileDelay
         send FireMissile to stack (the mainStack of this stack) in 0 milliseconds
      end if 
   end if
   if the visible of group "WarpPointSource" then send fadeWarpPoint to stack (the mainStack of this stack) in 2 milliseconds
   send PlayTest to stack (the mainStack of this stack) in 10 milliseconds
end PlayTest
Had wierdness calling FireMissile, where all the missiles stacked on the playerLoc until I let go of the mouse. I'm guessing the handler got called 20 plus times so fast all the missiles got sent to the player before they could escape the player. missileDelay check seems to help.

This post is already long so I'll review the Missile Scripts that are added to the main Stack in the next post.
SHMUP_GAME_TUTORIAL_STACK07.zip
SHMUP Tutorial stack 07 with mouse fired missiles.
(12 KiB) Downloaded 157 times
Last edited by xAction on Tue Oct 05, 2021 12:24 pm, edited 2 times in total.

stam
Posts: 2599
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by stam » Mon Oct 04, 2021 9:49 am

Dear xAction

Just FYI you can link to external domains and you can attach files (but they have to be zipped). You may not have been able to initially as i think you need to have posted at least 7 or 12 times, but you should be able to now.

I'm unclear if this is meant to be a tutorial, a question or just a running commentary of your effort - looks impressive but there's so much of it it's difficult to follow...

Would be really nice if you could post a (zipped) stack since you're so generously sharing!
S.

xAction
Posts: 86
Joined: Sun Oct 03, 2021 4:14 am

Re: LiveCode Game Tutorial: Side Scrolling Shoot'em'up

Post by xAction » Mon Oct 04, 2021 9:52 am

Part 10b. Review of Missile Script Handler of Game Stack

MakeMissiles

Code: Select all

--// create 20 graphic objects called missiles, copy script of button "MissileScript " into them
on MakeMissiles aName
   repeat with N = 1 to 20
      create graphic
      set  the loc of the last graphic to 100+(N*10),100
      set the style of the last graphic to "Rectangle"
      set the lineSize of the last graphic to 2
      set the width of the last graphic to 8
      set the height of the last graphic to 8
      put aName&"Script" into codeButtonName
      put the script of button codeButtonName into tScript
      set the script of the last graphic to tScript
      put item N of colorList into RGB
      set the foregroundColor of the last graphic to RGB
      set the outerGlow["color"] of the last graphic to RGB
      set the outerGlow["size"] of the last graphic to random(28)+20
      set the outerGlow["spread"] of the last graphic to random(28)+20
      put  aName &N into tName
      set the name of the last graphic to tName
   end repeat
   put 0 into lastMissile 
end MakeMissiles
StageMissiles

Code: Select all

--// hide 20 objects named "Missile"& a number off screen, copy 
on StageMissiles
   repeat with N = 1 to 20
      put quote & "Missile"&N & quote into tName
      put 500+(n*8) into x
      put "set the loc of the graphic" && tName && "to -2200,-2200" into tCom
      put tCom & cr after alCom
      do tCom
   end repeat
end StageMissiles
GetMissiles

Code: Select all

--// display 20 objects named "missile"& a number, set their scripsts to that of  button "MissileScript"
on GetMissiles
   repeat with N = 1 to 20
      put quote & "Missile"&N & quote into tName
      put the script of button "MissileScript" into tScript
      do "set the script of graphic" && tName && "to tScript"
      -- storing button script in stack for passing to objects without the button later
      set the MissileCode of stack (the mainStack of this stack) to tScript
      put 150+(N*10) into x
      put "set the loc of the graphic" && tName && "to x,100" into tCom
      put tCom & cr after alCom
      do tCom
   end repeat
end GetMissiles
ClearMissiles

Code: Select all

-- // delete objects named "Missile"& a number  from the stack
on ClearMissiles aName
   put the number of graphics of this stack into nG
   repeat with i = 1 to nG
      put the short name of graphic i of this stack & cr after grList
   end repeat
   filter grList without empty
   filter grList with aName&"*"
   repeat for each line M in grList
      delete graphic M of this stack
   end repeat
end ClearMissiles
FireMissile

Code: Select all

--// send ActivateMissile message to script of object called Missile & a number
on FireMissile 
   if playerCrash is true or playerCrash = "null" then exit fireMissile
   if lastMissile+1 > 20 then put 0 into lastMissile
   add 1 to lastMissile
   put quote & "Missile"&lastMissile & quote into nextMissile
   --if tDir is not empty then put tDir into flyDir
   put "send ActivateMissile &&" && quote& flyDir & quote &&"to graphic" && nextMissile &&"in 0 milliseconds" into tCom
   do tCom
   play soundDirectory() & "/" & "playerLaser00" & random(5) & ".wav"
end FireMissile
UpdateMissileSpeed

Code: Select all

--// insert value miSpeed into line "local missileSpeed =" of script of button "MissileScript", copy script to objects named "Missile" & a number
on UpdateMissileSpeed miSpeed
   put the script of button "MissileScript" into tScript
   put lineOffset("local missileSpeed",tScript) into N
   set itemDel to "="
   put miSpeed into item 2 of line N of tScript
   set the script of button "MissileScript" to tScript
   UpdateMissiles
end UpdateMissileSpeed
UpdateMissiles

Code: Select all

--// update the script of missile graphic objects without changing their positions
on UpdateMissiles
   repeat with N = 1 to 20
      put quote & "Missile"&N & quote into tName
      put the script of button "MissileScript" into tScript
      do "set the script of the graphic" && tName && "to tScript"
   end repeat
end UpdateMissiles
It all looks so easy from the other side of the screen. -- some User
Last edited by xAction on Tue Oct 05, 2021 9:58 am, edited 1 time in total.

Post Reply

Return to “Games”